From 414bf79debdce9bb682b4f23f87ea97568afa67b Mon Sep 17 00:00:00 2001 From: Zecheng Li Date: Mon, 25 Aug 2025 19:54:03 +0000 Subject: [PATCH] perf dwarf-aux: Use signed variable types in match_var_offset match_var_offset() compares address offsets to determine if an access falls within a variable's bounds. The offsets involved for those relative to base registers from DW_OP_breg can be negative. The current implementation uses unsigned types (u64) for these offsets, which rejects almost all negative values. Change the signature of match_var_offset() to use signed types (s64). This ensures correct behavior when addr_offset or addr_type are negative. Reviewed-by: Namhyung Kim Signed-off-by: Zecheng Li Cc: Adrian Hunter Cc: Alexander Shishkin Cc: Ian Rogers Cc: Ingo Molnar Cc: Jiri Olsa Cc: Kan Liang Cc: Mark Rutland Cc: Masami Hiramatsu Cc: Peter Zijlstra Cc: Xu Liu Link: https://lore.kernel.org/r/20250825195412.223077-2-zecheng@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/dwarf-aux.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index 559c953ca172..920054425578 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c @@ -1388,18 +1388,19 @@ struct find_var_data { #define DWARF_OP_DIRECT_REGS 32 static bool match_var_offset(Dwarf_Die *die_mem, struct find_var_data *data, - u64 addr_offset, u64 addr_type, bool is_pointer) + s64 addr_offset, s64 addr_type, bool is_pointer) { Dwarf_Die type_die; Dwarf_Word size; + s64 offset = addr_offset - addr_type; - if (addr_offset == addr_type) { + if (offset == 0) { /* Update offset relative to the start of the variable */ data->offset = 0; return true; } - if (addr_offset < addr_type) + if (offset < 0) return false; if (die_get_real_type(die_mem, &type_die) == NULL) @@ -1414,11 +1415,11 @@ static bool match_var_offset(Dwarf_Die *die_mem, struct find_var_data *data, if (dwarf_aggregate_size(&type_die, &size) < 0) return false; - if (addr_offset >= addr_type + size) + if ((u64)offset >= size) return false; /* Update offset relative to the start of the variable */ - data->offset = addr_offset - addr_type; + data->offset = offset; return true; } -- 2.51.0