From: Tom Tromey Date: Thu, 20 Jul 2023 21:48:46 +0000 (-0600) Subject: Fix crash with DW_FORM_implicit_const X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4d051f3a4e2839225f7de0ea783e2fdca1c7717e;p=binutils-gdb.git Fix crash with DW_FORM_implicit_const Jakub pointed out that using DW_FORM_implicit_const with DW_AT_bit_size would cause gdb to crash. This happened because DW_FORM_implicit_const is not an "unsigned" form, causing as_unsigned to assert. This patch fixes the problem. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30651 Approved-By: Andrew Burgess --- diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 3508f2c29ee..b1f1c1d7257 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -15420,20 +15420,25 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu) if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_INT) { attr = dwarf2_attr (die, DW_AT_bit_size, cu); - if (attr != nullptr && attr->as_unsigned () <= 8 * type->length ()) + if (attr != nullptr && attr->form_is_constant ()) { - unsigned real_bit_size = attr->as_unsigned (); - attr = dwarf2_attr (die, DW_AT_data_bit_offset, cu); - /* Only use the attributes if they make sense together. */ - if (attr == nullptr - || (attr->as_unsigned () + real_bit_size - <= 8 * type->length ())) + unsigned real_bit_size = attr->constant_value (0); + if (real_bit_size >= 0 && real_bit_size <= 8 * type->length ()) { - TYPE_MAIN_TYPE (type)->type_specific.int_stuff.bit_size - = real_bit_size; - if (attr != nullptr) - TYPE_MAIN_TYPE (type)->type_specific.int_stuff.bit_offset - = attr->as_unsigned (); + attr = dwarf2_attr (die, DW_AT_data_bit_offset, cu); + /* Only use the attributes if they make sense together. */ + if (attr == nullptr + || (attr->form_is_constant () + && attr->constant_value (0) >= 0 + && (attr->constant_value (0) + real_bit_size + <= 8 * type->length ()))) + { + TYPE_MAIN_TYPE (type)->type_specific.int_stuff.bit_size + = real_bit_size; + if (attr != nullptr) + TYPE_MAIN_TYPE (type)->type_specific.int_stuff.bit_offset + = attr->constant_value (0); + } } } } diff --git a/gdb/testsuite/gdb.dwarf2/intbits.exp b/gdb/testsuite/gdb.dwarf2/intbits.exp index c52e709316b..cf44d26b721 100644 --- a/gdb/testsuite/gdb.dwarf2/intbits.exp +++ b/gdb/testsuite/gdb.dwarf2/intbits.exp @@ -43,7 +43,7 @@ Dwarf::assemble ${asm_file} { {DW_AT_endianity @DW_END_little} {DW_AT_name "i7"} {DW_AT_byte_size 2 DW_FORM_udata} - {DW_AT_bit_size 7 DW_FORM_udata} + {DW_AT_bit_size 7 DW_FORM_implicit_const} } DW_TAG_variable { diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp index 434495df24a..f09da0430ab 100644 --- a/gdb/testsuite/lib/dwarf.exp +++ b/gdb/testsuite/lib/dwarf.exp @@ -693,6 +693,7 @@ namespace eval Dwarf { _op .ascii [_quote $value] } + DW_FORM_implicit_const - DW_FORM_flag_present { # We don't need to emit anything. } @@ -917,6 +918,9 @@ namespace eval Dwarf { } _op .uleb128 $_constants($attr_name) $attr_name _op .uleb128 $_constants($attr_form) $attr_form_comment + if {$attr_form eq "DW_FORM_implicit_const"} { + _op .sleb128 $attr_value "the constant" + } } }