unwind-arm.h: Reorder interface function declarations.

2005-11-16  Nathan Sidwell  <nathan@codesourcery.com>
gcc/
	* config/arm/unwind-arm.h: Reorder interface function declarations.
	(_URC_END_OF_STACK): New enumeration value.
	(_US_UNWIND_ACTION_MASK, _US_FORCE_UNWIND, _US_END_OF_STACK): Likewise.
	(struct _Unwind_Control_Block): Document reserved field use.
	(_Unwind_Stop_Fn): New typedef.
	(_Unwind_ForcedUnwind): Declare.
	(_Unwind_Resume_or_Rethrow): Declare.
	* config/arm/libunwind.S (UNWIND_WRAPER): Add nargs
	argument.  Adjust.
	(_Unwind_Resume_or_Rethrow, _Unwind_ForcedUnwind): New.
	* config/arm/unwind-arm.c (UCB_FORCED_STOP_FN)
	(UCB_FORCED_STOP_ARG): New.
	(search_EIT_table): Update boundary condition checks.
	(get_eit_entry): Return _URC_END_OF_STACK when cannot unwind.
	(unwind_phase2): Replace for with do..while.
	(unwind_phase2_forced): New.
	(__gnu_Unwind_RaiseException): Replace for with do..while.
	(__gnu_Unwind_ForcedUnwind): New.
	(__gnu_Unwind_Resume): Set FORCE_UNWIND flag, if forced unwinding.
	Use appropriate phase2 unwinder.
	(__gnu_Unwind_Resume_or_Rethrow): New.
	(__gnu_unwind_pr_common): Cope with forced unwinding.
gcc/testsuite/
	* g++.dg/eh/forced1.C: Adjust to cope with ARM EABI
	structures.
	* g++.dg/eh/forced2.C: Likewise.
	* g++.dg/eh/forced3.C: Likewise.
	* g++.dg/eh/forced4.C: Likewise.
libstdc++-v3/
	* libsupc++/eh_arm.cc (__cxa_begin_cleanup): Remember a
	foreign exception too.
	(__gnu_end_cleanup): Recover a foreign exception too.
	* libsupc++/eh_personality.cc (PERSONALITY_FUNCTION): Cope
	with forced unwinding.
	* libsupc++/eh_throw.cc (__cxxabiv1::__cxa_rethrow): Use
	_Unwind_Resume_or_Rethrow for ARM EABI.

From-SVN: r107089
This commit is contained in:
Nathan Sidwell 2005-11-16 17:04:41 +00:00 committed by Daniel Jacobowitz
parent 8656214b84
commit 1dcca6f361
13 changed files with 254 additions and 82 deletions

View file

@ -1,3 +1,28 @@
2005-11-16 Nathan Sidwell <nathan@codesourcery.com>
* config/arm/unwind-arm.h: Reorder interface function declarations.
(_URC_END_OF_STACK): New enumeration value.
(_US_UNWIND_ACTION_MASK, _US_FORCE_UNWIND, _US_END_OF_STACK): Likewise.
(struct _Unwind_Control_Block): Document reserved field use.
(_Unwind_Stop_Fn): New typedef.
(_Unwind_ForcedUnwind): Declare.
(_Unwind_Resume_or_Rethrow): Declare.
* gcc/config/arm/libunwind.S (UNWIND_WRAPER): Add nargs
argument. Adjust.
(_Unwind_Resume_or_Rethrow, _Unwind_ForcedUnwind): New.
* config/arm/unwind-arm.c (UCB_FORCED_STOP_FN)
(UCB_FORCED_STOP_ARG): New.
(search_EIT_table): Update boundary condition checks.
(get_eit_entry): Return _URC_END_OF_STACK when cannot unwind.
(unwind_phase2): Replace for with do..while.
(unwind_phase2_forced): New.
(__gnu_Unwind_RaiseException): Replace for with do..while.
(__gnu_Unwind_ForcedUnwind): New.
(__gnu_Unwind_Resume): Set FORCE_UNWIND flag, if forced unwinding.
Use appropriate phase2 unwinder.
(__gnu_Unwind_Resume_or_Rethrow): New.
(__gnu_unwind_pr_common): Cope with forced unwinding.
2005-11-16 David Edelsohn <edelsohn@gnu.org>
PR target/24772

