gcc-patches@gcc.gnu.org
[Top] [All Lists]

Tweak forced unwinding for SJLJ

Subject: Tweak forced unwinding for SJLJ
From: Daniel Jacobowitz
Date: Wed, 16 Nov 2005 10:28:06 -0500
This patch separates the go-on-to-the-next-context operation used in forced
unwinding from that used in both phases of normal two-phase unwinding.  The
difference between the two situations is that we call a user-provided
function during forced unwinding; it may longjmp away to run its own
cleanups and reenter the EH machinery via _Unwind_ForcedUnwind again.
Therefore, when we have unwound a stack frame and called the user function,
it's vital that we update the SJLJ state so that contexts for the clobbered
bits of the stack are no longer referenced.  Else we can end up jumping to
garbage.

This patch was the least invasive way I could see to accomplish that.  Is
this OK?

[Fixes nptl/tst-cancel17 in glibc, for ARM SJLJ, if anyone is keeping
score at home.]

-- 
Daniel Jacobowitz
CodeSourcery, LLC

2005-11-16  Daniel Jacobowitz  <dan@xxxxxxxxxxxxxxxx>

        * config/ia64/unwind-ia64.c (uw_advance_context): New.  Call
        uw_update_context.
        * unwind-dw2.c (uw_advance_context): Likewise.
        * unwind-sjlj.c (uw_advance_context): Likewise.  Also call
        _Unwind_SjLj_Unregister.
        * unwind.inc (_Unwind_ForcedUnwind_Phase2): Call uw_advance_context.

Index: gcc/gcc/config/ia64/unwind-ia64.c
===================================================================
--- gcc.orig/gcc/config/ia64/unwind-ia64.c      2005-11-03 15:07:48.000000000 
-0500
+++ gcc/gcc/config/ia64/unwind-ia64.c   2005-11-15 15:27:20.000000000 -0500
@@ -2060,6 +2060,12 @@ uw_update_context (struct _Unwind_Contex
     }
 }
 
+static void
+uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
+{
+  uw_update_context (context, fs);
+}
+
 /* Fill in CONTEXT for top-of-stack.  The only valid registers at this
    level will be the return address and the CFA.  Note that CFA = SP+16.  */
    
Index: gcc/gcc/unwind-dw2.c
===================================================================
--- gcc.orig/gcc/unwind-dw2.c   2005-11-03 15:08:39.000000000 -0500
+++ gcc/gcc/unwind-dw2.c        2005-11-15 15:28:44.000000000 -0500
@@ -1210,6 +1210,12 @@ uw_update_context (struct _Unwind_Contex
   context->ra = __builtin_extract_return_addr
     (_Unwind_GetPtr (context, fs->retaddr_column));
 }
+
+static void
+uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
+{
+  uw_update_context (context, fs);
+}
 
 /* Fill in CONTEXT for top-of-stack.  The only valid registers at this
    level will be the return address and the CFA.  */
Index: gcc/gcc/unwind-sjlj.c
===================================================================
--- gcc.orig/gcc/unwind-sjlj.c  2005-11-15 15:13:14.000000000 -0500
+++ gcc/gcc/unwind-sjlj.c       2005-11-15 15:29:27.000000000 -0500
@@ -276,6 +276,13 @@ uw_update_context (struct _Unwind_Contex
   context->fc = context->fc->prev;
 }
 
+static void
+uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
+{
+  _Unwind_SjLj_Unregister (context->fc);
+  uw_update_context (context, fs);
+}
+
 static inline void
 uw_init_context (struct _Unwind_Context *context)
 {
Index: gcc/gcc/unwind.inc
===================================================================
--- gcc.orig/gcc/unwind.inc     2005-11-03 15:08:38.000000000 -0500
+++ gcc/gcc/unwind.inc  2005-11-15 15:28:17.000000000 -0500
@@ -184,8 +184,9 @@ _Unwind_ForcedUnwind_Phase2 (struct _Unw
            return _URC_FATAL_PHASE2_ERROR;
        }
 
-      /* Update cur_context to describe the same frame as fs.  */
-      uw_update_context (context, &fs);
+      /* Update cur_context to describe the same frame as fs, and discard
+        the previous context if necessary.  */
+      uw_advance_context (context, &fs);
     }
 
   return code;

<Prev in Thread] Current Thread [Next in Thread>
  • Tweak forced unwinding for SJLJ, Daniel Jacobowitz <=