aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2021-03-31 09:17:23 -0600
committerTom Tromey <tromey@adacore.com>2021-03-31 09:17:23 -0600
commit3f49d080599421880799fa091b47160e3c587e5b (patch)
treef8bde6cf168011f020d83ac9ec8d9ee57b57eaea /gdb
parentcfcbd506fb0262070f58d089bf58502d8f677dd5 (diff)
downloadgdb-3f49d080599421880799fa091b47160e3c587e5b.zip
gdb-3f49d080599421880799fa091b47160e3c587e5b.tar.gz
gdb-3f49d080599421880799fa091b47160e3c587e5b.tar.bz2
Add some error checking to DWARF assembler
I had written a DWARF location expression like DW_OP_const1u DW_OP_stack_value ... and was surprised to see that the DW_OP_stack_value didn't appear in the "readelf" output. The problem here is that DW_OP_const1u requires an operand, but neither the DWARF assembler nor gas diagnosed this problem. This patch adds some checking to Dwarf::_location to try to avoid this in the future. The checking is done via a helper proc that also dissects the argument list and sets an array in the caller's frame. gdb/testsuite/ChangeLog 2021-03-31 Tom Tromey <tromey@adacore.com> * lib/dwarf.exp (Dwarf::_get_args): New proc. (Dwarf::_location): Use it.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/testsuite/ChangeLog5
-rw-r--r--gdb/testsuite/lib/dwarf.exp85
2 files changed, 57 insertions, 33 deletions
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index 2c73da6..eb655a0 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2021-03-31 Tom Tromey <tromey@adacore.com>
+
+ * lib/dwarf.exp (Dwarf::_get_args): New proc.
+ (Dwarf::_location): Use it.
+
2021-03-31 Tom de Vries <tdevries@suse.de>
PR testsuite/27667
diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp
index 4cd5e16..b9a4938 100644
--- a/gdb/testsuite/lib/dwarf.exp
+++ b/gdb/testsuite/lib/dwarf.exp
@@ -890,6 +890,20 @@ namespace eval Dwarf {
}
}
+ # Assign elements from LINE to the elements of an array named
+ # "argvec" in the caller scope. The keys used are named in ARGS.
+ # If the wrong number of elements appear in LINE, error.
+ proc _get_args {line op args} {
+ if {[llength $line] != [llength $args] + 1} {
+ error "usage: $op [string toupper $args]"
+ }
+
+ upvar argvec argvec
+ foreach var $args value [lreplace $line 0 0] {
+ set argvec($var) $value
+ }
+ }
+
# This is a miniature assembler for location expressions. It is
# suitable for use in the attributes to a DIE. Its output is
# prefixed with "=" to make it automatically use DW_FORM_block.
@@ -924,59 +938,72 @@ namespace eval Dwarf {
set opcode [_map_name [lindex $line 0] _OP]
_op .byte $_constants($opcode) $opcode
+ array unset argvec *
switch -exact -- $opcode {
DW_OP_addr {
- _op .${addr_size}byte [lindex $line 1]
+ _get_args $line $opcode size
+ _op .${addr_size}byte $argvec(size)
}
DW_OP_regx {
- _op .uleb128 [lindex $line 1]
+ _get_args $line $opcode register
+ _op .uleb128 $argvec(register)
}
DW_OP_pick -
DW_OP_const1u -
DW_OP_const1s {
- _op .byte [lindex $line 1]
+ _get_args $line $opcode const
+ _op .byte $argvec(const)
}
DW_OP_const2u -
DW_OP_const2s {
- _op .2byte [lindex $line 1]
+ _get_args $line $opcode const
+ _op .2byte $argvec(const)
}
DW_OP_const4u -
DW_OP_const4s {
- _op .4byte [lindex $line 1]
+ _get_args $line $opcode const
+ _op .4byte $argvec(const)
}
DW_OP_const8u -
DW_OP_const8s {
- _op .8byte [lindex $line 1]
+ _get_args $line $opcode const
+ _op .8byte $argvec(const)
}
DW_OP_constu {
- _op .uleb128 [lindex $line 1]
+ _get_args $line $opcode const
+ _op .uleb128 $argvec(const)
}
DW_OP_consts {
- _op .sleb128 [lindex $line 1]
+ _get_args $line $opcode const
+ _op .sleb128 $argvec(const)
}
DW_OP_plus_uconst {
- _op .uleb128 [lindex $line 1]
+ _get_args $line $opcode const
+ _op .uleb128 $argvec(const)
}
DW_OP_piece {
- _op .uleb128 [lindex $line 1]
+ _get_args $line $opcode size
+ _op .uleb128 $argvec(size)
}
DW_OP_bit_piece {
- _op .uleb128 [lindex $line 1]
- _op .uleb128 [lindex $line 2]
+ _get_args $line $opcode size offset
+ _op .uleb128 $argvec(size)
+ _op .uleb128 $argvec(offset)
}
DW_OP_skip -
DW_OP_bra {
- _op .2byte [lindex $line 1]
+ _get_args $line $opcode label
+ _op .2byte $argvec(label)
}
DW_OP_implicit_value {
@@ -1000,45 +1027,37 @@ namespace eval Dwarf {
DW_OP_implicit_pointer -
DW_OP_GNU_implicit_pointer {
- if {[llength $line] != 3} {
- error "usage: $opcode LABEL OFFSET"
- }
+ _get_args $line $opcode label offset
# Here label is a section offset.
- set label [lindex $line 1]
if { $dwarf_version == 2 } {
- _op .${addr_size}byte $label
+ _op .${addr_size}byte $argvec(label)
} else {
- _op .${offset_size}byte $label
+ _op .${offset_size}byte $argvec(label)
}
- _op .sleb128 [lindex $line 2]
+ _op .sleb128 $argvec(offset)
}
DW_OP_GNU_variable_value {
- if {[llength $line] != 2} {
- error "usage: $opcode LABEL"
- }
+ _get_args $line $opcode label
# Here label is a section offset.
- set label [lindex $line 1]
if { $dwarf_version == 2 } {
- _op .${addr_size}byte $label
+ _op .${addr_size}byte $argvec(label)
} else {
- _op .${offset_size}byte $label
+ _op .${offset_size}byte $argvec(label)
}
}
DW_OP_deref_size {
- if {[llength $line] != 2} {
- error "usage: DW_OP_deref_size SIZE"
- }
-
- _op .byte [lindex $line 1]
+ _get_args $line $opcode size
+ _op .byte $argvec(size)
}
DW_OP_bregx {
- _op .uleb128 [lindex $line 1]
- _op .sleb128 [lindex $line 2]
+ _get_args $line $opcode register offset
+ _op .uleb128 $argvec(register)
+ _op .sleb128 $argvec(offset)
}
default {