From: Tom de Vries Date: Wed, 28 Jul 2021 08:01:05 +0000 (+0200) Subject: [gdb/symtab] Fix unhandled dwarf expression opcode with gcc-11 -gdwarf-5 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ad14ab00eb89cccd32815ee7ebb6104aa7db040f;p=binutils-gdb.git [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 * dwarf2/read.c (attr_to_dynamic_prop): Handle DW_FORM_data16. --- diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 029b8bfad04..6f1b453ef45 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)