]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commit
Handle field with dynamic bit offset
authorTom Tromey <tromey@adacore.com>
Fri, 18 Apr 2025 15:28:13 +0000 (09:28 -0600)
committerTom Tromey <tromey@adacore.com>
Tue, 6 May 2025 15:01:55 +0000 (09:01 -0600)
commit420d030e88d2c8bbad6044278000fbd9efbf65d9
tree195fbc9b4699c4a1317156a179ee07d4afb8fb52
parentee580641bc5fbd5086e02cc94eb2dbc70ebb4b5d
Handle field with dynamic bit offset

I discovered that GCC emitted incorrect DWARF for the test case
included in this patch.  Eric wrote a fix for GCC, but then he found
that gdb crashed on the resulting file.

This test has a field that is at a non-constant bit offset from the
start of the type.  DWARF 5 does not allow for this situation (I've
sent a report to the DWARF list), but DWARF 3 did allow for this via a
combination of an expression for the byte offset and then the use of
DW_AT_bit_offset.  This looks like:

 <5><117a>: Abbrev Number: 17 (DW_TAG_member)
    <117b>   DW_AT_name        : (indirect string, offset: 0x1959): another_field
...
    <1188>   DW_AT_bit_offset  : 6
    <1189>   DW_AT_data_member_location: 6 byte block: 99 3d 1 0 0 22  (DW_OP_call4: <0x1193>; DW_OP_plus)
...
 <3><1193>: Abbrev Number: 2 (DW_TAG_dwarf_procedure)
    <1194>   DW_AT_location    : 15 byte block: 97 94 1 37 1a 32 1e 23 7 38 1b 31 1c 23 3  (DW_OP_push_object_address; DW_OP_deref_size: 1; DW_OP_lit7; DW_OP_and; DW_OP_lit2; DW_OP_mul; DW_OP_plus_uconst: 7; DW_OP_lit8; DW_OP_div; DW_OP_lit1; DW_OP_minus; DW_OP_plus_uconst: 3)

Now, that combination is not fully general, in that the bit offset
must be a constant -- only the byte offset may really vary.  However,
I couldn't come up with a situation where full generality is needed,
mainly because GNAT won't seem to pack fields into the padding of a
variable-length array.

Meanwhile, the reason for the gdb crash is that the code handling
DW_AT_bit_offset assumes that the byte offset is a constant.  This
causes an assertion failure.

This patch arranges for DW_AT_bit_offset to be applied during field
resolution, when needed.
gdb/dwarf2/loc.h
gdb/dwarf2/read.c
gdb/gdbtypes.c
gdb/testsuite/gdb.ada/dyn-bit-offset.exp [new file with mode: 0644]
gdb/testsuite/gdb.ada/dyn-bit-offset/exam.adb [new file with mode: 0644]