]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
unwind-arm.h: Reorder interface function declarations.
authorNathan Sidwell <nathan@codesourcery.com>
Wed, 16 Nov 2005 17:04:41 +0000 (17:04 +0000)
committerDaniel Jacobowitz <drow@gcc.gnu.org>
Wed, 16 Nov 2005 17:04:41 +0000 (17:04 +0000)
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

13 files changed:
gcc/ChangeLog
gcc/config/arm/libunwind.S
gcc/config/arm/unwind-arm.c
gcc/config/arm/unwind-arm.h
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/eh/forced1.C
gcc/testsuite/g++.dg/eh/forced2.C
gcc/testsuite/g++.dg/eh/forced3.C
gcc/testsuite/g++.dg/eh/forced4.C
libstdc++-v3/ChangeLog
libstdc++-v3/libsupc++/eh_arm.cc
libstdc++-v3/libsupc++/eh_personality.cc
libstdc++-v3/libsupc++/eh_throw.cc

index c7f4f79140e331c8ad9f3813baeb54774032ff50..34205f18fbb22ae064603d9199566cd8f348cce0 100644 (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
index 8d226df3fd2feb715f1c386b99c3ba940f7c6877..06e13107d2ab5a474ea696af626c260ebede31e8 100644 (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__ */
index e436f7c2659c377dcef5af07ee67047ac63f6196..4d703dbf09afe4fe4abc549694655c17a0f6ee59 100644 (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;
index 4d86407c73e3f95f4f1dd65c42588d9eaab44105..f0c545ff797948f7bab3ab83f66318e83c175fd3 100644 (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
index 8b43fc896855a7de0f1163be8725c40fbb412311..63f6361687b64dbd07af517164a33058bcb30d4b 100644 (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.
index 0068dae5b99fcb29ec3319d81b345228e91798ec..b0200813ece8a63ad69be552a489f114a98726a7 100644 (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;
index 3c6719da0f9306f6e32e2a53e35d0009e543e451..54586a006172d278f6cc39973ba63c75f9ea200d 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,
@@ -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__
index 34d27641eeb7c8748856582559861baed7e57fd4..96319d44ecd2955d65910ee269ea8e105d5ea9ef 100644 (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__
index df691caa16119d8f9e62241bd3b1e06d13163410..17fd94a40641884fed83982425868d17b56e4a9f 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,
@@ -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__
index 0fa503903529b0fa7b0346fd6040bccc702d2549..f84cefddd917c5a0582836dddeb35c853805bdc5 100644 (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
index d87d82ad5a09ed7921090447184037f7d3903cbd..269b2ec95af725a01ccf2ee934e69a1d5dcdd378 100644 (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;
 }
 
index 6205851a2c4e06e64b52ed196422875cfd82a512..f07864f1d6fa3994d436bf7b79aa76030a0a610a 100644 (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);
index 8b04f395c873fef023a844f75acf3d8b9340cd7f..9f26be008abfe642c761b8f03bf6f0b5662aeb40 100644 (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);