From 1bafda2c4595f0f936a5845caf9667b70b198091 Mon Sep 17 00:00:00 2001 From: Tom de Vries Date: Wed, 9 Apr 2025 12:02:18 +0200 Subject: [gdb/symtab] Handle DW_OP_entry_value at function entry On riscv64-linux, with test-case gdb.base/vla-optimized-out.exp I ran into: ... (gdb) p sizeof (a)^M $2 = ^M (gdb) FAIL: $exp: o1: printed size of optimized out vla ... The variable a has type 0xbf: ... <1>: Abbrev Number: 12 (DW_TAG_array_type) DW_AT_type : <0xe3> DW_AT_sibling : <0xdc> <2>: Abbrev Number: 13 (DW_TAG_subrange_type) DW_AT_type : <0xdc> DW_AT_upper_bound : 13 byte block: a3 1 5a 23 1 8 20 24 8 20 26 31 1c (DW_OP_entry_value: (DW_OP_reg10 (a0)); DW_OP_plus_uconst: 1; DW_OP_const1u: 32; DW_OP_shl; DW_OP_const1u: 32; DW_OP_shra; DW_OP_lit1; DW_OP_minus) ... which has an upper bound using a DW_OP_entry_value, and since the corresponding call site contains no information to resolve the value of a0 at function entry: ... <2><6b>: Abbrev Number: 6 (DW_TAG_call_site) <6c> DW_AT_call_return_pc: 0x638 <74> DW_AT_call_origin : <0x85> ... evaluting the dwarf expression fails, and we get . My first thought was to try breaking at *f1 instead of f1 to see if that would help, but actually the breakpoint resolved to the same address. In other words, the inferior is stopped at function entry. Fix this by resolving DW_OP_entry_value when stopped at function entry by simply evaluating the expression. This handles these two cases (x86_64, using reg rdi): - DW_OP_entry_value: (DW_OP_regx: 5 (rdi)) - DW_OP_entry_value: (DW_OP_bregx: 5 (rdi) 0; DW_OP_deref_size: 4) Tested on x86_64-linux. Tested gdb.base/vla-optimized-out.exp on riscv64-linux. Tested an earlier version of gdb.dwarf2/dw2-entry-value-2.exp on riscv64-linux, but atm I'm running into trouble on that machine (cfarm92) so I haven't tested the current version there. --- gdb/dwarf2/expr.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'gdb/dwarf2/expr.h') diff --git a/gdb/dwarf2/expr.h b/gdb/dwarf2/expr.h index ab92d9a..0129fb9 100644 --- a/gdb/dwarf2/expr.h +++ b/gdb/dwarf2/expr.h @@ -256,6 +256,10 @@ private: but with the address being 0. In this situation, we arrange for memory reads to come from the passed-in buffer. */ void read_mem (gdb_byte *buf, CORE_ADDR addr, size_t length); + + /* Deref ADDR with size SIZE and return a value of type TYPE. + If TYPE == nullptr, defaults to this->address_type (). */ + value *deref (CORE_ADDR addr, int size, struct type *type = nullptr); }; /* Return the value of register number REG (a DWARF register number), -- cgit v1.1