diff options
author | Kevin Buettner <kevinb@redhat.com> | 2008-02-05 16:20:20 +0000 |
---|---|---|
committer | Kevin Buettner <kevinb@redhat.com> | 2008-02-05 16:20:20 +0000 |
commit | ee3a2f014edfd19c428150f25be54e09528b91ea (patch) | |
tree | c5f2d5ae342c0f1d28bd8ecb50af9f20216d0e8f /gdb/mn10300-tdep.c | |
parent | d844e34bca5ee23fcda39c8808633a97a330cbd5 (diff) | |
download | gdb-ee3a2f014edfd19c428150f25be54e09528b91ea.zip gdb-ee3a2f014edfd19c428150f25be54e09528b91ea.tar.gz gdb-ee3a2f014edfd19c428150f25be54e09528b91ea.tar.bz2 |
* mn10300-tdep.c (mn10300_push_dummy_call): Adjust stack pointer
to account for call site optimizations.
Diffstat (limited to 'gdb/mn10300-tdep.c')
-rw-r--r-- | gdb/mn10300-tdep.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c index 8cf9bb3..3048336 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; } |