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:
Daniel Jacobowitz 2005-11-16 17:08:05 +00:00 committed by Daniel Jacobowitz
parent 1dcca6f361
commit 74d9c39f6a
12 changed files with 154 additions and 53 deletions

View File

@ -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.

View File

@ -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 ();

View File

@ -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. */

View File

@ -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]);
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_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_OK)
{
UCB_SAVED_CALLSITE_ADDR (ucbp) = saved_vrs.core.r[R_PC];
if (entry_code == _URC_END_OF_STACK)
return entry_code;
UCB_SAVED_CALLSITE_ADDR (ucbp) = entry_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 *) entry_vrs);
(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 *)&saved_vrs, stop_arg);
if (stop_code != _URC_NO_REASON)
return _URC_FAILURE;
if (entry_code != _URC_OK)
return entry_code;
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,9 +696,6 @@ __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);
default:
@ -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 ();
}

View File

@ -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 *);

View File

@ -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

View File

@ -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__

View File

@ -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__

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,
@ -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__

View File

@ -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__

View File

@ -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__

View File

@ -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