coreboot/fam15h: remove redundant patch
i previously added this just for kicks, but it's not actually needed; gnat isn't used on fam15h boards so lbmk doesn't even use it (it's disabled). in fact, i tested lbmk with crossgcc_ada handling taken out, but with said patch; i still got build errors with gnat anyway, on that old coreboot revision (but gnat isn't needed there anymore). Signed-off-by: Leah Rowe <leah@libreboot.org>btrfsvols
parent
1a299f1b0b
commit
34b8687e94
|
@ -1,232 +0,0 @@
|
||||||
From c5a03de594d6bb6ea5012a6549404e4631c903c8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Alexandre Oliva <oliva@adacore.com>
|
|
||||||
Date: Wed, 9 Aug 2023 16:57:31 +0200
|
|
||||||
Subject: [PATCH] crossgcc: Backport GNAT exception handler v1 patch
|
|
||||||
|
|
||||||
Signed-off-by: Adrien Bourmault <neox@gnu.org>
|
|
||||||
---
|
|
||||||
.../patches/gcc-8.3.0_gnat_eh_new.patch | 212 ++++++++++++++++++
|
|
||||||
1 file changed, 212 insertions(+)
|
|
||||||
create mode 100644 util/crossgcc/patches/gcc-8.3.0_gnat_eh_new.patch
|
|
||||||
|
|
||||||
diff --git a/util/crossgcc/patches/gcc-8.3.0_gnat_eh_new.patch b/util/crossgcc/patches/gcc-8.3.0_gnat_eh_new.patch
|
|
||||||
new file mode 100644
|
|
||||||
index 00000000..75e4f18d
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/util/crossgcc/patches/gcc-8.3.0_gnat_eh_new.patch
|
|
||||||
@@ -0,0 +1,212 @@
|
|
||||||
+diff --git a/gcc/ada/libgnat/a-exexpr.adb b/gcc/ada/libgnat/a-exexpr.adb
|
|
||||||
+index b1aa1c6e6ba..5e72fd6e3f2 100644
|
|
||||||
+--- a/gcc/ada/libgnat/a-exexpr.adb
|
|
||||||
++++ b/gcc/ada/libgnat/a-exexpr.adb
|
|
||||||
+@@ -197,15 +197,75 @@ package body Exception_Propagation is
|
|
||||||
+ -- whose machine occurrence is Mo. The message is empty, the backtrace
|
|
||||||
+ -- is empty too and the exception identity is Foreign_Exception.
|
|
||||||
+
|
|
||||||
+- -- Hooks called when entering/leaving an exception handler for a given
|
|
||||||
+- -- occurrence, aimed at handling the stack of active occurrences. The
|
|
||||||
+- -- calls are generated by gigi in tree_transform/N_Exception_Handler.
|
|
||||||
++ -- Hooks called when entering/leaving an exception handler for a
|
|
||||||
++ -- given occurrence. The calls are generated by gigi in
|
|
||||||
++ -- Exception_Handler_to_gnu_gcc.
|
|
||||||
++
|
|
||||||
++ -- Begin_Handler_v1, called when entering an exception handler,
|
|
||||||
++ -- claims responsibility for the handler to release the
|
|
||||||
++ -- GCC_Exception occurrence. End_Handler_v1, called when
|
|
||||||
++ -- leaving the handler, releases the occurrence, unless the
|
|
||||||
++ -- occurrence is propagating further up, or the handler is
|
|
||||||
++ -- dynamically nested in the context of another handler that
|
|
||||||
++ -- claimed responsibility for releasing that occurrence.
|
|
||||||
++
|
|
||||||
++ -- Responsibility is claimed by changing the Cleanup field to
|
|
||||||
++ -- Claimed_Cleanup, which enables claimed exceptions to be
|
|
||||||
++ -- recognized, and avoids accidental releases even by foreign
|
|
||||||
++ -- handlers.
|
|
||||||
++
|
|
||||||
++ function Begin_Handler_v1
|
|
||||||
++ (GCC_Exception : not null GCC_Exception_Access)
|
|
||||||
++ return System.Address;
|
|
||||||
++ pragma Export (C, Begin_Handler_v1, "__gnat_begin_handler_v1");
|
|
||||||
++ -- Called when entering an exception handler. Claim
|
|
||||||
++ -- responsibility for releasing GCC_Exception, by setting the
|
|
||||||
++ -- cleanup/release function to Claimed_Cleanup, and return the
|
|
||||||
++ -- address of the previous cleanup/release function.
|
|
||||||
++
|
|
||||||
++ procedure End_Handler_v1
|
|
||||||
++ (GCC_Exception : not null GCC_Exception_Access;
|
|
||||||
++ Saved_Cleanup : System.Address;
|
|
||||||
++ Propagating_Exception : GCC_Exception_Access);
|
|
||||||
++ pragma Export (C, End_Handler_v1, "__gnat_end_handler_v1");
|
|
||||||
++ -- Called when leaving an exception handler. Restore the
|
|
||||||
++ -- Saved_Cleanup in the GCC_Exception occurrence, and then release
|
|
||||||
++ -- it, unless it remains claimed by an enclosing handler, or
|
|
||||||
++ -- GCC_Exception and Propagating_Exception are the same
|
|
||||||
++ -- occurrence. Propagating_Exception could be either an
|
|
||||||
++ -- occurrence (re)raised within the handler of GCC_Exception, when
|
|
||||||
++ -- we're executing as an exceptional cleanup, or null, if we're
|
|
||||||
++ -- completing the handler of GCC_Exception normally.
|
|
||||||
++
|
|
||||||
++ procedure Claimed_Cleanup
|
|
||||||
++ (Reason : Unwind_Reason_Code;
|
|
||||||
++ GCC_Exception : not null GCC_Exception_Access);
|
|
||||||
++ pragma Export (C, Claimed_Cleanup, "__gnat_claimed_cleanup");
|
|
||||||
++ -- A do-nothing placeholder installed as GCC_Exception.Cleanup
|
|
||||||
++ -- while handling GCC_Exception, to claim responsibility for
|
|
||||||
++ -- releasing it, and to stop it from being accidentally released.
|
|
||||||
++
|
|
||||||
++ -- The following are version 0 implementations of the version 1
|
|
||||||
++ -- hooks above. They remain in place for compatibility with the
|
|
||||||
++ -- output of compilers that still use version 0, such as those
|
|
||||||
++ -- used during bootstrap. They are interoperable with the v1
|
|
||||||
++ -- hooks, except that the older versions may malfunction when
|
|
||||||
++ -- handling foreign exceptions passed to Reraise_Occurrence.
|
|
||||||
+
|
|
||||||
+ procedure Begin_Handler (GCC_Exception : not null GCC_Exception_Access);
|
|
||||||
+ pragma Export (C, Begin_Handler, "__gnat_begin_handler");
|
|
||||||
++ -- Called when entering an exception handler translated by an old
|
|
||||||
++ -- compiler. It does nothing.
|
|
||||||
+
|
|
||||||
+ procedure End_Handler (GCC_Exception : GCC_Exception_Access);
|
|
||||||
+ pragma Export (C, End_Handler, "__gnat_end_handler");
|
|
||||||
++ -- Called when leaving an exception handler translated by an old
|
|
||||||
++ -- compiler. It releases GCC_Exception, unless it is null. It is
|
|
||||||
++ -- only ever null when the handler has a 'raise;' translated by a
|
|
||||||
++ -- v0-using compiler. The artificial handler variable passed to
|
|
||||||
++ -- End_Handler was set to null to tell End_Handler to refrain from
|
|
||||||
++ -- releasing the reraised exception. In v1 safer ways are used to
|
|
||||||
++ -- accomplish that.
|
|
||||||
+
|
|
||||||
+ --------------------------------------------------------------------
|
|
||||||
+ -- Accessors to Basic Components of a GNAT Exception Data Pointer --
|
|
||||||
+@@ -352,6 +412,128 @@ package body Exception_Propagation is
|
|
||||||
+ end if;
|
|
||||||
+ end Setup_Current_Excep;
|
|
||||||
+
|
|
||||||
++ ----------------------
|
|
||||||
++ -- Begin_Handler_v1 --
|
|
||||||
++ ----------------------
|
|
||||||
++
|
|
||||||
++ function Begin_Handler_v1
|
|
||||||
++ (GCC_Exception : not null GCC_Exception_Access)
|
|
||||||
++ return System.Address is
|
|
||||||
++ Saved_Cleanup : constant System.Address := GCC_Exception.Cleanup;
|
|
||||||
++ begin
|
|
||||||
++ -- Claim responsibility for releasing this exception, and stop
|
|
||||||
++ -- others from releasing it.
|
|
||||||
++ GCC_Exception.Cleanup := Claimed_Cleanup'Address;
|
|
||||||
++ return Saved_Cleanup;
|
|
||||||
++ end Begin_Handler_v1;
|
|
||||||
++
|
|
||||||
++ --------------------
|
|
||||||
++ -- End_Handler_v1 --
|
|
||||||
++ --------------------
|
|
||||||
++
|
|
||||||
++ procedure End_Handler_v1
|
|
||||||
++ (GCC_Exception : not null GCC_Exception_Access;
|
|
||||||
++ Saved_Cleanup : System.Address;
|
|
||||||
++ Propagating_Exception : GCC_Exception_Access) is
|
|
||||||
++ begin
|
|
||||||
++ GCC_Exception.Cleanup := Saved_Cleanup;
|
|
||||||
++ -- Restore the Saved_Cleanup, so that it is either used to
|
|
||||||
++ -- release GCC_Exception below, or transferred to the next
|
|
||||||
++ -- handler of the Propagating_Exception occurrence. The
|
|
||||||
++ -- following test ensures that an occurrence is only released
|
|
||||||
++ -- once, even after reraises.
|
|
||||||
++ --
|
|
||||||
++ -- The idea is that the GCC_Exception is not to be released
|
|
||||||
++ -- unless it had an unclaimed Cleanup when the handler started
|
|
||||||
++ -- (see Begin_Handler_v1 above), but if we propagate across its
|
|
||||||
++ -- handler a reraise of the same exception, we transfer to the
|
|
||||||
++ -- Propagating_Exception the responsibility for running the
|
|
||||||
++ -- Saved_Cleanup when its handler completes.
|
|
||||||
++ --
|
|
||||||
++ -- This ownership transfer mechanism ensures safety, as in
|
|
||||||
++ -- single release and no dangling pointers, because there is no
|
|
||||||
++ -- way to hold on to the Machine_Occurrence of an
|
|
||||||
++ -- Exception_Occurrence: the only situations in which another
|
|
||||||
++ -- Exception_Occurrence gets the same Machine_Occurrence are
|
|
||||||
++ -- through Reraise_Occurrence, and plain reraise, and so we
|
|
||||||
++ -- have the following possibilities:
|
|
||||||
++ --
|
|
||||||
++ -- - Reraise_Occurrence is handled within the running handler,
|
|
||||||
++ -- and so when completing the dynamically nested handler, we
|
|
||||||
++ -- must NOT release the exception. A Claimed_Cleanup upon
|
|
||||||
++ -- entry of the nested handler, installed when entering the
|
|
||||||
++ -- enclosing handler, ensures the exception will not be
|
|
||||||
++ -- released by the nested handler, but rather by the enclosing
|
|
||||||
++ -- handler.
|
|
||||||
++ --
|
|
||||||
++ -- - Reraise_Occurrence/reraise escapes the running handler,
|
|
||||||
++ -- and we run as an exceptional cleanup for GCC_Exception. The
|
|
||||||
++ -- Saved_Cleanup was reinstalled, but since we're propagating
|
|
||||||
++ -- the same machine occurrence, we do not release it. Instead,
|
|
||||||
++ -- we transfer responsibility for releasing it to the eventual
|
|
||||||
++ -- handler of the propagating exception.
|
|
||||||
++ --
|
|
||||||
++ -- - An unrelated exception propagates through the running
|
|
||||||
++ -- handler. We restored GCC_Exception.Saved_Cleanup above.
|
|
||||||
++ -- Since we're propagating a different exception, we proceed to
|
|
||||||
++ -- release GCC_Exception, unless Saved_Cleanup was
|
|
||||||
++ -- Claimed_Cleanup, because then we know we're not in the
|
|
||||||
++ -- outermost handler for GCC_Exception.
|
|
||||||
++ --
|
|
||||||
++ -- - The handler completes normally, so it reinstalls the
|
|
||||||
++ -- Saved_Cleanup and runs it, unless it was Claimed_Cleanup.
|
|
||||||
++ -- If Saved_Cleanup is null, Unwind_DeleteException (currently)
|
|
||||||
++ -- has no effect, so we could skip it, but if it is ever
|
|
||||||
++ -- changed to do more in this case, we're ready for that,
|
|
||||||
++ -- calling it exactly once.
|
|
||||||
++ if Saved_Cleanup /= Claimed_Cleanup'Address
|
|
||||||
++ and then
|
|
||||||
++ Propagating_Exception /= GCC_Exception
|
|
||||||
++ then
|
|
||||||
++ declare
|
|
||||||
++ Current : constant EOA := Get_Current_Excep.all;
|
|
||||||
++ Cur_Occ : constant GCC_Exception_Access
|
|
||||||
++ := To_GCC_Exception (Current.Machine_Occurrence);
|
|
||||||
++ begin
|
|
||||||
++ -- If we are releasing the Machine_Occurrence of the current
|
|
||||||
++ -- exception, reset the access to it, so that it is no
|
|
||||||
++ -- longer accessible.
|
|
||||||
++ if Cur_Occ = GCC_Exception then
|
|
||||||
++ Current.Machine_Occurrence := System.Null_Address;
|
|
||||||
++ end if;
|
|
||||||
++ end;
|
|
||||||
++ Unwind_DeleteException (GCC_Exception);
|
|
||||||
++ end if;
|
|
||||||
++ end End_Handler_v1;
|
|
||||||
++
|
|
||||||
++ ---------------------
|
|
||||||
++ -- Claimed_Cleanup --
|
|
||||||
++ ---------------------
|
|
||||||
++
|
|
||||||
++ procedure Claimed_Cleanup
|
|
||||||
++ (Reason : Unwind_Reason_Code;
|
|
||||||
++ GCC_Exception : not null GCC_Exception_Access) is
|
|
||||||
++ pragma Unreferenced (Reason);
|
|
||||||
++ pragma Unreferenced (GCC_Exception);
|
|
||||||
++ begin
|
|
||||||
++ -- This procedure should never run. If it does, it's either a
|
|
||||||
++ -- version 0 handler or a foreign handler, attempting to
|
|
||||||
++ -- release an exception while a version 1 handler that claimed
|
|
||||||
++ -- responsibility for releasing the exception remains still
|
|
||||||
++ -- active. This placeholder stops GCC_Exception from being
|
|
||||||
++ -- released by them.
|
|
||||||
++
|
|
||||||
++ -- We could get away with just Null_Address instead, with
|
|
||||||
++ -- nearly the same effect, but with this placeholder we can
|
|
||||||
++ -- detect and report unexpected releases, and we can tell apart
|
|
||||||
++ -- a GCC_Exception without a Cleanup, from one with another
|
|
||||||
++ -- active handler, so as to still call Unwind_DeleteException
|
|
||||||
++ -- exactly once: currently, Unwind_DeleteException does nothing
|
|
||||||
++ -- when the Cleanup is null, but should it ever be changed to
|
|
||||||
++ -- do more, we'll still be safe.
|
|
||||||
++ null;
|
|
||||||
++ end Claimed_Cleanup;
|
|
||||||
++
|
|
||||||
+ -------------------
|
|
||||||
+ -- Begin_Handler --
|
|
||||||
+ -------------------
|
|
||||||
--
|
|
||||||
2.30.2
|
|
||||||
|
|
|
@ -1,232 +0,0 @@
|
||||||
From c5a03de594d6bb6ea5012a6549404e4631c903c8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Alexandre Oliva <oliva@adacore.com>
|
|
||||||
Date: Wed, 9 Aug 2023 16:57:31 +0200
|
|
||||||
Subject: [PATCH] crossgcc: Backport GNAT exception handler v1 patch
|
|
||||||
|
|
||||||
Signed-off-by: Adrien Bourmault <neox@gnu.org>
|
|
||||||
---
|
|
||||||
.../patches/gcc-8.3.0_gnat_eh_new.patch | 212 ++++++++++++++++++
|
|
||||||
1 file changed, 212 insertions(+)
|
|
||||||
create mode 100644 util/crossgcc/patches/gcc-8.3.0_gnat_eh_new.patch
|
|
||||||
|
|
||||||
diff --git a/util/crossgcc/patches/gcc-8.3.0_gnat_eh_new.patch b/util/crossgcc/patches/gcc-8.3.0_gnat_eh_new.patch
|
|
||||||
new file mode 100644
|
|
||||||
index 00000000..75e4f18d
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/util/crossgcc/patches/gcc-8.3.0_gnat_eh_new.patch
|
|
||||||
@@ -0,0 +1,212 @@
|
|
||||||
+diff --git a/gcc/ada/libgnat/a-exexpr.adb b/gcc/ada/libgnat/a-exexpr.adb
|
|
||||||
+index b1aa1c6e6ba..5e72fd6e3f2 100644
|
|
||||||
+--- a/gcc/ada/libgnat/a-exexpr.adb
|
|
||||||
++++ b/gcc/ada/libgnat/a-exexpr.adb
|
|
||||||
+@@ -197,15 +197,75 @@ package body Exception_Propagation is
|
|
||||||
+ -- whose machine occurrence is Mo. The message is empty, the backtrace
|
|
||||||
+ -- is empty too and the exception identity is Foreign_Exception.
|
|
||||||
+
|
|
||||||
+- -- Hooks called when entering/leaving an exception handler for a given
|
|
||||||
+- -- occurrence, aimed at handling the stack of active occurrences. The
|
|
||||||
+- -- calls are generated by gigi in tree_transform/N_Exception_Handler.
|
|
||||||
++ -- Hooks called when entering/leaving an exception handler for a
|
|
||||||
++ -- given occurrence. The calls are generated by gigi in
|
|
||||||
++ -- Exception_Handler_to_gnu_gcc.
|
|
||||||
++
|
|
||||||
++ -- Begin_Handler_v1, called when entering an exception handler,
|
|
||||||
++ -- claims responsibility for the handler to release the
|
|
||||||
++ -- GCC_Exception occurrence. End_Handler_v1, called when
|
|
||||||
++ -- leaving the handler, releases the occurrence, unless the
|
|
||||||
++ -- occurrence is propagating further up, or the handler is
|
|
||||||
++ -- dynamically nested in the context of another handler that
|
|
||||||
++ -- claimed responsibility for releasing that occurrence.
|
|
||||||
++
|
|
||||||
++ -- Responsibility is claimed by changing the Cleanup field to
|
|
||||||
++ -- Claimed_Cleanup, which enables claimed exceptions to be
|
|
||||||
++ -- recognized, and avoids accidental releases even by foreign
|
|
||||||
++ -- handlers.
|
|
||||||
++
|
|
||||||
++ function Begin_Handler_v1
|
|
||||||
++ (GCC_Exception : not null GCC_Exception_Access)
|
|
||||||
++ return System.Address;
|
|
||||||
++ pragma Export (C, Begin_Handler_v1, "__gnat_begin_handler_v1");
|
|
||||||
++ -- Called when entering an exception handler. Claim
|
|
||||||
++ -- responsibility for releasing GCC_Exception, by setting the
|
|
||||||
++ -- cleanup/release function to Claimed_Cleanup, and return the
|
|
||||||
++ -- address of the previous cleanup/release function.
|
|
||||||
++
|
|
||||||
++ procedure End_Handler_v1
|
|
||||||
++ (GCC_Exception : not null GCC_Exception_Access;
|
|
||||||
++ Saved_Cleanup : System.Address;
|
|
||||||
++ Propagating_Exception : GCC_Exception_Access);
|
|
||||||
++ pragma Export (C, End_Handler_v1, "__gnat_end_handler_v1");
|
|
||||||
++ -- Called when leaving an exception handler. Restore the
|
|
||||||
++ -- Saved_Cleanup in the GCC_Exception occurrence, and then release
|
|
||||||
++ -- it, unless it remains claimed by an enclosing handler, or
|
|
||||||
++ -- GCC_Exception and Propagating_Exception are the same
|
|
||||||
++ -- occurrence. Propagating_Exception could be either an
|
|
||||||
++ -- occurrence (re)raised within the handler of GCC_Exception, when
|
|
||||||
++ -- we're executing as an exceptional cleanup, or null, if we're
|
|
||||||
++ -- completing the handler of GCC_Exception normally.
|
|
||||||
++
|
|
||||||
++ procedure Claimed_Cleanup
|
|
||||||
++ (Reason : Unwind_Reason_Code;
|
|
||||||
++ GCC_Exception : not null GCC_Exception_Access);
|
|
||||||
++ pragma Export (C, Claimed_Cleanup, "__gnat_claimed_cleanup");
|
|
||||||
++ -- A do-nothing placeholder installed as GCC_Exception.Cleanup
|
|
||||||
++ -- while handling GCC_Exception, to claim responsibility for
|
|
||||||
++ -- releasing it, and to stop it from being accidentally released.
|
|
||||||
++
|
|
||||||
++ -- The following are version 0 implementations of the version 1
|
|
||||||
++ -- hooks above. They remain in place for compatibility with the
|
|
||||||
++ -- output of compilers that still use version 0, such as those
|
|
||||||
++ -- used during bootstrap. They are interoperable with the v1
|
|
||||||
++ -- hooks, except that the older versions may malfunction when
|
|
||||||
++ -- handling foreign exceptions passed to Reraise_Occurrence.
|
|
||||||
+
|
|
||||||
+ procedure Begin_Handler (GCC_Exception : not null GCC_Exception_Access);
|
|
||||||
+ pragma Export (C, Begin_Handler, "__gnat_begin_handler");
|
|
||||||
++ -- Called when entering an exception handler translated by an old
|
|
||||||
++ -- compiler. It does nothing.
|
|
||||||
+
|
|
||||||
+ procedure End_Handler (GCC_Exception : GCC_Exception_Access);
|
|
||||||
+ pragma Export (C, End_Handler, "__gnat_end_handler");
|
|
||||||
++ -- Called when leaving an exception handler translated by an old
|
|
||||||
++ -- compiler. It releases GCC_Exception, unless it is null. It is
|
|
||||||
++ -- only ever null when the handler has a 'raise;' translated by a
|
|
||||||
++ -- v0-using compiler. The artificial handler variable passed to
|
|
||||||
++ -- End_Handler was set to null to tell End_Handler to refrain from
|
|
||||||
++ -- releasing the reraised exception. In v1 safer ways are used to
|
|
||||||
++ -- accomplish that.
|
|
||||||
+
|
|
||||||
+ --------------------------------------------------------------------
|
|
||||||
+ -- Accessors to Basic Components of a GNAT Exception Data Pointer --
|
|
||||||
+@@ -352,6 +412,128 @@ package body Exception_Propagation is
|
|
||||||
+ end if;
|
|
||||||
+ end Setup_Current_Excep;
|
|
||||||
+
|
|
||||||
++ ----------------------
|
|
||||||
++ -- Begin_Handler_v1 --
|
|
||||||
++ ----------------------
|
|
||||||
++
|
|
||||||
++ function Begin_Handler_v1
|
|
||||||
++ (GCC_Exception : not null GCC_Exception_Access)
|
|
||||||
++ return System.Address is
|
|
||||||
++ Saved_Cleanup : constant System.Address := GCC_Exception.Cleanup;
|
|
||||||
++ begin
|
|
||||||
++ -- Claim responsibility for releasing this exception, and stop
|
|
||||||
++ -- others from releasing it.
|
|
||||||
++ GCC_Exception.Cleanup := Claimed_Cleanup'Address;
|
|
||||||
++ return Saved_Cleanup;
|
|
||||||
++ end Begin_Handler_v1;
|
|
||||||
++
|
|
||||||
++ --------------------
|
|
||||||
++ -- End_Handler_v1 --
|
|
||||||
++ --------------------
|
|
||||||
++
|
|
||||||
++ procedure End_Handler_v1
|
|
||||||
++ (GCC_Exception : not null GCC_Exception_Access;
|
|
||||||
++ Saved_Cleanup : System.Address;
|
|
||||||
++ Propagating_Exception : GCC_Exception_Access) is
|
|
||||||
++ begin
|
|
||||||
++ GCC_Exception.Cleanup := Saved_Cleanup;
|
|
||||||
++ -- Restore the Saved_Cleanup, so that it is either used to
|
|
||||||
++ -- release GCC_Exception below, or transferred to the next
|
|
||||||
++ -- handler of the Propagating_Exception occurrence. The
|
|
||||||
++ -- following test ensures that an occurrence is only released
|
|
||||||
++ -- once, even after reraises.
|
|
||||||
++ --
|
|
||||||
++ -- The idea is that the GCC_Exception is not to be released
|
|
||||||
++ -- unless it had an unclaimed Cleanup when the handler started
|
|
||||||
++ -- (see Begin_Handler_v1 above), but if we propagate across its
|
|
||||||
++ -- handler a reraise of the same exception, we transfer to the
|
|
||||||
++ -- Propagating_Exception the responsibility for running the
|
|
||||||
++ -- Saved_Cleanup when its handler completes.
|
|
||||||
++ --
|
|
||||||
++ -- This ownership transfer mechanism ensures safety, as in
|
|
||||||
++ -- single release and no dangling pointers, because there is no
|
|
||||||
++ -- way to hold on to the Machine_Occurrence of an
|
|
||||||
++ -- Exception_Occurrence: the only situations in which another
|
|
||||||
++ -- Exception_Occurrence gets the same Machine_Occurrence are
|
|
||||||
++ -- through Reraise_Occurrence, and plain reraise, and so we
|
|
||||||
++ -- have the following possibilities:
|
|
||||||
++ --
|
|
||||||
++ -- - Reraise_Occurrence is handled within the running handler,
|
|
||||||
++ -- and so when completing the dynamically nested handler, we
|
|
||||||
++ -- must NOT release the exception. A Claimed_Cleanup upon
|
|
||||||
++ -- entry of the nested handler, installed when entering the
|
|
||||||
++ -- enclosing handler, ensures the exception will not be
|
|
||||||
++ -- released by the nested handler, but rather by the enclosing
|
|
||||||
++ -- handler.
|
|
||||||
++ --
|
|
||||||
++ -- - Reraise_Occurrence/reraise escapes the running handler,
|
|
||||||
++ -- and we run as an exceptional cleanup for GCC_Exception. The
|
|
||||||
++ -- Saved_Cleanup was reinstalled, but since we're propagating
|
|
||||||
++ -- the same machine occurrence, we do not release it. Instead,
|
|
||||||
++ -- we transfer responsibility for releasing it to the eventual
|
|
||||||
++ -- handler of the propagating exception.
|
|
||||||
++ --
|
|
||||||
++ -- - An unrelated exception propagates through the running
|
|
||||||
++ -- handler. We restored GCC_Exception.Saved_Cleanup above.
|
|
||||||
++ -- Since we're propagating a different exception, we proceed to
|
|
||||||
++ -- release GCC_Exception, unless Saved_Cleanup was
|
|
||||||
++ -- Claimed_Cleanup, because then we know we're not in the
|
|
||||||
++ -- outermost handler for GCC_Exception.
|
|
||||||
++ --
|
|
||||||
++ -- - The handler completes normally, so it reinstalls the
|
|
||||||
++ -- Saved_Cleanup and runs it, unless it was Claimed_Cleanup.
|
|
||||||
++ -- If Saved_Cleanup is null, Unwind_DeleteException (currently)
|
|
||||||
++ -- has no effect, so we could skip it, but if it is ever
|
|
||||||
++ -- changed to do more in this case, we're ready for that,
|
|
||||||
++ -- calling it exactly once.
|
|
||||||
++ if Saved_Cleanup /= Claimed_Cleanup'Address
|
|
||||||
++ and then
|
|
||||||
++ Propagating_Exception /= GCC_Exception
|
|
||||||
++ then
|
|
||||||
++ declare
|
|
||||||
++ Current : constant EOA := Get_Current_Excep.all;
|
|
||||||
++ Cur_Occ : constant GCC_Exception_Access
|
|
||||||
++ := To_GCC_Exception (Current.Machine_Occurrence);
|
|
||||||
++ begin
|
|
||||||
++ -- If we are releasing the Machine_Occurrence of the current
|
|
||||||
++ -- exception, reset the access to it, so that it is no
|
|
||||||
++ -- longer accessible.
|
|
||||||
++ if Cur_Occ = GCC_Exception then
|
|
||||||
++ Current.Machine_Occurrence := System.Null_Address;
|
|
||||||
++ end if;
|
|
||||||
++ end;
|
|
||||||
++ Unwind_DeleteException (GCC_Exception);
|
|
||||||
++ end if;
|
|
||||||
++ end End_Handler_v1;
|
|
||||||
++
|
|
||||||
++ ---------------------
|
|
||||||
++ -- Claimed_Cleanup --
|
|
||||||
++ ---------------------
|
|
||||||
++
|
|
||||||
++ procedure Claimed_Cleanup
|
|
||||||
++ (Reason : Unwind_Reason_Code;
|
|
||||||
++ GCC_Exception : not null GCC_Exception_Access) is
|
|
||||||
++ pragma Unreferenced (Reason);
|
|
||||||
++ pragma Unreferenced (GCC_Exception);
|
|
||||||
++ begin
|
|
||||||
++ -- This procedure should never run. If it does, it's either a
|
|
||||||
++ -- version 0 handler or a foreign handler, attempting to
|
|
||||||
++ -- release an exception while a version 1 handler that claimed
|
|
||||||
++ -- responsibility for releasing the exception remains still
|
|
||||||
++ -- active. This placeholder stops GCC_Exception from being
|
|
||||||
++ -- released by them.
|
|
||||||
++
|
|
||||||
++ -- We could get away with just Null_Address instead, with
|
|
||||||
++ -- nearly the same effect, but with this placeholder we can
|
|
||||||
++ -- detect and report unexpected releases, and we can tell apart
|
|
||||||
++ -- a GCC_Exception without a Cleanup, from one with another
|
|
||||||
++ -- active handler, so as to still call Unwind_DeleteException
|
|
||||||
++ -- exactly once: currently, Unwind_DeleteException does nothing
|
|
||||||
++ -- when the Cleanup is null, but should it ever be changed to
|
|
||||||
++ -- do more, we'll still be safe.
|
|
||||||
++ null;
|
|
||||||
++ end Claimed_Cleanup;
|
|
||||||
++
|
|
||||||
+ -------------------
|
|
||||||
+ -- Begin_Handler --
|
|
||||||
+ -------------------
|
|
||||||
--
|
|
||||||
2.30.2
|
|
||||||
|
|
Loading…
Reference in New Issue