From: Joel Brobecker Date: Fri, 29 Jan 2010 05:29:21 +0000 (+0000) Subject: Implement return values on amd64-windows. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=cba6fab54a80261d8f1e6831bc5c560481cfc107;p=binutils-gdb.git Implement return values on amd64-windows. * amd64-windows-tdep.c: #include gdbcore.h and regcache.h. (amd64_windows_return_value): New function. (amd64_windows_init_abi): Call set_gdbarch_return_value with amd64_windows_return_value. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e8577283f41..da9d6f2cb5f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,7 +1,15 @@ +2010-01-29 Joel Brobecker + + Implement return values on amd64-windows. + * amd64-windows-tdep.c: #include gdbcore.h and regcache.h. + (amd64_windows_return_value): New function. + (amd64_windows_init_abi): Call set_gdbarch_return_value with + amd64_windows_return_value. + 2010-01-29 Joel Brobecker amd64-windows: 32 bytes allocated on stack by caller for integer - parameter registers + parameter registers. * i386-tdep.h (struct gdbarch_tdep): Add new field integer_param_regs_saved_in_caller_frame. * amd64-windows-tdep.c (amd64_windows_init_abi): Set diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c index 05c4c1edfc0..05d082458c7 100644 --- a/gdb/amd64-windows-tdep.c +++ b/gdb/amd64-windows-tdep.c @@ -21,6 +21,8 @@ #include "solib.h" #include "solib-target.h" #include "gdbtypes.h" +#include "gdbcore.h" +#include "regcache.h" /* The registers used to pass integer arguments during a function call. */ static int amd64_windows_dummy_call_integer_regs[] = @@ -68,6 +70,58 @@ amd64_windows_classify (struct type *type, enum amd64_reg_class class[2]) } } +/* Implement the "return_value" gdbarch method for amd64-windows. */ + +static enum return_value_convention +amd64_windows_return_value (struct gdbarch *gdbarch, struct type *func_type, + struct type *type, struct regcache *regcache, + gdb_byte *readbuf, const gdb_byte *writebuf) +{ + int len = TYPE_LENGTH (type); + int regnum = -1; + + /* See if our value is returned through a register. If it is, then + store the associated register number in REGNUM. */ + switch (TYPE_CODE (type)) + { + case TYPE_CODE_FLT: + case TYPE_CODE_DECFLOAT: + /* __m128, __m128i, __m128d, floats, and doubles are returned + via XMM0. */ + if (len == 4 || len == 8 || len == 16) + regnum = AMD64_XMM0_REGNUM; + break; + default: + /* All other values that are 1, 2, 4 or 8 bytes long are returned + via RAX. */ + if (len == 1 || len == 2 || len == 4 || len == 8) + regnum = AMD64_RAX_REGNUM; + break; + } + + if (regnum < 0) + { + /* RAX contains the address where the return value has been stored. */ + if (readbuf) + { + ULONGEST addr; + + regcache_raw_read_unsigned (regcache, AMD64_RAX_REGNUM, &addr); + read_memory (addr, readbuf, TYPE_LENGTH (type)); + } + return RETURN_VALUE_ABI_RETURNS_ADDRESS; + } + else + { + /* Extract the return value from the register where it was stored. */ + if (readbuf) + regcache_raw_read_part (regcache, regnum, 0, len, readbuf); + if (writebuf) + regcache_raw_write_part (regcache, regnum, 0, len, writebuf); + return RETURN_VALUE_REGISTER_CONVENTION; + } +} + static void amd64_windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { @@ -85,6 +139,7 @@ amd64_windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) tdep->classify = amd64_windows_classify; tdep->memory_args_by_pointer = 1; tdep->integer_param_regs_saved_in_caller_frame = 1; + set_gdbarch_return_value (gdbarch, amd64_windows_return_value); set_solib_ops (gdbarch, &solib_target_so_ops); }