diff options
Diffstat (limited to 'libgcc')
-rw-r--r-- | libgcc/config/rs6000/linux-unwind.h | 8 | ||||
-rw-r--r-- | libgcc/unwind.inc | 5 |
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); |