2005-03-11 Michael Snyder <msnyder@redhat.com>
authorMichael Snyder <msnyder@vmware.com>
Fri, 11 Mar 2005 23:16:47 +0000 (23:16 +0000)
committerMichael Snyder <msnyder@vmware.com>
Fri, 11 Mar 2005 23:16:47 +0000 (23:16 +0000)
* mn10300-tdep.c (mn10300_dummy_unwind_dummy_id): Replace
stub fn with real implementatin mn10300_unwind_dummy_id.
(mn10300_push_dummy_call): Implement.  Bare bones version,
does not handle structs or floats.

gdb/ChangeLog
gdb/mn10300-tdep.c

index a414ab0..e819ef5 100644 (file)
@@ -1,3 +1,10 @@
+2005-03-11  Michael Snyder  <msnyder@redhat.com>
+
+       * mn10300-tdep.c (mn10300_dummy_unwind_dummy_id): Replace 
+       stub fn with real implementatin mn10300_unwind_dummy_id.
+       (mn10300_push_dummy_call): Implement.  Bare bones version,
+       does not handle structs or floats.
+
 2005-03-11  Jim Blandy  <jimb@redhat.com>
 
        Avoid warnings due to the use of -Wuninitialized without -O.
index 929350b..cdb1cdc 100644 (file)
@@ -55,6 +55,9 @@
 #include "regcache.h"\r
 #include "gdb_string.h"\r
 #include "gdb_assert.h"\r
+#include "gdbcore.h"   /* for write_memory_unsigned_integer */\r
+#include "value.h"\r
+#include "gdbtypes.h"\r
 #include "frame.h"\r
 #include "frame-unwind.h"\r
 #include "frame-base.h"\r
@@ -311,7 +314,7 @@ mn10300_frame_unwind_cache (struct frame_info *next_frame,
 \r
   cache = trad_frame_cache_zalloc (next_frame);\r
   pc = gdbarch_unwind_pc (current_gdbarch, next_frame);\r
-  mn10300_analyze_prologue (next_frame, &cache, pc);\r
+  mn10300_analyze_prologue (next_frame, (void **) &cache, pc);\r
 \r
   trad_frame_set_id (cache, \r
                     frame_id_build (trad_frame_get_this_base (cache), pc));\r
@@ -322,10 +325,11 @@ mn10300_frame_unwind_cache (struct frame_info *next_frame,
 \r
 /* Here is a dummy implementation.  */\r
 static struct frame_id\r
-mn10300_dummy_unwind_dummy_id (struct gdbarch *gdbarch,\r
-                              struct frame_info *next_frame)\r
+mn10300_unwind_dummy_id (struct gdbarch *gdbarch,\r
+                        struct frame_info *next_frame)\r
 {\r
-  return frame_id_build (0, 0);\r
+  return frame_id_build (frame_sp_unwind (next_frame), \r
+                        frame_pc_unwind (next_frame));\r
 }\r
 \r
 /* Trad frame implementation.  */\r
@@ -411,21 +415,103 @@ mn10300_frame_unwind_init (struct gdbarch *gdbarch)
   frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);\r
   frame_unwind_append_sniffer (gdbarch, mn10300_frame_sniffer);\r
   frame_base_set_default (gdbarch, &mn10300_frame_base);\r
-  set_gdbarch_unwind_dummy_id (gdbarch, mn10300_dummy_unwind_dummy_id);\r
+  set_gdbarch_unwind_dummy_id (gdbarch, mn10300_unwind_dummy_id);\r
   set_gdbarch_unwind_pc (gdbarch, mn10300_unwind_pc);\r
   set_gdbarch_unwind_sp (gdbarch, mn10300_unwind_sp);\r
 }\r
 \r
-/* Dump out the mn10300 specific architecture information. */\r
+/* Function: push_dummy_call\r
+ *\r
+ * Set up machine state for a target call, including\r
+ * function arguments, stack, return address, etc.\r
+ *\r
+ */\r
 \r
