diff options
-rw-r--r-- | tools/perf/util/probe-finder.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index a2d1f790d937..abcaec555204 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c | |||
@@ -329,25 +329,35 @@ static Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, | |||
329 | return die_find_child(sp_die, __die_find_inline_cb, &addr, die_mem); | 329 | return die_find_child(sp_die, __die_find_inline_cb, &addr, die_mem); |
330 | } | 330 | } |
331 | 331 | ||
332 | struct __find_variable_param { | ||
333 | const char *name; | ||
334 | Dwarf_Addr addr; | ||
335 | }; | ||
336 | |||
332 | static int __die_find_variable_cb(Dwarf_Die *die_mem, void *data) | 337 | static int __die_find_variable_cb(Dwarf_Die *die_mem, void *data) |
333 | { | 338 | { |
334 | const char *name = data; | 339 | struct __find_variable_param *fvp = data; |
335 | int tag; | 340 | int tag; |
336 | 341 | ||
337 | tag = dwarf_tag(die_mem); | 342 | tag = dwarf_tag(die_mem); |
338 | if ((tag == DW_TAG_formal_parameter || | 343 | if ((tag == DW_TAG_formal_parameter || |
339 | tag == DW_TAG_variable) && | 344 | tag == DW_TAG_variable) && |
340 | die_compare_name(die_mem, name)) | 345 | die_compare_name(die_mem, fvp->name)) |
341 | return DIE_FIND_CB_FOUND; | 346 | return DIE_FIND_CB_FOUND; |
342 | 347 | ||
343 | return DIE_FIND_CB_CONTINUE; | 348 | if (dwarf_haspc(die_mem, fvp->addr)) |
349 | return DIE_FIND_CB_CONTINUE; | ||
350 | else | ||
351 | return DIE_FIND_CB_SIBLING; | ||
344 | } | 352 | } |
345 | 353 | ||
346 | /* Find a variable called 'name' */ | 354 | /* Find a variable called 'name' at given address */ |
347 | static Dwarf_Die *die_find_variable(Dwarf_Die *sp_die, const char *name, | 355 | static Dwarf_Die *die_find_variable_at(Dwarf_Die *sp_die, const char *name, |
348 | Dwarf_Die *die_mem) | 356 | Dwarf_Addr addr, Dwarf_Die *die_mem) |
349 | { | 357 | { |
350 | return die_find_child(sp_die, __die_find_variable_cb, (void *)name, | 358 | struct __find_variable_param fvp = { .name = name, .addr = addr}; |
359 | |||
360 | return die_find_child(sp_die, __die_find_variable_cb, (void *)&fvp, | ||
351 | die_mem); | 361 | die_mem); |
352 | } | 362 | } |
353 | 363 | ||
@@ -731,7 +741,7 @@ static int find_variable(Dwarf_Die *sp_die, struct probe_finder *pf) | |||
731 | pr_debug("Searching '%s' variable in context.\n", | 741 | pr_debug("Searching '%s' variable in context.\n", |
732 | pf->pvar->var); | 742 | pf->pvar->var); |
733 | /* Search child die for local variables and parameters. */ | 743 | /* Search child die for local variables and parameters. */ |
734 | if (die_find_variable(sp_die, pf->pvar->var, &vr_die)) | 744 | if (die_find_variable_at(sp_die, pf->pvar->var, pf->addr, &vr_die)) |
735 | ret = convert_variable(&vr_die, pf); | 745 | ret = convert_variable(&vr_die, pf); |
736 | else { | 746 | else { |
737 | /* Search upper class */ | 747 | /* Search upper class */ |