aboutsummaryrefslogtreecommitdiff
path: root/libgcc
diff options
context:
space:
mode:
Diffstat (limited to 'libgcc')
-rw-r--r--libgcc/config/rs6000/linux-unwind.h8
-rw-r--r--libgcc/unwind.inc5
2 files changed, 10 insertions, 3 deletions
diff --git a/libgcc/config/rs6000/linux-unwind.h b/libgcc/config/rs6000/linux-unwind.h
index 4788497..5ef9c1a 100644
--- a/libgcc/config/rs6000/linux-unwind.h
+++ b/libgcc/config/rs6000/linux-unwind.h
@@ -402,8 +402,14 @@ ppc_backchain_fallback (struct _Unwind_Context *context, void *a)
struct trace_arg *arg = a;
int count;
- /* Get the last address computed and start with the next. */
+ /* Get the last address computed. */
current = context->cfa;
+
+ /* If the trace CFA is not the context CFA the backtrace is done. */
+ if (arg == NULL || arg->cfa != current)
+ return;
+
+ /* Start with next address. */
current = current->backchain;
for (count = arg->count; current != NULL; current = current->backchain)
diff --git a/libgcc/unwind.inc b/libgcc/unwind.inc
index 456a5ee..dc2f9c1 100644
--- a/libgcc/unwind.inc
+++ b/libgcc/unwind.inc
@@ -160,12 +160,13 @@ _Unwind_ForcedUnwind_Phase2 (struct _Unwind_Exception *exc,
/* Set up fs to describe the FDE for the caller of cur_context. */
code = uw_frame_state_for (context, &fs);
- if (code != _URC_NO_REASON && code != _URC_END_OF_STACK)
+ if (code != _URC_NO_REASON && code != _URC_END_OF_STACK
+ && code != _URC_NORMAL_STOP)
return _URC_FATAL_PHASE2_ERROR;
/* Unwind successful. */
action = _UA_FORCE_UNWIND | _UA_CLEANUP_PHASE;
- if (code == _URC_END_OF_STACK)
+ if (code == _URC_END_OF_STACK || code == _URC_NORMAL_STOP)
action |= _UA_END_OF_STACK;
stop_code = (*stop) (1, action, exc->exception_class, exc,
context, stop_argument);