diff options
Diffstat (limited to 'kernel/trace/trace_probe.c')
-rw-r--r-- | kernel/trace/trace_probe.c | 65 |
1 files changed, 35 insertions, 30 deletions
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index 8364a421b4df..d4b9fc22cd27 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c | |||
@@ -37,13 +37,13 @@ const char *reserved_field_names[] = { | |||
37 | 37 | ||
38 | /* Printing in basic type function template */ | 38 | /* Printing in basic type function template */ |
39 | #define DEFINE_BASIC_PRINT_TYPE_FUNC(type, fmt) \ | 39 | #define DEFINE_BASIC_PRINT_TYPE_FUNC(type, fmt) \ |
40 | __kprobes int PRINT_TYPE_FUNC_NAME(type)(struct trace_seq *s, \ | 40 | int PRINT_TYPE_FUNC_NAME(type)(struct trace_seq *s, const char *name, \ |
41 | const char *name, \ | 41 | void *data, void *ent) \ |
42 | void *data, void *ent) \ | ||
43 | { \ | 42 | { \ |
44 | return trace_seq_printf(s, " %s=" fmt, name, *(type *)data); \ | 43 | return trace_seq_printf(s, " %s=" fmt, name, *(type *)data); \ |
45 | } \ | 44 | } \ |
46 | const char PRINT_TYPE_FMT_NAME(type)[] = fmt; | 45 | const char PRINT_TYPE_FMT_NAME(type)[] = fmt; \ |
46 | NOKPROBE_SYMBOL(PRINT_TYPE_FUNC_NAME(type)); | ||
47 | 47 | ||
48 | DEFINE_BASIC_PRINT_TYPE_FUNC(u8 , "0x%x") | 48 | DEFINE_BASIC_PRINT_TYPE_FUNC(u8 , "0x%x") |
49 | DEFINE_BASIC_PRINT_TYPE_FUNC(u16, "0x%x") | 49 | DEFINE_BASIC_PRINT_TYPE_FUNC(u16, "0x%x") |
@@ -55,9 +55,8 @@ DEFINE_BASIC_PRINT_TYPE_FUNC(s32, "%d") | |||
55 | DEFINE_BASIC_PRINT_TYPE_FUNC(s64, "%Ld") | 55 | DEFINE_BASIC_PRINT_TYPE_FUNC(s64, "%Ld") |
56 | 56 | ||
57 | /* Print type function for string type */ | 57 | /* Print type function for string type */ |
58 | __kprobes int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s, | 58 | int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s, const char *name, |
59 | const char *name, | 59 | void *data, void *ent) |
60 | void *data, void *ent) | ||
61 | { | 60 | { |
62 | int len = *(u32 *)data >> 16; | 61 | int len = *(u32 *)data >> 16; |
63 | 62 | ||
@@ -67,6 +66,7 @@ __kprobes int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s, | |||
67 | return trace_seq_printf(s, " %s=\"%s\"", name, | 66 | return trace_seq_printf(s, " %s=\"%s\"", name, |
68 | (const char *)get_loc_data(data, ent)); | 67 | (const char *)get_loc_data(data, ent)); |
69 | } | 68 | } |
69 | NOKPROBE_SYMBOL(PRINT_TYPE_FUNC_NAME(string)); | ||
70 | 70 | ||
71 | const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\""; | 71 | const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\""; |
72 | 72 | ||
@@ -81,23 +81,24 @@ const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\""; | |||
81 | 81 | ||
82 | /* Data fetch function templates */ | 82 | /* Data fetch function templates */ |
83 | #define DEFINE_FETCH_reg(type) \ | 83 | #define DEFINE_FETCH_reg(type) \ |
84 | __kprobes void FETCH_FUNC_NAME(reg, type)(struct pt_regs *regs, \ | 84 | void FETCH_FUNC_NAME(reg, type)(struct pt_regs *regs, void *offset, void *dest) \ |
85 | void *offset, void *dest) \ | ||
86 | { \ | 85 | { \ |
87 | *(type *)dest = (type)regs_get_register(regs, \ | 86 | *(type *)dest = (type)regs_get_register(regs, \ |
88 | (unsigned int)((unsigned long)offset)); \ | 87 | (unsigned int)((unsigned long)offset)); \ |
89 | } | 88 | } \ |
89 | NOKPROBE_SYMBOL(FETCH_FUNC_NAME(reg, type)); | ||
90 | DEFINE_BASIC_FETCH_FUNCS(reg) | 90 | DEFINE_BASIC_FETCH_FUNCS(reg) |
91 | /* No string on the register */ | 91 | /* No string on the register */ |
92 | #define fetch_reg_string NULL | 92 | #define fetch_reg_string NULL |
93 | #define fetch_reg_string_size NULL | 93 | #define fetch_reg_string_size NULL |
94 | 94 | ||
95 | #define DEFINE_FETCH_retval(type) \ | 95 | #define DEFINE_FETCH_retval(type) \ |
96 | __kprobes void FETCH_FUNC_NAME(retval, type)(struct pt_regs *regs, \ | 96 | void FETCH_FUNC_NAME(retval, type)(struct pt_regs *regs, \ |
97 | void *dummy, void *dest) \ | 97 | void *dummy, void *dest) \ |
98 | { \ | 98 | { \ |
99 | *(type *)dest = (type)regs_return_value(regs); \ | 99 | *(type *)dest = (type)regs_return_value(regs); \ |
100 | } | 100 | } \ |
101 | NOKPROBE_SYMBOL(FETCH_FUNC_NAME(retval, type)); | ||
101 | DEFINE_BASIC_FETCH_FUNCS(retval) | 102 | DEFINE_BASIC_FETCH_FUNCS(retval) |
102 | /* No string on the retval */ | 103 | /* No string on the retval */ |
103 | #define fetch_retval_string NULL | 104 | #define fetch_retval_string NULL |
@@ -112,8 +113,8 @@ struct deref_fetch_param { | |||
112 | }; | 113 | }; |
113 | 114 | ||
114 | #define DEFINE_FETCH_deref(type) \ | 115 | #define DEFINE_FETCH_deref(type) \ |
115 | __kprobes void FETCH_FUNC_NAME(deref, type)(struct pt_regs *regs, \ | 116 | void FETCH_FUNC_NAME(deref, type)(struct pt_regs *regs, \ |
116 | void *data, void *dest) \ | 117 | void *data, void *dest) \ |
117 | { \ | 118 | { \ |
118 | struct deref_fetch_param *dprm = data; \ | 119 | struct deref_fetch_param *dprm = data; \ |
119 | unsigned long addr; \ | 120 | unsigned long addr; \ |
@@ -123,12 +124,13 @@ __kprobes void FETCH_FUNC_NAME(deref, type)(struct pt_regs *regs, \ | |||
123 | dprm->fetch(regs, (void *)addr, dest); \ | 124 | dprm->fetch(regs, (void *)addr, dest); \ |
124 | } else \ | 125 | } else \ |
125 | *(type *)dest = 0; \ | 126 | *(type *)dest = 0; \ |
126 | } | 127 | } \ |
128 | NOKPROBE_SYMBOL(FETCH_FUNC_NAME(deref, type)); | ||
127 | DEFINE_BASIC_FETCH_FUNCS(deref) | 129 | DEFINE_BASIC_FETCH_FUNCS(deref) |
128 | DEFINE_FETCH_deref(string) | 130 | DEFINE_FETCH_deref(string) |
129 | 131 | ||
130 | __kprobes void FETCH_FUNC_NAME(deref, string_size)(struct pt_regs *regs, | 132 | void FETCH_FUNC_NAME(deref, string_size)(struct pt_regs *regs, |
131 | void *data, void *dest) | 133 | void *data, void *dest) |
132 | { | 134 | { |
133 | struct deref_fetch_param *dprm = data; | 135 | struct deref_fetch_param *dprm = data; |
134 | unsigned long addr; | 136 | unsigned long addr; |
@@ -140,16 +142,18 @@ __kprobes void FETCH_FUNC_NAME(deref, string_size)(struct pt_regs *regs, | |||
140 | } else | 142 | } else |
141 | *(string_size *)dest = 0; | 143 | *(string_size *)dest = 0; |
142 | } | 144 | } |
145 | NOKPROBE_SYMBOL(FETCH_FUNC_NAME(deref, string_size)); | ||
143 | 146 | ||
144 | static __kprobes void update_deref_fetch_param(struct deref_fetch_param *data) | 147 | static void update_deref_fetch_param(struct deref_fetch_param *data) |
145 | { | 148 | { |
146 | if (CHECK_FETCH_FUNCS(deref, data->orig.fn)) | 149 | if (CHECK_FETCH_FUNCS(deref, data->orig.fn)) |
147 | update_deref_fetch_param(data->orig.data); | 150 | update_deref_fetch_param(data->orig.data); |
148 | else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn)) | 151 | else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn)) |
149 | update_symbol_cache(data->orig.data); | 152 | update_symbol_cache(data->orig.data); |
150 | } | 153 | } |
154 | NOKPROBE_SYMBOL(update_deref_fetch_param); | ||
151 | 155 | ||
152 | static __kprobes void free_deref_fetch_param(struct deref_fetch_param *data) | 156 | static void free_deref_fetch_param(struct deref_fetch_param *data) |
153 | { | 157 | { |
154 | if (CHECK_FETCH_FUNCS(deref, data->orig.fn)) | 158 | if (CHECK_FETCH_FUNCS(deref, data->orig.fn)) |
155 | free_deref_fetch_param(data->orig.data); | 159 | free_deref_fetch_param(data->orig.data); |
@@ -157,6 +161,7 @@ static __kprobes void free_deref_fetch_param(struct deref_fetch_param *data) | |||
157 | free_symbol_cache(data->orig.data); | 161 | free_symbol_cache(data->orig.data); |
158 | kfree(data); | 162 | kfree(data); |
159 | } | 163 | } |
164 | NOKPROBE_SYMBOL(free_deref_fetch_param); | ||
160 | 165 | ||
161 | /* Bitfield fetch function */ | 166 | /* Bitfield fetch function */ |
162 | struct bitfield_fetch_param { | 167 | struct bitfield_fetch_param { |
@@ -166,8 +171,8 @@ struct bitfield_fetch_param { | |||
166 | }; | 171 | }; |
167 | 172 | ||
168 | #define DEFINE_FETCH_bitfield(type) \ | 173 | #define DEFINE_FETCH_bitfield(type) \ |
169 | __kprobes void FETCH_FUNC_NAME(bitfield, type)(struct pt_regs *regs, \ | 174 | void FETCH_FUNC_NAME(bitfield, type)(struct pt_regs *regs, \ |
170 | void *data, void *dest) \ | 175 | void *data, void *dest) \ |
171 | { \ | 176 | { \ |
172 | struct bitfield_fetch_param *bprm = data; \ | 177 | struct bitfield_fetch_param *bprm = data; \ |
173 | type buf = 0; \ | 178 | type buf = 0; \ |
@@ -177,13 +182,13 @@ __kprobes void FETCH_FUNC_NAME(bitfield, type)(struct pt_regs *regs, \ | |||
177 | buf >>= bprm->low_shift; \ | 182 | buf >>= bprm->low_shift; \ |
178 | } \ | 183 | } \ |
179 | *(type *)dest = buf; \ | 184 | *(type *)dest = buf; \ |
180 | } | 185 | } \ |
181 | 186 | NOKPROBE_SYMBOL(FETCH_FUNC_NAME(bitfield, type)); | |
182 | DEFINE_BASIC_FETCH_FUNCS(bitfield) | 187 | DEFINE_BASIC_FETCH_FUNCS(bitfield) |
183 | #define fetch_bitfield_string NULL | 188 | #define fetch_bitfield_string NULL |
184 | #define fetch_bitfield_string_size NULL | 189 | #define fetch_bitfield_string_size NULL |
185 | 190 | ||
186 | static __kprobes void | 191 | static void |
187 | update_bitfield_fetch_param(struct bitfield_fetch_param *data) | 192 | update_bitfield_fetch_param(struct bitfield_fetch_param *data) |
188 | { | 193 | { |
189 | /* | 194 | /* |
@@ -196,7 +201,7 @@ update_bitfield_fetch_param(struct bitfield_fetch_param *data) | |||
196 | update_symbol_cache(data->orig.data); | 201 | update_symbol_cache(data->orig.data); |
197 | } | 202 | } |
198 | 203 | ||
199 | static __kprobes void | 204 | static void |
200 | free_bitfield_fetch_param(struct bitfield_fetch_param *data) | 205 | free_bitfield_fetch_param(struct bitfield_fetch_param *data) |
201 | { | 206 | { |
202 | /* | 207 | /* |
@@ -255,17 +260,17 @@ fail: | |||
255 | } | 260 | } |
256 | 261 | ||
257 | /* Special function : only accept unsigned long */ | 262 | /* Special function : only accept unsigned long */ |
258 | static __kprobes void fetch_kernel_stack_address(struct pt_regs *regs, | 263 | static void fetch_kernel_stack_address(struct pt_regs *regs, void *dummy, void *dest) |
259 | void *dummy, void *dest) | ||
260 | { | 264 | { |
261 | *(unsigned long *)dest = kernel_stack_pointer(regs); | 265 | *(unsigned long *)dest = kernel_stack_pointer(regs); |
262 | } | 266 | } |
267 | NOKPROBE_SYMBOL(fetch_kernel_stack_address); | ||
263 | 268 | ||
264 | static __kprobes void fetch_user_stack_address(struct pt_regs *regs, | 269 | static void fetch_user_stack_address(struct pt_regs *regs, void *dummy, void *dest) |
265 | void *dummy, void *dest) | ||
266 | { | 270 | { |
267 | *(unsigned long *)dest = user_stack_pointer(regs); | 271 | *(unsigned long *)dest = user_stack_pointer(regs); |
268 | } | 272 | } |
273 | NOKPROBE_SYMBOL(fetch_user_stack_address); | ||
269 | 274 | ||
270 | static fetch_func_t get_fetch_size_function(const struct fetch_type *type, | 275 | static fetch_func_t get_fetch_size_function(const struct fetch_type *type, |
271 | fetch_func_t orig_fn, | 276 | fetch_func_t orig_fn, |