Created
May 20, 2016 15:25
-
-
Save stffrdhrn/964bea59775a4be25fed3d73618adfdd 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..ed27cc8 100644 | |
--- a/gdb/or1k-tdep.c | |
+++ b/gdb/or1k-tdep.c | |
@@ -443,7 +443,9 @@ 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)) && | |
+ | |
+ // 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) | |
@@ -1228,6 +1230,7 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, | |
unsigned int bpa = (gdbarch_tdep (gdbarch))->bytes_per_address; | |
unsigned int bpw = (gdbarch_tdep (gdbarch))->bytes_per_word; | |
+ struct type *func_type = value_type (function); | |
/* Return address */ | |
regcache_cooked_write_unsigned (regcache, OR1K_LR_REGNUM, bp_addr); | |
@@ -1237,7 +1240,6 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, | |
/* Location for a returned structure. This is passed as a silent first | |
argument. */ | |
- | |
if (struct_return) | |
{ | |
regcache_cooked_write_unsigned (regcache, OR1K_FIRST_ARG_REGNUM, | |
@@ -1256,13 +1258,33 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, | |
int len = arg_type->length; | |
enum type_code typecode = arg_type->main_type->code; | |
+ if (argnum >= TYPE_NFIELDS(func_type)) | |
+ { | |
+ break; /* end or regular args, varargs go to stack */ | |
+ } | |
+ | |
/* 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); | |
+ | |
+ /* if the arg is fabricated (i.e. 3*i, instead of i) valaddr is undefined */ | |
+ if (valaddr == 0) { | |
+ /* The argument needs to be copied into the target space */ | |
+ // FIXME This is a BIG hack now, we need to stuff the data somewhere, but down | |
+ // below we start storing stuff on the stack and the location is important. | |
+ // The location of this data isnt important. We need as way to put arbitrary | |
+ // data into the target memory. | |
+ valaddr = sp - 100 + stack_offset; | |
+ | |
+ write_memory (valaddr, value_contents(arg), len); | |
+ stack_offset += align_up (len, bpw); | |
+ } | |
+ | |
+ /* 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,8 +1308,6 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, | |
ULONGEST lo = regval & mask; | |
ULONGEST hi = regval >> bits_per_word; | |
- gdb_assert (len <= (bpw * 2)); | |
- | |
regcache_cooked_write_unsigned (regcache, argreg, hi); | |
regcache_cooked_write_unsigned (regcache, argreg + 1, lo); | |
argreg += 2; | |
@@ -1328,7 +1348,7 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, | |
int len = arg_type->length; | |
enum type_code typecode = arg_type->main_type->code; | |
- if((TYPE_CODE_STRUCT == typecode) || (TYPE_CODE_UNION == typecode)) | |
+ if ((TYPE_CODE_STRUCT == typecode) || (TYPE_CODE_UNION == typecode) || (len > bpw*2)) | |
{ | |
/* Structures are passed as addresses */ | |
sp -= bpa; | |
@@ -1342,7 +1362,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++) | |
@@ -1357,7 +1376,7 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, | |
/* The EABI passes structures that do not fit in a register by | |
reference. In all other cases, pass the structure by value. */ | |
- if((TYPE_CODE_STRUCT == typecode) || (TYPE_CODE_UNION == typecode)) | |
+ if ((TYPE_CODE_STRUCT == typecode) || (TYPE_CODE_UNION == typecode) || (len > bpw*2)) | |
{ | |
store_unsigned_integer (valbuf, bpa, byte_order, value_address (arg)); | |
len = bpa; | |
@@ -1368,10 +1387,15 @@ or1k_push_dummy_call (struct gdbarch *gdbarch, | |
val = value_contents (arg); | |
} | |
- gdb_assert (len <= (bpw * 2)); | |
+ while (len > 0) | |
+ { | |
+ int partial_len = (len < bpw ? len : bpw); | |
- write_memory (sp + stack_offset, val, len); | |
- stack_offset += ((len + bpw - 1) / bpw) * bpw; | |
+ write_memory (sp + stack_offset, val, partial_len); | |
+ stack_offset += align_up (partial_len, bpw); | |
+ len -= partial_len; | |
+ val += partial_len; | |
+ } | |
} | |
/* Save the updated stack pointer */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment