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 /gdb/dwarf2 | |
parent | e8fc65713d6e050348d443f9be7b61e6f54c6371 (diff) | |
download | binutils-4d051f3a4e2839225f7de0ea783e2fdca1c7717e.zip binutils-4d051f3a4e2839225f7de0ea783e2fdca1c7717e.tar.gz binutils-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>
Diffstat (limited to 'gdb/dwarf2')
-rw-r--r-- | gdb/dwarf2/read.c | 29 |
1 files changed, 17 insertions, 12 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); + } } } } |