Currently in DWARF, there are only two ways to specify an offset for a
location description.
For a memory location description, the location description can be
first converted to a DWARF value, after which an arithmetic operation
can be applied to it. This however, only works while there are no
address spaces involved, that are not mapped to a general address space
(CORE_ADDR). Another limitation is that there is no way to specify a
bit offset to that location description.
Second way of specifying an offset to a location description is more
universal and involves wrapping that location description in a
composite piece, where piece itself has a bit/byte offset defined. The
problem with this approach is that both DW_OP_piece and DW_OP_bit_piece
define an offset as a DWARF operation operand, which means that an
offset needs to be a constant value encoded into the DWARF expression.
By adding three new operations (DW_OP_LLVM_offset,
DW_OP_LLVM_offset_constu and DW_OP_LLVM_bit_offset) these restrictions
are now lifted.
Detailed descriptions of these new operations can be found here:
The same document also explores an idea of extending the
DW_OP_push_object_address operation to allow pushing any location
description on the DWARF stack. This together with the new bit/byte
offset operations, generalizes DWARF to work with bit fields and could
replace the odd passed-in buffer mechanics in a more elegant way.
There seem to be a difference in views on what the big endian machine
register byte ordering should be. On one hand, some would expect for
a register to behave in the same way as memory, but on another, there
seems to be an existing implementation for (IBM big endian based
machines) which seems to be viewing registers differently, depending
if the register location description is part of a composite piece or
not. More on this topic can be found here:
Unfortunately, the gdb current implementation favors the second option,
which feels like a target specific implementation.
Because of this, I've decided to not favor a specific implementation
in the added test for new DWARF operations (dw2-llvm-offset.exp), so
the test is restricted to only run on little endian platforms.
gdb/ChangeLog:
* ada-lang.c (coerce_unspec_val_to_type): Add source bit offset
argument to the value_contents_copy_raw call.
* compile/compile-loc2c.c (compute_stack_depth_worker): Add new
DWARF operations support.
* dwarf2/expr.c (rw_closure_value): Add bit offset support.
(dwarf_expr_context::dwarf_entry_to_gdb_value): Add source bit
offset argument to the value_contents_copy_raw call.
(dwarf_expr_context::execute_stack_op): Add new DWARF
operations support.
* dwarf2/loc.c (dwarf2_get_symbol_read_needs): Add new DWARF
operations support.
* findvar.c (read_frame_register_value): Add source bit offset
argument to the value_contents_copy_raw call.
* valops.c (read_value_memory): Add bit offset support.
(value_assign): Add bit offset support.
(value_repeat): Add bit offset support.
(value_array): Add source bit offset argument to the
value_contents_copy_raw call.
(value_slice): Add source bit offset argument to the
value_contents_copy_raw call.
* value.c (value_contents_copy_raw): Add source bit offset
support.
(value_contents_copy): Add source bit offset argument to
value_contents_copy_raw call.
(value_primitive_field): Add source bit offset argument to the
value_contents_copy_raw call.
(value_from_component): Add source bit offset argument to the
value_contents_copy_raw call.
(value_fetch_lazy_memory): Add bit offset argument to the
read_value_memory call.
(value_fetch_lazy_register): Add source bit offset argument to
the value_contents_copy call.
* value.h (value_contents_copy): Add source bit offset
argument.
include/ChangeLog:
* dwarf2.def (DW_OP_DUP): New DWARF operations enumeration.
gdb/testsuite/ChangeLog:
* lib/dwarf.exp: Add support for new DW_OP_LLVM_offset_constu
DWARF operation.
* gdb.dwarf2/dw2-llvm-offset.exp: New test.