diff options
-rw-r--r-- | tools/perf/util/probe-finder.c | 14 | ||||
-rw-r--r-- | tools/perf/util/probe-finder.h | 1 |
2 files changed, 12 insertions, 3 deletions
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index ab476736cbe7..1f4528555d42 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c | |||
@@ -398,7 +398,6 @@ static void convert_location(Dwarf_Op *op, struct probe_finder *pf) | |||
398 | const char *regs; | 398 | const char *regs; |
399 | struct kprobe_trace_arg *tvar = pf->tvar; | 399 | struct kprobe_trace_arg *tvar = pf->tvar; |
400 | 400 | ||
401 | /* TODO: support CFA */ | ||
402 | /* If this is based on frame buffer, set the offset */ | 401 | /* If this is based on frame buffer, set the offset */ |
403 | if (op->atom == DW_OP_fbreg) { | 402 | if (op->atom == DW_OP_fbreg) { |
404 | if (pf->fb_ops == NULL) | 403 | if (pf->fb_ops == NULL) |
@@ -629,11 +628,17 @@ static void convert_probe_point(Dwarf_Die *sp_die, struct probe_finder *pf) | |||
629 | /* Get the frame base attribute/ops */ | 628 | /* Get the frame base attribute/ops */ |
630 | dwarf_attr(sp_die, DW_AT_frame_base, &fb_attr); | 629 | dwarf_attr(sp_die, DW_AT_frame_base, &fb_attr); |
631 | ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1); | 630 | ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1); |
632 | if (ret <= 0 || nops == 0) | 631 | if (ret <= 0 || nops == 0) { |
633 | pf->fb_ops = NULL; | 632 | pf->fb_ops = NULL; |
633 | } else if (nops == 1 && pf->fb_ops[0].atom == DW_OP_call_frame_cfa && | ||
634 | pf->cfi != NULL) { | ||
635 | Dwarf_Frame *frame; | ||
636 | ret = dwarf_cfi_addrframe(pf->cfi, pf->addr, &frame); | ||
637 | DIE_IF(ret != 0); | ||
638 | dwarf_frame_cfa(frame, &pf->fb_ops, &nops); | ||
639 | } | ||
634 | 640 | ||
635 | /* Find each argument */ | 641 | /* Find each argument */ |
636 | /* TODO: use dwarf_cfi_addrframe */ | ||
637 | tev->nargs = pf->pev->nargs; | 642 | tev->nargs = pf->pev->nargs; |
638 | tev->args = xzalloc(sizeof(struct kprobe_trace_arg) * tev->nargs); | 643 | tev->args = xzalloc(sizeof(struct kprobe_trace_arg) * tev->nargs); |
639 | for (i = 0; i < pf->pev->nargs; i++) { | 644 | for (i = 0; i < pf->pev->nargs; i++) { |
@@ -842,6 +847,9 @@ int find_kprobe_trace_events(int fd, struct perf_probe_event *pev, | |||
842 | if (!dbg) | 847 | if (!dbg) |
843 | return -ENOENT; | 848 | return -ENOENT; |
844 | 849 | ||
850 | /* Get the call frame information from this dwarf */ | ||
851 | pf.cfi = dwarf_getcfi(dbg); | ||
852 | |||
845 | off = 0; | 853 | off = 0; |
846 | line_list__init(&pf.lcache); | 854 | line_list__init(&pf.lcache); |
847 | /* Loop on CUs (Compilation Unit) */ | 855 | /* Loop on CUs (Compilation Unit) */ |
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h index 2a271321944f..310ce897229c 100644 --- a/tools/perf/util/probe-finder.h +++ b/tools/perf/util/probe-finder.h | |||
@@ -42,6 +42,7 @@ struct probe_finder { | |||
42 | struct list_head lcache; /* Line cache for lazy match */ | 42 | struct list_head lcache; /* Line cache for lazy match */ |
43 | 43 | ||
44 | /* For variable searching */ | 44 | /* For variable searching */ |
45 | Dwarf_CFI *cfi; /* Call Frame Information */ | ||
45 | Dwarf_Op *fb_ops; /* Frame base attribute */ | 46 | Dwarf_Op *fb_ops; /* Frame base attribute */ |
46 | struct perf_probe_arg *pvar; /* Current target variable */ | 47 | struct perf_probe_arg *pvar; /* Current target variable */ |
47 | struct kprobe_trace_arg *tvar; /* Current result variable */ | 48 | struct kprobe_trace_arg *tvar; /* Current result variable */ |