[Ada] Rewrite CleanupUnwind_Handler to strictly follow ia64 ABI
Arnaud Charlet
charlet@adacore.com
Mon Jul 9 13:05:00 GMT 2012
Required when the unwinder is not the libgcc one (eg: on HP-UX).
No functionnal change.
Tested on x86_64-pc-linux-gnu, committed on trunk
2012-07-09 Tristan Gingold <gingold@adacore.com>
* a-exexpr-gcc.adb (CleanupUnwind_Handler): Now imported from
raise-gcc.c
* raise-gcc.c (__gnat_cleanupunwind_handler): Defined.
Strictly follow the ABI convention on ia64.
-------------- next part --------------
Index: a-exexpr-gcc.adb
===================================================================
--- a-exexpr-gcc.adb (revision 189368)
+++ a-exexpr-gcc.adb (working copy)
@@ -44,9 +44,7 @@
------------------------------------------------
-- These come from "C++ ABI for Itanium: Exception handling", which is
- -- the reference for GCC. They are used only when we are relying on
- -- back-end tables for exception propagation, which in turn is currently
- -- only the case for Zero_Cost_Exceptions in GNAT5.
+ -- the reference for GCC.
-- Return codes from the GCC runtime functions used to propagate
-- an exception.
@@ -63,7 +61,8 @@
URC_CONTINUE_UNWIND);
pragma Unreferenced
- (URC_FOREIGN_EXCEPTION_CAUGHT,
+ (URC_NO_REASON,
+ URC_FOREIGN_EXCEPTION_CAUGHT,
URC_PHASE2_ERROR,
URC_PHASE1_ERROR,
URC_NORMAL_STOP,
@@ -83,13 +82,14 @@
UA_CLEANUP_PHASE : constant Unwind_Action := 2;
UA_HANDLER_FRAME : constant Unwind_Action := 4;
UA_FORCE_UNWIND : constant Unwind_Action := 8;
- UA_END_OF_STACK : constant Unwind_Action := 16; -- GCC extension ?
+ UA_END_OF_STACK : constant Unwind_Action := 16; -- GCC extension
pragma Unreferenced
(UA_SEARCH_PHASE,
UA_CLEANUP_PHASE,
UA_HANDLER_FRAME,
- UA_FORCE_UNWIND);
+ UA_FORCE_UNWIND,
+ UA_END_OF_STACK);
-- Mandatory common header for any exception object handled by the
-- GCC unwinding runtime.
@@ -221,6 +221,8 @@
UW_Exception : not null GCC_Exception_Access;
UW_Context : System.Address;
UW_Argument : System.Address) return Unwind_Reason_Code;
+ pragma Import (C, CleanupUnwind_Handler,
+ "__gnat_cleanupunwind_handler");
-- Hook called at each step of the forced unwinding we perform to
-- trigger cleanups found during the propagation of an unhandled
-- exception.
@@ -316,34 +318,6 @@
Free (Copy);
end GNAT_GCC_Exception_Cleanup;
- ---------------------------
- -- CleanupUnwind_Handler --
- ---------------------------
-
- function CleanupUnwind_Handler
- (UW_Version : Integer;
- UW_Phases : Unwind_Action;
- UW_Eclass : Exception_Class;
- UW_Exception : not null GCC_Exception_Access;
- UW_Context : System.Address;
- UW_Argument : System.Address) return Unwind_Reason_Code
- is
- pragma Unreferenced (UW_Version, UW_Eclass, UW_Context, UW_Argument);
-
- begin
- -- Terminate when the end of the stack is reached
-
- if UW_Phases >= UA_END_OF_STACK then
- Unhandled_Except_Handler (UW_Exception);
- end if;
-
- -- We know there is at least one cleanup further up. Return so that it
- -- is searched and entered, after which Unwind_Resume will be called
- -- and this hook will gain control again.
-
- return URC_NO_REASON;
- end CleanupUnwind_Handler;
-
-------------------------
-- Setup_Current_Excep --
-------------------------
Index: raise-gcc.c
===================================================================
--- raise-gcc.c (revision 189369)
+++ raise-gcc.c (working copy)
@@ -58,6 +58,7 @@
#if defined (__hpux__) && defined (USE_LIBUNWIND_EXCEPTIONS)
/* HP-UX B.11.31 ia64 libunwind doesn't have _Unwind_GetIPInfo. */
#undef HAVE_GETIPINFO
+#define _UA_END_OF_STACK 0
#endif
/* The names of a couple of "standard" routines for unwinding/propagation
@@ -77,6 +78,7 @@
__gnat_Unwind_ForcedUnwind (_Unwind_Exception *, void *, void *);
extern void __gnat_setup_current_excep (_Unwind_Exception *);
+extern void __gnat_unhandled_except_handler (_Unwind_Exception *);
#include "dwarf2.h"
#include "unwind-dw2-fde.h"
@@ -1139,6 +1141,30 @@
return _URC_INSTALL_CONTEXT;
}
+_Unwind_Reason_Code
+__gnat_cleanupunwind_handler (int version,
+ _Unwind_Action phases,
+ _Unwind_Exception_Class eclass,
+ struct _Unwind_Exception *exception,
+ struct _Unwind_Context *context,
+ void *arg)
+{
+ /* Terminate when the end of the stack is reached. */
+ if ((phases & _UA_END_OF_STACK) != 0
+#ifdef __ia64__
+ /* Strictely follow the ia64 ABI: when end of stack is reached,
+ the callback will be called with a NULL stack pointer. */
+ || _Unwind_GetREG (context, 12) == 0
+#endif
+ )
+ __gnat_unhandled_except_handler (exception);
+
+ /* We know there is at least one cleanup further up. Return so that it
+ is searched and entered, after which Unwind_Resume will be called
+ and this hook will gain control again. */
+ return _URC_NO_REASON;
+}
+
/* Define the consistently named wrappers imported by Propagate_Exception. */
#ifdef __USING_SJLJ_EXCEPTIONS__
More information about the Gcc-patches
mailing list