summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gnu/usr.bin/gcc/gcc/unwind-dw2.c34
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. */