aboutsummaryrefslogtreecommitdiff
path: root/gdb/testsuite/lib
diff options
context:
space:
mode:
authorTom de Vries <tdevries@suse.de>2025-04-09 12:02:18 +0200
committerTom de Vries <tdevries@suse.de>2025-04-09 12:02:18 +0200
commit1bafda2c4595f0f936a5845caf9667b70b198091 (patch)
treebfa39a306a83e53607626c26e150d1f238a9716a /gdb/testsuite/lib
parent981fe5fd80faf511aa265e841a380c9b46be30e6 (diff)
downloadbinutils-1bafda2c4595f0f936a5845caf9667b70b198091.zip
binutils-1bafda2c4595f0f936a5845caf9667b70b198091.tar.gz
binutils-1bafda2c4595f0f936a5845caf9667b70b198091.tar.bz2
[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 = <optimized out>^M (gdb) FAIL: $exp: o1: printed size of optimized out vla ... The variable a has type 0xbf: ... <1><bf>: Abbrev Number: 12 (DW_TAG_array_type) <c0> DW_AT_type : <0xe3> <c4> DW_AT_sibling : <0xdc> <2><c8>: Abbrev Number: 13 (DW_TAG_subrange_type) <c9> DW_AT_type : <0xdc> <cd> 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 <optimized out>. 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.
Diffstat (limited to 'gdb/testsuite/lib')
-rw-r--r--gdb/testsuite/lib/dwarf.exp23
1 files changed, 21 insertions, 2 deletions
diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp
index f765bca..46b39a1 100644
--- a/gdb/testsuite/lib/dwarf.exp
+++ b/gdb/testsuite/lib/dwarf.exp
@@ -1244,7 +1244,6 @@ namespace eval Dwarf {
# used, as indicated in the header of the section where the location
# description is found.
#
- # (FIXME should use 'info complete' here.)
# Each list's first element is the opcode, either short or long
# forms are accepted.
# FIXME argument handling
@@ -1252,9 +1251,18 @@ namespace eval Dwarf {
proc _location { body dwarf_version addr_size offset_size } {
variable _constants
+ set collected_lines ""
foreach line [split $body \n] {
# Ignore blank lines, and allow embedded comments.
- if {[lindex $line 0] == "" || [regexp -- {^[ \t]*#} $line]} {
+ if { [regexp -- {^[ \t]*$} $line] || [regexp -- {^[ \t]*#} $line] } {
+ continue
+ }
+ if { $collected_lines != "" } {
+ set line "$collected_lines\n$line"
+ set collected_lines ""
+ }
+ if { ! [info complete $line] } {
+ set collected_lines $line
continue
}
set opcode [_map_name [lindex $line 0] _OP]
@@ -1340,6 +1348,17 @@ namespace eval Dwarf {
_op .2byte $argvec(label)
}
+ DW_OP_entry_value {
+ _get_args $line $opcode body
+ set l1 [new_label "expr_start"]
+ set l2 [new_label "expr_end"]
+ _op .uleb128 "$l2 - $l1" "expression"
+ define_label $l1
+ _location $argvec(body) $dwarf_version $addr_size \
+ $offset_size
+ define_label $l2
+ }
+
DW_OP_implicit_value {
set l1 [new_label "value_start"]
set l2 [new_label "value_end"]