On Sun, Mar 6, 2011 at 9:18 AM, H.J. Lu <hongjiu...@intel.com> wrote:

> We shouldn't save call frame hard registers as "void *".  This patch
> changes the unwind library to save call frame hard registers as
> _Unwind_Word.  OK for 4.7?

> +       PR other/48007
> +       * unwind-dw2.c (_Unwind_Context): Save call frame hard registers
> +       as _Unwind_Word.
> +       (_Unwind_GetGR): Get GR value as _Unwind_Word.
> +       (_Unwind_SetGR): Set GR value as _Unwind_Word.
> +       (_Unwind_SetGRValue): Likewise.
> +       (_Unwind_GetGRPtr): Cast return to "void *".
> +       (_Unwind_SetGRPtr): Cast pointer to _Unwind_Word.
> +       (uw_install_context_1): Cast pointer to "void *".

The approach you are using here looks wrong to me.  When looking at
the DWARF2 _Unwind_Context, you have to look at the by_value field for
the register.  If by_value is true, then the reg field for that
register holds an _Unwind_Word which is the value of the register.  If
by_value is false, then the reg field holds a pointer to the place
where the actual value is stored.  The size of the actual value is
determined by dwarf_reg_size_table.  In other words, the reg field is
a really a union of _Unwind_Word and void*.

You have correctly observed that the current code fails for the case
where sizeof(_Unwind_Word) > sizeof(void*).  However, the answer is
not to change the type from void* to _Unwind_Word.  That will fail
when sizeof(void*) > sizeof(_Unwind_Word).

I think you have to make the reg field a union.

By the way, don't use intptr_t in the unwind code.  Use
_Unwind_Internal_Ptr.  But I think if you make the field a union, you
won't need to use either type.

Ian

Reply via email to