aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorTom de Vries <tdevries@suse.de>2021-07-28 10:01:05 +0200
committerTom de Vries <tdevries@suse.de>2021-07-28 10:01:05 +0200
commitad14ab00eb89cccd32815ee7ebb6104aa7db040f (patch)
tree2d28c7addffb0ef040c69ee9fcb05be99deaf2c0 /gdb
parent254db2f3369039ba20d9a418dc07542c1617eeb1 (diff)
downloadgdb-ad14ab00eb89cccd32815ee7ebb6104aa7db040f.zip
gdb-ad14ab00eb89cccd32815ee7ebb6104aa7db040f.tar.gz
gdb-ad14ab00eb89cccd32815ee7ebb6104aa7db040f.tar.bz2
[gdb/symtab] Fix unhandled dwarf expression opcode with gcc-11 -gdwarf-5
[ I've confused things by forgetting to add -gdwarf-4 in $subject of commit 0057a7ee0d9 "[gdb/testsuite] Add KFAILs for gdb.ada FAILs with gcc-11". So I'm adding here -gdwarf-5 in $subject, even though -gdwarf-5 is the default for gcc-11. I keep getting confused because of working with a system gcc-11 compiler that was patched to switch the default back to -gdwarf-4. ] When running test-case gdb.ada/arrayptr.exp with gcc-11 (and default -gdwarf-5), I run into: ... (gdb) print pa_ptr.all^M Unhandled dwarf expression opcode 0xff^M (gdb) FAIL: gdb.ada/arrayptr.exp: scenario=all: print pa_ptr.all ... What happens is that pa_ptr: ... <2><1523>: Abbrev Number: 3 (DW_TAG_variable) <1524> DW_AT_name : pa_ptr <1529> DW_AT_type : <0x14fa> ... has type: ... <2><14fa>: Abbrev Number: 2 (DW_TAG_typedef) <14fb> DW_AT_name : foo__packed_array_ptr <1500> DW_AT_type : <0x1504> <2><1504>: Abbrev Number: 4 (DW_TAG_pointer_type) <1505> DW_AT_byte_size : 8 <1505> DW_AT_type : <0x1509> ... which is a pointer to a subrange: ... <2><1509>: Abbrev Number: 12 (DW_TAG_subrange_type) <150a> DW_AT_lower_bound : 0 <150b> DW_AT_upper_bound : 0x3fffffffffffffffff <151b> DW_AT_name : foo__packed_array <151f> DW_AT_type : <0x15cc> <1523> DW_AT_artificial : 1 <1><15cc>: Abbrev Number: 5 (DW_TAG_base_type) <15cd> DW_AT_byte_size : 16 <15ce> DW_AT_encoding : 7 (unsigned) <15cf> DW_AT_name : long_long_long_unsigned <15d3> DW_AT_artificial : 1 ... with upper bound of form DW_FORM_data16. In gdb/dwarf/attribute.h we have: ... /* Return non-zero if ATTR's value falls in the 'constant' class, or zero otherwise. When this function returns true, you can apply the constant_value method to it. ... DW_FORM_data16 is not considered as constant_value cannot handle that. */ bool form_is_constant () const; ... so instead we have attribute::form_is_block (DW_FORM_data16) == true. Then in attr_to_dynamic_prop for the upper bound, we get a PROC_LOCEXPR instead of a PROP_CONST and end up trying to evaluate the constant 0x3fffffffffffffffff as if it were a locexpr, which causes the "Unhandled dwarf expression opcode 0xff". In contrast, with -gdwarf-4 we have: ... <164c> DW_AT_upper_bound : 18 byte block: \ 9e 10 ff ff ff ff ff ff ff ff 3f 0 0 0 0 0 0 0 \ (DW_OP_implicit_value 16 byte block: \ ff ff ff ff ff ff ff ff 3f 0 0 0 0 0 0 0 ) ... Fix the dwarf error by translating the DW_FORM_data16 constant into a PROC_LOCEXPR, effectively by prepending 0x9e 0x10, such that we have same result as with -gdwarf-4: ... (gdb) print pa_ptr.all^M That operation is not available on integers of more than 8 bytes.^M (gdb) KFAIL: gdb.ada/arrayptr.exp: scenario=all: print pa_ptr.all \ (PRMS: gdb/20991) ... Tested on x86_64-linux, with gcc-11 and target board unix/gdb:debug_flags=-gdwarf-5. gdb/ChangeLog: 2021-07-25 Tom de Vries <tdevries@suse.de> * dwarf2/read.c (attr_to_dynamic_prop): Handle DW_FORM_data16.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/dwarf2/read.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 029b8bf..6f1b453 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -18254,7 +18254,22 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
baton->locexpr.per_cu = cu->per_cu;
baton->locexpr.per_objfile = per_objfile;
- struct dwarf_block *block = attr->as_block ();
+ struct dwarf_block *block;
+ if (attr->form == DW_FORM_data16)
+ {
+ size_t data_size = 16;
+ block = XOBNEW (obstack, struct dwarf_block);
+ block->size = (data_size
+ + 2 /* Extra bytes for DW_OP and arg. */);
+ gdb_byte *data = XOBNEWVEC (obstack, gdb_byte, block->size);
+ data[0] = DW_OP_implicit_value;
+ data[1] = data_size;
+ memcpy (&data[2], attr->as_block ()->data, data_size);
+ block->data = data;
+ }
+ else
+ block = attr->as_block ();
+
baton->locexpr.size = block->size;
baton->locexpr.data = block->data;
switch (attr->name)