aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/perf/util/probe-finder.c14
-rw-r--r--tools/perf/util/probe-finder.h1
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 */