diff --git a/util/crossgcc/patches/gcc-8.3.0_gnat_eh.patch b/util/crossgcc/patches/gcc-8.3.0_gnat_eh.patch
new file mode 100644
index 0000000..151a3e6
--- /dev/null
+++ b/util/crossgcc/patches/gcc-8.3.0_gnat_eh.patch
@@ -0,0 +1,270 @@
+commit 5d733372faa97c1c3943a20a252d000db37c738b
+Author: Alexandre Oliva <oliva@adacore.com>
+Date:   Fri Aug 2 18:46:51 2019 +0000
+
+    rework Ada EH Machine_Occurrence deallocation
+
+    Introduce exception handler ABI #1 to ensure single release, no access
+    after release of reraised Machine_Occurrences, and no failure to
+    re-reraise a Machine_Occurrence.
+
+    Unlike Ada exceptions, foreign exceptions do not get a new
+    Machine_Occurrence upon reraise, but each handler would delete the
+    exception upon completion, normal or exceptional, save for the case of
+    a 'raise;' statement within the handler, that avoided the delete by
+    clearing the exception pointer that the cleanup would use to release
+    it.  The cleared exception pointer might then be used by a subsequent
+    reraise within the same handler.  Get_Current_Excep.all would also
+    expose the Machine_Occurrence to reuse by Reraise_Occurrence, even for
+    native exceptions.
+
+    Under ABI #1, Begin_Handler_v1 claims responsibility for releasing an
+    exception by saving its cleanup and setting it to Claimed_Cleanup.
+    End_Handler_v1 restores the cleanup and runs it, as long as it isn't
+    still Claimed_Cleanup (which indicates an enclosing handler has
+    already claimed responsibility for releasing it), and as long as the
+    same exception is not being propagated up (the next handler of the
+    propagating exception will then claim responsibility for releasing
+    it), so reraise no longer needs to clear the exception pointer, and it
+    can just propagate the exception, just like Reraise_Occurrence.
+
+    ABI #1 is fully interoperable with ABI #0, i.e., exception handlers
+    that call the #0 primitives can be linked together with ones that call
+    the #1 primitives, and they will not misbehave.  When a #1 handler
+    claims responsibility for releasing an exception, even #0 reraises
+    dynamically nested within it will refrain from releasing it.  However,
+    when a #0 handler is a handler of a foreign exception that would have
+    been responsible for releasing it with #1, a Reraise_Occurrence of
+    that foreign or other Machine_Occurrence-carrying exception may still
+    cause the exception to be released multiple times, and to be used
+    after it is first released, even if other handlers of the foreign
+    exception use #1.
+
+
+    for  gcc/ada/ChangeLog
+
+            * libgnat/a-exexpr.adb (Begin_Handler_v1, End_Handler_v1): New.
+            (Claimed_Cleanup): New.
+            (Begin_Handler, End_Handler): Document.
+            * gcc-interface/trans.c (gigi): Switch to exception handler
+            ABI #1.
+            (Exception_Handler_to_gnu_gcc): Save the original cleanup
+            returned by begin handler, pass it to end handler, and use
+            EH_ELSE_EXPR to pass a propagating exception to end handler.
+            (gnat_to_gnu): Leave the exception pointer alone for reraise.
+            (add_cleanup): Handle EH_ELSE_EXPR, require it by itself.
+
+    From-SVN: r274029
+
+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 --
+    -------------------
