diff --git a/rtl/inc/except.inc b/rtl/inc/except.inc
index dc518bcf7f..ebf82fae44 100644
--- a/rtl/inc/except.inc
+++ b/rtl/inc/except.inc
@@ -354,11 +354,13 @@ begin
 end;
 {$endif FPC_SYSTEM_HAS_DONEEXCEPTION}
 
+{$ifndef FPC_SYSTEM_HAS_RAISENESTED}
 procedure fpc_raise_nested;[public,alias:'FPC_RAISE_NESTED']compilerproc;
 begin
   Internal_PopSecondObjectStack.Free;
   Internal_Reraise;
 end;
+{$endif FPC_SYSTEM_HAS_RAISENESTED}
 
 {$ifndef FPC_SYSTEM_HAS_SAFECALLHANDLER}
 function fpc_safecallhandler(obj: TObject): HResult; [public,alias:'FPC_SAFECALLHANDLER']; compilerproc;
diff --git a/rtl/inc/psabieh.inc b/rtl/inc/psabieh.inc
index 0c40613c82..bdcd80ff83 100644
--- a/rtl/inc/psabieh.inc
+++ b/rtl/inc/psabieh.inc
@@ -55,6 +55,7 @@ function FPC_psabieh_GetExceptionWrapper(exceptionObject: PFPC_Unwind_Exception)
     result:=PExceptObject(exceptionObject+1)-1;
   end;
 
+function _Unwind_Resume_or_Rethrow (context:PFPC_Unwind_Context): FPC_Unwind_Reason_Code;cdecl;external;
 procedure _Unwind_DeleteException(context:PFPC_Unwind_Context);cdecl;external;
 function _Unwind_GetGR(context:PFPC_Unwind_Context; index:cint):PtrUInt;cdecl;external;
 procedure _Unwind_SetGR(context:PFPC_Unwind_Context; index:cint; new_value:PtrUInt);cdecl;external;
@@ -901,6 +902,10 @@ procedure FPC_psabi_end_catch; cdecl; compilerproc;
 {$endif}
     if refcount<0 then
       begin
+        { Can happen in the original glibc code, but not for us. When re-raising an
+          exception, we always immediately do this to an outer frame }
+        halt(217);
+(*
         // This exception was rethrown.  Decrement the (inverted) catch
         // count and remove it from the chain when it reaches zero.
         inc(refcount);
@@ -909,6 +914,7 @@ procedure FPC_psabi_end_catch; cdecl; compilerproc;
 {$endif}
         if refcount = 0 then
           ExceptObjectStack:=_ExceptObjectStack^.next;
+*)
       end
     else
       begin
@@ -934,3 +940,102 @@ procedure FPC_psabi_end_catch; cdecl; compilerproc;
       end;
     _ExceptObjectStack^.refcount:=refcount;
   end;
+
+{$ifdef FPC_PSABIEH_CPLUSPLUSSUPPORT}
+procedure __cxa_rethrow; cdecl; external; noreturn;
+{$endif FPC_PSABIEH_CPLUSPLUSSUPPORT}
+
+{$define FPC_SYSTEM_HAS_RERAISE}
+procedure fpc_ReRaise; [public,alias:'FPC_RERAISE']; compilerproc;
+  var
+    _ExceptObjectStack: PExceptObject;
+    refcount: longint;
+    reraise_error: FPC_Unwind_Reason_Code;
+  begin
+    _ExceptObjectStack:=ExceptObjectStack;
+    // globals->uncaughtExceptions += 1;
+
+{$ifdef excdebug}
+    writeln('start reraise for wrapper ',hexstr(_ExceptObjectStack));
+{$endif}
+    // Watch for luser rethrowing with no active exception.
+    if assigned(_ExceptObjectStack) then
+      begin
+        // Tell __cxa_end_catch this is a rethrow.
+        if _ExceptObjectStack^.unwind_exception.exception_class<>FPC_psabieh_exceptionClass_ID.u then
+{$ifdef FPC_PSABIEH_CPLUSPLUSSUPPORT}
+          begin
+            { remove foreign exception; since we never link multiple foreign
+              exceptions, we know the stack is now empty }
+            ExceptObjectStack:=nil;
+            __cxa_rethrow;
+            { should never be reached }
+            halt(217);
+          end
+{$endif FPC_PSABIEH_CPLUSPLUSSUPPORT}
+        else
+          begin
+            { undo the begin_catch }
+            dec(_ExceptObjectStack^.refcount);
+          end;
+
+{$ifdef excdebug}
+    writeln('Stop reraise, new refcount = ',_ExceptObjectStack^.refcount);
+{$endif}
+//  #ifdef _GLIBCXX_SJLJ_EXCEPTIONS
+//        _Unwind_SjLj_Resume_or_Rethrow (&header->unwindHeader);
+//  #else
+//  #if defined(_LIBUNWIND_STD_ABI)
+//        _Unwind_RaiseException (@_ExceptObjectStack^.unwind_exception);
+//  #else
+        reraise_error:=_Unwind_Resume_or_Rethrow (@_ExceptObjectStack^.unwind_exception);
+{$ifdef excdebug}
+        writeln('reraise failed, error = ',reraise_error);
+{$endif}
+//  #endif
+//  #endif
+        // Some sort of unwinding error.
+        halt(217);
+      end;
+    halt(217);
+  end;
+
+
+{$define FPC_SYSTEM_HAS_RAISENESTED}
+procedure fpc_raise_nested;compilerproc;
+  var
+    hp, _ExceptObjectStack: PExceptObject;
+  begin
+    _ExceptObjectStack:=ExceptObjectStack;
+    if not(assigned(_ExceptObjectStack)) or
+       not(assigned(_ExceptObjectStack^.next)) then
+      begin
+{$ifdef excdebug}
+        writeln ('raise_nested: At end of ExceptionObjectStack');
+{$endif}
+        halt(217);
+      end;
+
+    if _ExceptObjectStack^.unwind_exception.exception_class<>FPC_psabieh_exceptionClass_ID.u then
+      begin
+{$ifdef excdebug}
+        writeln ('raise_nested: top of stack contains foreign exception');
+{$endif}
+        halt(217);
+      end;
+
+    hp:=_ExceptObjectStack^.next;
+    _ExceptObjectStack^.next:=hp^.next;
+{$ifdef excdebug}
+    writeln('raise_nested: raising nested wrapper ',hexstr(_ExceptObjectStack),' = fpc exception ',hexstr(_ExceptObjectStack^.FObject),' with refcount ',_ExceptObjectStack^.refcount{,' (will increase to ',_ExceptObjectStack^.refcount+1,')'});
+    writeln('raise_nested: previous exception ',hexstr(hp),' = fpc exception ',hexstr(hp^.FObject),' with refcount ',hp^.refcount,' (will delete if refcount = 1, otherwise decrease to',hp^.refcount-1,')');
+{$endif}
+    if hp^.refcount=1 then
+      { we need to free the original exception object if its refcount=1
+        (means it was not acquired, only refcount increase by begin_catch) }
+      _Unwind_DeleteException(@hp^.unwind_exception)
+    else
+      dec(hp^.refcount);
+    _Unwind_RaiseException(@_ExceptObjectStack^.unwind_exception);
+    halt(217);
+  end;