* mn10300-tdep.c (mn10300_push_dummy_call): Adjust stack pointer
authorKevin Buettner <kevinb@redhat.com>
Tue, 5 Feb 2008 16:20:20 +0000 (16:20 +0000)
committerKevin Buettner <kevinb@redhat.com>
Tue, 5 Feb 2008 16:20:20 +0000 (16:20 +0000)
to account for call site optimizations.

gdb/ChangeLog
gdb/mn10300-tdep.c

index fd8974f..ae3c56e 100644 (file)
@@ -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
index 8cf9bb3..3048336 100644 (file)
@@ -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;
 }