diff options
Diffstat (limited to 'kernel/trace/trace_kprobe.c')
-rw-r--r-- | kernel/trace/trace_kprobe.c | 60 |
1 files changed, 37 insertions, 23 deletions
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 97309d4714f7..f63ead0cc5cf 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c | |||
@@ -220,24 +220,24 @@ static int probe_arg_string(char *buf, size_t n, struct fetch_func *ff) | |||
220 | int ret = -EINVAL; | 220 | int ret = -EINVAL; |
221 | 221 | ||
222 | if (ff->func == fetch_argument) | 222 | if (ff->func == fetch_argument) |
223 | ret = snprintf(buf, n, "a%lu", (unsigned long)ff->data); | 223 | ret = snprintf(buf, n, "$a%lu", (unsigned long)ff->data); |
224 | else if (ff->func == fetch_register) { | 224 | else if (ff->func == fetch_register) { |
225 | const char *name; | 225 | const char *name; |
226 | name = regs_query_register_name((unsigned int)((long)ff->data)); | 226 | name = regs_query_register_name((unsigned int)((long)ff->data)); |
227 | ret = snprintf(buf, n, "%%%s", name); | 227 | ret = snprintf(buf, n, "%%%s", name); |
228 | } else if (ff->func == fetch_stack) | 228 | } else if (ff->func == fetch_stack) |
229 | ret = snprintf(buf, n, "s%lu", (unsigned long)ff->data); | 229 | ret = snprintf(buf, n, "$s%lu", (unsigned long)ff->data); |
230 | else if (ff->func == fetch_memory) | 230 | else if (ff->func == fetch_memory) |
231 | ret = snprintf(buf, n, "@0x%p", ff->data); | 231 | ret = snprintf(buf, n, "@0x%p", ff->data); |
232 | else if (ff->func == fetch_symbol) { | 232 | else if (ff->func == fetch_symbol) { |
233 | struct symbol_cache *sc = ff->data; | 233 | struct symbol_cache *sc = ff->data; |
234 | ret = snprintf(buf, n, "@%s%+ld", sc->symbol, sc->offset); | 234 | ret = snprintf(buf, n, "@%s%+ld", sc->symbol, sc->offset); |
235 | } else if (ff->func == fetch_retvalue) | 235 | } else if (ff->func == fetch_retvalue) |
236 | ret = snprintf(buf, n, "rv"); | 236 | ret = snprintf(buf, n, "$rv"); |
237 | else if (ff->func == fetch_ip) | 237 | else if (ff->func == fetch_ip) |
238 | ret = snprintf(buf, n, "ra"); | 238 | ret = snprintf(buf, n, "$ra"); |
239 | else if (ff->func == fetch_stack_address) | 239 | else if (ff->func == fetch_stack_address) |
240 | ret = snprintf(buf, n, "sa"); | 240 | ret = snprintf(buf, n, "$sa"); |
241 | else if (ff->func == fetch_indirect) { | 241 | else if (ff->func == fetch_indirect) { |
242 | struct indirect_fetch_data *id = ff->data; | 242 | struct indirect_fetch_data *id = ff->data; |
243 | size_t l = 0; | 243 | size_t l = 0; |
@@ -429,12 +429,10 @@ static int split_symbol_offset(char *symbol, unsigned long *offset) | |||
429 | #define PARAM_MAX_ARGS 16 | 429 | #define PARAM_MAX_ARGS 16 |
430 | #define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long)) | 430 | #define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long)) |
431 | 431 | ||
432 | static int parse_probe_arg(char *arg, struct fetch_func *ff, int is_return) | 432 | static int parse_probe_vars(char *arg, struct fetch_func *ff, int is_return) |
433 | { | 433 | { |
434 | int ret = 0; | 434 | int ret = 0; |
435 | unsigned long param; | 435 | unsigned long param; |
436 | long offset; | ||
437 | char *tmp; | ||
438 | 436 | ||
439 | switch (arg[0]) { | 437 | switch (arg[0]) { |
440 | case 'a': /* argument */ | 438 | case 'a': /* argument */ |
@@ -456,14 +454,6 @@ static int parse_probe_arg(char *arg, struct fetch_func *ff, int is_return) | |||
456 | } else | 454 | } else |
457 | ret = -EINVAL; | 455 | ret = -EINVAL; |
458 | break; | 456 | break; |
459 | case '%': /* named register */ | ||
460 | ret = regs_query_register_offset(arg + 1); | ||
461 | if (ret >= 0) { | ||
462 | ff->func = fetch_register; | ||
463 | ff->data = (void *)(unsigned long)ret; | ||
464 | ret = 0; | ||
465 | } | ||
466 | break; | ||
467 | case 's': /* stack */ | 457 | case 's': /* stack */ |
468 | if (arg[1] == 'a') { | 458 | if (arg[1] == 'a') { |
469 | ff->func = fetch_stack_address; | 459 | ff->func = fetch_stack_address; |
@@ -478,6 +468,31 @@ static int parse_probe_arg(char *arg, struct fetch_func *ff, int is_return) | |||
478 | } | 468 | } |
479 | } | 469 | } |
480 | break; | 470 | break; |
471 | default: | ||
472 | ret = -EINVAL; | ||
473 | } | ||
474 | return ret; | ||
475 | } | ||
476 | |||
477 | static int parse_probe_arg(char *arg, struct fetch_func *ff, int is_return) | ||
478 | { | ||
479 | int ret = 0; | ||
480 | unsigned long param; | ||
481 | long offset; | ||
482 | char *tmp; | ||
483 | |||
484 | switch (arg[0]) { | ||
485 | case '$': | ||
486 | ret = parse_probe_vars(arg + 1, ff, is_return); | ||
487 | break; | ||
488 | case '%': /* named register */ | ||
489 | ret = regs_query_register_offset(arg + 1); | ||
490 | if (ret >= 0) { | ||
491 | ff->func = fetch_register; | ||
492 | ff->data = (void *)(unsigned long)ret; | ||
493 | ret = 0; | ||
494 | } | ||
495 | break; | ||
481 | case '@': /* memory or symbol */ | 496 | case '@': /* memory or symbol */ |
482 | if (isdigit(arg[1])) { | 497 | if (isdigit(arg[1])) { |
483 | ret = strict_strtoul(arg + 1, 0, ¶m); | 498 | ret = strict_strtoul(arg + 1, 0, ¶m); |
@@ -489,8 +504,7 @@ static int parse_probe_arg(char *arg, struct fetch_func *ff, int is_return) | |||
489 | ret = split_symbol_offset(arg + 1, &offset); | 504 | ret = split_symbol_offset(arg + 1, &offset); |
490 | if (ret) | 505 | if (ret) |
491 | break; | 506 | break; |
492 | ff->data = alloc_symbol_cache(arg + 1, | 507 | ff->data = alloc_symbol_cache(arg + 1, offset); |
493 | offset); | ||
494 | if (ff->data) | 508 | if (ff->data) |
495 | ff->func = fetch_symbol; | 509 | ff->func = fetch_symbol; |
496 | else | 510 | else |
@@ -544,11 +558,11 @@ static int create_trace_probe(int argc, char **argv) | |||
544 | * - Add kprobe: p[:[GRP/]EVENT] KSYM[+OFFS]|KADDR [FETCHARGS] | 558 | * - Add kprobe: p[:[GRP/]EVENT] KSYM[+OFFS]|KADDR [FETCHARGS] |
545 | * - Add kretprobe: r[:[GRP/]EVENT] KSYM[+0] [FETCHARGS] | 559 | * - Add kretprobe: r[:[GRP/]EVENT] KSYM[+0] [FETCHARGS] |
546 | * Fetch args: | 560 | * Fetch args: |
547 | * aN : fetch Nth of function argument. (N:0-) | 561 | * $aN : fetch Nth of function argument. (N:0-) |
548 | * rv : fetch return value | 562 | * $rv : fetch return value |
549 | * ra : fetch return address | 563 | * $ra : fetch return address |
550 | * sa : fetch stack address | 564 | * $sa : fetch stack address |
551 | * sN : fetch Nth of stack (N:0-) | 565 | * $sN : fetch Nth of stack (N:0-) |
552 | * @ADDR : fetch memory at ADDR (ADDR should be in kernel) | 566 | * @ADDR : fetch memory at ADDR (ADDR should be in kernel) |
553 | * @SYM[+|-offs] : fetch memory at SYM +|- offs (SYM is a data symbol) | 567 | * @SYM[+|-offs] : fetch memory at SYM +|- offs (SYM is a data symbol) |
554 | * %REG : fetch register REG | 568 | * %REG : fetch register REG |