summaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorKevin Buettner <kevinb@redhat.com>2008-02-05 16:20:20 +0000
committerKevin Buettner <kevinb@redhat.com>2008-02-05 16:20:20 +0000
commitad2a3a21b1bd5de3f8bd81074302316481220045 (patch)
tree747d8cb8153459eaa33bd8be1e05e3e464644ca0 /gdb
parentc6ee1b52c66b32e4abb6073714c251185f1158b4 (diff)
downloadgdb-ad2a3a21b1bd5de3f8bd81074302316481220045.tar.gz
* mn10300-tdep.c (mn10300_push_dummy_call): Adjust stack pointer
to account for call site optimizations.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog5
-rw-r--r--gdb/mn10300-tdep.c28
2 files changed, 33 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index fd8974f0b2e..ae3c56e814b 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@
+2008-02-05 Kevin Buettner <kevinb@redhat.com>
+
+ * mn10300-tdep.c (mn10300_push_dummy_call): Adjust stack pointer
+ to account for call site optimizations.
+
2008-02-05 Andrzej Zaborowski <balrogg@gmail.com>
* tracepoint.c (read_actions): Handle end-of-text indicator
diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c
index 8cf9bb3cabb..30483364b19 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;
}