On Wed, 11 Oct 2023 20:50:29 -0700 Namhyung Kim <namhyung@xxxxxxxxxx> wrote: > The die_get_scopes() would return 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. This looks good to me. Acked-by: Masami Hiramatsu (Google) <mhiramat@xxxxxxxxxx> Thanks > > Cc: Masami Hiramatsu <mhiramat@xxxxxxxxxx> > Signed-off-by: Namhyung Kim <namhyung@xxxxxxxxxx> > --- > tools/perf/util/dwarf-aux.c | 53 +++++++++++++++++++++++++++++++++++++ > tools/perf/util/dwarf-aux.h | 3 +++ > 2 files changed, 56 insertions(+) > > diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c > index adef2635587d..10aa32334d6f 100644 > --- a/tools/perf/util/dwarf-aux.c > +++ b/tools/perf/util/dwarf-aux.c > @@ -1425,3 +1425,56 @@ void die_skip_prologue(Dwarf_Die *sp_die, Dwarf_Die *cu_die, > > *entrypc = postprologue_addr; > } > + > +/* Internal parameters for __die_find_scope_cb() */ > +struct find_scope_data { > + /* Target instruction address */ > + Dwarf_Addr pc; > + /* Number of scopes found [output] */ > + int nr; > + /* Array of scopes found, 0 for the outermost one. [output] */ > + Dwarf_Die *scopes; > +}; > + > +static int __die_find_scope_cb(Dwarf_Die *die_mem, void *arg) > +{ > + struct find_scope_data *data = arg; > + > + if (dwarf_haspc(die_mem, data->pc)) { > + Dwarf_Die *tmp; > + > + tmp = realloc(data->scopes, (data->nr + 1) * sizeof(*tmp)); > + if (tmp == NULL) > + return DIE_FIND_CB_END; > + > + memcpy(tmp + data->nr, die_mem, sizeof(*die_mem)); > + data->scopes = tmp; > + data->nr++; > + return DIE_FIND_CB_CHILD; > + } > + return DIE_FIND_CB_SIBLING; > +} > + > +/** > + * die_get_scopes - Return a list of scopes including the address > + * @cu_die: a compile unit DIE > + * @pc: the address to find > + * @scopes: the array of DIEs for scopes (result) > + * > + * This function does the same as the dwarf_getscopes() but doesn't follow > + * the origins of inlined functions. It returns the number of scopes saved > + * in the @scopes argument. The outer scope will be saved first (index 0) and > + * the last one is the innermost scope at the @pc. > + */ > +int die_get_scopes(Dwarf_Die *cu_die, Dwarf_Addr pc, Dwarf_Die **scopes) > +{ > + struct find_scope_data data = { > + .pc = pc, > + }; > + Dwarf_Die die_mem; > + > + die_find_child(cu_die, __die_find_scope_cb, &data, &die_mem); > + > + *scopes = data.scopes; > + return data.nr; > +} > diff --git a/tools/perf/util/dwarf-aux.h b/tools/perf/util/dwarf-aux.h > index 4f5d0211ee4f..f9d765f80fb0 100644 > --- a/tools/perf/util/dwarf-aux.h > +++ b/tools/perf/util/dwarf-aux.h > @@ -129,6 +129,9 @@ bool die_is_optimized_target(Dwarf_Die *cu_die); > void die_skip_prologue(Dwarf_Die *sp_die, Dwarf_Die *cu_die, > Dwarf_Addr *entrypc); > > +/* Get the list of including scopes */ > +int die_get_scopes(Dwarf_Die *cu_die, Dwarf_Addr pc, Dwarf_Die **scopes); > + > #ifdef HAVE_DWARF_GETLOCATIONS_SUPPORT > > /* Get byte offset range of given variable DIE */ > -- > 2.42.0.655.g421f12c284-goog > -- Masami Hiramatsu (Google) <mhiramat@xxxxxxxxxx>