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