aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Snyder <msnyder@vmware.com>2005-04-02 00:40:51 +0000
committerMichael Snyder <msnyder@vmware.com>2005-04-02 00:40:51 +0000
commit1fb1ca27820f5247042cb786acd8f0a7a8455cc6 (patch)
treeb7c501f8bc4bb1ae89aa6f0a18ba27e08416a3f8
parent9b3c083c83dca517211431bdb3f23fbb6ce5236a (diff)
downloadgdb-1fb1ca27820f5247042cb786acd8f0a7a8455cc6.zip
gdb-1fb1ca27820f5247042cb786acd8f0a7a8455cc6.tar.gz
gdb-1fb1ca27820f5247042cb786acd8f0a7a8455cc6.tar.bz2
2005-04-01 Michael Snyder <msnyder@redhat.com>
* mn10300-tdep.c (mn10300_frame_unwind_cache): Use find_partial_func instead of unwind_pc to identify frame. (mn10300_push_dummy_call): Handle struct args, struct_return.
-rw-r--r--gdb/ChangeLog4
-rw-r--r--gdb/mn10300-tdep.c54
2 files changed, 45 insertions, 13 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 25f6540..d96c503 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,9 @@
2005-04-01 Michael Snyder <msnyder@redhat.com>
+ * mn10300-tdep.c (mn10300_frame_unwind_cache): Use
+ find_partial_func instead of unwind_pc to identify frame.
+ (mn10300_push_dummy_call): Handle struct args, struct_return.
+
* mn10300-prologue.c (set_movm_offsets): Don't test variable
before setting it.
* mn10300-tdep.c (mn10300_skip_prologue): Use analyze_prologue
diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c
index 8fa50d0..51feba4 100644
--- a/gdb/mn10300-tdep.c
+++ b/gdb/mn10300-tdep.c
@@ -313,7 +313,7 @@ mn10300_frame_unwind_cache (struct frame_info *next_frame,
void **this_prologue_cache)
{
struct trad_frame_cache *cache;
- CORE_ADDR pc;
+ CORE_ADDR pc, start, end;
if (*this_prologue_cache)
return (*this_prologue_cache);
@@ -321,10 +321,14 @@ mn10300_frame_unwind_cache (struct frame_info *next_frame,
cache = trad_frame_cache_zalloc (next_frame);
pc = gdbarch_unwind_pc (current_gdbarch, next_frame);
mn10300_analyze_prologue (next_frame, (void **) &cache, pc);
-
- trad_frame_set_id (cache,
- frame_id_build (trad_frame_get_this_base (cache),
- frame_func_unwind (next_frame)));
+ if (find_pc_partial_function (pc, NULL, &start, &end))
+ trad_frame_set_id (cache,
+ frame_id_build (trad_frame_get_this_base (cache),
+ start));
+ else
+ trad_frame_set_id (cache,
+ frame_id_build (trad_frame_get_this_base (cache),
+ frame_func_unwind (next_frame)));
(*this_prologue_cache) = cache;
return cache;
@@ -445,15 +449,17 @@ mn10300_push_dummy_call (struct gdbarch *gdbarch,
CORE_ADDR struct_addr)
{
const int push_size = register_size (gdbarch, E_PC_REGNUM);
- int regs_used = struct_return ? 1 : 0;
+ int regs_used;
int len, arg_len;
int stack_offset = 0;
int argnum;
- char *val;
+ char *val, valbuf[MAX_REGISTER_SIZE];
+#if 0
/* FIXME temp, don't handle struct args at all. */
if (struct_return)
error ("Target doesn't handle struct return");
+#endif
/* This should be a nop, but align the stack just in case something
went wrong. Stacks are four byte aligned on the mn10300. */
@@ -463,11 +469,14 @@ mn10300_push_dummy_call (struct gdbarch *gdbarch,
XXX This doesn't appear to handle pass-by-invisible reference
arguments. */
+ regs_used = struct_return ? 1 : 0;
for (len = 0, argnum = 0; argnum < nargs; argnum++)
{
arg_len = (TYPE_LENGTH (value_type (args[argnum])) + 3) & ~3;
+#if 0
if (TYPE_CODE (value_type (args[argnum])) == TYPE_CODE_STRUCT)
error ("Target does not handle struct args");
+#endif
while (regs_used < 2 && arg_len > 0)
{
regs_used++;
@@ -479,18 +488,37 @@ mn10300_push_dummy_call (struct gdbarch *gdbarch,
/* Allocate stack space. */
sp -= len;
- regs_used = struct_return ? 1 : 0;
+ if (struct_return)
+ {
+ regs_used = 1;
+ write_register (E_D0_REGNUM, struct_addr);
+ }
+ else
+ regs_used = 0;
+
/* Push all arguments onto the stack. */
for (argnum = 0; argnum < nargs; argnum++)
{
- /* FIXME what about structs? */
- arg_len = TYPE_LENGTH (value_type (*args));
- val = (char *) value_contents (*args);
+ /* FIXME what about structs? Unions? */
+ if (TYPE_CODE (value_type (*args)) == TYPE_CODE_STRUCT
+ && TYPE_LENGTH (value_type (*args)) > 8)
+ {
+ /* Change to pointer-to-type. */
+ arg_len = push_size;
+ store_unsigned_integer (valbuf, push_size,
+ VALUE_ADDRESS (*args));
+ val = &valbuf[0];
+ }
+ else
+ {
+ arg_len = TYPE_LENGTH (value_type (*args));
+ val = (char *) value_contents (*args);
+ }
while (regs_used < 2 && arg_len > 0)
{
- write_register (regs_used, extract_unsigned_integer (val,
- push_size));
+ write_register (regs_used,
+ extract_unsigned_integer (val, push_size));
val += push_size;
arg_len -= push_size;
regs_used++;