From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13416 invoked by alias); 24 Oct 2012 17:23:57 -0000 Received: (qmail 13348 invoked by uid 22791); 24 Oct 2012 17:23:56 -0000 X-SWARE-Spam-Status: No, hits=-3.0 required=5.0 tests=AWL,BAYES_00,KHOP_THREADED,RCVD_IN_HOSTKARMA_NO,RP_MATCHES_RCVD,TW_CP,TW_EG X-Spam-Check-By: sourceware.org Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 24 Oct 2012 17:23:49 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 2CEFA2E057; Wed, 24 Oct 2012 13:23:49 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id SBxFVx9vOPRU; Wed, 24 Oct 2012 13:23:49 -0400 (EDT) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 0E6762E021; Wed, 24 Oct 2012 13:23:49 -0400 (EDT) Received: by joel.gnat.com (Postfix, from userid 1000) id BCBB5C88A1; Wed, 24 Oct 2012 13:23:46 -0400 (EDT) From: Joel Brobecker To: gdb-patches@sourceware.org Cc: kettenis@gnu.org, Joel Brobecker Subject: [RFA 2/2] amd64-windows: Arguments passed by pointer Date: Wed, 24 Oct 2012 17:23:00 -0000 Message-Id: <1351099417-18960-3-git-send-email-brobecker@adacore.com> In-Reply-To: <1351099417-18960-1-git-send-email-brobecker@adacore.com> References: <1351099417-18960-1-git-send-email-brobecker@adacore.com> Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2012-10/txt/msg00467.txt.bz2 This patch provides support for arguments passed by pointer in inferior function calls. gdb/ChangeLog: * i386-tdep.h (struct gdbarch_tdep): Add new field "handle_args_passed_by_pointer". * amd64-tdep.c (amd64_push_arguments): Add handling of arguments to be passed by pointer. * amd64-windows-tdep.c: #include "value.h". (amd64_windows_passed_by_pointer): New function. (amd64_windows_handle_args_passed_by_pointer): New function. (amd64_windows_init_abi): Set tdep->handle_args_passed_by_pointer. Tested on amd64-windows and amd64-linux. OK to commit? Thanks, -- Joel --- gdb/amd64-tdep.c | 12 +++++++++++ gdb/amd64-windows-tdep.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++ gdb/i386-tdep.h | 14 ++++++++++++ 3 files changed, 79 insertions(+) diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index c6ee493..d464a35 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -771,6 +771,18 @@ amd64_push_arguments (struct regcache *regcache, int nargs, gdb_assert (tdep->classify); + if (tdep->handle_args_passed_by_pointer) + { + /* Make a copy of the array of arguments, and let + handle_args_passed_by_pointer transform those that need + to be passed by pointer. */ + struct value **args1 = alloca (nargs * sizeof (struct value *)); + + memcpy (args1, args, nargs * sizeof (struct value *)); + sp = tdep->handle_args_passed_by_pointer (args1, nargs, sp); + args = args1; + } + /* Reserve a register for the "hidden" argument. */ if (struct_return) integer_reg++; diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c index 3e8a830..0b616f3 100644 --- a/gdb/amd64-windows-tdep.c +++ b/gdb/amd64-windows-tdep.c @@ -25,6 +25,7 @@ #include "regcache.h" #include "windows-tdep.h" #include "frame.h" +#include "value.h" /* The registers used to pass integer arguments during a function call. */ static int amd64_windows_dummy_call_integer_regs[] = @@ -35,6 +36,56 @@ static int amd64_windows_dummy_call_integer_regs[] = 9 /* %r9 */ }; +/* Return non-zero iff an argument of the given TYPE should be passed + by pointer. */ + +static int +amd64_windows_passed_by_pointer (struct type *type) +{ + /* Only structs and unions are passed by pointer. */ + if (TYPE_CODE (type) != TYPE_CODE_STRUCT + && TYPE_CODE (type) != TYPE_CODE_UNION) + return 0; + + /* Among these, only struct/unions whose size is different from + 1, 2, 4 or 8 bytes are passed by pointer. */ + return (TYPE_LENGTH (type) != 1 + && TYPE_LENGTH (type) != 2 + && TYPE_LENGTH (type) != 4 + && TYPE_LENGTH (type) != 8); +} + +/* Implement the "handle_args_passed_by_pointer" in the gdbarch_tdep + structure for amd64-windows. */ + +static CORE_ADDR +amd64_windows_handle_args_passed_by_pointer (struct value **args, + int nargs, CORE_ADDR sp) +{ + int i; + + for (i = 0; i < nargs; i++) + if (amd64_windows_passed_by_pointer (value_type (args[i]))) + { + struct type *type = value_type (args[i]); + const gdb_byte *valbuf = value_contents (args[i]); + const int len = TYPE_LENGTH (type); + + /* Store a copy of that argument on the stack, aligned to + a 16 bytes boundary, and then use the copy's address as + the argument. */ + + sp -= len; + sp &= ~0xf; + write_memory (sp, valbuf, len); + + args[i] = + value_addr (value_from_contents_and_address (type, valbuf, sp)); + } + + return sp; +} + /* Implement the "classify" method in the gdbarch_tdep structure for amd64-windows. */ @@ -212,6 +263,8 @@ amd64_windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 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->handle_args_passed_by_pointer = + amd64_windows_handle_args_passed_by_pointer; tdep->classify = amd64_windows_classify; tdep->integer_param_regs_saved_in_caller_frame = 1; set_gdbarch_return_value (gdbarch, amd64_windows_return_value); diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h index 01b0936..ce38600 100644 --- a/gdb/i386-tdep.h +++ b/gdb/i386-tdep.h @@ -81,6 +81,20 @@ struct gdbarch_tdep int call_dummy_num_integer_regs; int *call_dummy_integer_regs; + /* Only used on platforms where some arguments are to be passed + by pointer (the caller is expected to make a copy of the argument + and then pass its address as the argument). + + For each argument that should be passed by pointer, reserve some + stack space, store a copy of the argument on the stack, and replace + the argument by its address. Return the new Stack Pointer value. + + NARGS is the number of arguments. ARGS is the array containing + the value of each argument. SP is value of the Stack Pointer. */ + + CORE_ADDR (*handle_args_passed_by_pointer) (struct value **args, + int nargs, CORE_ADDR sp); + /* Used on amd64 only. Classify TYPE according to calling conventions, and store the result in CLASS. */ void (*classify) (struct type *type, enum amd64_reg_class class[2]); -- 1.7.9.5