$OpenBSD: patch-libgcc_unwind-dw2_c,v 1.1.1.1 2021/08/15 18:42:11 pascal Exp $

Index: libgcc/unwind-dw2.c
--- libgcc/unwind-dw2.c.orig
+++ libgcc/unwind-dw2.c
@@ -216,6 +216,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.  */
 
@@ -246,6 +265,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;
@@ -254,6 +280,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 *
