]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
unwind-dw2.c (uw_update_context_1): Only set cfa as sp if previous frame didn't save sp.
authorRichard Henderson <rth@redhat.com>
Tue, 6 May 2003 17:35:58 +0000 (10:35 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Tue, 6 May 2003 17:35:58 +0000 (10:35 -0700)
        * unwind-dw2.c (uw_update_context_1): Only set cfa as sp if
        previous frame didn't save sp.  Clear sp for next frame.
        (uw_install_context_1): Honor saved sp from frame.

From-SVN: r66527

gcc/ChangeLog
gcc/unwind-dw2.c

index 8f149816dc39105a224cb266718867d88fdf0d0c..a6e456c278e1c0fcdc38cb93f9cf6e356d195b91 100644 (file)
@@ -1,3 +1,9 @@
+2003-05-06  Richard Henderson  <rth@redhat.com>
+
+        * unwind-dw2.c (uw_update_context_1): Only set cfa as sp if 
+        previous frame didn't save sp.  Clear sp for next frame.
+        (uw_install_context_1): Honor saved sp from frame.
+
 2003-05-03  Richard Henderson  <rth@redhat.com>
 
         * builtins.c (expand_builtin) <BUILT_IN_DWARF_FP_REGNUM>: Remove.
index d4269dfcd928fe0e6c3b060fe922fd7d35b29af7..52b0b8db04b681915cb93ee608a81daba4bbe6e9 100644 (file)
@@ -1033,11 +1033,17 @@ uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs)
      In very special situations (such as unwind info for signal return),
      there may be location expressions that use the stack pointer as well.
 
-     Given that other unwind mechanisms generally won't work if you try
-     to represent stack pointer saves and restores directly, we don't
-     bother conditionalizing this at all.  */
-  tmp_sp = (_Unwind_Ptr) context->cfa;
-  orig_context.reg[__builtin_dwarf_sp_column ()] = &tmp_sp;
+     Do this conditionally for one frame.  This allows the unwind info
+     for one frame to save a copy of the stack pointer from the previous
+     frame, and be able to use much easier CFA mechanisms to do it.
+     Always zap the saved stack pointer value for the next frame; carrying
+     the value over from one frame to another doesn't make sense.  */
+  if (!orig_context.reg[__builtin_dwarf_sp_column ()])
+    {
+      tmp_sp = (_Unwind_Ptr) context->cfa;
+      orig_context.reg[__builtin_dwarf_sp_column ()] = &tmp_sp;
+    }
+  context->reg[__builtin_dwarf_sp_column ()] = NULL;
 
   /* Compute this frame's CFA.  */
   switch (fs->cfa_how)
@@ -1170,6 +1176,7 @@ uw_install_context_1 (struct _Unwind_Context *current,
                      struct _Unwind_Context *target)
 {
   long i;
+  void *target_cfa;
 
 #if __GTHREADS
   {
@@ -1191,11 +1198,18 @@ uw_install_context_1 (struct _Unwind_Context *current,
        memcpy (c, t, dwarf_reg_size_table[i]);
     }
 
+  /* If the last frame records a saved stack pointer, use it.  */
+  if (target->reg[__builtin_dwarf_sp_column ()])
+    target_cfa = (void *)(_Unwind_Ptr)
+      _Unwind_GetGR (target, __builtin_dwarf_sp_column ());
+  else
+    target_cfa = target->cfa;
+
   /* We adjust SP by the difference between CURRENT and TARGET's CFA.  */
   if (STACK_GROWS_DOWNWARD)
-    return target->cfa - current->cfa + target->args_size;
+    return target_cfa - current->cfa + target->args_size;
   else
-    return current->cfa - target->cfa - target->args_size;
+    return current->cfa - target_cfa - target->args_size;
 }
 
 static inline _Unwind_Ptr