aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_kprobe.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/trace_kprobe.c')
-rw-r--r--kernel/trace/trace_kprobe.c60
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
432static int parse_probe_arg(char *arg, struct fetch_func *ff, int is_return) 432static 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
477static 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, &param); 498 ret = strict_strtoul(arg + 1, 0, &param);
@@ -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