View file

@ -78,7 +78,7 @@ ARM_FUNC_START gnu_Unwind_Save_VFP
/* Wrappers to save core registers, then call the real routine. */
.macro UNWIND_WRAPPER name
.macro UNWIND_WRAPPER name nargs
ARM_FUNC_START \name
/* Create a phase2_vrs structure. */
/* Split reg push in two to ensure the correct value for sp. */
@ -89,8 +89,8 @@ ARM_FUNC_START gnu_Unwind_Save_VFP
mov r3, #0
stmfd sp!, {r2, r3}
/* Point r1 at the block. Pass r0 unchanged. */
add r1, sp, #4
/* Point r1 at the block. Pass r[0..nargs) unchanged. */
add r\nargs, sp, #4
#if defined(__thumb__)
/* Switch back to thumb mode to avoid interworking hassle. */
adr ip, .L1_\name
@ -112,7 +112,9 @@ ARM_FUNC_START gnu_Unwind_Save_VFP
UNPREFIX \name
.endm
UNWIND_WRAPPER _Unwind_RaiseException
UNWIND_WRAPPER _Unwind_Resume
UNWIND_WRAPPER _Unwind_RaiseException 1
UNWIND_WRAPPER _Unwind_Resume 1
UNWIND_WRAPPER _Unwind_Resume_or_Rethrow 1
UNWIND_WRAPPER _Unwind_ForcedUnwind 3
#endif /* __symbian__ */

View file

