diff options
Diffstat (limited to 'kernel/trace/trace_kprobe.c')
| -rw-r--r-- | kernel/trace/trace_kprobe.c | 383 |
1 files changed, 296 insertions, 87 deletions
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index f52b5f50299d..8b27c9849b42 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c | |||
| @@ -30,6 +30,8 @@ | |||
| 30 | #include <linux/ptrace.h> | 30 | #include <linux/ptrace.h> |
| 31 | #include <linux/perf_event.h> | 31 | #include <linux/perf_event.h> |
| 32 | #include <linux/stringify.h> | 32 | #include <linux/stringify.h> |
| 33 | #include <linux/limits.h> | ||
| 34 | #include <linux/uaccess.h> | ||
| 33 | #include <asm/bitsperlong.h> | 35 | #include <asm/bitsperlong.h> |
| 34 | 36 | ||
| 35 | #include "trace.h" | 37 | #include "trace.h" |
| @@ -38,6 +40,7 @@ | |||
| 38 | #define MAX_TRACE_ARGS 128 | 40 | #define MAX_TRACE_ARGS 128 |
| 39 | #define MAX_ARGSTR_LEN 63 | 41 | #define MAX_ARGSTR_LEN 63 |
| 40 | #define MAX_EVENT_NAME_LEN 64 | 42 | #define MAX_EVENT_NAME_LEN 64 |
| 43 | #define MAX_STRING_SIZE PATH_MAX | ||
| 41 | #define KPROBE_EVENT_SYSTEM "kprobes" | 44 | #define KPROBE_EVENT_SYSTEM "kprobes" |
| 42 | 45 | ||
| 43 | /* Reserved field names */ | 46 | /* Reserved field names */ |
| @@ -58,14 +61,16 @@ const char *reserved_field_names[] = { | |||
| 58 | }; | 61 | }; |
| 59 | 62 | ||
| 60 | /* Printing function type */ | 63 | /* Printing function type */ |
| 61 | typedef int (*print_type_func_t)(struct trace_seq *, const char *, void *); | 64 | typedef int (*print_type_func_t)(struct trace_seq *, const char *, void *, |
| 65 | void *); | ||
| 62 | #define PRINT_TYPE_FUNC_NAME(type) print_type_##type | 66 | #define PRINT_TYPE_FUNC_NAME(type) print_type_##type |
| 63 | #define PRINT_TYPE_FMT_NAME(type) print_type_format_##type | 67 | #define PRINT_TYPE_FMT_NAME(type) print_type_format_##type |
| 64 | 68 | ||
| 65 | /* Printing in basic type function template */ | 69 | /* Printing in basic type function template */ |
| 66 | #define DEFINE_BASIC_PRINT_TYPE_FUNC(type, fmt, cast) \ | 70 | #define DEFINE_BASIC_PRINT_TYPE_FUNC(type, fmt, cast) \ |
| 67 | static __kprobes int PRINT_TYPE_FUNC_NAME(type)(struct trace_seq *s, \ | 71 | static __kprobes int PRINT_TYPE_FUNC_NAME(type)(struct trace_seq *s, \ |
| 68 | const char *name, void *data)\ | 72 | const char *name, \ |
| 73 | void *data, void *ent)\ | ||
| 69 | { \ | 74 | { \ |
| 70 | return trace_seq_printf(s, " %s=" fmt, name, (cast)*(type *)data);\ | 75 | return trace_seq_printf(s, " %s=" fmt, name, (cast)*(type *)data);\ |
| 71 | } \ | 76 | } \ |
| @@ -80,6 +85,49 @@ DEFINE_BASIC_PRINT_TYPE_FUNC(s16, "%d", int) | |||
| 80 | DEFINE_BASIC_PRINT_TYPE_FUNC(s32, "%ld", long) | 85 | DEFINE_BASIC_PRINT_TYPE_FUNC(s32, "%ld", long) |
| 81 | DEFINE_BASIC_PRINT_TYPE_FUNC(s64, "%lld", long long) | 86 | DEFINE_BASIC_PRINT_TYPE_FUNC(s64, "%lld", long long) |
| 82 | 87 | ||
| 88 | /* data_rloc: data relative location, compatible with u32 */ | ||
| 89 | #define make_data_rloc(len, roffs) \ | ||
| 90 | (((u32)(len) << 16) | ((u32)(roffs) & 0xffff)) | ||
| 91 | #define get_rloc_len(dl) ((u32)(dl) >> 16) | ||
| 92 | #define get_rloc_offs(dl) ((u32)(dl) & 0xffff) | ||
| 93 | |||
| 94 | static inline void *get_rloc_data(u32 *dl) | ||
| 95 | { | ||
| 96 | return (u8 *)dl + get_rloc_offs(*dl); | ||
| 97 | } | ||
| 98 | |||
| 99 | /* For data_loc conversion */ | ||
| 100 | static inline void *get_loc_data(u32 *dl, void *ent) | ||
| 101 | { | ||
| 102 | return (u8 *)ent + get_rloc_offs(*dl); | ||
| 103 | } | ||
| 104 | |||
| 105 | /* | ||
| 106 | * Convert data_rloc to data_loc: | ||
| 107 | * data_rloc stores the offset from data_rloc itself, but data_loc | ||
| 108 | * stores the offset from event entry. | ||
| 109 | */ | ||
| 110 | #define convert_rloc_to_loc(dl, offs) ((u32)(dl) + (offs)) | ||
| 111 | |||
| 112 | /* For defining macros, define string/string_size types */ | ||
| 113 | typedef u32 string; | ||
| 114 | typedef u32 string_size; | ||
| 115 | |||
| 116 | /* Print type function for string type */ | ||
| 117 | static __kprobes int PRINT_TYPE_FUNC_NAME(string)(struct trace_seq *s, | ||
| 118 | const char *name, | ||
| 119 | void *data, void *ent) | ||
| 120 | { | ||
| 121 | int len = *(u32 *)data >> 16; | ||
| 122 | |||
| 123 | if (!len) | ||
| 124 | return trace_seq_printf(s, " %s=(fault)", name); | ||
| 125 | else | ||
| 126 | return trace_seq_printf(s, " %s=\"%s\"", name, | ||
| 127 | (const char *)get_loc_data(data, ent)); | ||
| 128 | } | ||
| 129 | static const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\""; | ||
| 130 | |||
| 83 | /* Data fetch function type */ | 131 | /* Data fetch function type */ |
| 84 | typedef void (*fetch_func_t)(struct pt_regs *, void *, void *); | 132 | typedef void (*fetch_func_t)(struct pt_regs *, void *, void *); |
| 85 | 133 | ||
| @@ -94,32 +142,38 @@ static __kprobes void call_fetch(struct fetch_param *fprm, | |||
| 94 | return fprm->fn(regs, fprm->data, dest); | 142 | return fprm->fn(regs, fprm->data, dest); |
| 95 | } | 143 | } |
| 96 | 144 | ||
| 97 | #define FETCH_FUNC_NAME(kind, type) fetch_##kind##_##type | 145 | #define FETCH_FUNC_NAME(method, type) fetch_##method##_##type |
| 98 | /* | 146 | /* |
| 99 | * Define macro for basic types - we don't need to define s* types, because | 147 | * Define macro for basic types - we don't need to define s* types, because |
| 100 | * we have to care only about bitwidth at recording time. | 148 | * we have to care only about bitwidth at recording time. |
| 101 | */ | 149 | */ |
| 102 | #define DEFINE_BASIC_FETCH_FUNCS(kind) \ | 150 | #define DEFINE_BASIC_FETCH_FUNCS(method) \ |
| 103 | DEFINE_FETCH_##kind(u8) \ | 151 | DEFINE_FETCH_##method(u8) \ |
| 104 | DEFINE_FETCH_##kind(u16) \ | 152 | DEFINE_FETCH_##method(u16) \ |
| 105 | DEFINE_FETCH_##kind(u32) \ | 153 | DEFINE_FETCH_##method(u32) \ |
| 106 | DEFINE_FETCH_##kind(u64) | 154 | DEFINE_FETCH_##method(u64) |
| 107 | 155 | ||
| 108 | #define CHECK_BASIC_FETCH_FUNCS(kind, fn) \ | 156 | #define CHECK_FETCH_FUNCS(method, fn) \ |
| 109 | ((FETCH_FUNC_NAME(kind, u8) == fn) || \ | 157 | (((FETCH_FUNC_NAME(method, u8) == fn) || \ |
| 110 | (FETCH_FUNC_NAME(kind, u16) == fn) || \ | 158 | (FETCH_FUNC_NAME(method, u16) == fn) || \ |
| 111 | (FETCH_FUNC_NAME(kind, u32) == fn) || \ | 159 | (FETCH_FUNC_NAME(method, u32) == fn) || \ |
| 112 | (FETCH_FUNC_NAME(kind, u64) == fn)) | 160 | (FETCH_FUNC_NAME(method, u64) == fn) || \ |
| 161 | (FETCH_FUNC_NAME(method, string) == fn) || \ | ||
| 162 | (FETCH_FUNC_NAME(method, string_size) == fn)) \ | ||
| 163 | && (fn != NULL)) | ||
| 113 | 164 | ||
| 114 | /* Data fetch function templates */ | 165 | /* Data fetch function templates */ |
| 115 | #define DEFINE_FETCH_reg(type) \ | 166 | #define DEFINE_FETCH_reg(type) \ |
| 116 | static __kprobes void FETCH_FUNC_NAME(reg, type)(struct pt_regs *regs, \ | 167 | static __kprobes void FETCH_FUNC_NAME(reg, type)(struct pt_regs *regs, \ |
| 117 | void *offset, void *dest) \ | 168 | void *offset, void *dest) \ |
| 118 | { \ | 169 | { \ |
| 119 | *(type *)dest = (type)regs_get_register(regs, \ | 170 | *(type *)dest = (type)regs_get_register(regs, \ |
| 120 | (unsigned int)((unsigned long)offset)); \ | 171 | (unsigned int)((unsigned long)offset)); \ |
| 121 | } | 172 | } |
| 122 | DEFINE_BASIC_FETCH_FUNCS(reg) | 173 | DEFINE_BASIC_FETCH_FUNCS(reg) |
| 174 | /* No string on the register */ | ||
| 175 | #define fetch_reg_string NULL | ||
| 176 | #define fetch_reg_string_size NULL | ||
| 123 | 177 | ||
| 124 | #define DEFINE_FETCH_stack(type) \ | 178 | #define DEFINE_FETCH_stack(type) \ |
| 125 | static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\ | 179 | static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\ |
| @@ -129,6 +183,9 @@ static __kprobes void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs,\ | |||
| 129 | (unsigned int)((unsigned long)offset)); \ | 183 | (unsigned int)((unsigned long)offset)); \ |
| 130 | } | 184 | } |
| 131 | DEFINE_BASIC_FETCH_FUNCS(stack) | 185 | DEFINE_BASIC_FETCH_FUNCS(stack) |
| 186 | /* No string on the stack entry */ | ||
| 187 | #define fetch_stack_string NULL | ||
| 188 | #define fetch_stack_string_size NULL | ||
| 132 | 189 | ||
| 133 | #define DEFINE_FETCH_retval(type) \ | 190 | #define DEFINE_FETCH_retval(type) \ |
| 134 | static __kprobes void FETCH_FUNC_NAME(retval, type)(struct pt_regs *regs,\ | 191 | static __kprobes void FETCH_FUNC_NAME(retval, type)(struct pt_regs *regs,\ |
| @@ -137,6 +194,9 @@ static __kprobes void FETCH_FUNC_NAME(retval, type)(struct pt_regs *regs,\ | |||
| 137 | *(type *)dest = (type)regs_return_value(regs); \ | 194 | *(type *)dest = (type)regs_return_value(regs); \ |
| 138 | } | 195 | } |
| 139 | DEFINE_BASIC_FETCH_FUNCS(retval) | 196 | DEFINE_BASIC_FETCH_FUNCS(retval) |
| 197 | /* No string on the retval */ | ||
| 198 | #define fetch_retval_string NULL | ||
| 199 | #define fetch_retval_string_size NULL | ||
| 140 | 200 | ||
| 141 | #define DEFINE_FETCH_memory(type) \ | 201 | #define DEFINE_FETCH_memory(type) \ |
| 142 | static __kprobes void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs,\ | 202 | static __kprobes void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs,\ |
| @@ -149,6 +209,62 @@ static __kprobes void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs,\ | |||
| 149 | *(type *)dest = retval; \ | 209 | *(type *)dest = retval; \ |
| 150 | } | 210 | } |
| 151 | DEFINE_BASIC_FETCH_FUNCS(memory) | 211 | DEFINE_BASIC_FETCH_FUNCS(memory) |
| 212 | /* | ||
| 213 | * Fetch a null-terminated string. Caller MUST set *(u32 *)dest with max | ||
| 214 | * length and relative data location. | ||
| 215 | */ | ||
| 216 | static __kprobes void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs, | ||
| 217 | void *addr, void *dest) | ||
| 218 | { | ||
| 219 | long ret; | ||
| 220 | int maxlen = get_rloc_len(*(u32 *)dest); | ||
| 221 | u8 *dst = get_rloc_data(dest); | ||
| 222 | u8 *src = addr; | ||
| 223 | mm_segment_t old_fs = get_fs(); | ||
| 224 | if (!maxlen) | ||
| 225 | return; | ||
| 226 | /* | ||
| 227 | * Try to get string again, since the string can be changed while | ||
| 228 | * probing. | ||
| 229 | */ | ||
| 230 | set_fs(KERNEL_DS); | ||
| 231 | pagefault_disable(); | ||
| 232 | do | ||
| 233 | ret = __copy_from_user_inatomic(dst++, src++, 1); | ||
| 234 | while (dst[-1] && ret == 0 && src - (u8 *)addr < maxlen); | ||
| 235 | dst[-1] = '\0'; | ||
| 236 | pagefault_enable(); | ||
| 237 | set_fs(old_fs); | ||
| 238 | |||
| 239 | if (ret < 0) { /* Failed to fetch string */ | ||
| 240 | ((u8 *)get_rloc_data(dest))[0] = '\0'; | ||
| 241 | *(u32 *)dest = make_data_rloc(0, get_rloc_offs(*(u32 *)dest)); | ||
| 242 | } else | ||
| 243 | *(u32 *)dest = make_data_rloc(src - (u8 *)addr, | ||
| 244 | get_rloc_offs(*(u32 *)dest)); | ||
| 245 | } | ||
| 246 | /* Return the length of string -- including null terminal byte */ | ||
| 247 | static __kprobes void FETCH_FUNC_NAME(memory, string_size)(struct pt_regs *regs, | ||
| 248 | void *addr, void *dest) | ||
| 249 | { | ||
| 250 | int ret, len = 0; | ||
| 251 | u8 c; | ||
| 252 | mm_segment_t old_fs = get_fs(); | ||
| 253 | |||
| 254 | set_fs(KERNEL_DS); | ||
| 255 | pagefault_disable(); | ||
| 256 | do { | ||
| 257 | ret = __copy_from_user_inatomic(&c, (u8 *)addr + len, 1); | ||
| 258 | len++; | ||
| 259 | } while (c && ret == 0 && len < MAX_STRING_SIZE); | ||
| 260 | pagefault_enable(); | ||
| 261 | set_fs(old_fs); | ||
| 262 | |||
| 263 | if (ret < 0) /* Failed to check the length */ | ||
| 264 | *(u32 *)dest = 0; | ||
| 265 | else | ||
| 266 | *(u32 *)dest = len; | ||
| 267 | } | ||
| 152 | 268 | ||
| 153 | /* Memory fetching by symbol */ | 269 | /* Memory fetching by symbol */ |
| 154 | struct symbol_cache { | 270 | struct symbol_cache { |
| @@ -203,6 +319,8 @@ static __kprobes void FETCH_FUNC_NAME(symbol, type)(struct pt_regs *regs,\ | |||
| 203 | *(type *)dest = 0; \ | 319 | *(type *)dest = 0; \ |
| 204 | } | 320 | } |
| 205 | DEFINE_BASIC_FETCH_FUNCS(symbol) | 321 | DEFINE_BASIC_FETCH_FUNCS(symbol) |
| 322 | DEFINE_FETCH_symbol(string) | ||
| 323 | DEFINE_FETCH_symbol(string_size) | ||
| 206 | 324 | ||
| 207 | /* Dereference memory access function */ | 325 | /* Dereference memory access function */ |
| 208 | struct deref_fetch_param { | 326 | struct deref_fetch_param { |
| @@ -224,12 +342,14 @@ static __kprobes void FETCH_FUNC_NAME(deref, type)(struct pt_regs *regs,\ | |||
| 224 | *(type *)dest = 0; \ | 342 | *(type *)dest = 0; \ |
| 225 | } | 343 | } |
| 226 | DEFINE_BASIC_FETCH_FUNCS(deref) | 344 | DEFINE_BASIC_FETCH_FUNCS(deref) |
| 345 | DEFINE_FETCH_deref(string) | ||
| 346 | DEFINE_FETCH_deref(string_size) | ||
| 227 | 347 | ||
| 228 | static __kprobes void free_deref_fetch_param(struct deref_fetch_param *data) | 348 | static __kprobes void free_deref_fetch_param(struct deref_fetch_param *data) |
| 229 | { | 349 | { |
| 230 | if (CHECK_BASIC_FETCH_FUNCS(deref, data->orig.fn)) | 350 | if (CHECK_FETCH_FUNCS(deref, data->orig.fn)) |
| 231 | free_deref_fetch_param(data->orig.data); | 351 | free_deref_fetch_param(data->orig.data); |
| 232 | else if (CHECK_BASIC_FETCH_FUNCS(symbol, data->orig.fn)) | 352 | else if (CHECK_FETCH_FUNCS(symbol, data->orig.fn)) |
| 233 | free_symbol_cache(data->orig.data); | 353 | free_symbol_cache(data->orig.data); |
| 234 | kfree(data); | 354 | kfree(data); |
| 235 | } | 355 | } |
| @@ -240,23 +360,43 @@ static __kprobes void free_deref_fetch_param(struct deref_fetch_param *data) | |||
| 240 | #define DEFAULT_FETCH_TYPE _DEFAULT_FETCH_TYPE(BITS_PER_LONG) | 360 | #define DEFAULT_FETCH_TYPE _DEFAULT_FETCH_TYPE(BITS_PER_LONG) |
| 241 | #define DEFAULT_FETCH_TYPE_STR __stringify(DEFAULT_FETCH_TYPE) | 361 | #define DEFAULT_FETCH_TYPE_STR __stringify(DEFAULT_FETCH_TYPE) |
| 242 | 362 | ||
| 243 | #define ASSIGN_FETCH_FUNC(kind, type) \ | 363 | /* Fetch types */ |
| 244 | .kind = FETCH_FUNC_NAME(kind, type) | 364 | enum { |
| 245 | 365 | FETCH_MTD_reg = 0, | |
| 246 | #define ASSIGN_FETCH_TYPE(ptype, ftype, sign) \ | 366 | FETCH_MTD_stack, |
| 247 | {.name = #ptype, \ | 367 | FETCH_MTD_retval, |
| 248 | .size = sizeof(ftype), \ | 368 | FETCH_MTD_memory, |
| 249 | .is_signed = sign, \ | 369 | FETCH_MTD_symbol, |
| 250 | .print = PRINT_TYPE_FUNC_NAME(ptype), \ | 370 | FETCH_MTD_deref, |
| 251 | .fmt = PRINT_TYPE_FMT_NAME(ptype), \ | 371 | FETCH_MTD_END, |
| 252 | ASSIGN_FETCH_FUNC(reg, ftype), \ | 372 | }; |
| 253 | ASSIGN_FETCH_FUNC(stack, ftype), \ | 373 | |
| 254 | ASSIGN_FETCH_FUNC(retval, ftype), \ | 374 | #define ASSIGN_FETCH_FUNC(method, type) \ |
| 255 | ASSIGN_FETCH_FUNC(memory, ftype), \ | 375 | [FETCH_MTD_##method] = FETCH_FUNC_NAME(method, type) |
| 256 | ASSIGN_FETCH_FUNC(symbol, ftype), \ | 376 | |
| 257 | ASSIGN_FETCH_FUNC(deref, ftype), \ | 377 | #define __ASSIGN_FETCH_TYPE(_name, ptype, ftype, _size, sign, _fmttype) \ |
| 378 | {.name = _name, \ | ||
| 379 | .size = _size, \ | ||
| 380 | .is_signed = sign, \ | ||
| 381 | .print = PRINT_TYPE_FUNC_NAME(ptype), \ | ||
| 382 | .fmt = PRINT_TYPE_FMT_NAME(ptype), \ | ||
| 383 | .fmttype = _fmttype, \ | ||
| 384 | .fetch = { \ | ||
| 385 | ASSIGN_FETCH_FUNC(reg, ftype), \ | ||
| 386 | ASSIGN_FETCH_FUNC(stack, ftype), \ | ||
| 387 | ASSIGN_FETCH_FUNC(retval, ftype), \ | ||
| 388 | ASSIGN_FETCH_FUNC(memory, ftype), \ | ||
| 389 | ASSIGN_FETCH_FUNC(symbol, ftype), \ | ||
| 390 | ASSIGN_FETCH_FUNC(deref, ftype), \ | ||
| 391 | } \ | ||
| 258 | } | 392 | } |
| 259 | 393 | ||
| 394 | #define ASSIGN_FETCH_TYPE(ptype, ftype, sign) \ | ||
| 395 | __ASSIGN_FETCH_TYPE(#ptype, ptype, ftype, sizeof(ftype), sign, #ptype) | ||
| 396 | |||
| 397 | #define FETCH_TYPE_STRING 0 | ||
| 398 | #define FETCH_TYPE_STRSIZE 1 | ||
| 399 | |||
| 260 | /* Fetch type information table */ | 400 | /* Fetch type information table */ |
| 261 | static const struct fetch_type { | 401 | static const struct fetch_type { |
| 262 | const char *name; /* Name of type */ | 402 | const char *name; /* Name of type */ |
| @@ -264,14 +404,16 @@ static const struct fetch_type { | |||
| 264 | int is_signed; /* Signed flag */ | 404 | int is_signed; /* Signed flag */ |
| 265 | print_type_func_t print; /* Print functions */ | 405 | print_type_func_t print; /* Print functions */ |
| 266 | const char *fmt; /* Fromat string */ | 406 | const char *fmt; /* Fromat string */ |
| 407 | const char *fmttype; /* Name in format file */ | ||
| 267 | /* Fetch functions */ | 408 | /* Fetch functions */ |
| 268 | fetch_func_t reg; | 409 | fetch_func_t fetch[FETCH_MTD_END]; |
| 269 | fetch_func_t stack; | ||
| 270 | fetch_func_t retval; | ||
| 271 | fetch_func_t memory; | ||
| 272 | fetch_func_t symbol; | ||
| 273 | fetch_func_t deref; | ||
| 274 | } fetch_type_table[] = { | 410 | } fetch_type_table[] = { |
| 411 | /* Special types */ | ||
| 412 | [FETCH_TYPE_STRING] = __ASSIGN_FETCH_TYPE("string", string, string, | ||
| 413 | sizeof(u32), 1, "__data_loc char[]"), | ||
| 414 | [FETCH_TYPE_STRSIZE] = __ASSIGN_FETCH_TYPE("string_size", u32, | ||
| 415 | string_size, sizeof(u32), 0, "u32"), | ||
| 416 | /* Basic types */ | ||
| 275 | ASSIGN_FETCH_TYPE(u8, u8, 0), | 417 | ASSIGN_FETCH_TYPE(u8, u8, 0), |
| 276 | ASSIGN_FETCH_TYPE(u16, u16, 0), | 418 | ASSIGN_FETCH_TYPE(u16, u16, 0), |
| 277 | ASSIGN_FETCH_TYPE(u32, u32, 0), | 419 | ASSIGN_FETCH_TYPE(u32, u32, 0), |
| @@ -302,12 +444,28 @@ static __kprobes void fetch_stack_address(struct pt_regs *regs, | |||
| 302 | *(unsigned long *)dest = kernel_stack_pointer(regs); | 444 | *(unsigned long *)dest = kernel_stack_pointer(regs); |
| 303 | } | 445 | } |
| 304 | 446 | ||
| 447 | static fetch_func_t get_fetch_size_function(const struct fetch_type *type, | ||
| 448 | fetch_func_t orig_fn) | ||
| 449 | { | ||
| 450 | int i; | ||
| 451 | |||
| 452 | if (type != &fetch_type_table[FETCH_TYPE_STRING]) | ||
| 453 | return NULL; /* Only string type needs size function */ | ||
| 454 | for (i = 0; i < FETCH_MTD_END; i++) | ||
| 455 | if (type->fetch[i] == orig_fn) | ||
| 456 | return fetch_type_table[FETCH_TYPE_STRSIZE].fetch[i]; | ||
| 457 | |||
| 458 | WARN_ON(1); /* This should not happen */ | ||
| 459 | return NULL; | ||
| 460 | } | ||
| 461 | |||
| 305 | /** | 462 | /** |
| 306 | * Kprobe event core functions | 463 | * Kprobe event core functions |
| 307 | */ | 464 | */ |
| 308 | 465 | ||
| 309 | struct probe_arg { | 466 | struct probe_arg { |
| 310 | struct fetch_param fetch; | 467 | struct fetch_param fetch; |
| 468 | struct fetch_param fetch_size; | ||
| 311 | unsigned int offset; /* Offset from argument entry */ | 469 | unsigned int offset; /* Offset from argument entry */ |
| 312 | const char *name; /* Name of this argument */ | 470 | const char *name; /* Name of this argument */ |
| 313 | const char *comm; /* Command of this argument */ | 471 | const char *comm; /* Command of this argument */ |
| @@ -429,9 +587,9 @@ error: | |||
| 429 | 587 | ||
| 430 | static void free_probe_arg(struct probe_arg *arg) | 588 | static void free_probe_arg(struct probe_arg *arg) |
| 431 | { | 589 | { |
| 432 | if (CHECK_BASIC_FETCH_FUNCS(deref, arg->fetch.fn)) | 590 | if (CHECK_FETCH_FUNCS(deref, arg->fetch.fn)) |
| 433 | free_deref_fetch_param(arg->fetch.data); | 591 | free_deref_fetch_param(arg->fetch.data); |
| 434 | else if (CHECK_BASIC_FETCH_FUNCS(symbol, arg->fetch.fn)) | 592 | else if (CHECK_FETCH_FUNCS(symbol, arg->fetch.fn)) |
| 435 | free_symbol_cache(arg->fetch.data); | 593 | free_symbol_cache(arg->fetch.data); |
| 436 | kfree(arg->name); | 594 | kfree(arg->name); |
| 437 | kfree(arg->comm); | 595 | kfree(arg->comm); |
| @@ -548,7 +706,7 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t, | |||
| 548 | 706 | ||
| 549 | if (strcmp(arg, "retval") == 0) { | 707 | if (strcmp(arg, "retval") == 0) { |
| 550 | if (is_return) | 708 | if (is_return) |
| 551 | f->fn = t->retval; | 709 | f->fn = t->fetch[FETCH_MTD_retval]; |
| 552 | else | 710 | else |
| 553 | ret = -EINVAL; | 711 | ret = -EINVAL; |
| 554 | } else if (strncmp(arg, "stack", 5) == 0) { | 712 | } else if (strncmp(arg, "stack", 5) == 0) { |
| @@ -562,7 +720,7 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t, | |||
| 562 | if (ret || param > PARAM_MAX_STACK) | 720 | if (ret || param > PARAM_MAX_STACK) |
| 563 | ret = -EINVAL; | 721 | ret = -EINVAL; |
| 564 | else { | 722 | else { |
| 565 | f->fn = t->stack; | 723 | f->fn = t->fetch[FETCH_MTD_stack]; |
| 566 | f->data = (void *)param; | 724 | f->data = (void *)param; |
| 567 | } | 725 | } |
| 568 | } else | 726 | } else |
| @@ -588,7 +746,7 @@ static int __parse_probe_arg(char *arg, const struct fetch_type *t, | |||
| 588 | case '%': /* named register */ | 746 | case '%': /* named register */ |
| 589 | ret = regs_query_register_offset(arg + 1); | 747 | ret = regs_query_register_offset(arg + 1); |
| 590 | if (ret >= 0) { | 748 | if (ret >= 0) { |
| 591 | f->fn = t->reg; | 749 | f->fn = t->fetch[FETCH_MTD_reg]; |
| 592 | f->data = (void *)(unsigned long)ret; | 750 | f->data = (void *)(unsigned long)ret; |
| 593 | ret = 0; | 751 | ret = 0; |
| 594 | } | 752 | } |
| @@ -598,7 +756,7 @@ static int __parse_probe_arg(char *arg, const struct fetch_type *t, | |||
| 598 | ret = strict_strtoul(arg + 1, 0, ¶m); | 756 | ret = strict_strtoul(arg + 1, 0, ¶m); |
| 599 | if (ret) | 757 | if (ret) |
| 600 | break; | 758 | break; |
| 601 | f->fn = t->memory; | 759 | f->fn = t->fetch[FETCH_MTD_memory]; |
| 602 | f->data = (void *)param; | 760 | f->data = (void *)param; |
| 603 | } else { | 761 | } else { |
| 604 | ret = split_symbol_offset(arg + 1, &offset); | 762 | ret = split_symbol_offset(arg + 1, &offset); |
| @@ -606,7 +764,7 @@ static int __parse_probe_arg(char *arg, const struct fetch_type *t, | |||
| 606 | break; | 764 | break; |
| 607 | f->data = alloc_symbol_cache(arg + 1, offset); | 765 | f->data = alloc_symbol_cache(arg + 1, offset); |
| 608 | if (f->data) | 766 | if (f->data) |
| 609 | f->fn = t->symbol; | 767 | f->fn = t->fetch[FETCH_MTD_symbol]; |
| 610 | } | 768 | } |
| 611 | break; | 769 | break; |
| 612 | case '+': /* deref memory */ | 770 | case '+': /* deref memory */ |
| @@ -636,14 +794,17 @@ static int __parse_probe_arg(char *arg, const struct fetch_type *t, | |||
| 636 | if (ret) | 794 | if (ret) |
| 637 | kfree(dprm); | 795 | kfree(dprm); |
| 638 | else { | 796 | else { |
| 639 | f->fn = t->deref; | 797 | f->fn = t->fetch[FETCH_MTD_deref]; |
| 640 | f->data = (void *)dprm; | 798 | f->data = (void *)dprm; |
| 641 | } | 799 | } |
| 642 | } | 800 | } |
| 643 | break; | 801 | break; |
| 644 | } | 802 | } |
| 645 | if (!ret && !f->fn) | 803 | if (!ret && !f->fn) { /* Parsed, but do not find fetch method */ |
| 804 | pr_info("%s type has no corresponding fetch method.\n", | ||
| 805 | t->name); | ||
| 646 | ret = -EINVAL; | 806 | ret = -EINVAL; |
| 807 | } | ||
| 647 | return ret; | 808 | return ret; |
| 648 | } | 809 | } |
| 649 | 810 | ||
| @@ -652,6 +813,7 @@ static int parse_probe_arg(char *arg, struct trace_probe *tp, | |||
| 652 | struct probe_arg *parg, int is_return) | 813 | struct probe_arg *parg, int is_return) |
| 653 | { | 814 | { |
| 654 | const char *t; | 815 | const char *t; |
| 816 | int ret; | ||
| 655 | 817 | ||
| 656 | if (strlen(arg) > MAX_ARGSTR_LEN) { | 818 | if (strlen(arg) > MAX_ARGSTR_LEN) { |
| 657 | pr_info("Argument is too long.: %s\n", arg); | 819 | pr_info("Argument is too long.: %s\n", arg); |
| @@ -674,7 +836,13 @@ static int parse_probe_arg(char *arg, struct trace_probe *tp, | |||
| 674 | } | 836 | } |
| 675 | parg->offset = tp->size; | 837 | parg->offset = tp->size; |
| 676 | tp->size += parg->type->size; | 838 | tp->size += parg->type->size; |
| 677 | return __parse_probe_arg(arg, parg->type, &parg->fetch, is_return); | 839 | ret = __parse_probe_arg(arg, parg->type, &parg->fetch, is_return); |
| 840 | if (ret >= 0) { | ||
| 841 | parg->fetch_size.fn = get_fetch_size_function(parg->type, | ||
| 842 | parg->fetch.fn); | ||
| 843 | parg->fetch_size.data = parg->fetch.data; | ||
| 844 | } | ||
| 845 | return ret; | ||
| 678 | } | 846 | } |
| 679 | 847 | ||
| 680 | /* Return 1 if name is reserved or already used by another argument */ | 848 | /* Return 1 if name is reserved or already used by another argument */ |
| @@ -757,14 +925,17 @@ static int create_trace_probe(int argc, char **argv) | |||
| 757 | pr_info("Delete command needs an event name.\n"); | 925 | pr_info("Delete command needs an event name.\n"); |
| 758 | return -EINVAL; | 926 | return -EINVAL; |
| 759 | } | 927 | } |
| 928 | mutex_lock(&probe_lock); | ||
| 760 | tp = find_probe_event(event, group); | 929 | tp = find_probe_event(event, group); |
| 761 | if (!tp) { | 930 | if (!tp) { |
| 931 | mutex_unlock(&probe_lock); | ||
| 762 | pr_info("Event %s/%s doesn't exist.\n", group, event); | 932 | pr_info("Event %s/%s doesn't exist.\n", group, event); |
| 763 | return -ENOENT; | 933 | return -ENOENT; |
| 764 | } | 934 | } |
| 765 | /* delete an event */ | 935 | /* delete an event */ |
| 766 | unregister_trace_probe(tp); | 936 | unregister_trace_probe(tp); |
| 767 | free_trace_probe(tp); | 937 | free_trace_probe(tp); |
| 938 | mutex_unlock(&probe_lock); | ||
| 768 | return 0; | 939 | return 0; |
| 769 | } | 940 | } |
| 770 | 941 | ||
| @@ -1043,6 +1214,54 @@ static const struct file_operations kprobe_profile_ops = { | |||
| 1043 | .release = seq_release, | 1214 | .release = seq_release, |
| 1044 | }; | 1215 | }; |
| 1045 | 1216 | ||
| 1217 | /* Sum up total data length for dynamic arraies (strings) */ | ||
| 1218 | static __kprobes int __get_data_size(struct trace_probe *tp, | ||
| 1219 | struct pt_regs *regs) | ||
| 1220 | { | ||
| 1221 | int i, ret = 0; | ||
| 1222 | u32 len; | ||
| 1223 | |||
| 1224 | for (i = 0; i < tp->nr_args; i++) | ||
| 1225 | if (unlikely(tp->args[i].fetch_size.fn)) { | ||
| 1226 | call_fetch(&tp->args[i].fetch_size, regs, &len); | ||
| 1227 | ret += len; | ||
| 1228 | } | ||
| 1229 | |||
| 1230 | return ret; | ||
| 1231 | } | ||
| 1232 | |||
| 1233 | /* Store the value of each argument */ | ||
| 1234 | static __kprobes void store_trace_args(int ent_size, struct trace_probe *tp, | ||
| 1235 | struct pt_regs *regs, | ||
| 1236 | u8 *data, int maxlen) | ||
| 1237 | { | ||
| 1238 | int i; | ||
| 1239 | u32 end = tp->size; | ||
| 1240 | u32 *dl; /* Data (relative) location */ | ||
| 1241 | |||
| 1242 | for (i = 0; i < tp->nr_args; i++) { | ||
| 1243 | if (unlikely(tp->args[i].fetch_size.fn)) { | ||
| 1244 | /* | ||
| 1245 | * First, we set the relative location and | ||
| 1246 | * maximum data length to *dl | ||
| 1247 | */ | ||
| 1248 | dl = (u32 *)(data + tp->args[i].offset); | ||
| 1249 | *dl = make_data_rloc(maxlen, end - tp->args[i].offset); | ||
| 1250 | /* Then try to fetch string or dynamic array data */ | ||
| 1251 | call_fetch(&tp->args[i].fetch, regs, dl); | ||
| 1252 | /* Reduce maximum length */ | ||
| 1253 | end += get_rloc_len(*dl); | ||
| 1254 | maxlen -= get_rloc_len(*dl); | ||
| 1255 | /* Trick here, convert data_rloc to data_loc */ | ||
| 1256 | *dl = convert_rloc_to_loc(*dl, | ||
| 1257 | ent_size + tp->args[i].offset); | ||
| 1258 | } else | ||
| 1259 | /* Just fetching data normally */ | ||
| 1260 | call_fetch(&tp->args[i].fetch, regs, | ||
| 1261 | data + tp->args[i].offset); | ||
| 1262 | } | ||
| 1263 | } | ||
| 1264 | |||
| 1046 | /* Kprobe handler */ | 1265 | /* Kprobe handler */ |
| 1047 | static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs) | 1266 | static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs) |
| 1048 | { | 1267 | { |
| @@ -1050,8 +1269,7 @@ static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs) | |||
| 1050 | struct kprobe_trace_entry_head *entry; | 1269 | struct kprobe_trace_entry_head *entry; |
| 1051 | struct ring_buffer_event *event; | 1270 | struct ring_buffer_event *event; |
| 1052 | struct ring_buffer *buffer; | 1271 | struct ring_buffer *buffer; |
| 1053 | u8 *data; | 1272 | int size, dsize, pc; |
| 1054 | int size, i, pc; | ||
| 1055 | unsigned long irq_flags; | 1273 | unsigned long irq_flags; |
| 1056 | struct ftrace_event_call *call = &tp->call; | 1274 | struct ftrace_event_call *call = &tp->call; |
| 1057 | 1275 | ||
| @@ -1060,7 +1278,8 @@ static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs) | |||
| 1060 | local_save_flags(irq_flags); | 1278 | local_save_flags(irq_flags); |
| 1061 | pc = preempt_count(); | 1279 | pc = preempt_count(); |
| 1062 | 1280 | ||
| 1063 | size = sizeof(*entry) + tp->size; | 1281 | dsize = __get_data_size(tp, regs); |
| 1282 | size = sizeof(*entry) + tp->size + dsize; | ||
| 1064 | 1283 | ||
| 1065 | event = trace_current_buffer_lock_reserve(&buffer, call->event.type, | 1284 | event = trace_current_buffer_lock_reserve(&buffer, call->event.type, |
| 1066 | size, irq_flags, pc); | 1285 | size, irq_flags, pc); |
| @@ -1069,9 +1288,7 @@ static __kprobes void kprobe_trace_func(struct kprobe *kp, struct pt_regs *regs) | |||
| 1069 | 1288 | ||
| 1070 | entry = ring_buffer_event_data(event); | 1289 | entry = ring_buffer_event_data(event); |
| 1071 | entry->ip = (unsigned long)kp->addr; | 1290 | entry->ip = (unsigned long)kp->addr; |
| 1072 | data = (u8 *)&entry[1]; | 1291 | store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize); |
| 1073 | for (i = 0; i < tp->nr_args; i++) | ||
| 1074 | call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset); | ||
| 1075 | 1292 | ||
| 1076 | if (!filter_current_check_discard(buffer, call, entry, event)) | 1293 | if (!filter_current_check_discard(buffer, call, entry, event)) |
| 1077 | trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc); | 1294 | trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc); |
| @@ -1085,15 +1302,15 @@ static __kprobes void kretprobe_trace_func(struct kretprobe_instance *ri, | |||
| 1085 | struct kretprobe_trace_entry_head *entry; | 1302 | struct kretprobe_trace_entry_head *entry; |
| 1086 | struct ring_buffer_event *event; | 1303 | struct ring_buffer_event *event; |
| 1087 | struct ring_buffer *buffer; | 1304 | struct ring_buffer *buffer; |
| 1088 | u8 *data; | 1305 | int size, pc, dsize; |
| 1089 | int size, i, pc; | ||
| 1090 | unsigned long irq_flags; | 1306 | unsigned long irq_flags; |
| 1091 | struct ftrace_event_call *call = &tp->call; | 1307 | struct ftrace_event_call *call = &tp->call; |
| 1092 | 1308 | ||
| 1093 | local_save_flags(irq_flags); | 1309 | local_save_flags(irq_flags); |
| 1094 | pc = preempt_count(); | 1310 | pc = preempt_count(); |
| 1095 | 1311 | ||
| 1096 | size = sizeof(*entry) + tp->size; | 1312 | dsize = __get_data_size(tp, regs); |
| 1313 | size = sizeof(*entry) + tp->size + dsize; | ||
| 1097 | 1314 | ||
| 1098 | event = trace_current_buffer_lock_reserve(&buffer, call->event.type, | 1315 | event = trace_current_buffer_lock_reserve(&buffer, call->event.type, |
| 1099 | size, irq_flags, pc); | 1316 | size, irq_flags, pc); |
| @@ -1103,9 +1320,7 @@ static __kprobes void kretprobe_trace_func(struct kretprobe_instance *ri, | |||
| 1103 | entry = ring_buffer_event_data(event); | 1320 | entry = ring_buffer_event_data(event); |
| 1104 | entry->func = (unsigned long)tp->rp.kp.addr; | 1321 | entry->func = (unsigned long)tp->rp.kp.addr; |
| 1105 | entry->ret_ip = (unsigned long)ri->ret_addr; | 1322 | entry->ret_ip = (unsigned long)ri->ret_addr; |
| 1106 | data = (u8 *)&entry[1]; | 1323 | store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize); |
| 1107 | for (i = 0; i < tp->nr_args; i++) | ||
| 1108 | call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset); | ||
| 1109 | 1324 | ||
| 1110 | if (!filter_current_check_discard(buffer, call, entry, event)) | 1325 | if (!filter_current_check_discard(buffer, call, entry, event)) |
| 1111 | trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc); | 1326 | trace_nowake_buffer_unlock_commit(buffer, event, irq_flags, pc); |
| @@ -1137,7 +1352,7 @@ print_kprobe_event(struct trace_iterator *iter, int flags, | |||
| 1137 | data = (u8 *)&field[1]; | 1352 | data = (u8 *)&field[1]; |
| 1138 | for (i = 0; i < tp->nr_args; i++) | 1353 | for (i = 0; i < tp->nr_args; i++) |
| 1139 | if (!tp->args[i].type->print(s, tp->args[i].name, | 1354 | if (!tp->args[i].type->print(s, tp->args[i].name, |
| 1140 | data + tp->args[i].offset)) | 1355 | data + tp->args[i].offset, field)) |
| 1141 | goto partial; | 1356 | goto partial; |
| 1142 | 1357 | ||
| 1143 | if (!trace_seq_puts(s, "\n")) | 1358 | if (!trace_seq_puts(s, "\n")) |
| @@ -1179,7 +1394,7 @@ print_kretprobe_event(struct trace_iterator *iter, int flags, | |||
| 1179 | data = (u8 *)&field[1]; | 1394 | data = (u8 *)&field[1]; |
| 1180 | for (i = 0; i < tp->nr_args; i++) | 1395 | for (i = 0; i < tp->nr_args; i++) |
| 1181 | if (!tp->args[i].type->print(s, tp->args[i].name, | 1396 | if (!tp->args[i].type->print(s, tp->args[i].name, |
| 1182 | data + tp->args[i].offset)) | 1397 | data + tp->args[i].offset, field)) |
| 1183 | goto partial; | 1398 | goto partial; |
| 1184 | 1399 | ||
| 1185 | if (!trace_seq_puts(s, "\n")) | 1400 | if (!trace_seq_puts(s, "\n")) |
| @@ -1214,11 +1429,6 @@ static void probe_event_disable(struct ftrace_event_call *call) | |||
| 1214 | } | 1429 | } |
| 1215 | } | 1430 | } |
| 1216 | 1431 | ||
| 1217 | static int probe_event_raw_init(struct ftrace_event_call *event_call) | ||
| 1218 | { | ||
| 1219 | return 0; | ||
| 1220 | } | ||
| 1221 | |||
| 1222 | #undef DEFINE_FIELD | 1432 | #undef DEFINE_FIELD |
| 1223 | #define DEFINE_FIELD(type, item, name, is_signed) \ | 1433 | #define DEFINE_FIELD(type, item, name, is_signed) \ |
| 1224 | do { \ | 1434 | do { \ |
| @@ -1239,7 +1449,7 @@ static int kprobe_event_define_fields(struct ftrace_event_call *event_call) | |||
| 1239 | DEFINE_FIELD(unsigned long, ip, FIELD_STRING_IP, 0); | 1449 | DEFINE_FIELD(unsigned long, ip, FIELD_STRING_IP, 0); |
| 1240 | /* Set argument names as fields */ | 1450 | /* Set argument names as fields */ |
| 1241 | for (i = 0; i < tp->nr_args; i++) { | 1451 | for (i = 0; i < tp->nr_args; i++) { |
| 1242 | ret = trace_define_field(event_call, tp->args[i].type->name, | 1452 | ret = trace_define_field(event_call, tp->args[i].type->fmttype, |
| 1243 | tp->args[i].name, | 1453 | tp->args[i].name, |
| 1244 | sizeof(field) + tp->args[i].offset, | 1454 | sizeof(field) + tp->args[i].offset, |
| 1245 | tp->args[i].type->size, | 1455 | tp->args[i].type->size, |
| @@ -1261,7 +1471,7 @@ static int kretprobe_event_define_fields(struct ftrace_event_call *event_call) | |||
| 1261 | DEFINE_FIELD(unsigned long, ret_ip, FIELD_STRING_RETIP, 0); | 1471 | DEFINE_FIELD(unsigned long, ret_ip, FIELD_STRING_RETIP, 0); |
| 1262 | /* Set argument names as fields */ | 1472 | /* Set argument names as fields */ |
| 1263 | for (i = 0; i < tp->nr_args; i++) { | 1473 | for (i = 0; i < tp->nr_args; i++) { |
| 1264 | ret = trace_define_field(event_call, tp->args[i].type->name, | 1474 | ret = trace_define_field(event_call, tp->args[i].type->fmttype, |
| 1265 | tp->args[i].name, | 1475 | tp->args[i].name, |
| 1266 | sizeof(field) + tp->args[i].offset, | 1476 | sizeof(field) + tp->args[i].offset, |
| 1267 | tp->args[i].type->size, | 1477 | tp->args[i].type->size, |
| @@ -1301,8 +1511,13 @@ static int __set_print_fmt(struct trace_probe *tp, char *buf, int len) | |||
| 1301 | pos += snprintf(buf + pos, LEN_OR_ZERO, "\", %s", arg); | 1511 | pos += snprintf(buf + pos, LEN_OR_ZERO, "\", %s", arg); |
| 1302 | 1512 | ||
| 1303 | for (i = 0; i < tp->nr_args; i++) { | 1513 | for (i = 0; i < tp->nr_args; i++) { |
| 1304 | pos += snprintf(buf + pos, LEN_OR_ZERO, ", REC->%s", | 1514 | if (strcmp(tp->args[i].type->name, "string") == 0) |
| 1305 | tp->args[i].name); | 1515 | pos += snprintf(buf + pos, LEN_OR_ZERO, |
| 1516 | ", __get_str(%s)", | ||
| 1517 | tp->args[i].name); | ||
| 1518 | else | ||
| 1519 | pos += snprintf(buf + pos, LEN_OR_ZERO, ", REC->%s", | ||
| 1520 | tp->args[i].name); | ||
| 1306 | } | 1521 | } |
| 1307 | 1522 | ||
| 1308 | #undef LEN_OR_ZERO | 1523 | #undef LEN_OR_ZERO |
| @@ -1339,11 +1554,11 @@ static __kprobes void kprobe_perf_func(struct kprobe *kp, | |||
| 1339 | struct ftrace_event_call *call = &tp->call; | 1554 | struct ftrace_event_call *call = &tp->call; |
| 1340 | struct kprobe_trace_entry_head *entry; | 1555 | struct kprobe_trace_entry_head *entry; |
| 1341 | struct hlist_head *head; | 1556 | struct hlist_head *head; |
| 1342 | u8 *data; | 1557 | int size, __size, dsize; |
| 1343 | int size, __size, i; | ||
| 1344 | int rctx; | 1558 | int rctx; |
| 1345 | 1559 | ||
| 1346 | __size = sizeof(*entry) + tp->size; | 1560 | dsize = __get_data_size(tp, regs); |
| 1561 | __size = sizeof(*entry) + tp->size + dsize; | ||
| 1347 | size = ALIGN(__size + sizeof(u32), sizeof(u64)); | 1562 | size = ALIGN(__size + sizeof(u32), sizeof(u64)); |
| 1348 | size -= sizeof(u32); | 1563 | size -= sizeof(u32); |
| 1349 | if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE, | 1564 | if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE, |
| @@ -1355,9 +1570,8 @@ static __kprobes void kprobe_perf_func(struct kprobe *kp, | |||
| 1355 | return; | 1570 | return; |
| 1356 | 1571 | ||
| 1357 | entry->ip = (unsigned long)kp->addr; | 1572 | entry->ip = (unsigned long)kp->addr; |
| 1358 | data = (u8 *)&entry[1]; | 1573 | memset(&entry[1], 0, dsize); |
| 1359 | for (i = 0; i < tp->nr_args; i++) | 1574 | store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize); |
| 1360 | call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset); | ||
| 1361 | 1575 | ||
| 1362 | head = this_cpu_ptr(call->perf_events); | 1576 | head = this_cpu_ptr(call->perf_events); |
| 1363 | perf_trace_buf_submit(entry, size, rctx, entry->ip, 1, regs, head); | 1577 | perf_trace_buf_submit(entry, size, rctx, entry->ip, 1, regs, head); |
| @@ -1371,11 +1585,11 @@ static __kprobes void kretprobe_perf_func(struct kretprobe_instance *ri, | |||
| 1371 | struct ftrace_event_call *call = &tp->call; | 1585 | struct ftrace_event_call *call = &tp->call; |
| 1372 | struct kretprobe_trace_entry_head *entry; | 1586 | struct kretprobe_trace_entry_head *entry; |
| 1373 | struct hlist_head *head; | 1587 | struct hlist_head *head; |
| 1374 | u8 *data; | 1588 | int size, __size, dsize; |
| 1375 | int size, __size, i; | ||
| 1376 | int rctx; | 1589 | int rctx; |
| 1377 | 1590 | ||
| 1378 | __size = sizeof(*entry) + tp->size; | 1591 | dsize = __get_data_size(tp, regs); |
| 1592 | __size = sizeof(*entry) + tp->size + dsize; | ||
| 1379 | size = ALIGN(__size + sizeof(u32), sizeof(u64)); | 1593 | size = ALIGN(__size + sizeof(u32), sizeof(u64)); |
| 1380 | size -= sizeof(u32); | 1594 | size -= sizeof(u32); |
| 1381 | if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE, | 1595 | if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE, |
| @@ -1388,9 +1602,7 @@ static __kprobes void kretprobe_perf_func(struct kretprobe_instance *ri, | |||
| 1388 | 1602 | ||
| 1389 | entry->func = (unsigned long)tp->rp.kp.addr; | 1603 | entry->func = (unsigned long)tp->rp.kp.addr; |
| 1390 | entry->ret_ip = (unsigned long)ri->ret_addr; | 1604 | entry->ret_ip = (unsigned long)ri->ret_addr; |
| 1391 | data = (u8 *)&entry[1]; | 1605 | store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize); |
| 1392 | for (i = 0; i < tp->nr_args; i++) | ||
| 1393 | call_fetch(&tp->args[i].fetch, regs, data + tp->args[i].offset); | ||
| 1394 | 1606 | ||
| 1395 | head = this_cpu_ptr(call->perf_events); | 1607 | head = this_cpu_ptr(call->perf_events); |
| 1396 | perf_trace_buf_submit(entry, size, rctx, entry->ret_ip, 1, regs, head); | 1608 | perf_trace_buf_submit(entry, size, rctx, entry->ret_ip, 1, regs, head); |
| @@ -1486,15 +1698,12 @@ static int register_probe_event(struct trace_probe *tp) | |||
| 1486 | int ret; | 1698 | int ret; |
| 1487 | 1699 | ||
| 1488 | /* Initialize ftrace_event_call */ | 1700 | /* Initialize ftrace_event_call */ |
| 1701 | INIT_LIST_HEAD(&call->class->fields); | ||
| 1489 | if (probe_is_return(tp)) { | 1702 | if (probe_is_return(tp)) { |
| 1490 | INIT_LIST_HEAD(&call->class->fields); | ||
| 1491 | call->event.funcs = &kretprobe_funcs; | 1703 | call->event.funcs = &kretprobe_funcs; |
| 1492 | call->class->raw_init = probe_event_raw_init; | ||
| 1493 | call->class->define_fields = kretprobe_event_define_fields; | 1704 | call->class->define_fields = kretprobe_event_define_fields; |
| 1494 | } else { | 1705 | } else { |
| 1495 | INIT_LIST_HEAD(&call->class->fields); | ||
| 1496 | call->event.funcs = &kprobe_funcs; | 1706 | call->event.funcs = &kprobe_funcs; |
| 1497 | call->class->raw_init = probe_event_raw_init; | ||
| 1498 | call->class->define_fields = kprobe_event_define_fields; | 1707 | call->class->define_fields = kprobe_event_define_fields; |
| 1499 | } | 1708 | } |
| 1500 | if (set_print_fmt(tp) < 0) | 1709 | if (set_print_fmt(tp) < 0) |
