From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29577 invoked by alias); 25 Jan 2010 05:42:48 -0000 Received: (qmail 29303 invoked by uid 22791); 25 Jan 2010 05:42:47 -0000 X-SWARE-Spam-Status: No, hits=-2.4 required=5.0 tests=AWL,BAYES_00,SPF_PASS 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; Mon, 25 Jan 2010 05:42:35 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 3DCD92BAB79 for ; Mon, 25 Jan 2010 00:42:34 -0500 (EST) 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 hH00Y54aEUF3 for ; Mon, 25 Jan 2010 00:42:34 -0500 (EST) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 540832BAB7A for ; Mon, 25 Jan 2010 00:42:33 -0500 (EST) Received: by joel.gnat.com (Postfix, from userid 1000) id 6349CF598D; Mon, 25 Jan 2010 09:42:18 +0400 (RET) From: Joel Brobecker To: gdb-patches@sourceware.org Subject: [RFA/commit 3/3] amd64: 32 bytes allocated on stack by caller for integer parameter registers. Date: Mon, 25 Jan 2010 05:42:00 -0000 Message-Id: <1264398132-1429-4-git-send-email-brobecker@adacore.com> In-Reply-To: <1264398132-1429-1-git-send-email-brobecker@adacore.com> References: <1264398132-1429-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: 2010-01/txt/msg00561.txt.bz2 From: brobecke Yet another difference between Linux and Windows in the calling convention. When calling a function, the caller is responsible for allocating a 32byte memory region in the caller's frame; the callee can use this region to spill the 4 registers used for INTEGER parameter passing. It showed up when trying to call a function that takes a string as a parameter, but could probably show up anywhere the INTEGER registers are being used. This depends on the actual implementation of the function being called. In all likeliness, the larger the function, the more chances the registers used for parameter passing are going to be needed, and thus need to be spilled on stack. This patch enhances amd64_push_dummy_call allowing it to also allocated this spaces on the stack if the ABI mandates it. Whether it is required or not is determined by the value of a new tdep field: integer_param_regs_saved_in_caller_frame. The default value is zero, and amd64-windows-tdep.c sets it to 1. gdb/ChangeLog: * 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 tdep->integer_param_regs_saved_in_caller_frame to 1. * amd64-tdep.c (amd64_push_dummy_call): Allocate some memory on stack if tdep->integer_param_regs_saved_in_caller_frame is set. I can submit the exact testcase that allowed us to spot this problem. But I think that gdb.ada/arrayparam.exp already covers this issue. -- Joel --- gdb/amd64-tdep.c | 6 ++++++ gdb/amd64-windows-tdep.c | 1 + gdb/i386-tdep.h | 18 ++++++++++++++---- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index e9e0809..2b15141 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -731,6 +731,7 @@ amd64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, int struct_return, CORE_ADDR struct_addr) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); gdb_byte buf[8]; /* Pass arguments. */ @@ -748,6 +749,11 @@ amd64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, regcache_cooked_write (regcache, arg_regnum, buf); } + /* Reserve some memory on the stack for the integer-parameter registers, + if required by the ABI. */ + if (tdep->integer_param_regs_saved_in_caller_frame) + sp -= tdep->call_dummy_num_integer_regs * 8; + /* Store return address. */ sp -= 8; store_unsigned_integer (buf, 8, byte_order, bp_addr); diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c index 0ed9368..05c4c1e 100644 --- a/gdb/amd64-windows-tdep.c +++ b/gdb/amd64-windows-tdep.c @@ -84,6 +84,7 @@ amd64_windows_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) tdep->call_dummy_integer_regs = amd64_windows_dummy_call_integer_regs; tdep->classify = amd64_windows_classify; tdep->memory_args_by_pointer = 1; + tdep->integer_param_regs_saved_in_caller_frame = 1; set_solib_ops (gdbarch, &solib_target_so_ops); } diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h index f79a15d..5915eb9 100644 --- a/gdb/i386-tdep.h +++ b/gdb/i386-tdep.h @@ -82,12 +82,12 @@ struct gdbarch_tdep int call_dummy_num_integer_regs; int *call_dummy_integer_regs; - /* Classify TYPE according to calling conventions, and store - the result in CLASS. Used on amd64 only. */ + /* 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]); - /* Non-zero if the first few MEMORY arguments should be passed by - pointer. + /* Used on amd64 only. Non-zero if the first few MEMORY arguments + should be passed by pointer. More precisely, MEMORY arguments are passed through the stack. But certain architectures require that their address be passed @@ -95,6 +95,16 @@ struct gdbarch_tdep available for argument passing. */ int memory_args_by_pointer; + /* Used on amd64 only. + + If non-zero, then the callers of a function are expected to reserve + some space in the stack just before the area where the PC is saved + so that the callee may save the integer-parameter registers there. + The amount of space is dependent on the list of registers used for + integer parameter passing (see component call_dummy_num_integer_regs + above). */ + int integer_param_regs_saved_in_caller_frame; + /* Floating-point registers. */ struct regset *fpregset; size_t sizeof_fpregset; -- 1.6.3.3