Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

perf dwarf-aux: Add die_get_scopes() alternative to dwarf_getscopes()

The die_get_scopes() returns the number of enclosing DIEs for the given
address and it fills an array of DIEs like dwarf_getscopes(). But it
doesn't follow the abstract origin of inlined functions as we want
information of the concrete instance. This is needed to check the
location of parameters and local variables properly. Users can check
the origin separately if needed.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: linux-toolchains@vger.kernel.org
Cc: linux-trace-devel@vger.kernel.org
Link: https://lore.kernel.org/r/20231110000012.3538610-7-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Namhyung Kim and committed by
Arnaldo Carvalho de Melo
981620fd 3796eba7

+56
+53
tools/perf/util/dwarf-aux.c
··· 1425 1425 1426 1426 *entrypc = postprologue_addr; 1427 1427 } 1428 + 1429 + /* Internal parameters for __die_find_scope_cb() */ 1430 + struct find_scope_data { 1431 + /* Target instruction address */ 1432 + Dwarf_Addr pc; 1433 + /* Number of scopes found [output] */ 1434 + int nr; 1435 + /* Array of scopes found, 0 for the outermost one. [output] */ 1436 + Dwarf_Die *scopes; 1437 + }; 1438 + 1439 + static int __die_find_scope_cb(Dwarf_Die *die_mem, void *arg) 1440 + { 1441 + struct find_scope_data *data = arg; 1442 + 1443 + if (dwarf_haspc(die_mem, data->pc)) { 1444 + Dwarf_Die *tmp; 1445 + 1446 + tmp = realloc(data->scopes, (data->nr + 1) * sizeof(*tmp)); 1447 + if (tmp == NULL) 1448 + return DIE_FIND_CB_END; 1449 + 1450 + memcpy(tmp + data->nr, die_mem, sizeof(*die_mem)); 1451 + data->scopes = tmp; 1452 + data->nr++; 1453 + return DIE_FIND_CB_CHILD; 1454 + } 1455 + return DIE_FIND_CB_SIBLING; 1456 + } 1457 + 1458 + /** 1459 + * die_get_scopes - Return a list of scopes including the address 1460 + * @cu_die: a compile unit DIE 1461 + * @pc: the address to find 1462 + * @scopes: the array of DIEs for scopes (result) 1463 + * 1464 + * This function does the same as the dwarf_getscopes() but doesn't follow 1465 + * the origins of inlined functions. It returns the number of scopes saved 1466 + * in the @scopes argument. The outer scope will be saved first (index 0) and 1467 + * the last one is the innermost scope at the @pc. 1468 + */ 1469 + int die_get_scopes(Dwarf_Die *cu_die, Dwarf_Addr pc, Dwarf_Die **scopes) 1470 + { 1471 + struct find_scope_data data = { 1472 + .pc = pc, 1473 + }; 1474 + Dwarf_Die die_mem; 1475 + 1476 + die_find_child(cu_die, __die_find_scope_cb, &data, &die_mem); 1477 + 1478 + *scopes = data.scopes; 1479 + return data.nr; 1480 + }
+3
tools/perf/util/dwarf-aux.h
··· 129 129 void die_skip_prologue(Dwarf_Die *sp_die, Dwarf_Die *cu_die, 130 130 Dwarf_Addr *entrypc); 131 131 132 + /* Get the list of including scopes */ 133 + int die_get_scopes(Dwarf_Die *cu_die, Dwarf_Addr pc, Dwarf_Die **scopes); 134 + 132 135 #ifdef HAVE_DWARF_GETLOCATIONS_SUPPORT 133 136 134 137 /* Get byte offset range of given variable DIE */