Created
May 17, 2016 14:03
-
-
Save stffrdhrn/ef0a3d95c7460dd24540db7b99b4eee6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/gdb/or1k-tdep.c b/gdb/or1k-tdep.c | |
index 8cfa440..4726c24 100644 | |
--- a/gdb/or1k-tdep.c | |
+++ b/gdb/or1k-tdep.c | |
@@ -443,7 +443,10 @@ or1k_return_value (struct gdbarch *gdbarch, | |
is returned in memory. Large (2 word) scalars are returned in r11 and r12 | |
(this is a change from GCC 4.2.2, when they were apparently returned in | |
memory). */ | |
- if (((TYPE_CODE_STRUCT == rv_type) || (TYPE_CODE_UNION == rv_type)) && | |
+ | |
+ printf ("Checking return type size %d vs bpw %d\n", rv_size, bpw); | |
+ // FIXME should this be ARRAY? or should we juse to > bpw? | |
+ if (((TYPE_CODE_STRUCT == rv_type) || (TYPE_CODE_UNION == rv_type) || (TYPE_CODE_ARRAY == rv_type)) && | |
(rv_size > bpw)) | |
{ | |
if (readbuf) | |
@@ -1237,9 +1240,11 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, | |
/* Location for a returned structure. This is passed as a silent first | |
argument. */ | |
+ // FIXME handle varags, they should go to the stack logic | |
if (struct_return) | |
{ | |
+ printf ("return: stuct return r%d\n", argreg); | |
regcache_cooked_write_unsigned (regcache, OR1K_FIRST_ARG_REGNUM, | |
struct_addr); | |
argreg++; | |
@@ -1257,12 +1262,32 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, | |
enum type_code typecode = arg_type->main_type->code; | |
/* Handle the different argument types. */ | |
- if((TYPE_CODE_STRUCT == typecode) || (TYPE_CODE_UNION == typecode)) | |
+ if ((TYPE_CODE_STRUCT == typecode) || (TYPE_CODE_UNION == typecode) || (len > bpw*2)) | |
{ | |
- /* The ABI passes all structures by reference, so get its address. */ | |
- store_unsigned_integer (valbuf, bpa, byte_order, value_address (arg)); | |
- len = bpa; | |
- val = valbuf; | |
+ CORE_ADDR valaddr = value_address (arg); | |
+ | |
+ printf ("regs: storing struct arg on stack\n"); | |
+ val = value_contents (arg); | |
+ for (int i = 0; i < len; i=i+4) { | |
+ printf ("regs: storing data [%x,%x,%x,%x]\n", val[i], val[i+1], val[i+2], val[i+3]); | |
+ } | |
+ | |
+ /* if the arg is fabricated (i.e. 3*i, instead of i) val is null */ | |
+ if (valaddr == 0) { | |
+ printf("regs: storing internal val to stack\n"); | |
+ /* The argument is being passed on the stack. */ | |
+ // FIXME I go up the stack, here is this going to stomp on something, probably need to | |
+ // do this with the rest below | |
+ valaddr = sp + stack_offset; | |
+ | |
+ write_memory (valaddr, val, len); | |
+ stack_offset += align_up (len, 4); | |
+ } | |
+ | |
+ /* The ABI passes all structures by reference, so get its address. */ | |
+ store_unsigned_integer (valbuf, bpa, byte_order, valaddr); | |
+ len = bpa; | |
+ val = valbuf; | |
} | |
else | |
{ | |
@@ -1286,7 +1311,7 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, | |
ULONGEST lo = regval & mask; | |
ULONGEST hi = regval >> bits_per_word; | |
- gdb_assert (len <= (bpw * 2)); | |
+ printf ("regs: putting double word arg to r%d and r%d\n", argreg, argreg+1); | |
regcache_cooked_write_unsigned (regcache, argreg, hi); | |
regcache_cooked_write_unsigned (regcache, argreg + 1, lo); | |
@@ -1300,6 +1325,7 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, | |
} | |
else if (argreg <= OR1K_LAST_ARG_REGNUM) | |
{ | |
+ printf ("regs: putting single word arg to r%d [%x,%x,%x,%x]\n", argreg, val[0], val[1], val[2], val[3]); | |
/* Smaller scalars fit in a single register */ | |
regcache_cooked_write_unsigned (regcache, argreg, | |
extract_unsigned_integer (val, len, | |
@@ -1342,7 +1368,6 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, | |
} | |
sp = gdbarch_frame_align (gdbarch, sp); | |
- stack_offset = 0; | |
/* Push the remaining args on the stack */ | |
for (argnum = first_stack_arg; argnum < nargs; argnum++) | |
@@ -1370,6 +1395,7 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, | |
gdb_assert (len <= (bpw * 2)); | |
+ printf ("out-of-args: putting %d len arg to stack\n", len); | |
write_memory (sp + stack_offset, val, len); | |
stack_offset += ((len + bpw - 1) / bpw) * bpw; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment