aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/raise-gcc.c
diff options
context:
space:
mode:
authorArnaud Charlet <charlet@gcc.gnu.org>2012-07-16 14:51:41 +0200
committerArnaud Charlet <charlet@gcc.gnu.org>2012-07-16 14:51:41 +0200
commite187fa72fb4806da5b93af1d346446b9fc7f0993 (patch)
tree519b73a3579b0657a1ff1d6be8e64614831db7cd /gcc/ada/raise-gcc.c
parent59a6c9d56580c806c493a50c8902fd2177074399 (diff)
downloadgcc-e187fa72fb4806da5b93af1d346446b9fc7f0993.zip
gcc-e187fa72fb4806da5b93af1d346446b9fc7f0993.tar.gz
gcc-e187fa72fb4806da5b93af1d346446b9fc7f0993.tar.bz2
[multiple changes]
2012-07-16 Robert Dewar <dewar@adacore.com> * freeze.adb, g-debpoo.adb, exp_ch3.adb: Minor reformatting. 2012-07-16 Thomas Quinot <quinot@adacore.com> * s-oscons-tmplt.c: Add definitions of E2BIG and EILSEQ. 2012-07-16 Tristan Gingold <gingold@adacore.com> * a-exexpr.adb (Propagate_Continue): New function replacing Raise_Current_Excep. (Allocate_Occurrence): New function. (Propagate_Exception): Add Excep parameter, remove call to Call_Chain. * a-exexpr-gcc.adb (GNAT_GCC_Exception): Occurrence component is now aliased. (To_GCC_Exception): Convert from Address. (Allocate_Occurrence): Allocate an Unwind exception occurrence. (Setup_Current_Excep): Fill the machine occurrence in case of foreign exception. (Propagate_Exception): Add Excep parameter, remove call to Call_Chain. * a-except.adb (Set_Exception_C_Msg, Set_Exception_Msg): add Excep parameter. (Raise_Exception, Raise_Exception_Always, Raise_Exception_No_Defer): Adjust calls to the above procedures. (Raise_From_Signal_Handler, Raise_With_Location_And_Msg) (Rcheck_PE_Finalize_Raised_Exception): Likewise. * a-except-2005.adb (Set_Exception_C_Msg, Set_Exception_Msg): add Excep parameter. (Propagate_Exception): Likewise. (Allocate_Occurrence): New function. (Raise_Current_Excep): Removed. (Complete_Occurrence): New function to save the call chain. (Complete_And_Propagate_Occurrence): New procedure. (Create_Occurrence_From_Signal_Handler): New function to build an occurrence without propagating it. (Create_Machine_Occurrence_From_Signal_Handler): Likewise, but return the machine occurrence. (Raise_From_Signal_Handler): Use Create_Occurrence_From_Signal_Handler. (Raise_Exception, Raise_Exception_Always, Raise_Exception_No_Defer): Adjust calls to the above procedures. Allocate the occurrence at the beginning. (Raise_With_Location_And_Msg, Raise_With_Msg) (Rcheck_PE_Finalize_Raised_Exceptionm Reraise): Likewise. (Reraise_Occurrence): Use Reraise_Occurrence_Always. (Reraise_Occurrence_Always): Use Reraise_Occurrence_No_Defer. (Reraise_Occurrence_No_Defer): Preserve machine occurrence. (Save_Occurrence): Do not save machine occurrence. * a-except-2005.ads (Exception_Occurrence): Add Machine_Occurrence component. (Null_Occurrence): Consider it. * a-exexda.adb (Set_Exception_C_Msg, Set_Exception_Msg): add Excep parameter. 2012-07-16 Tristan Gingold <gingold@adacore.com> * seh_init.c (__gnat_map_SEH): New function extracted from __gnat_SEH_error_handler. * raise-gcc.c: __gnat_personality_seh0: Directly transforms Windows system exception into GCC one when possible, in order to save stack room (particularly useful when Storage_Error will be propagated). From-SVN: r189530
Diffstat (limited to 'gcc/ada/raise-gcc.c')
-rw-r--r--gcc/ada/raise-gcc.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/gcc/ada/raise-gcc.c b/gcc/ada/raise-gcc.c
index 2383aa8..8aef5b0 100644
--- a/gcc/ada/raise-gcc.c
+++ b/gcc/ada/raise-gcc.c
@@ -1213,9 +1213,23 @@ __gnat_Unwind_ForcedUnwind (_Unwind_Exception *e,
#ifdef __SEH__
#define STATUS_USER_DEFINED (1U << 29)
+
+/* From unwind-seh.c. */
+#define GCC_MAGIC (('G' << 16) | ('C' << 8) | 'C')
+#define GCC_EXCEPTION(TYPE) \
+ (STATUS_USER_DEFINED | ((TYPE) << 24) | GCC_MAGIC)
+#define STATUS_GCC_THROW GCC_EXCEPTION (0)
+
EXCEPTION_DISPOSITION __gnat_SEH_error_handler
(struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, void*);
+struct Exception_Data *
+__gnat_map_SEH (EXCEPTION_RECORD* ExceptionRecord, const char **msg);
+
+struct _Unwind_Exception *
+__gnat_create_machine_occurrence_from_signal_handler (Exception_Id,
+ const char *);
+
/* Unwind opcodes. */
#define UWOP_PUSH_NONVOL 0
#define UWOP_ALLOC_LARGE 1
@@ -1295,7 +1309,10 @@ __gnat_personality_seh0 (PEXCEPTION_RECORD ms_exc, void *this_frame,
exceptions. */
if (!(ms_exc->ExceptionCode & STATUS_USER_DEFINED))
{
+ struct Exception_Data *exception;
+ const char *msg;
ULONG64 excpip = (ULONG64) ms_exc->ExceptionAddress;
+
if (excpip != 0
&& excpip >= (ms_disp->ImageBase
+ ms_disp->FunctionEntry->BeginAddress)
@@ -1353,7 +1370,26 @@ __gnat_personality_seh0 (PEXCEPTION_RECORD ms_exc, void *this_frame,
__gnat_adjust_context
((unsigned char *)(mf_imagebase + mf_func->UnwindData), mf_rsp);
}
- __gnat_SEH_error_handler (ms_exc, this_frame, ms_orig_context, ms_disp);
+
+ exception = __gnat_map_SEH (ms_exc, &msg);
+ if (exception != NULL)
+ {
+ struct _Unwind_Exception *exc;
+
+ /* Directly convert the system exception to a GCC one.
+ This is really breaking the API, but is necessary for stack size
+ reasons: the normal way is to call Raise_From_Signal_Handler,
+ which build the exception and calls _Unwind_RaiseException, which
+ unwinds the stack and will call this personality routine. But
+ the Windows unwinder needs about 2KB of stack. */
+ exc = __gnat_create_machine_occurrence_from_signal_handler
+ (exception, msg);
+ memset (exc->private_, 0, sizeof (exc->private_));
+ ms_exc->ExceptionCode = STATUS_GCC_THROW;
+ ms_exc->NumberParameters = 1;
+ ms_exc->ExceptionInformation[0] = (ULONG_PTR)exc;
+ }
+
}
return _GCC_specific_handler (ms_exc, this_frame, ms_orig_context,