diff options
author | Andreas Arnez <arnez@linux.vnet.ibm.com> | 2017-03-16 19:50:24 +0100 |
---|---|---|
committer | Andreas Arnez <arnez@linux.vnet.ibm.com> | 2017-03-16 19:50:24 +0100 |
commit | 7942e96e435d1cf4d4dbf58c47bb28d9f628c9e6 (patch) | |
tree | f09fed51fefa8ee276a87a786374ba95f4e2ece6 /gdb/dwarf2loc.h | |
parent | 6ebac3fbacebaebd9e2c9393da3b612342d953a9 (diff) | |
download | gdb-7942e96e435d1cf4d4dbf58c47bb28d9f628c9e6.zip gdb-7942e96e435d1cf4d4dbf58c47bb28d9f628c9e6.tar.gz gdb-7942e96e435d1cf4d4dbf58c47bb28d9f628c9e6.tar.bz2 |
Big-endian targets: Don't ignore offset into DW_OP_stack_value
Recently I fixed a bug that caused a DW_OP_implicit_pointer with non-zero
offset into a DW_OP_implicit_value to be handled incorrectly on big-endian
targets. GDB ignored the offset and copied the wrong bytes:
https://sourceware.org/ml/gdb-patches/2017-01/msg00251.html
But there is still a similar issue when a DW_OP_implicit_pointer points
into a DW_OP_stack_value instead; and again, the offset is ignored. There
is an important difference, though: While implicit values are treated like
blocks of data and anchored at the lowest-addressed byte, stack values
traditionally contain integer numbers and are anchored at the *least
significant* byte. Also, stack values do not come in varying sizes, but
are cut down appropriately when used. Thus, on big-endian targets the
scenario looks like this (higher addresses shown right):
|<- - - - - Stack value - - - - - - ->|
| |
|<- original object ->|
|
| offset ->|####|
^^^^
de-referenced
implicit pointer
(Note how the original object's size influences the position of the
de-referenced implicit pointer within the stack value. This is not the
case for little-endian targets, where the original object starts at offset
zero within the stack value.)
This patch implements the logic indicated in the above diagram and adds an
appropriate test case. A new function dwarf2_fetch_die_type_sect_off is
added; it is used for retrieving the original object's type, so its size
can be determined. That type is passed to dwarf2_evaluate_loc_desc_full
via a new parameter.
gdb/ChangeLog:
* dwarf2loc.c (indirect_synthetic_pointer): Get data type of
pointed-to DIE and pass it to dwarf2_evaluate_loc_desc_full.
(dwarf2_evaluate_loc_desc_full): New parameter subobj_type; rename
byte_offset to subobj_byte_offset. Fix the handling of
DWARF_VALUE_STACK on big-endian targets when coming via an
implicit pointer.
(dwarf2_evaluate_loc_desc): Adjust call to
dwarf2_evaluate_loc_desc_full.
* dwarf2loc.h (dwarf2_fetch_die_type_sect_off): New declaration.
* dwarf2read.c (dwarf2_fetch_die_type_sect_off): New function.
gdb/testsuite/ChangeLog:
* lib/dwarf.exp: Add support for DW_OP_implicit_pointer.
* gdb.dwarf2/nonvar-access.exp: Add test for stack value location
and implicit pointer into such a location.
Diffstat (limited to 'gdb/dwarf2loc.h')
-rw-r--r-- | gdb/dwarf2loc.h | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/gdb/dwarf2loc.h b/gdb/dwarf2loc.h index 1f3e20e..9063b6e 100644 --- a/gdb/dwarf2loc.h +++ b/gdb/dwarf2loc.h @@ -79,6 +79,9 @@ extern const gdb_byte *dwarf2_fetch_constant_bytes (sect_offset, struct obstack *, LONGEST *); +struct type *dwarf2_fetch_die_type_sect_off (sect_offset, + struct dwarf2_per_cu_data *); + struct type *dwarf2_get_die_type (cu_offset die_offset, struct dwarf2_per_cu_data *per_cu); |