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: [rfa] frame address size incorrect if address size != ptr size


Corinna Vinschen wrote:

> At one point in this thread you mentioned that .eh_frame isn't really
> standarized.
> 
> Additionally, using the pointer size in .eh_frame sections would
> invariably break unwinding on targets like avr and XStormy16.

No, it would make it work :-)  In .eh_frame sections, the contents
of DW_EH_PE_absptr encoded fields are *used as pointer values* at
run time.  See e.g. unwind-pe.h:read_encoded_value_with_base:

static const unsigned char *
read_encoded_value_with_base (unsigned char encoding, _Unwind_Ptr base,
                              const unsigned char *p, _Unwind_Ptr *val)
{
  union unaligned
    {
      void *ptr;
      unsigned u2 __attribute__ ((mode (HI)));
      unsigned u4 __attribute__ ((mode (SI)));
      unsigned u8 __attribute__ ((mode (DI)));
      signed s2 __attribute__ ((mode (HI)));
      signed s4 __attribute__ ((mode (SI)));
      signed s8 __attribute__ ((mode (DI)));
    } __attribute__((__packed__));

  const union unaligned *u = (const union unaligned *) p;
  _Unwind_Internal_Ptr result;
[...]
      switch (encoding & 0x0f)
        {
        case DW_EH_PE_absptr:
          result = (_Unwind_Internal_Ptr) u->ptr;
          p += sizeof (void *);
          break;

"p" points directly into the mapped .eh_frame image.  The contents
are simply interpreted as a native "void *" at run-time.  If GDB
wants to use this section as well, it has to treat it like it would
read a "void *" global variable from the target ...

> > It would then be interesting to see whether *both* .debug_frame and
> > .eh_frame work on xstormy16 ... you might be able to try the latter
> > by building with -fasynchronous-unwind-tables.
>
> ... .eh_frame sections are never generated for XStormy16.  The
> -fasynchronous-unwind-tables option is a no-op.

OK, that's unfortunate.

> Consequentially, is it *really* correct to define the ptr_size as you
> requested now, or isn't it *more* correct to use the target dependent
> approach as my previous patch implemented?  Since it's using the pointer
> size as fallback, it will be correct for all existing .eh_frame sections
> anyway.

The difference between .eh_frame and .debug_frame is really fundamental;
.eh_frame holds *pointer* values in target "void *" format; while
.debug_frame holds *address* values using the same format as the rest
of the DWARF debug sections.

Therefore we will definitely have to make a distinction between the two.
If you have another suggestion how to achieve that, I'd certainly be
interested ...


> 	* dwarf2-frame.c (struct dwarf2_cie): Add ptr_size member.
> 	Throughout, call read_encoded_value with ptr_size rather than addr_size.
> 	(decode_frame_entry_1): Remove redundant setting of
> 	addr_size.  Call gdbarch_dwarf2_addr_size rather than gdbarch_ptr_bit
> 	to determine addr_size in Dwarf versions < 4.  Set ptr_size dependent
> 	on examined frame section.  Add comment to explain why.
> 	* gdbarch.sh (dwarf2_addr_size): Define as variable.  Add lengthy
> 	comment to explain usage.
> 	* gdbarch.c: Regenerate.
> 	* gdbarch.h: Regenerate.
> 	* xstormy16-tdep.c (xstormy16_gdbarch_init): Set dwarf2_addr_size to 4.

This looks good to me, except a couple of the comments:

> +      /* Address values in .eh_frame sections are defined to have the
> +	 target's pointer size.  Watchout: This breaks frame info for
> +	 targets with pointer size < address size, unless a .debug_frame
> +	 section exists as well. */

As discussed above, I don't agree that this breaks anything ...  Do you
still feel it does?

> +# dwarf2_addr_size is the target address size as used int the Dwarf debug
> +# info.  For .eh_frame FDEs this is considered equal to the size of a target
> +# pointer.  For .debug_frame FDEs, this is supposed to be the target address
> +# size from the associated CU header, and which is equivalent to the
> +# DWARF2_ADDR_SIZE as defined by the target specific GCC back-end.
> +# Unfortunately there is no good way to determine this value.  Therefore
> +# dwarf2_addr_size simply defaults to the target pointer size.

I'd reword this to make clear that this value is *not* used for .eh_frame,
but solely for .debug_frame.

Thanks,
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]