Index: libgcc/unwind-dw2.c --- libgcc/unwind-dw2.c.orig +++ libgcc/unwind-dw2.c @@ -215,6 +215,25 @@ _Unwind_IsExtendedContext (struct _Unwind_Context *con return (ASSUME_EXTENDED_UNWIND_CONTEXT || (context->flags & EXTENDED_CONTEXT_BIT)); } + +#ifdef __sparc64__ + +/* Figure out StackGhost cookie. */ +_Unwind_Word uw_get_wcookie(void); + +asm(".text\n" + "uw_get_wcookie:\n" + " add %o7, %g0, %g4\n" + " save %sp, -176, %sp\n" + " save %sp, -176, %sp\n" + " flushw\n" + " restore\n" + " ldx [%sp + 2047 + 120], %g5\n" + " xor %g4, %g5, %i0\n" + " ret\n" + " restore\n"); +#endif + /* Get the value of register REGNO as saved in CONTEXT. */ @@ -245,6 +264,13 @@ _Unwind_GetGR (struct _Unwind_Context *context, int re } #endif +#ifdef __sparc64__ + /* _Unwind_Word and _Unwind_Ptr are the same size on sparc64 */ + _Unwind_Word reg = * (_Unwind_Word *) val; + if (index == 15 || index == 31) + reg ^= uw_get_wcookie (); + return reg; +#else /* This will segfault if the register hasn't been saved. */ if (size == sizeof(_Unwind_Ptr)) return * (_Unwind_Ptr *) (_Unwind_Internal_Ptr) val; @@ -253,6 +279,7 @@ _Unwind_GetGR (struct _Unwind_Context *context, int re gcc_assert (size == sizeof(_Unwind_Word)); return * (_Unwind_Word *) (_Unwind_Internal_Ptr) val; } +#endif } static inline void *