diff options
author | Tom Tromey <tom@tromey.com> | 2023-07-20 15:48:46 -0600 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2023-07-21 14:03:23 -0600 |
commit | 4d051f3a4e2839225f7de0ea783e2fdca1c7717e (patch) | |
tree | fb789b6eacda3b87ba6bae190af22d5246fa9088 | |
parent | e8fc65713d6e050348d443f9be7b61e6f54c6371 (diff) | |
download | gdb-4d051f3a4e2839225f7de0ea783e2fdca1c7717e.zip gdb-4d051f3a4e2839225f7de0ea783e2fdca1c7717e.tar.gz gdb-4d051f3a4e2839225f7de0ea783e2fdca1c7717e.tar.bz2 |
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 <aburgess@redhat.com>
-rw-r--r-- | gdb/dwarf2/read.c | 29 | ||||
-rw-r--r-- | gdb/testsuite/gdb.dwarf2/intbits.exp | 2 | ||||
-rw-r--r-- | gdb/testsuite/lib/dwarf.exp | 4 |
3 files changed, 22 insertions, 13 deletions
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 3508f2c..b1f1c1d 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 c52e709..cf44d26 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 434495d..f09da04 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" + } } } |