unwind-arm.c (abort): Add prototype here.
authorDaniel Jacobowitz <dan@codesourcery.com>
Wed, 16 Nov 2005 17:08:05 +0000 (17:08 +0000)
committerDaniel Jacobowitz <drow@gcc.gnu.org>
Wed, 16 Nov 2005 17:08:05 +0000 (17:08 +0000)
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

12 files changed:
gcc/ChangeLog
gcc/config/arm/arm.c
gcc/config/arm/pr-support.c
gcc/config/arm/unwind-arm.c
gcc/config/arm/unwind-arm.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/cleanup-10.c
gcc/testsuite/gcc.dg/cleanup-11.c
gcc/testsuite/gcc.dg/cleanup-5.c
gcc/testsuite/gcc.dg/cleanup-8.c
gcc/testsuite/gcc.dg/cleanup-9.c
gcc/unwind-c.c

index 34205f1..0b14036 100644 (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.
index c3a7562..b2fad56 100644 (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 ();
index 8ea1e60..072b4a9 100644 (file)
    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.  */
index 4d703db..b3f8a00 100644 (file)
    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 ();
+}
index f0c545f..dd8d2af 100644 (file)
 #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 *);
 
index 63f6361..22335ac 100644 (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
index 35936ea..e8ae3bc 100644 (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__
index 447b398..ff315f7 100644 (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__
index 497ab0b..c335c1e 100644 (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__
index 25bc305..321e1f0 100644 (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__
index 4cf4a41..c3ac5fb 100644 (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__
index 6fb66e0..e3e2eca 100644 (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