]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commit
gdb/dwarf: apply DW_AT_bit_offset when DW_AT_data_member_location is constant block
authorSimon Marchi <simon.marchi@polymtl.ca>
Tue, 8 Jul 2025 19:52:37 +0000 (15:52 -0400)
committerSimon Marchi <simon.marchi@efficios.com>
Fri, 25 Jul 2025 13:25:37 +0000 (09:25 -0400)
commit91bca5d7bcaa357f63e8000c346dc2003939242a
treedf938f777b9754ee85b6cad853ef393dc8c0b298
parent165d75b0ec7ab1d0708f661f8f5696933dafacf1
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 = <unavailable>, c = <unavailable>, d = <unavailable>, e = <unavailable>, f = <unavailable>, g = <unavailable>, h = <unavailable>, i = <unavailable>, 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 = <unavailable>, 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 <tom@tromey.com>
gdb/dwarf2/read.c