aboutsummaryrefslogtreecommitdiff
path: root/gdb/x86-64-tdep.c
diff options
context:
space:
mode:
authorAndreas Jaeger <aj@suse.de>2003-07-02 07:45:57 +0000
committerAndreas Jaeger <aj@suse.de>2003-07-02 07:45:57 +0000
commitc1da67ba852959291ddc38782423a60472d06b43 (patch)
tree6d3bcd55b77c6e041f7dee92acada48f928a4e8a /gdb/x86-64-tdep.c
parent772119ce53adb8885567f097e4959f54c6f2322c (diff)
downloadgdb-c1da67ba852959291ddc38782423a60472d06b43.zip
gdb-c1da67ba852959291ddc38782423a60472d06b43.tar.gz
gdb-c1da67ba852959291ddc38782423a60472d06b43.tar.bz2
* x86-64-tdep.c (x86_64_push_arguments): Align stack to 16-byte
before the call. Set %rax only to number of SSE registers used.
Diffstat (limited to 'gdb/x86-64-tdep.c')
-rw-r--r--gdb/x86-64-tdep.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/gdb/x86-64-tdep.c b/gdb/x86-64-tdep.c
index 0fe2485..f4ceee86 100644
--- a/gdb/x86-64-tdep.c
+++ b/gdb/x86-64-tdep.c
@@ -597,13 +597,14 @@ x86_64_push_arguments (struct regcache *regcache, int nargs,
{
int intreg = 0;
int ssereg = 0;
- /* For varargs functions we have to pass the total number of SSE arguments
- in %rax. So, let's count this number. */
+ /* For varargs functions we have to pass the total number of SSE
+ registers used in %rax. So, let's count this number. */
int total_sse_args = 0;
/* Once an SSE/int argument is passed on the stack, all subsequent
arguments are passed there. */
int sse_stack = 0;
int int_stack = 0;
+ unsigned total_sp;
int i;
char buf[8];
static int int_parameter_registers[INT_REGS] =
@@ -644,7 +645,8 @@ x86_64_push_arguments (struct regcache *regcache, int nargs,
int_stack = 1;
if (ssereg / 2 + needed_sseregs > SSE_REGS)
sse_stack = 1;
- total_sse_args += needed_sseregs;
+ if (!sse_stack)
+ total_sse_args += needed_sseregs;
for (j = 0; j < n; j++)
{
@@ -720,13 +722,29 @@ x86_64_push_arguments (struct regcache *regcache, int nargs,
}
}
+ /* We have to make sure that the stack is 16-byte aligned after the
+ setup. Let's calculate size of arguments first, align stack and
+ then fill in the arguments. */
+ total_sp = 0;
+ for (i = 0; i < stack_values_count; i++)
+ {
+ struct value *arg = args[stack_values[i]];
+ int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg));
+ total_sp += (len + 7) & ~7;
+ }
+ /* total_sp is now a multiple of 8, if it is not a multiple of 16,
+ change the stack pointer so that it will be afterwards correctly
+ aligned. */
+ if (total_sp & 15)
+ sp -= 8;
+
/* Push any remaining arguments onto the stack. */
while (--stack_values_count >= 0)
{
struct value *arg = args[stack_values[stack_values_count]];
int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg));
- /* Make sure the stack stays eightbyte-aligned. */
+ /* Make sure the stack is 8-byte-aligned. */
sp -= (len + 7) & ~7;
write_memory (sp, VALUE_CONTENTS_ALL (arg), len);
}