]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - libgcc/unwind.inc
Update copyright years.
[thirdparty/gcc.git] / libgcc / unwind.inc
index 658bd94f8f3a9d3afd48fa615f7aea766f85394b..90832eba4d7ece7345ee960328303ff4d07201d7 100644 (file)
@@ -1,5 +1,5 @@
 /* Exception handling and frame unwind runtime interface routines. -*- C -*-
-   Copyright (C) 2001-2017 Free Software Foundation, Inc.
+   Copyright (C) 2001-2023 Free Software Foundation, Inc.
 
    This file is part of GCC.
 
 
 static _Unwind_Reason_Code
 _Unwind_RaiseException_Phase2(struct _Unwind_Exception *exc,
-                             struct _Unwind_Context *context)
+                             struct _Unwind_Context *context,
+                             unsigned long *frames_p)
 {
   _Unwind_Reason_Code code;
+  unsigned long frames = 1;
 
   while (1)
     {
@@ -71,8 +73,10 @@ _Unwind_RaiseException_Phase2(struct _Unwind_Exception *exc,
       gcc_assert (!match_handler);
 
       uw_update_context (context, &fs);
+      _Unwind_Frames_Increment (exc, context, frames);
     }
 
+  *frames_p = frames;
   return code;
 }
 
@@ -83,6 +87,7 @@ _Unwind_RaiseException(struct _Unwind_Exception *exc)
 {
   struct _Unwind_Context this_context, cur_context;
   _Unwind_Reason_Code code;
+  unsigned long frames;
 
   /* Set up this_context to describe the current stack frame.  */
   uw_init_context (&this_context);
@@ -128,11 +133,11 @@ _Unwind_RaiseException(struct _Unwind_Exception *exc)
   exc->private_2 = uw_identify_context (&cur_context);
 
   cur_context = this_context;
-  code = _Unwind_RaiseException_Phase2 (exc, &cur_context);
+  code = _Unwind_RaiseException_Phase2 (exc, &cur_context, &frames);
   if (code != _URC_INSTALL_CONTEXT)
     return code;
 
-  uw_install_context (&this_context, &cur_context);
+  uw_install_context (&this_context, &cur_context, frames);
 }
 
 
