aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2003-05-06 10:28:37 -0700
committerRichard Henderson <rth@gcc.gnu.org>2003-05-06 10:28:37 -0700
commit8b6891963bc53520c4a1751a1e175c5c37eee441 (patch)
tree068f6d2a17823731401099fa70401c572b4f0ad3
parent3612c9efbb5409dff4cc71c7908ecaa47a9ddf22 (diff)
downloadgcc-8b6891963bc53520c4a1751a1e175c5c37eee441.zip
gcc-8b6891963bc53520c4a1751a1e175c5c37eee441.tar.gz
gcc-8b6891963bc53520c4a1751a1e175c5c37eee441.tar.bz2
unwind-dw2.c (uw_update_context_1): Only set cfa as sp if previous frame didn't save sp.
* 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: r66526
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/unwind-dw2.c28
2 files changed, 27 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 70bdd48..2cdf5b7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/unwind-dw2.c b/gcc/unwind-dw2.c
index 7596ef0..5a26d0b 100644
--- a/gcc/unwind-dw2.c
+++ b/gcc/unwind-dw2.c
@@ -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