From f5e97d99d162740fc965aef3516ddd90adaa9ce8 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 6 May 2003 17:35:58 +0000 Subject: * 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. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/gcc-3_2-branch@66527 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 ++++++ gcc/unwind-dw2.c | 28 +++++++++++++++++++++------- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8f149816dc3..a6e456c278e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2003-05-06 Richard Henderson + + * 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 * builtins.c (expand_builtin) : Remove. diff --git a/gcc/unwind-dw2.c b/gcc/unwind-dw2.c index d4269dfcd92..52b0b8db04b 100644 --- a/gcc/unwind-dw2.c +++ b/gcc/unwind-dw2.c @@ -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 -- cgit v1.2.3