diff options
-rw-r--r-- | tools/perf/util/dwarf-aux.c | 15 | ||||
-rw-r--r-- | tools/perf/util/dwarf-aux.h | 3 | ||||
-rw-r--r-- | tools/perf/util/probe-finder.c | 12 |
3 files changed, 22 insertions, 8 deletions
diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index cc66c4049e09..780b2bc11128 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c | |||
@@ -278,6 +278,21 @@ bool die_is_func_def(Dwarf_Die *dw_die) | |||
278 | } | 278 | } |
279 | 279 | ||
280 | /** | 280 | /** |
281 | * die_is_func_instance - Ensure that this DIE is an instance of a subprogram | ||
282 | * @dw_die: a DIE | ||
283 | * | ||
284 | * Ensure that this DIE is an instance (which has an entry address). | ||
285 | * This returns true if @dw_die is a function instance. If not, you need to | ||
286 | * call die_walk_instances() to find actual instances. | ||
287 | **/ | ||
288 | bool die_is_func_instance(Dwarf_Die *dw_die) | ||
289 | { | ||
290 | Dwarf_Addr tmp; | ||
291 | |||
292 | /* Actually gcc optimizes non-inline as like as inlined */ | ||
293 | return !dwarf_func_inline(dw_die) && dwarf_entrypc(dw_die, &tmp) == 0; | ||
294 | } | ||
295 | /** | ||
281 | * die_get_data_member_location - Get the data-member offset | 296 | * die_get_data_member_location - Get the data-member offset |
282 | * @mb_die: a DIE of a member of a data structure | 297 | * @mb_die: a DIE of a member of a data structure |
283 | * @offs: The offset of the member in the data structure | 298 | * @offs: The offset of the member in the data structure |
diff --git a/tools/perf/util/dwarf-aux.h b/tools/perf/util/dwarf-aux.h index b4fe90c6cb2d..af7dbcd5f929 100644 --- a/tools/perf/util/dwarf-aux.h +++ b/tools/perf/util/dwarf-aux.h | |||
@@ -41,6 +41,9 @@ extern int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr, | |||
41 | /* Ensure that this DIE is a subprogram and definition (not declaration) */ | 41 | /* Ensure that this DIE is a subprogram and definition (not declaration) */ |
42 | extern bool die_is_func_def(Dwarf_Die *dw_die); | 42 | extern bool die_is_func_def(Dwarf_Die *dw_die); |
43 | 43 | ||
44 | /* Ensure that this DIE is an instance of a subprogram */ | ||
45 | extern bool die_is_func_instance(Dwarf_Die *dw_die); | ||
46 | |||
44 | /* Compare diename and tname */ | 47 | /* Compare diename and tname */ |
45 | extern bool die_compare_name(Dwarf_Die *dw_die, const char *tname); | 48 | extern bool die_compare_name(Dwarf_Die *dw_die, const char *tname); |
46 | 49 | ||
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index b5247d777f0e..d14193518e4d 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c | |||
@@ -915,17 +915,13 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data) | |||
915 | dwarf_decl_line(sp_die, &pf->lno); | 915 | dwarf_decl_line(sp_die, &pf->lno); |
916 | pf->lno += pp->line; | 916 | pf->lno += pp->line; |
917 | param->retval = find_probe_point_by_line(pf); | 917 | param->retval = find_probe_point_by_line(pf); |
918 | } else if (!dwarf_func_inline(sp_die)) { | 918 | } else if (die_is_func_instance(sp_die)) { |
919 | /* Instances always have the entry address */ | ||
920 | dwarf_entrypc(sp_die, &pf->addr); | ||
919 | /* Real function */ | 921 | /* Real function */ |
920 | if (pp->lazy_line) | 922 | if (pp->lazy_line) |
921 | param->retval = find_probe_point_lazy(sp_die, pf); | 923 | param->retval = find_probe_point_lazy(sp_die, pf); |
922 | else { | 924 | else { |
923 | if (dwarf_entrypc(sp_die, &pf->addr) != 0) { | ||
924 | pr_warning("Failed to get entry address of " | ||
925 | "%s.\n", dwarf_diename(sp_die)); | ||
926 | param->retval = -ENOENT; | ||
927 | return DWARF_CB_ABORT; | ||
928 | } | ||
929 | pf->addr += pp->offset; | 925 | pf->addr += pp->offset; |
930 | /* TODO: Check the address in this function */ | 926 | /* TODO: Check the address in this function */ |
931 | param->retval = call_probe_finder(sp_die, pf); | 927 | param->retval = call_probe_finder(sp_die, pf); |
@@ -1536,7 +1532,7 @@ static int line_range_search_cb(Dwarf_Die *sp_die, void *data) | |||
1536 | pr_debug("New line range: %d to %d\n", lf->lno_s, lf->lno_e); | 1532 | pr_debug("New line range: %d to %d\n", lf->lno_s, lf->lno_e); |
1537 | lr->start = lf->lno_s; | 1533 | lr->start = lf->lno_s; |
1538 | lr->end = lf->lno_e; | 1534 | lr->end = lf->lno_e; |
1539 | if (dwarf_func_inline(sp_die)) | 1535 | if (!die_is_func_instance(sp_die)) |
1540 | param->retval = die_walk_instances(sp_die, | 1536 | param->retval = die_walk_instances(sp_die, |
1541 | line_range_inline_cb, lf); | 1537 | line_range_inline_cb, lf); |
1542 | else | 1538 | else |