diff options
Diffstat (limited to 'kernel/trace/trace_kprobe.c')
-rw-r--r-- | kernel/trace/trace_kprobe.c | 52 |
1 files changed, 24 insertions, 28 deletions
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index ba6d3bd48889..3313fa74ce5f 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c | |||
@@ -215,22 +215,22 @@ static int probe_arg_string(char *buf, size_t n, struct fetch_func *ff) | |||
215 | int ret = -EINVAL; | 215 | int ret = -EINVAL; |
216 | 216 | ||
217 | if (ff->func == fetch_argument) | 217 | if (ff->func == fetch_argument) |
218 | ret = snprintf(buf, n, "$a%lu", (unsigned long)ff->data); | 218 | ret = snprintf(buf, n, "$arg%lu", (unsigned long)ff->data); |
219 | else if (ff->func == fetch_register) { | 219 | else if (ff->func == fetch_register) { |
220 | const char *name; | 220 | const char *name; |
221 | name = regs_query_register_name((unsigned int)((long)ff->data)); | 221 | name = regs_query_register_name((unsigned int)((long)ff->data)); |
222 | ret = snprintf(buf, n, "%%%s", name); | 222 | ret = snprintf(buf, n, "%%%s", name); |
223 | } else if (ff->func == fetch_stack) | 223 | } else if (ff->func == fetch_stack) |
224 | ret = snprintf(buf, n, "$s%lu", (unsigned long)ff->data); | 224 | ret = snprintf(buf, n, "$stack%lu", (unsigned long)ff->data); |
225 | else if (ff->func == fetch_memory) | 225 | else if (ff->func == fetch_memory) |
226 | ret = snprintf(buf, n, "@0x%p", ff->data); | 226 | ret = snprintf(buf, n, "@0x%p", ff->data); |
227 | else if (ff->func == fetch_symbol) { | 227 | else if (ff->func == fetch_symbol) { |
228 | struct symbol_cache *sc = ff->data; | 228 | struct symbol_cache *sc = ff->data; |
229 | ret = snprintf(buf, n, "@%s%+ld", sc->symbol, sc->offset); | 229 | ret = snprintf(buf, n, "@%s%+ld", sc->symbol, sc->offset); |
230 | } else if (ff->func == fetch_retvalue) | 230 | } else if (ff->func == fetch_retvalue) |
231 | ret = snprintf(buf, n, "$rv"); | 231 | ret = snprintf(buf, n, "$retval"); |
232 | else if (ff->func == fetch_stack_address) | 232 | else if (ff->func == fetch_stack_address) |
233 | ret = snprintf(buf, n, "$sa"); | 233 | ret = snprintf(buf, n, "$stack"); |
234 | else if (ff->func == fetch_indirect) { | 234 | else if (ff->func == fetch_indirect) { |
235 | struct indirect_fetch_data *id = ff->data; | 235 | struct indirect_fetch_data *id = ff->data; |
236 | size_t l = 0; | 236 | size_t l = 0; |
@@ -427,40 +427,36 @@ static int parse_probe_vars(char *arg, struct fetch_func *ff, int is_return) | |||
427 | int ret = 0; | 427 | int ret = 0; |
428 | unsigned long param; | 428 | unsigned long param; |
429 | 429 | ||
430 | switch (arg[0]) { | 430 | if (strcmp(arg, "retval") == 0) { |
431 | case 'a': /* argument */ | 431 | if (is_return) { |
432 | ret = strict_strtoul(arg + 1, 10, ¶m); | ||
433 | if (ret || param > PARAM_MAX_ARGS) | ||
434 | ret = -EINVAL; | ||
435 | else { | ||
436 | ff->func = fetch_argument; | ||
437 | ff->data = (void *)param; | ||
438 | } | ||
439 | break; | ||
440 | case 'r': /* retval or retaddr */ | ||
441 | if (is_return && arg[1] == 'v') { | ||
442 | ff->func = fetch_retvalue; | 432 | ff->func = fetch_retvalue; |
443 | ff->data = NULL; | 433 | ff->data = NULL; |
444 | } else | 434 | } else |
445 | ret = -EINVAL; | 435 | ret = -EINVAL; |
446 | break; | 436 | } else if (strncmp(arg, "stack", 5) == 0) { |
447 | case 's': /* stack */ | 437 | if (arg[5] == '\0') { |
448 | if (arg[1] == 'a') { | ||
449 | ff->func = fetch_stack_address; | 438 | ff->func = fetch_stack_address; |
450 | ff->data = NULL; | 439 | ff->data = NULL; |
451 | } else { | 440 | } else if (isdigit(arg[5])) { |
452 | ret = strict_strtoul(arg + 1, 10, ¶m); | 441 | ret = strict_strtoul(arg + 5, 10, ¶m); |
453 | if (ret || param > PARAM_MAX_STACK) | 442 | if (ret || param > PARAM_MAX_STACK) |
454 | ret = -EINVAL; | 443 | ret = -EINVAL; |
455 | else { | 444 | else { |
456 | ff->func = fetch_stack; | 445 | ff->func = fetch_stack; |
457 | ff->data = (void *)param; | 446 | ff->data = (void *)param; |
458 | } | 447 | } |
448 | } else | ||
449 | ret = -EINVAL; | ||
450 | } else if (strncmp(arg, "arg", 3) == 0 && isdigit(arg[3])) { | ||
451 | ret = strict_strtoul(arg + 3, 10, ¶m); | ||
452 | if (ret || param > PARAM_MAX_ARGS) | ||
453 | ret = -EINVAL; | ||
454 | else { | ||
455 | ff->func = fetch_argument; | ||
456 | ff->data = (void *)param; | ||
459 | } | 457 | } |
460 | break; | 458 | } else |
461 | default: | ||
462 | ret = -EINVAL; | 459 | ret = -EINVAL; |
463 | } | ||
464 | return ret; | 460 | return ret; |
465 | } | 461 | } |
466 | 462 | ||
@@ -548,10 +544,10 @@ static int create_trace_probe(int argc, char **argv) | |||
548 | * - Add kprobe: p[:[GRP/]EVENT] KSYM[+OFFS]|KADDR [FETCHARGS] | 544 | * - Add kprobe: p[:[GRP/]EVENT] KSYM[+OFFS]|KADDR [FETCHARGS] |
549 | * - Add kretprobe: r[:[GRP/]EVENT] KSYM[+0] [FETCHARGS] | 545 | * - Add kretprobe: r[:[GRP/]EVENT] KSYM[+0] [FETCHARGS] |
550 | * Fetch args: | 546 | * Fetch args: |
551 | * $aN : fetch Nth of function argument. (N:0-) | 547 | * $argN : fetch Nth of function argument. (N:0-) |
552 | * $rv : fetch return value | 548 | * $retval : fetch return value |
553 | * $sa : fetch stack address | 549 | * $stack : fetch stack address |
554 | * $sN : fetch Nth of stack (N:0-) | 550 | * $stackN : fetch Nth of stack (N:0-) |
555 | * @ADDR : fetch memory at ADDR (ADDR should be in kernel) | 551 | * @ADDR : fetch memory at ADDR (ADDR should be in kernel) |
556 | * @SYM[+|-offs] : fetch memory at SYM +|- offs (SYM is a data symbol) | 552 | * @SYM[+|-offs] : fetch memory at SYM +|- offs (SYM is a data symbol) |
557 | * %REG : fetch register REG | 553 | * %REG : fetch register REG |