diff options
-rw-r--r-- | gnu/usr.bin/gcc/gcc/unwind-dw2.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/gnu/usr.bin/gcc/gcc/unwind-dw2.c b/gnu/usr.bin/gcc/gcc/unwind-dw2.c index 0e59c7b2ba2..59c1e9c4237 100644 --- a/gnu/usr.bin/gcc/gcc/unwind-dw2.c +++ b/gnu/usr.bin/gcc/gcc/unwind-dw2.c @@ -23,6 +23,9 @@ #include "tsystem.h" #include "dwarf2.h" #include "unwind.h" +#ifdef __USING_SJLJ_EXCEPTIONS__ +# define NO_SIZE_OF_ENCODED_VALUE +#endif #include "unwind-pe.h" #include "unwind-dw2-fde.h" #include "gthr.h" @@ -157,13 +160,40 @@ read_8u (const void *p) { const union unaligned *up = p; return up->u8; } static inline unsigned long read_8s (const void *p) { const union unaligned *up = p; return up->s8; } + +#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 REG as saved in CONTEXT. */ inline _Unwind_Word _Unwind_GetGR (struct _Unwind_Context *context, int index) { /* This will segfault if the register hasn't been saved. */ - return * (_Unwind_Word *) context->reg[index]; + _Unwind_Word reg = * (_Unwind_Word *) context->reg[index]; + +#ifdef __sparc64__ + if (index == 15 || index == 31) + reg ^= uw_get_wcookie (); +#endif + + return reg; } /* Get the value of the CFA as saved in CONTEXT. */ @@ -171,7 +201,7 @@ _Unwind_GetGR (struct _Unwind_Context *context, int index) _Unwind_Word _Unwind_GetCFA (struct _Unwind_Context *context) { - return (_Unwind_Word) context->cfa; + return (_Unwind_Ptr) context->cfa; } /* Overwrite the saved value for register REG in CONTEXT with VAL. */ |