mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-13 12:25:12 +08:00
unwind-arm.c (abort): Add prototype here.
gcc/ * config/arm/unwind-arm.c (abort): Add prototype here. (UCB_FORCED_STOP_ARG): Correct typo in macro argument. (struct phase1_vrs): Add prev_sp. (unwind_phase2_forced): Save the original core registers instead of modifying entry_vrs. Take a new flag argument for resuming unwinding and set action flags accordingly. Always set _US_END_OF_STACK when get_eit_entry fails. Unwind before calling the stop function. (_Unwind_GetCFA): New function. (__gnu_Unwind_ForcedUnwind): Update call to unwind_phase2_forced. (__gnu_Unwind_Resume_or_Rethrow): Likewise. (__gnu_Unwind_Resume): Do not unwind here for forced unwinding; just call unwind_phase2_forced. (_Unwind_GetDataRelBase, _Unwind_GetTextRelBase): Move to here. * config/arm/unwind-arm.h (abort): Remove prototype. (_Unwind_GetDataRelBase, _Unwind_GetTextRelBase): Change to prototypes. (_Unwind_GetCFA): New prototype. * config/arm/pr-support.c (abort): Add prototype here. * unwind-c.c (PERSONALITY_FUNCTION) [__ARM_EABI_UNWINDER__]: Handle forced unwinding. * config/arm/arm.c (arm_expand_prologue, thumb_expand_prologue): Do not schedule the prologue with non-call exceptions and EABI. gcc/testsuite/ * gcc.dg/cleanup-5.c, gcc.dg/cleanup-8.c, gcc.dg/cleanup-9.c, gcc.dg/cleanup-10.c, gcc.dg/cleanup-11.c: Update for ARM EABI. From-SVN: r107091
This commit is contained in:
parent
1dcca6f361
commit
74d9c39f6a
@ -1,3 +1,28 @@
|
||||
2005-11-16 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* config/arm/unwind-arm.c (abort): Add prototype here.
|
||||
(UCB_FORCED_STOP_ARG): Correct typo in macro argument.
|
||||
(struct phase1_vrs): Add prev_sp.
|
||||
(unwind_phase2_forced): Save the original core registers instead of
|
||||
modifying entry_vrs. Take a new flag argument for resuming unwinding
|
||||
and set action flags accordingly. Always set _US_END_OF_STACK when
|
||||
get_eit_entry fails. Unwind before calling the stop function.
|
||||
(_Unwind_GetCFA): New function.
|
||||
(__gnu_Unwind_ForcedUnwind): Update call to unwind_phase2_forced.
|
||||
(__gnu_Unwind_Resume_or_Rethrow): Likewise.
|
||||
(__gnu_Unwind_Resume): Do not unwind here for forced unwinding;
|
||||
just call unwind_phase2_forced.
|
||||
(_Unwind_GetDataRelBase, _Unwind_GetTextRelBase): Move to here.
|
||||
* config/arm/unwind-arm.h (abort): Remove prototype.
|
||||
(_Unwind_GetDataRelBase, _Unwind_GetTextRelBase): Change to
|
||||
prototypes.
|
||||
(_Unwind_GetCFA): New prototype.
|
||||
* config/arm/pr-support.c (abort): Add prototype here.
|
||||
* unwind-c.c (PERSONALITY_FUNCTION) [__ARM_EABI_UNWINDER__]: Handle
|
||||
forced unwinding.
|
||||
* config/arm/arm.c (arm_expand_prologue, thumb_expand_prologue): Do
|
||||
not schedule the prologue with non-call exceptions and EABI.
|
||||
|
||||
2005-11-16 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* config/arm/unwind-arm.h: Reorder interface function declarations.
|
||||
|
@ -10850,8 +10850,11 @@ arm_expand_prologue (void)
|
||||
|
||||
/* If we are profiling, make sure no instructions are scheduled before
|
||||
the call to mcount. Similarly if the user has requested no
|
||||
scheduling in the prolog. */
|
||||
if (current_function_profile || !TARGET_SCHED_PROLOG)
|
||||
scheduling in the prolog. Similarly if we want non-call exceptions
|
||||
using the EABI unwinder, to prevent faulting instructions from being
|
||||
swapped with a stack adjustment. */
|
||||
if (current_function_profile || !TARGET_SCHED_PROLOG
|
||||
|| (ARM_EABI_UNWIND_TABLES && flag_non_call_exceptions))
|
||||
emit_insn (gen_blockage ());
|
||||
|
||||
/* If the link register is being kept alive, with the return address in it,
|
||||
@ -13714,7 +13717,13 @@ thumb_expand_prologue (void)
|
||||
RTX_FRAME_RELATED_P (insn) = 1;
|
||||
}
|
||||
|
||||
if (current_function_profile || !TARGET_SCHED_PROLOG)
|
||||
/* If we are profiling, make sure no instructions are scheduled before
|
||||
the call to mcount. Similarly if the user has requested no
|
||||
scheduling in the prolog. Similarly if we want non-call exceptions
|
||||
using the EABI unwinder, to prevent faulting instructions from being
|
||||
swapped with a stack adjustment. */
|
||||
if (current_function_profile || !TARGET_SCHED_PROLOG
|
||||
|| (ARM_EABI_UNWIND_TABLES && flag_non_call_exceptions))
|
||||
emit_insn (gen_blockage ());
|
||||
|
||||
cfun->machine->lr_save_eliminated = !thumb_force_lr_save ();
|
||||
|
@ -27,6 +27,10 @@
|
||||
Boston, MA 02110-1301, USA. */
|
||||
#include "unwind.h"
|
||||
|
||||
/* We add a prototype for abort here to avoid creating a dependency on
|
||||
target headers. */
|
||||
extern void abort (void);
|
||||
|
||||
typedef struct _ZSt9type_info type_info; /* This names C++ type_info type */
|
||||
|
||||
/* Misc constants. */
|
||||
|
@ -27,6 +27,10 @@
|
||||
Boston, MA 02110-1301, USA. */
|
||||
#include "unwind.h"
|
||||
|
||||
/* We add a prototype for abort here to avoid creating a dependency on
|
||||
target headers. */
|
||||
extern void abort (void);
|
||||
|
||||
/* Definitions for C++ runtime support routines. We make these weak
|
||||
declarations to avoid pulling in libsupc++ unnecessarily. */
|
||||
typedef unsigned char bool;
|
||||
@ -54,7 +58,7 @@ __gnu_Unwind_Find_exidx (_Unwind_Ptr, int *);
|
||||
#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)
|
||||
#define UCB_FORCED_STOP_ARG(ucbp) ((ucbp)->unwinder_cache.reserved4)
|
||||
|
||||
struct core_regs
|
||||
{
|
||||
@ -107,6 +111,7 @@ typedef struct
|
||||
/* The first fields must be the same as a phase2_vrs. */
|
||||
_uw demand_save_flags;
|
||||
struct core_regs core;
|
||||
_uw prev_sp; /* Only valid during forced unwinding. */
|
||||
struct vfp_regs vfp;
|
||||
struct fpa_regs fpa;
|
||||
} phase1_vrs;
|
||||
@ -497,11 +502,21 @@ unwind_phase2 (_Unwind_Control_Block * ucbp, phase2_vrs * vrs)
|
||||
/* Perform phase2 forced unwinding. */
|
||||
|
||||
static _Unwind_Reason_Code
|
||||
unwind_phase2_forced (_Unwind_Control_Block *ucbp, phase2_vrs *entry_vrs)
|
||||
unwind_phase2_forced (_Unwind_Control_Block *ucbp, phase2_vrs *entry_vrs,
|
||||
int resuming)
|
||||
{
|
||||
_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_Reason_Code pr_result = 0;
|
||||
/* We use phase1_vrs here even though we do not demand save, for the
|
||||
prev_sp field. */
|
||||
phase1_vrs saved_vrs, next_vrs;
|
||||
|
||||
/* Save the core registers. */
|
||||
saved_vrs.core = entry_vrs->core;
|
||||
/* We don't need to demand-save the non-core registers, because we
|
||||
unwind in a single pass. */
|
||||
saved_vrs.demand_save_flags = 0;
|
||||
|
||||
/* Unwind until we reach a propagation barrier. */
|
||||
do
|
||||
@ -511,27 +526,51 @@ unwind_phase2_forced (_Unwind_Control_Block *ucbp, phase2_vrs *entry_vrs)
|
||||
_Unwind_Reason_Code stop_code;
|
||||
|
||||
/* Find the entry for this routine. */
|
||||
entry_code = get_eit_entry (ucbp, entry_vrs->core.r[R_PC]);
|
||||
entry_code = get_eit_entry (ucbp, saved_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;
|
||||
if (resuming)
|
||||
{
|
||||
action = _US_UNWIND_FRAME_RESUME | _US_FORCE_UNWIND;
|
||||
resuming = 0;
|
||||
}
|
||||
else
|
||||
action = _US_UNWIND_FRAME_STARTING | _US_FORCE_UNWIND;
|
||||
|
||||
if (entry_code == _URC_OK)
|
||||
{
|
||||
UCB_SAVED_CALLSITE_ADDR (ucbp) = saved_vrs.core.r[R_PC];
|
||||
|
||||
next_vrs = saved_vrs;
|
||||
|
||||
/* Call the pr to decide what to do. */
|
||||
pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
|
||||
(action, ucbp, (void *) &next_vrs);
|
||||
|
||||
saved_vrs.prev_sp = next_vrs.core.r[R_SP];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Treat any failure as the end of unwinding, to cope more
|
||||
gracefully with missing EH information. Mixed EH and
|
||||
non-EH within one object will usually result in failure,
|
||||
because the .ARM.exidx tables do not indicate the end
|
||||
of the code to which they apply; but mixed EH and non-EH
|
||||
shared objects should return an unwind failure at the
|
||||
entry of a non-EH shared object. */
|
||||
action |= _US_END_OF_STACK;
|
||||
|
||||
saved_vrs.prev_sp = saved_vrs.core.r[R_SP];
|
||||
}
|
||||
|
||||
stop_code = stop_fn (1, action, ucbp->exception_class, ucbp,
|
||||
(void *)entry_vrs, stop_arg);
|
||||
(void *)&saved_vrs, stop_arg);
|
||||
if (stop_code != _URC_NO_REASON)
|
||||
return _URC_FAILURE;
|
||||
|
||||
if (entry_code == _URC_END_OF_STACK)
|
||||
if (entry_code != _URC_OK)
|
||||
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);
|
||||
saved_vrs = next_vrs;
|
||||
}
|
||||
while (pr_result == _URC_CONTINUE_UNWIND);
|
||||
|
||||
@ -542,7 +581,20 @@ unwind_phase2_forced (_Unwind_Control_Block *ucbp, phase2_vrs *entry_vrs)
|
||||
return _URC_FAILURE;
|
||||
}
|
||||
|
||||
restore_core_regs (&entry_vrs->core);
|
||||
restore_core_regs (&saved_vrs.core);
|
||||
}
|
||||
|
||||
/* This is a very limited implementation of _Unwind_GetCFA. It returns
|
||||
the stack pointer as it is about to be unwound, and is only valid
|
||||
while calling the stop function during forced unwinding. If the
|
||||
current personality routine result is going to run a cleanup, this
|
||||
will not be the CFA; but when the frame is really unwound, it will
|
||||
be. */
|
||||
|
||||
_Unwind_Word
|
||||
_Unwind_GetCFA (_Unwind_Context *context)
|
||||
{
|
||||
return ((phase1_vrs *) context)->prev_sp;
|
||||
}
|
||||
|
||||
/* Perform phase1 unwinding. UCBP is the exception being thrown, and
|
||||
@ -610,7 +662,7 @@ __gnu_Unwind_ForcedUnwind (_Unwind_Control_Block *ucbp,
|
||||
/* 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);
|
||||
return unwind_phase2_forced (ucbp, entry_vrs, 0);
|
||||
}
|
||||
|
||||
_Unwind_Reason_Code
|
||||
@ -620,18 +672,21 @@ _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;
|
||||
{
|
||||
unwind_phase2_forced (ucbp, entry_vrs, 1);
|
||||
|
||||
/* We can't return failure at this point. */
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Call the cached PR. */
|
||||
pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
|
||||
(action, ucbp, (_Unwind_Context *) entry_vrs);
|
||||
(_US_UNWIND_FRAME_RESUME, ucbp, (_Unwind_Context *) entry_vrs);
|
||||
|
||||
switch (pr_result)
|
||||
{
|
||||
@ -641,10 +696,7 @@ __gnu_Unwind_Resume (_Unwind_Control_Block * ucbp, phase2_vrs * entry_vrs)
|
||||
|
||||
case _URC_CONTINUE_UNWIND:
|
||||
/* Continue unwinding the next frame. */
|
||||
if (UCB_FORCED_STOP_FN (ucbp))
|
||||
return unwind_phase2_forced (ucbp, entry_vrs);
|
||||
else
|
||||
unwind_phase2 (ucbp, entry_vrs);
|
||||
unwind_phase2 (ucbp, entry_vrs);
|
||||
|
||||
default:
|
||||
abort ();
|
||||
@ -664,7 +716,7 @@ __gnu_Unwind_Resume_or_Rethrow (_Unwind_Control_Block * ucbp,
|
||||
/* 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);
|
||||
return unwind_phase2_forced (ucbp, entry_vrs, 0);
|
||||
}
|
||||
|
||||
/* Clean up an exception object when unwinding is complete. */
|
||||
@ -947,3 +999,16 @@ __aeabi_unwind_cpp_pr2 (_Unwind_State state,
|
||||
{
|
||||
return __gnu_unwind_pr_common (state, ucbp, context, 2);
|
||||
}
|
||||
|
||||
/* These two should never be used. */
|
||||
_Unwind_Ptr
|
||||
_Unwind_GetDataRelBase (_Unwind_Context *context __attribute__ ((unused)))
|
||||
{
|
||||
abort ();
|
||||
}
|
||||
|
||||
_Unwind_Ptr
|
||||
_Unwind_GetTextRelBase (_Unwind_Context *context __attribute__ ((unused)))
|
||||
{
|
||||
abort ();
|
||||
}
|
||||
|
@ -37,10 +37,6 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/* We add a prototype for abort here to avoid creating a dependency on
|
||||
target headers. */
|
||||
extern void abort();
|
||||
|
||||
typedef unsigned _Unwind_Word __attribute__((__mode__(__word__)));
|
||||
typedef signed _Unwind_Sword __attribute__((__mode__(__word__)));
|
||||
typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__)));
|
||||
@ -195,18 +191,9 @@ extern "C" {
|
||||
void * _Unwind_GetLanguageSpecificData (_Unwind_Context *);
|
||||
_Unwind_Ptr _Unwind_GetRegionStart (_Unwind_Context *);
|
||||
|
||||
/* These two should never be used */
|
||||
static inline _Unwind_Ptr
|
||||
_Unwind_GetDataRelBase (_Unwind_Context * context __attribute__ ((unused)))
|
||||
{
|
||||
abort ();
|
||||
}
|
||||
|
||||
static inline _Unwind_Ptr
|
||||
_Unwind_GetTextRelBase (_Unwind_Context * context __attribute__ ((unused)))
|
||||
{
|
||||
abort ();
|
||||
}
|
||||
/* These two should never be used. */
|
||||
_Unwind_Ptr _Unwind_GetDataRelBase (_Unwind_Context *);
|
||||
_Unwind_Ptr _Unwind_GetTextRelBase (_Unwind_Context *);
|
||||
|
||||
/* Interface functions: */
|
||||
_Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Control_Block *ucbp);
|
||||
@ -218,6 +205,7 @@ extern "C" {
|
||||
_Unwind_Control_Block *, struct _Unwind_Context *, void *);
|
||||
_Unwind_Reason_Code _Unwind_ForcedUnwind (_Unwind_Control_Block *,
|
||||
_Unwind_Stop_Fn, void *);
|
||||
_Unwind_Word _Unwind_GetCFA (struct _Unwind_Context *);
|
||||
void _Unwind_Complete(_Unwind_Control_Block *ucbp);
|
||||
void _Unwind_DeleteException (_Unwind_Exception *);
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
2005-11-16 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* gcc.dg/cleanup-5.c, gcc.dg/cleanup-8.c, gcc.dg/cleanup-9.c,
|
||||
gcc.dg/cleanup-10.c, gcc.dg/cleanup-11.c: Update for ARM EABI.
|
||||
|
||||
2005-11-16 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* g++.dg/eh/forced1.C: Adjust to cope with ARM EABI
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
static _Unwind_Reason_Code
|
||||
force_unwind_stop (int version, _Unwind_Action actions,
|
||||
@ -23,7 +24,7 @@ force_unwind_stop (int version, _Unwind_Action actions,
|
||||
static void force_unwind ()
|
||||
{
|
||||
struct _Unwind_Exception *exc = malloc (sizeof (*exc));
|
||||
exc->exception_class = 0;
|
||||
memset (&exc->exception_class, 0, sizeof (exc->exception_class));
|
||||
exc->exception_cleanup = 0;
|
||||
|
||||
#ifndef __USING_SJLJ_EXCEPTIONS__
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
static _Unwind_Reason_Code
|
||||
force_unwind_stop (int version, _Unwind_Action actions,
|
||||
@ -23,7 +24,7 @@ force_unwind_stop (int version, _Unwind_Action actions,
|
||||
static void force_unwind ()
|
||||
{
|
||||
struct _Unwind_Exception *exc = malloc (sizeof (*exc));
|
||||
exc->exception_class = 0;
|
||||
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,
|
||||
@ -22,7 +23,7 @@ force_unwind_stop (int version, _Unwind_Action actions,
|
||||
static void force_unwind ()
|
||||
{
|
||||
struct _Unwind_Exception *exc = malloc (sizeof (*exc));
|
||||
exc->exception_class = 0;
|
||||
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 <signal.h>
|
||||
#include <string.h>
|
||||
|
||||
static _Unwind_Reason_Code
|
||||
force_unwind_stop (int version, _Unwind_Action actions,
|
||||
@ -22,7 +23,7 @@ force_unwind_stop (int version, _Unwind_Action actions,
|
||||
static void force_unwind ()
|
||||
{
|
||||
struct _Unwind_Exception *exc = malloc (sizeof (*exc));
|
||||
exc->exception_class = 0;
|
||||
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 <signal.h>
|
||||
#include <string.h>
|
||||
|
||||
static _Unwind_Reason_Code
|
||||
force_unwind_stop (int version, _Unwind_Action actions,
|
||||
@ -22,7 +23,7 @@ force_unwind_stop (int version, _Unwind_Action actions,
|
||||
static void force_unwind ()
|
||||
{
|
||||
struct _Unwind_Exception *exc = malloc (sizeof (*exc));
|
||||
exc->exception_class = 0;
|
||||
memset (&exc->exception_class, 0, sizeof (exc->exception_class));
|
||||
exc->exception_cleanup = 0;
|
||||
|
||||
#ifndef __USING_SJLJ_EXCEPTIONS__
|
||||
|
@ -129,7 +129,7 @@ PERSONALITY_FUNCTION (int version,
|
||||
_Unwind_Ptr landing_pad, ip;
|
||||
|
||||
#ifdef __ARM_EABI_UNWINDER__
|
||||
if (state != _US_UNWIND_FRAME_STARTING)
|
||||
if ((state & _US_ACTION_MASK) != _US_UNWIND_FRAME_STARTING)
|
||||
CONTINUE_UNWINDING;
|
||||
|
||||
/* The dwarf unwinder assumes the context structure holds things like the
|
||||
|
Loading…
Reference in New Issue
Block a user