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:
parent
8656214b84
commit
1dcca6f361
13 changed files with 254 additions and 82 deletions
|
@ -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
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue