#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
\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
\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
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
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