summaryrefslogtreecommitdiffstats
path: root/tools/perf/util/probe-finder.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/probe-finder.c')
-rw-r--r--tools/perf/util/probe-finder.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index ab47673..1f45285 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)
const char *regs;
struct kprobe_trace_arg *tvar = pf->tvar;
- /* TODO: support CFA */
/* If this is based on frame buffer, set the offset */
if (op->atom == DW_OP_fbreg) {
if (pf->fb_ops == NULL)
@@ -629,11 +628,17 @@ static void convert_probe_point(Dwarf_Die *sp_die, struct probe_finder *pf)
/* Get the frame base attribute/ops */
dwarf_attr(sp_die, DW_AT_frame_base, &fb_attr);
ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1);
- if (ret <= 0 || nops == 0)
+ if (ret <= 0 || nops == 0) {
pf->fb_ops = NULL;
+ } else if (nops == 1 && pf->fb_ops[0].atom == DW_OP_call_frame_cfa &&
+ pf->cfi != NULL) {
+ Dwarf_Frame *frame;
+ ret = dwarf_cfi_addrframe(pf->cfi, pf->addr, &frame);
+ DIE_IF(ret != 0);
+ dwarf_frame_cfa(frame, &pf->fb_ops, &nops);
+ }
/* Find each argument */
- /* TODO: use dwarf_cfi_addrframe */
tev->nargs = pf->pev->nargs;
tev->args = xzalloc(sizeof(struct kprobe_trace_arg) * tev->nargs);
for (i = 0; i < pf->pev->nargs; i++) {
@@ -842,6 +847,9 @@ int find_kprobe_trace_events(int fd, struct perf_probe_event *pev,
if (!dbg)
return -ENOENT;
+ /* Get the call frame information from this dwarf */
+ pf.cfi = dwarf_getcfi(dbg);
+
off = 0;
line_list__init(&pf.lcache);
/* Loop on CUs (Compilation Unit) */
OpenPOWER on IntegriCloud