mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-27 01:28:46 +00:00
Handle dynamic DW_AT_data_bit_offset
In Ada, a field can have a dynamic bit offset in its enclosing record.
In DWARF 3, this was handled using a dynamic
DW_AT_data_member_location, combined with a DW_AT_bit_offset -- this
combination worked out ok because in practice GNAT only needs a
dynamic byte offset with a fixed offset within the byte.
However, this approach was deprecated in DWARF 4 and then removed in
DWARF 5. No replacement approach was given, meaning that in strict
mode there is no way to express this.
This is a DWARF bug, see
https://dwarfstd.org/issues/250501.1.html
In a discussion on the DWARF mailing list, a couple people mentioned
that compilers could use the obvious extension of a dynamic
DW_AT_data_bit_offset. I've implemented this for LLVM:
https://github.com/llvm/llvm-project/pull/141106
In preparation for that landing, this patch implements support for
this construct in gdb.
New in v2: renamed some constants and added a helper method, per
Simon's review.
New in v3: more renamings.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
This commit is contained in:
@@ -480,7 +480,10 @@ enum field_loc_kind
|
||||
FIELD_LOC_KIND_ENUMVAL, /**< enumval */
|
||||
FIELD_LOC_KIND_PHYSADDR, /**< physaddr */
|
||||
FIELD_LOC_KIND_PHYSNAME, /**< physname */
|
||||
FIELD_LOC_KIND_DWARF_BLOCK /**< dwarf_block */
|
||||
/* A DWARF block that computes the address of the field. */
|
||||
FIELD_LOC_KIND_DWARF_BLOCK_ADDR, /**< dwarf_block */
|
||||
/* A DWARF block that computes the bit offset of the field. */
|
||||
FIELD_LOC_KIND_DWARF_BLOCK_BITPOS,
|
||||
};
|
||||
|
||||
/* * A discriminant to determine which field in the
|
||||
@@ -616,6 +619,13 @@ struct field
|
||||
return m_loc_kind;
|
||||
}
|
||||
|
||||
/* Return true if this location has either "DWARF block" kind. */
|
||||
bool loc_is_dwarf_block () const
|
||||
{
|
||||
return (m_loc_kind == FIELD_LOC_KIND_DWARF_BLOCK_ADDR
|
||||
|| m_loc_kind == FIELD_LOC_KIND_DWARF_BLOCK_BITPOS);
|
||||
}
|
||||
|
||||
LONGEST loc_bitpos () const
|
||||
{
|
||||
gdb_assert (m_loc_kind == FIELD_LOC_KIND_BITPOS);
|
||||
@@ -666,13 +676,19 @@ struct field
|
||||
|
||||
dwarf2_locexpr_baton *loc_dwarf_block () const
|
||||
{
|
||||
gdb_assert (m_loc_kind == FIELD_LOC_KIND_DWARF_BLOCK);
|
||||
gdb_assert (loc_is_dwarf_block ());
|
||||
return m_loc.dwarf_block;
|
||||
}
|
||||
|
||||
void set_loc_dwarf_block (dwarf2_locexpr_baton *dwarf_block)
|
||||
void set_loc_dwarf_block_addr (dwarf2_locexpr_baton *dwarf_block)
|
||||
{
|
||||
m_loc_kind = FIELD_LOC_KIND_DWARF_BLOCK;
|
||||
m_loc_kind = FIELD_LOC_KIND_DWARF_BLOCK_ADDR;
|
||||
m_loc.dwarf_block = dwarf_block;
|
||||
}
|
||||
|
||||
void set_loc_dwarf_block_bitpos (dwarf2_locexpr_baton *dwarf_block)
|
||||
{
|
||||
m_loc_kind = FIELD_LOC_KIND_DWARF_BLOCK_BITPOS;
|
||||
m_loc.dwarf_block = dwarf_block;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user