|
|
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;
|
|