Skip to content
  • Andreas Arnez's avatar
    Big-endian targets: Don't ignore offset into DW_OP_stack_value · 7942e96e
    Andreas Arnez authored
    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.
    7942e96e