From cb86f3880e61c79e59b9225e79c3544a1fcd8005 Mon Sep 17 00:00:00 2001 From: Denis Chertykov Date: Sat, 5 Mar 2016 15:17:15 +0300 Subject: [PATCH] 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. --- gdb/ChangeLog | 7 +++++++ gdb/avr-tdep.c | 16 +++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 7f37014a950..b84326c243d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2016-03-05 Pitchumani Sivanupandi + + * 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. + 2016-03-04 Yao Qi * arm-tdep.c (arm_record_vdata_transfer_insn): Simplify the diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c index 597cfb411e6..088fe51b4c0 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 -- 2.30.2