diff options
author | Denis Chertykov <chertykov@gmail.com> | 2016-03-05 15:17:15 +0300 |
---|---|---|
committer | Denis Chertykov <chertykov@gmail.com> | 2016-03-05 15:17:15 +0300 |
commit | cb86f3880e61c79e59b9225e79c3544a1fcd8005 (patch) | |
tree | f4919e65da77ec69c2c63be966291ba49002355f /gdb/avr-tdep.c | |
parent | 57f9b1448fb0de3313d1525707278131bfd8eec4 (diff) | |
download | gdb-cb86f3880e61c79e59b9225e79c3544a1fcd8005.zip gdb-cb86f3880e61c79e59b9225e79c3544a1fcd8005.tar.gz gdb-cb86f3880e61c79e59b9225e79c3544a1fcd8005.tar.bz2 |
Fix argument passing for call
When calling function with argument of size more than 8 bytes fails with
an error "That operation is not available on integers of more than 8 bytes.".
avr-gdb considers only 8 bytes (sizeof(long long)) in case of passing the
argument in registers. When the argument is of size more than 8 byte
then the utility function to extract bytes failed with the above error.
gdb/
* avr-tdep.c (AVR_LAST_ARG_REGNUM): Define.
(avr_push_dummy_call): Correct last needed argument register.
Write MSB of argument into register and subsequent bytes into
other registers in decreasing order.
Diffstat (limited to 'gdb/avr-tdep.c')
-rw-r--r-- | gdb/avr-tdep.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c index 597cfb4..088fe51 100644 --- a/gdb/avr-tdep.c +++ b/gdb/avr-tdep.c @@ -111,6 +111,7 @@ enum AVR_ARG1_REGNUM = 24, /* Single byte argument */ AVR_ARGN_REGNUM = 25, /* Multi byte argments */ + AVR_LAST_ARG_REGNUM = 8, /* Last argument register */ AVR_RET1_REGNUM = 24, /* Single byte return value */ AVR_RETN_REGNUM = 25, /* Multi byte return value */ @@ -1298,23 +1299,24 @@ avr_push_dummy_call (struct gdbarch *gdbarch, struct value *function, const bfd_byte *contents = value_contents (arg); int len = TYPE_LENGTH (type); - /* Calculate the potential last register needed. */ - last_regnum = regnum - (len + (len & 1)); + /* Calculate the potential last register needed. + E.g. For length 2, registers regnum and regnum-1 (say 25 and 24) + shall be used. So, last needed register will be regnum-1(24). */ + last_regnum = regnum - (len + (len & 1)) + 1; /* If there are registers available, use them. Once we start putting stuff on the stack, all subsequent args go on stack. */ - if ((si == NULL) && (last_regnum >= 8)) + if ((si == NULL) && (last_regnum >= AVR_LAST_ARG_REGNUM)) { - ULONGEST val; - /* Skip a register for odd length args. */ if (len & 1) regnum--; - val = extract_unsigned_integer (contents, len, byte_order); + /* Write MSB of argument into register and subsequent bytes in + decreasing register numbers. */ for (j = 0; j < len; j++) regcache_cooked_write_unsigned - (regcache, regnum--, val >> (8 * (len - j - 1))); + (regcache, regnum--, contents[len - j - 1]); } /* No registers available, push the args onto the stack. */ else |