@@ -140,11 +145,13 @@ _Unwind_RaiseException(struct _Unwind_Exception *exc)
 
 static _Unwind_Reason_Code
 _Unwind_ForcedUnwind_Phase2 (struct _Unwind_Exception *exc,
-                            struct _Unwind_Context *context)
+                            struct _Unwind_Context *context,
+                            unsigned long *frames_p)
 {
   _Unwind_Stop_Fn stop = (_Unwind_Stop_Fn) (_Unwind_Ptr) exc->private_1;
   void *stop_argument = (void *) (_Unwind_Ptr) exc->private_2;
   _Unwind_Reason_Code code, stop_code;
+  unsigned long frames = 1;
 
   while (1)
     {
@@ -153,12 +160,13 @@ _Unwind_ForcedUnwind_Phase2 (struct _Unwind_Exception *exc,
 
       /* Set up fs to describe the FDE for the caller of cur_context.  */
       code = uw_frame_state_for (context, &fs);
-      if (code != _URC_NO_REASON && code != _URC_END_OF_STACK)
+      if (code != _URC_NO_REASON && code != _URC_END_OF_STACK
+         && code != _URC_NORMAL_STOP)
        return _URC_FATAL_PHASE2_ERROR;
 
       /* Unwind successful.  */
       action = _UA_FORCE_UNWIND | _UA_CLEANUP_PHASE;
-      if (code == _URC_END_OF_STACK)
+      if (code == _URC_END_OF_STACK || code == _URC_NORMAL_STOP)
        action |= _UA_END_OF_STACK;
       stop_code = (*stop) (1, action, exc->exception_class, exc,
                           context, stop_argument);
@@ -183,8 +191,10 @@ _Unwind_ForcedUnwind_Phase2 (struct _Unwind_Exception *exc,
       /* Update cur_context to describe the same frame as fs, and discard
         the previous context if necessary.  */
       uw_advance_context (context, &fs);
+      _Unwind_Frames_Increment (exc, context, frames);
     }
 
+  *frames_p = frames;
   return code;
 }
 
@@ -197,6 +207,7 @@ _Unwind_ForcedUnwind (struct _Unwind_Exception *exc,
 {
   struct _Unwind_Context this_context, cur_context;
   _Unwind_Reason_Code code;
+  unsigned long frames;
 
   uw_init_context (&this_context);
   cur_context = this_context;
@@ -204,11 +215,11 @@ _Unwind_ForcedUnwind (struct _Unwind_Exception *exc,
   exc->private_1 = (_Unwind_Ptr) stop;
   exc->private_2 = (_Unwind_Ptr) stop_argument;
 
-  code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context);
+  code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context, &frames);
   if (code != _URC_INSTALL_CONTEXT)
     return code;
 
-  uw_install_context (&this_context, &cur_context);
+  uw_install_context (&this_context, &cur_context, frames);
 }
 
 
@@ -220,6 +231,7 @@ _Unwind_Resume (struct _Unwind_Exception *exc)
 {
   struct _Unwind_Context this_context, cur_context;
   _Unwind_Reason_Code code;
+  unsigned long frames;
 
   uw_init_context (&this_context);
   cur_context = this_context;
@@ -227,13 +239,13 @@ _Unwind_Resume (struct _Unwind_Exception *exc)
   /* Choose between continuing to process _Unwind_RaiseException
      or _Unwind_ForcedUnwind.  */
   if (exc->private_1 == 0)
-    code = _Unwind_RaiseException_Phase2 (exc, &cur_context);
+    code = _Unwind_RaiseException_Phase2 (exc, &cur_context, &frames);
   else
-    code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context);
+    code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context, &frames);
 
   gcc_assert (code == _URC_INSTALL_CONTEXT);
 
-  uw_install_context (&this_context, &cur_context);
+  uw_install_context (&this_context, &cur_context, frames);
 }
 
 
@@ -245,6 +257,7 @@ _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exc)
 {
   struct _Unwind_Context this_context, cur_context;
   _Unwind_Reason_Code code;
+  unsigned long frames;
 
   /* Choose between continuing to process _Unwind_RaiseException
      or _Unwind_ForcedUnwind.  */
@@ -254,11 +267,11 @@ _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exc)
   uw_init_context (&this_context);
   cur_context = this_context;
 
-  code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context);
+  code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context, &frames);
 
   gcc_assert (code == _URC_INSTALL_CONTEXT);
 
-  uw_install_context (&this_context, &cur_context);
+  uw_install_context (&this_context, &cur_context, frames);
 }
 
 
@@ -288,14 +301,24 @@ _Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument)
 
       /* Set up fs to describe the FDE for the caller of context.  */
       code = uw_frame_state_for (&context, &fs);
-      if (code != _URC_NO_REASON && code != _URC_END_OF_STACK)
+      if (code != _URC_NO_REASON && code != _URC_END_OF_STACK
+          && code != _URC_NORMAL_STOP)
        return _URC_FATAL_PHASE1_ERROR;
 
       /* Call trace function.  */
       if ((*trace) (&context, trace_argument) != _URC_NO_REASON)
        return _URC_FATAL_PHASE1_ERROR;
 
-      /* We're done at end of stack.  */       
+#ifdef MD_BACKCHAIN_FALLBACK
+      /* Do a backchain if there is no DWARF data.  */
+      if (code == _URC_NORMAL_STOP)
+       {
+         MD_BACKCHAIN_FALLBACK(&context, trace_argument);
+         break;
+       }
+#endif
+
+      /* We're done at end of stack.  */
       if (code == _URC_END_OF_STACK)
        break;