From ee3a2f014edfd19c428150f25be54e09528b91ea Mon Sep 17 00:00:00 2001 From: Kevin Buettner Date: Tue, 5 Feb 2008 16:20:20 +0000 Subject: [PATCH] * mn10300-tdep.c (mn10300_push_dummy_call): Adjust stack pointer to account for call site optimizations. --- gdb/ChangeLog | 5 +++++ gdb/mn10300-tdep.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index fd8974f0b2..ae3c56e814 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2008-02-05 Kevin Buettner + + * mn10300-tdep.c (mn10300_push_dummy_call): Adjust stack pointer + to account for call site optimizations. + 2008-02-05 Andrzej Zaborowski * tracepoint.c (read_actions): Handle end-of-text indicator diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c index 8cf9bb3cab..30483364b1 100644 --- a/gdb/mn10300-tdep.c +++ b/gdb/mn10300-tdep.c @@ -35,6 +35,7 @@ #include "symtab.h" #include "dwarf2-frame.h" #include "osabi.h" +#include "infcall.h" #include "mn10300-tdep.h" @@ -1079,6 +1080,33 @@ mn10300_push_dummy_call (struct gdbarch *gdbarch, /* Update $sp. */ regcache_cooked_write_unsigned (regcache, E_SP_REGNUM, sp); + + /* On the mn10300, it's possible to move some of the stack adjustment + and saving of the caller-save registers out of the prologue and + into the call sites. (When using gcc, this optimization can + occur when using the -mrelax switch.) If this occurs, the dwarf2 + info will reflect this fact. We can test to see if this is the + case by creating a new frame using the current stack pointer and + the address of the function that we're about to call. We then + unwind SP and see if it's different than the SP of our newly + created frame. If the SP values are the same, the caller is not + expected to allocate any additional stack. On the other hand, if + the SP values are different, the difference determines the + additional stack that must be allocated. + + Note that we don't update the return value though because that's + the value of the stack just after pushing the arguments, but prior + to performing the call. This value is needed in order to + construct the frame ID of the dummy call. */ + { + CORE_ADDR func_addr = find_function_addr (target_func, NULL); + CORE_ADDR unwound_sp + = mn10300_unwind_sp (gdbarch, create_new_frame (sp, func_addr)); + if (sp != unwound_sp) + regcache_cooked_write_unsigned (regcache, E_SP_REGNUM, + sp - (unwound_sp - sp)); + } + return sp; }