OSDN Git Service

* unwind-dw2.c (uw_update_context_1): Only set cfa as sp if
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 6 May 2003 17:28:37 +0000 (17:28 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 6 May 2003 17:28:37 +0000 (17:28 +0000)
        previous frame didn't save sp.  Clear sp for next frame.
        (uw_install_context_1): Honor saved sp from frame.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@66526 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/unwind-dw2.c

index 70bdd48..2cdf5b7 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-06  Richard Sandiford  <rsandifo@redhat.com>
 
        * config/mips/mips-protos.h (mips_subword, mips_output_move): Declare.
index 7596ef0..5a26d0b 100644 (file)
@@ -1089,11 +1089,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;
-  _Unwind_SetGRPtr (&orig_context, __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 (!_Unwind_GetGRPtr (&orig_context, __builtin_dwarf_sp_column ()))
+    {
+      tmp_sp = (_Unwind_Ptr) context->cfa;
+      _Unwind_SetGRPtr (&orig_context, __builtin_dwarf_sp_column (), &tmp_sp);
+    }
+  _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), NULL);
 
   /* Compute this frame's CFA.  */
   switch (fs->cfa_how)
@@ -1234,6 +1240,7 @@ uw_install_context_1 (struct _Unwind_Context *current,
                      struct _Unwind_Context *target)
 {
   long i;
+  void *target_cfa;
 
 #if __GTHREADS
   {
@@ -1256,11 +1263,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 (_Unwind_GetGRPtr (target, __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