-static void\r
-mn10300_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)\r
+static CORE_ADDR\r
+mn10300_push_dummy_call (struct gdbarch *gdbarch, \r
+                        struct value *target_func,\r
+                        struct regcache *regcache,\r
+                        CORE_ADDR bp_addr, \r
+                        int nargs, struct value **args,\r
+                        CORE_ADDR sp, \r
+                        int struct_return,\r
+                        CORE_ADDR struct_addr)\r
 {\r
-  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);\r
-  fprintf_unfiltered (file, "mn10300_dump_tdep: am33_mode = %d\n",\r
-                     tdep->am33_mode);\r
+  const int push_size = register_size (gdbarch, E_PC_REGNUM);\r
+  int regs_used = struct_return ? 1 : 0;\r
+  int len, arg_len; \r
+  int stack_offset = 0;\r
+  int argnum;\r
+  char *val;\r
+\r
+  /* FIXME temp, don't handle struct args at all.  */\r
+  if (struct_return)\r
+    error ("Target doesn't handle struct return");\r
+\r
+  /* This should be a nop, but align the stack just in case something\r
+     went wrong.  Stacks are four byte aligned on the mn10300.  */\r
+  sp &= ~3;\r
+\r
+  /* Now make space on the stack for the args.\r
+\r
+     XXX This doesn't appear to handle pass-by-invisible reference\r
+     arguments.  */\r
+  for (len = 0, argnum = 0; argnum < nargs; argnum++)\r
+    {\r
+      arg_len = (TYPE_LENGTH (value_type (args[argnum])) + 3) & ~3;\r
+      if (TYPE_CODE (value_type (args[argnum])) == TYPE_CODE_STRUCT)\r
+       error ("Target does not handle struct args");\r
+      while (regs_used < 2 && arg_len > 0)\r
+       {\r
+         regs_used++;\r
+         arg_len -= push_size;\r
+       }\r
+      len += arg_len;\r
+    }\r
+\r
+  /* Allocate stack space.  */\r
+  sp -= len;\r
+\r
+  regs_used = struct_return ? 1 : 0;\r
+  /* Push all arguments onto the stack. */\r
+  for (argnum = 0; argnum < nargs; argnum++)\r
+    {\r
+      /* FIXME what about structs?  */\r
+      arg_len = TYPE_LENGTH (value_type (*args));\r
+      val = (char *) value_contents (*args);\r
+\r
+      while (regs_used < 2 && arg_len > 0)\r
+       {\r
+         write_register (regs_used, extract_unsigned_integer (val, \r
+                                                              push_size));\r
+         val += push_size;\r
+         arg_len -= push_size;\r
+         regs_used++;\r
+       }\r
+\r
+      while (arg_len > 0)\r
+       {\r
+         write_memory (sp + stack_offset, val, push_size);\r
+         arg_len -= push_size;\r
+         val += push_size;\r
+         stack_offset += push_size;\r
+       }\r
+\r
+      args++;\r
+    }\r
+\r
+  /* Make space for the flushback area.  */\r
+  sp -= 8;\r
+\r
+  /* Push the return address that contains the magic breakpoint.  */\r
+  sp -= 4;\r
+  write_memory_unsigned_integer (sp, push_size, bp_addr);\r
+  /* Update $sp.  */\r
+  regcache_cooked_write_unsigned (regcache, E_SP_REGNUM, sp);\r
+  return sp;\r
 }\r
 \r
+\r
 static struct gdbarch *\r
 mn10300_gdbarch_init (struct gdbarch_info info,\r
                      struct gdbarch_list *arches)\r
@@ -480,12 +566,27 @@ mn10300_gdbarch_init (struct gdbarch_info info,
                                                mn10300_use_struct_convention);\r
   set_gdbarch_store_return_value (gdbarch, mn10300_store_return_value);\r
   set_gdbarch_extract_return_value (gdbarch, mn10300_extract_return_value);\r
+  \r
+  /* Stage 3 -- get target calls working.  */\r
+  set_gdbarch_push_dummy_call (gdbarch, mn10300_push_dummy_call);\r
+  /* set_gdbarch_return_value (store, extract) */\r
+\r
 \r
   mn10300_frame_unwind_init (gdbarch);\r
 \r
   return gdbarch;\r
 }\r
  \r
+/* Dump out the mn10300 specific architecture information. */\r
+\r
+static void\r
+mn10300_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)\r
+{\r
+  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);\r
+  fprintf_unfiltered (file, "mn10300_dump_tdep: am33_mode = %d\n",\r
+                     tdep->am33_mode);\r
+}\r
+\r
 void\r
 _initialize_mn10300_tdep (void)\r
 {\r