Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Joel Brobecker <brobecker@adacore.com>
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	[thread overview]
Message-ID: <1264398132-1429-4-git-send-email-brobecker@adacore.com> (raw)
In-Reply-To: <1264398132-1429-1-git-send-email-brobecker@adacore.com>

From: brobecke <brobecke@f8352e7e-cb20-0410-8ce7-b5d9e71c585c>

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


  parent reply	other threads:[~2010-01-25  5:42 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-01-25  5:42 [amd64-windows] Fix function calls on amd64-windows Joel Brobecker
2010-01-25  5:42 ` [RFA/commit 2/3] amd64-windows: memory args passed by pointer during function calls Joel Brobecker
2010-01-25  5:42 ` [RFA/commit 1/3] amd64: Integer parameters in function calls on Windows Joel Brobecker
2010-01-25  5:42 ` Joel Brobecker [this message]
2010-01-25 18:28 ` [amd64-windows] Fix function calls on amd64-windows Christopher Faylor
2010-01-29  5:32   ` Joel Brobecker
2010-01-30 19:26 ` Mark Kettenis
2010-01-31  5:35   ` Joel Brobecker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1264398132-1429-4-git-send-email-brobecker@adacore.com \
    --to=brobecker@adacore.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox