Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
kernel
gcov
base.c
Go to the documentation of this file.
1
/*
2
* This code maintains a list of active profiling data structures.
3
*
4
* Copyright IBM Corp. 2009
5
* Author(s): Peter Oberparleiter <
[email protected]
>
6
*
7
* Uses gcc-internal data definitions.
8
* Based on the gcov-kernel patch by:
9
* Hubertus Franke <
[email protected]
>
10
* Nigel Hinds <
[email protected]
>
11
* Rajan Ravindran <
[email protected]
>
12
* Peter Oberparleiter <
[email protected]
>
13
* Paul Larson
14
*/
15
16
#define pr_fmt(fmt) "gcov: " fmt
17
18
#include <
linux/init.h
>
19
#include <linux/module.h>
20
#include <
linux/mutex.h
>
21
#include "
gcov.h
"
22
23
static
struct
gcov_info
*gcov_info_head;
24
static
int
gcov_events_enabled;
25
static
DEFINE_MUTEX
(gcov_lock);
26
27
/*
28
* __gcov_init is called by gcc-generated constructor code for each object
29
* file compiled with -fprofile-arcs.
30
*/
31
void
__gcov_init
(
struct
gcov_info
*
info
)
32
{
33
static
unsigned
int
gcov_version;
34
35
mutex_lock
(&gcov_lock);
36
if
(gcov_version == 0) {
37
gcov_version = info->
version
;
38
/*
39
* Printing gcc's version magic may prove useful for debugging
40
* incompatibility reports.
41
*/
42
pr_info
(
"version magic: 0x%x\n"
, gcov_version);
43
}
44
/*
45
* Add new profiling data structure to list and inform event
46
* listener.
47
*/
48
info->
next
= gcov_info_head;
49
gcov_info_head =
info
;
50
if
(gcov_events_enabled)
51
gcov_event
(
GCOV_ADD
, info);
52
mutex_unlock
(&gcov_lock);
53
}
54
EXPORT_SYMBOL
(
__gcov_init
);
55
56
/*
57
* These functions may be referenced by gcc-generated profiling code but serve
58
* no function for kernel profiling.
59
*/
60
void
__gcov_flush
(
void
)
61
{
62
/* Unused. */
63
}
64
EXPORT_SYMBOL
(
__gcov_flush
);
65
66
void
__gcov_merge_add
(
gcov_type
*counters,
unsigned
int
n_counters)
67
{
68
/* Unused. */
69
}
70
EXPORT_SYMBOL
(
__gcov_merge_add
);
71
72
void
__gcov_merge_single
(
gcov_type
*counters,
unsigned
int
n_counters)
73
{
74
/* Unused. */
75
}
76
EXPORT_SYMBOL
(
__gcov_merge_single
);
77
78
void
__gcov_merge_delta
(
gcov_type
*counters,
unsigned
int
n_counters)
79
{
80
/* Unused. */
81
}
82
EXPORT_SYMBOL
(
__gcov_merge_delta
);
83
92
void
gcov_enable_events
(
void
)
93
{
94
struct
gcov_info
*
info
;
95
96
mutex_lock
(&gcov_lock);
97
gcov_events_enabled = 1;
98
/* Perform event callback for previously registered entries. */
99
for
(info = gcov_info_head;
info
; info = info->
next
)
100
gcov_event
(
GCOV_ADD
, info);
101
mutex_unlock
(&gcov_lock);
102
}
103
104
#ifdef CONFIG_MODULES
105
static
inline
int
within(
void
*
addr
,
void
*
start
,
unsigned
long
size
)
106
{
107
return
((addr >= start) && (addr < start + size));
108
}
109
110
/* Update list and generate events when modules are unloaded. */
111
static
int
gcov_module_notifier(
struct
notifier_block
*nb,
unsigned
long
event
,
112
void
*
data
)
113
{
114
struct
module
*
mod
=
data
;
115
struct
gcov_info
*
info
;
116
struct
gcov_info
*
prev
;
117
118
if
(event != MODULE_STATE_GOING)
119
return
NOTIFY_OK;
120
mutex_lock
(&gcov_lock);
121
prev =
NULL
;
122
/* Remove entries located in module from linked list. */
123
for
(info = gcov_info_head;
info
; info = info->
next
) {
124
if
(within(info, mod->module_core, mod->core_size)) {
125
if
(prev)
126
prev->
next
= info->
next
;
127
else
128
gcov_info_head = info->
next
;
129
if
(gcov_events_enabled)
130
gcov_event
(
GCOV_REMOVE
, info);
131
}
else
132
prev =
info
;
133
}
134
mutex_unlock
(&gcov_lock);
135
136
return
NOTIFY_OK;
137
}
138
139
static
struct
notifier_block
gcov_nb = {
140
.
notifier_call
= gcov_module_notifier,
141
};
142
143
static
int
__init
gcov_init(
void
)
144
{
145
return
register_module_notifier
(&gcov_nb);
146
}
147
device_initcall
(gcov_init);
148
#endif
/* CONFIG_MODULES */
Generated on Thu Jan 10 2013 13:32:32 for Linux Kernel by
1.8.2