aboutsummaryrefslogtreecommitdiff
path: root/gdb/amd64-windows-tdep.c
diff options
context:
space:
mode:
authorJoel Brobecker <brobecker@gnat.com>2010-01-29 05:19:23 +0000
committerJoel Brobecker <brobecker@gnat.com>2010-01-29 05:19:23 +0000
commitba581dc13b5e3ca555a49df501d5ac74287f504d (patch)
tree8264995f3071246435079ed1ef4e6118335caeff /gdb/amd64-windows-tdep.c
parenta1504221ad15cfb08f22fd5548835d33f3d041de (diff)
downloadgdb-ba581dc13b5e3ca555a49df501d5ac74287f504d.zip
gdb-ba581dc13b5e3ca555a49df501d5ac74287f504d.tar.gz
gdb-ba581dc13b5e3ca555a49df501d5ac74287f504d.tar.bz2
amd64: Integer parameters in function calls on Windows.
gdb/ChangeLog: * i386-tdep.h (enum amd64_reg_class): New, moved here from amd64-tdep.c. (struct gdbarch_tdep): Add fields call_dummy_num_integer_regs, call_dummy_integer_regs, and classify. * amd64-tdep.h (amd64_classify): Add declaration. * amd64-tdep.c (amd64_dummy_call_integer_regs): New static constant. (amd64_reg_class): Delete, moved to i386-tdep.h. (amd64_classify): Make non-static. Move declaration to amd64-tdep.h. Replace call to amd64_classify by call to tdep->classify. (amd64_push_arguments): Get the list of registers to use for passing integer parameters from the gdbarch tdep structure, rather than using a hardcoded one. Replace calls to amd64_classify by calls to tdep->classify. (amd64_push_dummy_call): Get the register number used for the "hidden" argument from tdep->call_dummy_integer_regs. (amd64_init_abi): Initialize tdep->call_dummy_num_integer_regs and tdep->call_dummy_integer_regs. Set tdep->classify. * amd64-windows-tdep.c: Add include of gdbtypes.h. (amd64_windows_dummy_call_integer_regs): New static global. (amd64_windows_classify): New function. (amd64_windows_init_abi): Initialize tdep->call_dummy_num_integer_regs tdep->call_dummy_integer_regs and tdep->classify. gdb/testsuite/ChangeLog: * gdb.ada/call_pn: New testcase.
Diffstat (limited to 'gdb/amd64-windows-tdep.c')
-rw-r--r--gdb/amd64-windows-tdep.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c
index bdad9bd..b5a0035 100644
--- a/gdb/amd64-windows-tdep.c
+++ b/gdb/amd64-windows-tdep.c
@@ -20,15 +20,70 @@
#include "amd64-tdep.h"
#include "solib.h"
#include "solib-target.h"
+#include "gdbtypes.h"
+
+/* The registers used to pass integer arguments during a function call. */
+static int amd64_windows_dummy_call_integer_regs[] =
+{
+ AMD64_RCX_REGNUM, /* %rcx */
+ AMD64_RDX_REGNUM, /* %rdx */
+ 8, /* %r8 */
+ 9 /* %r9 */
+};
+
+/* Implement the "classify" method in the gdbarch_tdep structure
+ for amd64-windows. */
+
+static void
+amd64_windows_classify (struct type *type, enum amd64_reg_class class[2])
+{
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_ARRAY:
+ /* Arrays are always passed by memory. */
+ class[0] = class[1] = AMD64_MEMORY;
+ break;
+
+ case TYPE_CODE_STRUCT:
+ case TYPE_CODE_UNION:
+ /* Struct/Union types whose size is 1, 2, 4, or 8 bytes
+ are passed as if they were integers of the same size.
+ Types of different sizes are passed by memory. */
+ if (TYPE_LENGTH (type) == 1
+ || TYPE_LENGTH (type) == 2
+ || TYPE_LENGTH (type) == 4
+ || TYPE_LENGTH (type) == 8)
+ {
+ class[0] = AMD64_INTEGER;
+ class[1] = AMD64_NO_CLASS;
+ }
+ else
+ class[0] = class[1] = AMD64_MEMORY;
+ break;
+
+ default:
+ /* For all the other types, the conventions are the same as
+ with the System V ABI. */
+ amd64_classify (type, class);
+ }
+}
static void
amd64_windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
amd64_init_abi (info, gdbarch);
/* On Windows, "long"s are only 32bit. */
set_gdbarch_long_bit (gdbarch, 32);
+ /* Function calls. */
+ tdep->call_dummy_num_integer_regs =
+ ARRAY_SIZE (amd64_windows_dummy_call_integer_regs);
+ tdep->call_dummy_integer_regs = amd64_windows_dummy_call_integer_regs;
+ tdep->classify = amd64_windows_classify;
+
set_solib_ops (gdbarch, &solib_target_so_ops);
}