@ -51,8 +51,10 @@ __gnu_Unwind_Find_exidx (_Unwind_Ptr, int *);
#define EXIDX_CANTUNWIND 1
#define uint32_highbit (((_uw) 1) << 31)
#define UCB_FORCED_STOP_FN(ucbp) ((ucbp)->unwinder_cache.reserved1)
#define UCB_PR_ADDR(ucbp) ((ucbp)->unwinder_cache.reserved2)
#define UCB_SAVED_CALLSITE_ADDR(ucbp) ((ucbp)->unwinder_cache.reserved3)
#define UCB_FORCED_STOP_ARG(ucb) ((ucbp)->unwinder_cache.reserved4)
struct core_regs
{
@ -356,9 +358,9 @@ search_EIT_table (const __EIT_entry * table, int nrec, _uw return_address)
n = (left + right) / 2;
this_fn = selfrel_offset31 (&table[n].fnoffset);
if (n != nrec - 1)
next_fn = selfrel_offset31 (&table[n + 1].fnoffset);
next_fn = selfrel_offset31 (&table[n + 1].fnoffset) - 1;
else
next_fn = ~(_uw) 0;
next_fn = (_uw)0 - 1;
if (return_address < this_fn)
{
@ -366,7 +368,7 @@ search_EIT_table (const __EIT_entry * table, int nrec, _uw return_address)
return (__EIT_entry *) 0;
right = n - 1;
}
else if (return_address < next_fn)
else if (return_address <= next_fn)
return &table[n];
else
left = n + 1;
@ -419,7 +421,7 @@ get_eit_entry (_Unwind_Control_Block *ucbp, _uw return_address)
if (eitp->content == EXIDX_CANTUNWIND)
{
UCB_PR_ADDR (ucbp) = 0;
return _URC_FAILURE;
return _URC_END_OF_STACK;
}
/* Obtain the address of the "real" __EHT_Header word. */
@ -472,21 +474,19 @@ unwind_phase2 (_Unwind_Control_Block * ucbp, phase2_vrs * vrs)
{
_Unwind_Reason_Code pr_result;
for(;;)
do
{
/* Find the entry for this routine. */
if (get_eit_entry (ucbp, vrs->core.r[R_PC]) != _URC_OK)
abort ();
UCB_SAVED_CALLSITE_ADDR (ucbp) = vrs->core.r[R_PC];
/* Call the pr to decide what to do. */
pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
(_US_UNWIND_FRAME_STARTING, ucbp, (_Unwind_Context *) vrs);
if (pr_result != _URC_CONTINUE_UNWIND)
break;
}
while (pr_result == _URC_CONTINUE_UNWIND);
if (pr_result != _URC_INSTALL_CONTEXT)
abort();
@ -494,6 +494,57 @@ unwind_phase2 (_Unwind_Control_Block * ucbp, phase2_vrs * vrs)
restore_core_regs (&vrs->core);
}
/* Perform phase2 forced unwinding. */
static _Unwind_Reason_Code
unwind_phase2_forced (_Unwind_Control_Block *ucbp, phase2_vrs *entry_vrs)
{
_Unwind_Stop_Fn stop_fn = (_Unwind_Stop_Fn) UCB_FORCED_STOP_FN (ucbp);
void *stop_arg = (void *)UCB_FORCED_STOP_ARG (ucbp);
_Unwind_Reason_Code pr_result;
/* Unwind until we reach a propagation barrier. */
do
{
_Unwind_State action;
_Unwind_Reason_Code entry_code;
_Unwind_Reason_Code stop_code;
/* Find the entry for this routine. */
entry_code = get_eit_entry (ucbp, entry_vrs->core.r[R_PC]);
action = _US_UNWIND_FRAME_STARTING | _US_FORCE_UNWIND;
if (entry_code == _URC_END_OF_STACK)
action |= _US_END_OF_STACK;
else if (entry_code != _URC_OK)
return _URC_FAILURE;
stop_code = stop_fn (1, action, ucbp->exception_class, ucbp,
(void *)entry_vrs, stop_arg);
if (stop_code != _URC_NO_REASON)
return _URC_FAILURE;
if (entry_code == _URC_END_OF_STACK)
return entry_code;
UCB_SAVED_CALLSITE_ADDR (ucbp) = entry_vrs->core.r[R_PC];
/* Call the pr to decide what to do. */
pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
(action, ucbp, (void *) entry_vrs);
}
while (pr_result == _URC_CONTINUE_UNWIND);
if (pr_result != _URC_INSTALL_CONTEXT)
{
/* Some sort of failure has occurred in the pr and probably the
pr returned _URC_FAILURE. */
return _URC_FAILURE;
}
restore_core_regs (&entry_vrs->core);
}
/* Perform phase1 unwinding. UCBP is the exception being thrown, and
entry_VRS is the register state on entry to _Unwind_RaiseException. */
@ -516,7 +567,7 @@ __gnu_Unwind_RaiseException (_Unwind_Control_Block * ucbp,
saved_vrs.demand_save_flags = ~(_uw) 0;
/* Unwind until we reach a propagation barrier. */
for (;;)
do
{
/* Find the entry for this routine. */
if (get_eit_entry (ucbp, saved_vrs.core.r[R_PC]) != _URC_OK)
@ -525,10 +576,8 @@ __gnu_Unwind_RaiseException (_Unwind_Control_Block * ucbp,
/* Call the pr to decide what to do. */
pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
(_US_VIRTUAL_UNWIND_FRAME, ucbp, (void *) &saved_vrs);
if (pr_result != _URC_CONTINUE_UNWIND)
break;
}
while (pr_result == _URC_CONTINUE_UNWIND);
/* We've unwound as far as we want to go, so restore the original
register state. */
@ -546,6 +595,24 @@ __gnu_Unwind_RaiseException (_Unwind_Control_Block * ucbp,
/* Resume unwinding after a cleanup has been run. UCBP is the exception
being thrown and ENTRY_VRS is the register state on entry to
_Unwind_Resume. */
_Unwind_Reason_Code
__gnu_Unwind_ForcedUnwind (_Unwind_Control_Block *,
_Unwind_Stop_Fn, void *, phase2_vrs *);
_Unwind_Reason_Code
__gnu_Unwind_ForcedUnwind (_Unwind_Control_Block *ucbp,
_Unwind_Stop_Fn stop_fn, void *stop_arg,
phase2_vrs *entry_vrs)
{
UCB_FORCED_STOP_FN (ucbp) = (_uw) stop_fn;
UCB_FORCED_STOP_ARG (ucbp) = (_uw) stop_arg;
/* Set the pc to the call site. */
entry_vrs->core.r[R_PC] = entry_vrs->core.r[R_LR];
return unwind_phase2_forced (ucbp, entry_vrs);
}
_Unwind_Reason_Code
__gnu_Unwind_Resume (_Unwind_Control_Block *, phase2_vrs *);
@ -553,13 +620,18 @@ _Unwind_Reason_Code
__gnu_Unwind_Resume (_Unwind_Control_Block * ucbp, phase2_vrs * entry_vrs)
{
_Unwind_Reason_Code pr_result;
_Unwind_State action;
/* Recover the saved address. */
entry_vrs->core.r[R_PC] = UCB_SAVED_CALLSITE_ADDR (ucbp);
/* Call the cached PR. */
action = _US_UNWIND_FRAME_RESUME;
if (UCB_FORCED_STOP_FN (ucbp))
action |= _US_FORCE_UNWIND;
pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
(_US_UNWIND_FRAME_RESUME, ucbp, (_Unwind_Context *) entry_vrs);
(action, ucbp, (_Unwind_Context *) entry_vrs);
switch (pr_result)
{
@ -569,13 +641,32 @@ __gnu_Unwind_Resume (_Unwind_Control_Block * ucbp, phase2_vrs * entry_vrs)
case _URC_CONTINUE_UNWIND:
/* Continue unwinding the next frame. */
unwind_phase2 (ucbp, entry_vrs);
if (UCB_FORCED_STOP_FN (ucbp))
return unwind_phase2_forced (ucbp, entry_vrs);
else
unwind_phase2 (ucbp, entry_vrs);
default:
abort ();
}
}
_Unwind_Reason_Code
__gnu_Unwind_Resume_or_Rethrow (_Unwind_Control_Block *, phase2_vrs *);
_Unwind_Reason_Code
__gnu_Unwind_Resume_or_Rethrow (_Unwind_Control_Block * ucbp,
phase2_vrs * entry_vrs)
{
if (!UCB_FORCED_STOP_FN (ucbp))
return __gnu_Unwind_RaiseException (ucbp, entry_vrs);
/* Set the pc to the call site. */
entry_vrs->core.r[R_PC] = entry_vrs->core.r[R_LR];
/* Continue unwinding the next frame. */
return unwind_phase2_forced (ucbp, entry_vrs);
}
/* Clean up an exception object when unwinding is complete. */
void
_Unwind_Complete (_Unwind_Control_Block * ucbp __attribute__((unused)))
@ -619,6 +710,9 @@ __gnu_unwind_pr_common (_Unwind_State state,
_uw rtti_count;
int phase2_call_unexpected_after_unwind = 0;
int in_range = 0;
int forced_unwind = state & _US_FORCE_UNWIND;
state &= _US_ACTION_MASK;
data = (_uw *) ucbp->pr_cache.ehtp;
uws.data = *(data++);
@ -748,9 +842,9 @@ __gnu_unwind_pr_common (_Unwind_State state,
/* Exception specification. */
if (state == _US_VIRTUAL_UNWIND_FRAME)
{
if (in_range)
if (in_range && (!forced_unwind || !rtti_count))
{
/* Match against teh exception specification. */
/* Match against the exception specification. */
_uw i;
_uw rtti;
void *matched;

View file

@ -1,5 +1,5 @@
/* Header file for the ARM EABI unwinder
Copyright (C) 2003, 2004 Free Software Foundation, Inc.
Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
Contributed by Paul Brook
This file is free software; you can redistribute it and/or modify it
@ -54,28 +54,41 @@ extern "C" {
{
_URC_OK = 0, /* operation completed successfully */
_URC_FOREIGN_EXCEPTION_CAUGHT = 1,
_URC_END_OF_STACK = 5,
_URC_HANDLER_FOUND = 6,
_URC_INSTALL_CONTEXT = 7,
_URC_CONTINUE_UNWIND = 8,
_URC_FAILURE = 9 /* unspecified failure of some kind */
}
_Unwind_Reason_Code;
typedef enum
{
_US_VIRTUAL_UNWIND_FRAME = 0,
_US_UNWIND_FRAME_STARTING = 1,
_US_UNWIND_FRAME_RESUME = 2
_US_UNWIND_FRAME_RESUME = 2,
_US_ACTION_MASK = 3,
_US_FORCE_UNWIND = 8,
_US_END_OF_STACK = 16
}
_Unwind_State;
/* Provided only for for compatibility with existing code. */
typedef int _Unwind_Action;
#define _UA_SEARCH_PHASE 1
#define _UA_CLEANUP_PHASE 2
#define _UA_HANDLER_FRAME 4
#define _UA_FORCE_UNWIND 8
#define _UA_END_OF_STACK 16
#define _URC_NO_REASON _URC_OK
typedef struct _Unwind_Control_Block _Unwind_Control_Block;
typedef struct _Unwind_Context _Unwind_Context;
typedef _uw _Unwind_EHT_Header;
/* UCB: */
struct _Unwind_Control_Block
{
char exception_class[8];
@ -83,10 +96,10 @@ extern "C" {
/* Unwinder cache, private fields for the unwinder's use */
struct
{
_uw reserved1; /* init reserved1 to 0, then don't touch */
_uw reserved2;
_uw reserved3;
_uw reserved4;
_uw reserved1; /* Forced unwind stop fn, 0 if not forced */
_uw reserved2; /* Personality routine address */
_uw reserved3; /* Saved callsite address */
_uw reserved4; /* Forced unwind stop arg */
_uw reserved5;
}
unwinder_cache;
@ -114,14 +127,9 @@ extern "C" {
pr_cache;
long long int :0; /* Force alignment to 8-byte boundary */
};
/* Interface functions: */
_Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Control_Block *ucbp);
void __attribute__((noreturn)) _Unwind_Resume(_Unwind_Control_Block *ucbp);
void _Unwind_Complete(_Unwind_Control_Block *ucbp);
/* Virtual Register Set*/
typedef enum
{
_UVRSC_CORE = 0, /* integer register */
@ -131,7 +139,7 @@ extern "C" {
_UVRSC_WMMXC = 4 /* Intel WMMX control register */
}
_Unwind_VRS_RegClass;
typedef enum
{
_UVRSD_UINT32 = 0,
@ -142,13 +150,13 @@ extern "C" {
_UVRSD_DOUBLE = 5
}
_Unwind_VRS_DataRepresentation;
typedef enum
{
_UVRSR_OK = 0,
_UVRSR_NOT_IMPLEMENTED = 1,
_UVRSR_FAILED = 2
}
}
_Unwind_VRS_Result;
/* Frame unwinding state. */
@ -171,11 +179,11 @@ extern "C" {
_Unwind_VRS_Result _Unwind_VRS_Set(_Unwind_Context *, _Unwind_VRS_RegClass,
_uw, _Unwind_VRS_DataRepresentation,
void *);
_Unwind_VRS_Result _Unwind_VRS_Get(_Unwind_Context *, _Unwind_VRS_RegClass,
_uw, _Unwind_VRS_DataRepresentation,
void *);
_Unwind_VRS_Result _Unwind_VRS_Pop(_Unwind_Context *, _Unwind_VRS_RegClass,
_uw, _Unwind_VRS_DataRepresentation);
@ -200,6 +208,17 @@ extern "C" {
abort ();
}
/* Interface functions: */
_Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Control_Block *ucbp);
void __attribute__((noreturn)) _Unwind_Resume(_Unwind_Control_Block *ucbp);
_Unwind_Reason_Code _Unwind_Resume_or_Rethrow (_Unwind_Control_Block *ucbp);
typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn)
(int, _Unwind_Action, _Unwind_Exception_Class,
_Unwind_Control_Block *, struct _Unwind_Context *, void *);
_Unwind_Reason_Code _Unwind_ForcedUnwind (_Unwind_Control_Block *,
_Unwind_Stop_Fn, void *);
void _Unwind_Complete(_Unwind_Control_Block *ucbp);
void _Unwind_DeleteException (_Unwind_Exception *);
_Unwind_Reason_Code __gnu_unwind_frame (_Unwind_Control_Block *,
@ -254,16 +273,6 @@ extern "C" {
#define _Unwind_SetIP(context, val) \
_Unwind_SetGR (context, 15, val | (_Unwind_GetGR (context, 15) & 1))
/* Provided only for for compatibility with existing code. */
typedef int _Unwind_Action;
#define _UA_SEARCH_PHASE 1
#define _UA_CLEANUP_PHASE 2
#define _UA_HANDLER_FRAME 4
#define _UA_FORCE_UNWIND 8
#define _UA_END_OF_STACK 16
#define _URC_NO_REASON _URC_OK
#ifdef __cplusplus
} /* extern "C" */
#endif

View file

@ -1,3 +1,11 @@
2005-11-16 Nathan Sidwell <nathan@codesourcery.com>
* g++.dg/eh/forced1.C: Adjust to cope with ARM EABI
structures.
* g++.dg/eh/forced2.C: Likewise.
* g++.dg/eh/forced3.C: Likewise.
* g++.dg/eh/forced4.C: Likewise.
2005-11-11 Mike Stump <mrs@apple.com>
* g++.old-deja/g++.mike/unused.C: Add.

View file

@ -6,6 +6,7 @@
#include <unwind.h>
#include <stdlib.h>
#include <string.h>
static int test = 0;
@ -35,7 +36,8 @@ force_unwind_cleanup (_Unwind_Reason_Code, struct _Unwind_Exception *)
static void force_unwind ()
{
_Unwind_Exception *exc = new _Unwind_Exception;
exc->exception_class = 0;
// exception_class might not be a scalar.
memset (&exc->exception_class, 0, sizeof (exc->exception_class));
exc->exception_cleanup = force_unwind_cleanup;
#ifndef __USING_SJLJ_EXCEPTIONS__
@ -54,7 +56,7 @@ struct S
~S() { test |= bit; }
};
static void doit ()
static __attribute__ ((noinline)) void doit ()
{
try {
S four(4);
@ -62,7 +64,6 @@ static void doit ()
try {
S one(1);
force_unwind ();
} catch(...) {
test |= 2;
throw;

View file

@ -6,6 +6,7 @@
#include <unwind.h>
#include <stdlib.h>
#include <string.h>
static _Unwind_Reason_Code
force_unwind_stop (int version, _Unwind_Action actions,
@ -29,7 +30,8 @@ static void
force_unwind ()
{
_Unwind_Exception *exc = new _Unwind_Exception;
exc->exception_class = 0;
// exception_class might not be a scalar.
memset (&exc->exception_class, 0, sizeof (exc->exception_class));
exc->exception_cleanup = force_unwind_cleanup;
#ifndef __USING_SJLJ_EXCEPTIONS__

View file

@ -7,6 +7,7 @@
#include <unwind.h>
#include <stdlib.h>
#include <exception>
#include <string.h>
static _Unwind_Reason_Code
force_unwind_stop (int version, _Unwind_Action actions,
@ -24,7 +25,8 @@ static void __attribute__((noreturn))
force_unwind ()
{
_Unwind_Exception *exc = new _Unwind_Exception;
exc->exception_class = 0;
// exception_class might not be a scalar.
memset (&exc->exception_class, 0, sizeof (exc->exception_class));
exc->exception_cleanup = 0;
#ifndef __USING_SJLJ_EXCEPTIONS__

View file

@ -6,6 +6,7 @@
#include <unwind.h>
#include <stdlib.h>
#include <string.h>
static _Unwind_Reason_Code
force_unwind_stop (int version, _Unwind_Action actions,
@ -23,7 +24,8 @@ static void __attribute__((noreturn))
force_unwind ()
{
_Unwind_Exception *exc = new _Unwind_Exception;
exc->exception_class = 0;
// exception_class might not be a scalar.
memset (&exc->exception_class, 0, sizeof (exc->exception_class));
exc->exception_cleanup = 0;
#ifndef __USING_SJLJ_EXCEPTIONS__

View file

@ -1,3 +1,13 @@
2005-11-16 Nathan Sidwell <nathan@codesourcery.com>
* libsupc++/eh_arm.cc (__cxa_begin_cleanup): Remember a
foreign exception too.
(__gnu_end_cleanup): Recover a foreign exception too.
* libsupc++/eh_personality.cc (PERSONALITY_FUNCTION): Cope
with forced unwinding.
* libsupc++/eh_throw.cc (__cxxabiv1::__cxa_rethrow): Use
_Unwind_Resume_or_Rethrow for ARM EABI.
2005-11-14 Geoffrey Keating <geoffk@apple.com>
* acinclude.m4 (GLIBCXX_CHECK_LINKER_FEATURES): Don't check for

View file

@ -89,20 +89,31 @@ __cxa_begin_cleanup(_Unwind_Exception* ue_header)
{
__cxa_eh_globals *globals = __cxa_get_globals();
__cxa_exception *header = __get_exception_header_from_ue(ue_header);
bool native = __is_gxx_exception_class(header->unwindHeader.exception_class);
if (!__is_gxx_exception_class(header->unwindHeader.exception_class))
if (native)
{
// TODO: cleanups with foreign exceptions.
return false;
header->propagationCount++;
// Add it to the chain if this is the first time we've seen this
// exception.
if (header->propagationCount == 1)
{
header->nextPropagatingException = globals->propagatingExceptions;
globals->propagatingExceptions = header;
}
}
header->propagationCount++;
// Add it to the chain if this is the first time we've seen this exception.
if (header->propagationCount == 1)
else
{
header->nextPropagatingException = globals->propagatingExceptions;
// Remember the exception object, so end_cleanup can return it.
// These cannot be stacked, so we must abort if we already have
// a propagating exception.
if (globals->propagatingExceptions)
std::terminate ();
globals->propagatingExceptions = header;
}
return true;
return !native;
}
// Do the work for __cxa_end_cleanup. Returns the currently propagating
@ -119,13 +130,19 @@ __gnu_end_cleanup(void)
if (!header)
std::terminate();
header->propagationCount--;
if (header->propagationCount == 0)
if (__is_gxx_exception_class(header->unwindHeader.exception_class))
{
// Remove exception from chain.
globals->propagatingExceptions = header->nextPropagatingException;
header->nextPropagatingException = NULL;
header->propagationCount--;
if (header->propagationCount == 0)
{
// Remove exception from chain.
globals->propagatingExceptions = header->nextPropagatingException;
header->nextPropagatingException = NULL;
}
}
else
globals->propagatingExceptions = NULL;
return &header->unwindHeader;
}

View file

@ -369,7 +369,7 @@ PERSONALITY_FUNCTION (int version,
#ifdef __ARM_EABI_UNWINDER__
_Unwind_Action actions;
switch (state)
switch (state & _US_ACTION_MASK)
{
case _US_VIRTUAL_UNWIND_FRAME:
actions = _UA_SEARCH_PHASE;
@ -377,7 +377,8 @@ PERSONALITY_FUNCTION (int version,
case _US_UNWIND_FRAME_STARTING:
actions = _UA_CLEANUP_PHASE;
if (ue_header->barrier_cache.sp == _Unwind_GetGR(context, 13))
if (!(state & _US_FORCE_UNWIND)
&& ue_header->barrier_cache.sp == _Unwind_GetGR(context, 13))
actions |= _UA_HANDLER_FRAME;
break;
@ -388,6 +389,7 @@ PERSONALITY_FUNCTION (int version,
default:
abort();
}
actions |= state & _US_FORCE_UNWIND;
// We don't know which runtime we're working with, so can't check this.
// However the ABI routines hide this from us, and we don't actually need
@ -523,13 +525,13 @@ PERSONALITY_FUNCTION (int version,
// exception class, there's no exception type.
// ??? What to do about GNU Java and GNU Ada exceptions.
#ifdef __ARM_EABI_UNWINDER__
throw_type = ue_header;
#else
if ((actions & _UA_FORCE_UNWIND)
|| foreign_exception)
throw_type = 0;
else
#ifdef __ARM_EABI_UNWINDER__
throw_type = ue_header;
#else
throw_type = xh->exceptionType;
#endif
@ -613,7 +615,6 @@ PERSONALITY_FUNCTION (int version,
install_context:
#ifndef __ARM_EABI_UNWINDER__
// We can't use any of the cxa routines with foreign exceptions,
// because they all expect ue_header to be a struct __cxa_exception.
// So in that case, call terminate or unexpected directly.
@ -631,7 +632,6 @@ PERSONALITY_FUNCTION (int version,
}
}
else
#endif
{
if (found_type == found_terminate)
__cxa_call_terminate(ue_header);

View file

@ -97,7 +97,7 @@ __cxxabiv1::__cxa_rethrow ()
#ifdef _GLIBCXX_SJLJ_EXCEPTIONS
_Unwind_SjLj_Resume_or_Rethrow (&header->unwindHeader);
#else
#if defined(_LIBUNWIND_STD_ABI) || defined (__ARM_EABI_UNWINDER__)
#if defined(_LIBUNWIND_STD_ABI)
_Unwind_RaiseException (&header->unwindHeader);
#else
_Unwind_Resume_or_Rethrow (&header->unwindHeader);