From: Simon Marchi Date: Tue, 8 Jul 2025 19:52:37 +0000 (-0400) Subject: gdb/dwarf: apply DW_AT_bit_offset when DW_AT_data_member_location is constant block X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=91bca5d7bcaa357f63e8000c346dc2003939242a;p=thirdparty%2Fbinutils-gdb.git gdb/dwarf: apply DW_AT_bit_offset when DW_AT_data_member_location is constant block Since commit 420d030e88 ("Handle field with dynamic bit offset"), I see: $ make check TESTS="gdb.trace/unavailable-dwarf-piece.exp" RUNTESTFLAGS="--target_board=native-extended-gdbserver" FAIL: gdb.trace/unavailable-dwarf-piece.exp: tracing bar: p/d x FAIL: gdb.trace/unavailable-dwarf-piece.exp: tracing bar: p/d y FAIL: gdb.trace/unavailable-dwarf-piece.exp: tracing bar: p/d z The first FAIL is: p/d x $4 = {a = 0, b = , c = , d = , e = , f = , g = , h = , i = , j = 0} (gdb) FAIL: gdb.trace/unavailable-dwarf-piece.exp: tracing bar: p/d x When we should see: p/d x $4 = {a = 0, b = , c = 0, d = 0, e = 0, f = 0, g = 0, h = 0, i = 0, j = 0} (gdb) PASS: gdb.trace/unavailable-dwarf-piece.exp: tracing bar: p/d x The structure we print is: 0x0000004f: DW_TAG_structure_type DW_AT_name [DW_FORM_string] ("t") DW_AT_byte_size [DW_FORM_sdata] (3) DW_AT_decl_file [DW_FORM_udata] (0) DW_AT_decl_line [DW_FORM_udata] (1) 0x00000055: DW_TAG_member DW_AT_name [DW_FORM_string] ("a") DW_AT_type [DW_FORM_ref4] (0x00000019 "unsigned char") DW_AT_data_member_location [DW_FORM_exprloc] (DW_OP_plus_uconst 0x0) 0x0000005f: DW_TAG_member DW_AT_name [DW_FORM_string] ("b") DW_AT_type [DW_FORM_ref4] (0x00000019 "unsigned char") DW_AT_byte_size [DW_FORM_sdata] (1) DW_AT_bit_size [DW_FORM_sdata] (1) DW_AT_bit_offset [DW_FORM_sdata] (7) DW_AT_data_member_location [DW_FORM_exprloc] (DW_OP_plus_uconst 0x1) ... The particularity of field "b" (and the following ones, not shown here) is that they have: - a DW_AT_data_member_location of expression form, but that GDB reduces to a constant - a DW_AT_bit_offset What I think happens is that the code path taken in this particular scenario never ends up using the DW_AT_bit_offset value. Fix it by calling apply_bit_offset_to_field, like what is done when data_member_location_attr is using a constant form. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33136 Change-Id: I18e838e6c56a548495d3af332aeff3051188eaa9 Approved-By: Tom Tromey --- diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index a9f38cfe792..634d67a9eba 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -9971,7 +9971,12 @@ handle_member_location (struct die_info *die, struct dwarf2_cu *cu, CORE_ADDR offset; if (decode_locdesc (data_member_location_attr->as_block (), cu, &offset)) - field->set_loc_bitpos (offset * bits_per_byte); + { + field->set_loc_bitpos (offset * bits_per_byte); + + if (has_bit_offset) + apply_bit_offset_to_field (*field, bit_offset, anonymous_size); + } else { dwarf2_per_objfile *per_objfile = cu->per_objfile;