aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/probe-finder.c
diff options
context:
space:
mode:
authorMasami Hiramatsu <mhiramat@redhat.com>2010-05-19 15:57:35 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2010-07-05 17:47:28 -0400
commit73317b954041031249e8968d2e9023ff4e960d99 (patch)
tree44768b7724bacbb15c54057710c70accce1cd8c3 /tools/perf/util/probe-finder.c
parente09c8614b32915c16f68e039ac7040e602d73e35 (diff)
perf probe: Support "string" type
Support string type casting to event argument. If perf-probe finds an argument casted as string, it ensures the target variable is "(unsigned/signed) char *(or []). perf-probe also adds dereference if the target is a pointer. So, both of 'char buf[10];' and 'char *buf;' can be accessed by 'buf:string' Cc: Ingo Molnar <mingo@elte.hu> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Mike Galbraith <efault@gmx.de> Cc: Frederic Weisbecker <fweisbec@gmail.com> LKML-Reference: <20100519195734.2885.1666.stgit@localhost6.localdomain6> Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/probe-finder.c')
-rw-r--r--tools/perf/util/probe-finder.c59
1 files changed, 48 insertions, 11 deletions
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index baf66538349..aaea16b1c60 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -464,18 +464,61 @@ static int convert_location(Dwarf_Op *op, struct probe_finder *pf)
464} 464}
465 465
466static int convert_variable_type(Dwarf_Die *vr_die, 466static int convert_variable_type(Dwarf_Die *vr_die,
467 struct kprobe_trace_arg *targ) 467 struct kprobe_trace_arg *tvar,
468 const char *cast)
468{ 469{
470 struct kprobe_trace_arg_ref **ref_ptr = &tvar->ref;
469 Dwarf_Die type; 471 Dwarf_Die type;
470 char buf[16]; 472 char buf[16];
471 int ret; 473 int ret;
472 474
475 /* TODO: check all types */
476 if (cast && strcmp(cast, "string") != 0) {
477 /* Non string type is OK */
478 tvar->type = strdup(cast);
479 return (tvar->type == NULL) ? -ENOMEM : 0;
480 }
481
473 if (die_get_real_type(vr_die, &type) == NULL) { 482 if (die_get_real_type(vr_die, &type) == NULL) {
474 pr_warning("Failed to get a type information of %s.\n", 483 pr_warning("Failed to get a type information of %s.\n",
475 dwarf_diename(vr_die)); 484 dwarf_diename(vr_die));
476 return -ENOENT; 485 return -ENOENT;
477 } 486 }
478 487
488 if (cast && strcmp(cast, "string") == 0) { /* String type */
489 ret = dwarf_tag(&type);
490 if (ret != DW_TAG_pointer_type &&
491 ret != DW_TAG_array_type) {
492 pr_warning("Failed to cast into string: "
493 "%s(%s) is not a pointer nor array.",
494 dwarf_diename(vr_die), dwarf_diename(&type));
495 return -EINVAL;
496 }
497 if (ret == DW_TAG_pointer_type) {
498 if (die_get_real_type(&type, &type) == NULL) {
499 pr_warning("Failed to get a type information.");
500 return -ENOENT;
501 }
502 while (*ref_ptr)
503 ref_ptr = &(*ref_ptr)->next;
504 /* Add new reference with offset +0 */
505 *ref_ptr = zalloc(sizeof(struct kprobe_trace_arg_ref));
506 if (*ref_ptr == NULL) {
507 pr_warning("Out of memory error\n");
508 return -ENOMEM;
509 }
510 }
511 if (die_compare_name(&type, "char") != 0 &&
512 die_compare_name(&type, "unsigned char") != 0) {
513 pr_warning("Failed to cast into string: "
514 "%s is not (unsigned) char *.",
515 dwarf_diename(vr_die));
516 return -EINVAL;
517 }
518 tvar->type = strdup(cast);
519 return (tvar->type == NULL) ? -ENOMEM : 0;
520 }
521
479 ret = die_get_byte_size(&type) * 8; 522 ret = die_get_byte_size(&type) * 8;
480 if (ret) { 523 if (ret) {
481 /* Check the bitwidth */ 524 /* Check the bitwidth */
@@ -495,8 +538,8 @@ static int convert_variable_type(Dwarf_Die *vr_die,
495 strerror(-ret)); 538 strerror(-ret));
496 return ret; 539 return ret;
497 } 540 }
498 targ->type = strdup(buf); 541 tvar->type = strdup(buf);
499 if (targ->type == NULL) 542 if (tvar->type == NULL)
500 return -ENOMEM; 543 return -ENOMEM;
501 } 544 }
502 return 0; 545 return 0;
@@ -606,14 +649,8 @@ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
606 &die_mem); 649 &die_mem);
607 vr_die = &die_mem; 650 vr_die = &die_mem;
608 } 651 }
609 if (ret == 0) { 652 if (ret == 0)
610 if (pf->pvar->type) { 653 ret = convert_variable_type(vr_die, pf->tvar, pf->pvar->type);
611 pf->tvar->type = strdup(pf->pvar->type);
612 if (pf->tvar->type == NULL)
613 ret = -ENOMEM;
614 } else
615 ret = convert_variable_type(vr_die, pf->tvar);
616 }
617 /* *expr will be cached in libdw. Don't free it. */ 654 /* *expr will be cached in libdw. Don't free it. */
618 return ret; 655 return ret;
619error: 656error: