This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [rfc] Make DWARF-2 "address size" explicit


I wrote:
> Apart from that, the behaviour should be identical, with one
> exception: what address size to use for CFI.  Your patch uses
>   size_of_encoded_value (DW_EH_PE_absptr)
> which basically boils down to:
>   gdbarch_ptr_bit (current_gdbarch) / TARGET_CHAR_BIT
> 
> This would be an effective change in behaviour to what we have
> now, which is:
>   gdbarch_addr_bit (current_gdbarch) / TARGET_CHAR_BIT
> 
> My patch uses in effect
>   gdbarch_addr_bit (get_frame_arch (frame)) / TARGET_CHAR_BIT
> which does not change behaviour.
> 
> However, it might well be that the original code is simply wrong
> and we *should* be using ...ptr_bit instead of ...addr_bit.
> What do you think?

The notion of "target address size" is relevant in several places of Dwarf
Call Frame Information: target addresses are used explicitly in the 
"initial location" and "address range" fields of the FDE header, as well
as as immediate operand of the DW_CFA_set_loc call frame instruction.

In addition, the DW_CFA_def_cfa_expression, DW_CFA_expression and
DW_CFA_val_expression call frame instructions refer to DWARF expressions
as operand, which implicitly depend on the target address size: first,
the whole process of expression evaluation implicitly depends on the
target address size in that each element of the stack used is considered
to be of target address size (this affects e.g. rounding/truncation of
arithmetic operations).  In addition, the DW_OP_addr operation explicitly
takes an immediate target address as operand, and the DW_OP_deref and
DW_OP_xderef operations implicitly use the target address size.


I've now looked both at generation of CFI by GCC (dwarf2out.c) and
use of CFI by the GCC exception handling runtime (unwind-dw.c) to try
to determine what GCC uses and/or expects as "target address size"
in all of those cases.  Note that the CFI provided in the (standard)
.debug_frame section and the CFI in the (GCC / C++ ABI extension)
.eh_frame section *differ* in critical aspects here.

For the explicit uses of target addresses in FDE header fields and
the DW_CFA_set_loc instruction the situation is pretty clear.  For
.debug_frame, GCC uses its notion of "DWARF2_ADDR_SIZE" to define
the target address size.  This is a value that defaults to the size
of a "void *" on the target, but can be overridden by the platform
back-end.  This currently appears to be done by xstormy16, m68hc11,
m32c, and avr (which use a 4-byte DWARF address size even while
using 2-byte pointers), as well as certain ABI modes of mips64
(where the DWARF address size is defined by -mabi= while the pointer
size is defined by -mlong32 vs. -mlong64).  Note that this value is
used throughout the .debug_ sections, and could be retrieved e.g.
from the .debug_info address size header field.

For .eh_frame, GCC uses a completely different way to represent
target addresses: the "FDE encoding" field of the CIE augmentation
record defined which of a variety of encoding methods is used to
encode the FDE header fields as well as the DW_CFA_set_loc operand.
Most of these encodings explicitly specify a size; those that rely
on an implicit address size (DW_EH_PE_aligned, DW_EH_PE_absptr and
DW_EH_PE_indirect) always employ the size of a "void *" (*not* the
"DWARF2 address size as used in .debug_frame!).  As should be 
expected, the GCC code generator and the GCC exception runtime
are in complete agreement on this.  (This applies to .eh_frame only,
there is no *user* of .debug_frame anywhere in GCC.)

For the address sizes used in DWARF *expressions*, the picture gets
a lot less clear.  (Un?)fortunately, GCC currently generates only
a small subset of DWARF expressions as part of call frame information.
It never generates DW_CFA_expression or DW_CFA_val_expression, and
while it does generate DW_CFA_def_cfa_expression instructions, they
only contain a subset of all possible expressions.  In particular,
they never contain DW_OP_addr; GCC simply assumes arithmetic operations
never wrap so the exact size used for the value stack does not matter;
and DW_OP_deref is only generated for some platforms (where apparently
the address size issue doesn't really come up).  On the other hand,
in some places GCC seems to assume an address size as specified by
DWARF2_ADDR_SIZE (both for .eh_frame and .dwarf_frame -- this certainly
appears to be broken ...).

On the user side, the exception handling infrastructure assumes
the size of "void *" for DW_OP_addr and DW_OP_deref, but uses
"_Unwind_Word" (which represents the size of a target *register*,
not necessarily a target pointer) as size of the value stack
elements.  (Again this applies to .eh_frame only, there is no
user of .debug_frame in GCC.)


When comparing all this with what GDB currently does, there is
one obvious error: GDB does not take the FDE encoding into
account *at all* when accessing the operand of DW_CFA_set_loc
in the .eh_frame section.  It looks like this was already noticed
by Dan some time ago, but the associated patch:

http://www.cygwin.com/ml/gdb-patches/2006-10/msg00063.html

apparently was never applied.  Dan, are you still planning on
applying this patch?


Apart from that, it would appear that the most logical size to
use for target addresses in DWARF expression evaluation would
be the target "void *" size for .eh_frame FDEs, and the value
of the associated compilation unit's .debug_info address size
header field value for .debug_frame FDEs (however, I'm not sure
how to best determine that).


Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]