summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZecheng Li <zecheng@google.com>2026-03-09 20:55:15 +0300
committerNamhyung Kim <namhyung@kernel.org>2026-03-20 00:42:29 +0300
commitace16303179efad4e1a2aebb27a661e5d1e7277d (patch)
treed4953da4f6f3f21a7e1295c53a1b856a1ba52c8f
parent30b2e6fa58f3b9eff86fb851a8926bf814d82dcd (diff)
downloadlinux-ace16303179efad4e1a2aebb27a661e5d1e7277d.tar.xz
perf dwarf-aux: Preserve typedefs in match_var_offset
Preserve typedefs in match_var_offset to match the results by __die_get_real_type. Also move the (offset == 0) branch after the is_pointer check to ensure the correct type is used, fixing cases where an incorrect pointer type was chosen when the access offset was 0. Signed-off-by: Zecheng Li <zecheng@google.com> Signed-off-by: Zecheng Li <zli94@ncsu.edu> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
-rw-r--r--tools/perf/util/dwarf-aux.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c
index 38142062d6e5..3b0fc9038f19 100644
--- a/tools/perf/util/dwarf-aux.c
+++ b/tools/perf/util/dwarf-aux.c
@@ -1405,6 +1405,8 @@ struct find_var_data {
Dwarf_Addr addr;
/* Target register */
unsigned reg;
+ /* Access data type */
+ Dwarf_Die type;
/* Access offset, set for global data */
int offset;
/* True if the current register is the frame base */
@@ -1417,29 +1419,31 @@ struct find_var_data {
static bool match_var_offset(Dwarf_Die *die_mem, struct find_var_data *data,
s64 addr_offset, s64 addr_type, bool is_pointer)
{
- Dwarf_Die type_die;
Dwarf_Word size;
+ Dwarf_Die ptr_die;
+ Dwarf_Die *ptr_type;
s64 offset = addr_offset - addr_type;
- if (offset == 0) {
- /* Update offset relative to the start of the variable */
- data->offset = 0;
- return true;
- }
-
if (offset < 0)
return false;
- if (die_get_real_type(die_mem, &type_die) == NULL)
+ if (__die_get_real_type(die_mem, &data->type) == NULL)
return false;
- if (is_pointer && dwarf_tag(&type_die) == DW_TAG_pointer_type) {
+ ptr_type = die_get_pointer_type(&data->type, &ptr_die);
+ if (is_pointer && ptr_type) {
/* Get the target type of the pointer */
- if (die_get_real_type(&type_die, &type_die) == NULL)
+ if (__die_get_real_type(ptr_type, &data->type) == NULL)
return false;
}
- if (dwarf_aggregate_size(&type_die, &size) < 0)
+ if (offset == 0) {
+ /* Update offset relative to the start of the variable */
+ data->offset = 0;
+ return true;
+ }
+
+ if (dwarf_aggregate_size(&data->type, &size) < 0)
return false;
if ((u64)offset >= size)