From: Andreas Jaeger <aj@suse.de>
To: gdb-patches@sources.redhat.com
Subject: Fix push_arguments on x86-64
Date: Thu, 26 Jun 2003 06:38:00 -0000 [thread overview]
Message-ID: <u8y8zpcphe.fsf@gromit.moeb> (raw)
[-- Attachment #1: Type: text/plain, Size: 6264 bytes --]
I've looked into fixing this failure:
FAIL: gdb.base/varargs.exp: print find_max_double(5,1.0,17.0,2.0,3.0,4.0)
I did a code inspection of x86_64_push_arguments and noted a number of
problems in the way we handle arguments and fixed them with the
appended patch. I'm now setting %rax always to the number of SSE
registers. This is only needed for functions taking variable argument
lists but does not hurt in other cases, so it's a safe thing to do.
I was surprised to see that these testcase now do not fail anymore:
FAIL: gdb.base/interrupt.exp: call function when asleep (stays asleep)
FAIL: gdb.base/interrupt.exp: call function after waking it
FAIL: gdb.base/interrupt.exp: continue
FAIL: gdb.base/interrupt.exp: send end of file
FAIL: gdb.base/signals.exp: p func1 () #1 in signals.exp
FAIL: gdb.gdb/complaints.exp: serial start
FAIL: gdb.gdb/complaints.exp: short start
With this patch and the previous one for returning/float double, the
testsuite is down to:
# of expected passes 8971
# of unexpected failures 86
# of unexpected successes 4
# of expected failures 46
# of known failures 23
# of unresolved testcases 3
# of untested testcases 6
# of unsupported tests 1
/usr/src/aj/build/gdb/gdb/testsuite/../../gdb/gdb version 2003-06-26-cvs -nx
(from 93-96 unexpected failures depending whether
gdb.threads/linux-dp.exp failed or not)
Ok to commit to both mainline and 6.0 branch?
Andreas
2003-06-26 Andreas Jaeger <aj@suse.de>
* x86-64-tdep.c (x86_64_push_arguments): Always set %rax to number
of SSE registers so that varargs functions work.
Rework handling of passing arguments on the stack.
Index: x86-64-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/x86-64-tdep.c,v
retrieving revision 1.79
diff -u -p -r1.79 x86-64-tdep.c
--- x86-64-tdep.c 15 Jun 2003 11:01:46 -0000 1.79
+++ x86-64-tdep.c 26 Jun 2003 06:21:39 -0000
@@ -597,7 +597,15 @@ x86_64_push_arguments (struct regcache *
{
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. */
+ 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;
int i;
+ char buf[8];
static int int_parameter_registers[INT_REGS] =
{
X86_64_RDI_REGNUM, 4, /* %rdi, %rsi */
@@ -623,9 +631,7 @@ x86_64_push_arguments (struct regcache *
int needed_sseregs;
if (!n ||
- !examine_argument (class, n, &needed_intregs, &needed_sseregs)
- || intreg / 2 + needed_intregs > INT_REGS
- || ssereg / 2 + needed_sseregs > SSE_REGS)
+ !examine_argument (class, n, &needed_intregs, &needed_sseregs))
{ /* memory class */
stack_values[stack_values_count++] = i;
}
@@ -633,6 +639,13 @@ x86_64_push_arguments (struct regcache *
{
int j;
int offset = 0;
+
+ if (intreg / 2 + needed_intregs > INT_REGS)
+ int_stack = 1;
+ if (ssereg / 2 + needed_sseregs > SSE_REGS)
+ sse_stack = 1;
+ total_sse_args += needed_sseregs;
+
for (j = 0; j < n; j++)
{
switch (class[j])
@@ -640,38 +653,56 @@ x86_64_push_arguments (struct regcache *
case X86_64_NO_CLASS:
break;
case X86_64_INTEGER_CLASS:
- regcache_cooked_write
- (regcache, int_parameter_registers[(intreg + 1) / 2],
- VALUE_CONTENTS_ALL (args[i]) + offset);
- offset += 8;
- intreg += 2;
+ if (int_stack)
+ stack_values[stack_values_count++] = i;
+ else
+ {
+ regcache_cooked_write
+ (regcache, int_parameter_registers[(intreg + 1) / 2],
+ VALUE_CONTENTS_ALL (args[i]) + offset);
+ offset += 8;
+ intreg += 2;
+ }
break;
case X86_64_INTEGERSI_CLASS:
- {
- LONGEST val = extract_signed_integer
- (VALUE_CONTENTS_ALL (args[i]) + offset, 4);
- regcache_cooked_write_signed
- (regcache, int_parameter_registers[intreg / 2], val);
-
- offset += 8;
- intreg++;
- break;
- }
+ if (int_stack)
+ stack_values[stack_values_count++] = i;
+ else
+ {
+ LONGEST val = extract_signed_integer
+ (VALUE_CONTENTS_ALL (args[i]) + offset, 4);
+ regcache_cooked_write_signed
+ (regcache, int_parameter_registers[intreg / 2], val);
+
+ offset += 8;
+ intreg++;
+ }
+ break;
case X86_64_SSEDF_CLASS:
case X86_64_SSESF_CLASS:
case X86_64_SSE_CLASS:
- regcache_cooked_write
- (regcache, sse_parameter_registers[(ssereg + 1) / 2],
- VALUE_CONTENTS_ALL (args[i]) + offset);
- offset += 8;
- ssereg += 2;
+ if (sse_stack)
+ stack_values[stack_values_count++] = i;
+ else
+ {
+ regcache_cooked_write
+ (regcache, sse_parameter_registers[(ssereg + 1) / 2],
+ VALUE_CONTENTS_ALL (args[i]) + offset);
+ offset += 8;
+ ssereg += 2;
+ }
break;
case X86_64_SSEUP_CLASS:
- regcache_cooked_write
- (regcache, sse_parameter_registers[ssereg / 2],
- VALUE_CONTENTS_ALL (args[i]) + offset);
- offset += 8;
- ssereg++;
+ if (sse_stack)
+ stack_values[stack_values_count++] = i;
+ else
+ {
+ regcache_cooked_write
+ (regcache, sse_parameter_registers[ssereg / 2],
+ VALUE_CONTENTS_ALL (args[i]) + offset);
+ offset += 8;
+ ssereg++;
+ }
break;
case X86_64_X87_CLASS:
case X86_64_MEMORY_CLASS:
@@ -699,6 +730,11 @@ x86_64_push_arguments (struct regcache *
sp -= (len + 7) & ~7;
write_memory (sp, VALUE_CONTENTS_ALL (arg), len);
}
+
+ /* Write number of SSE type arguments to RAX to take care of varargs
+ functions. */
+ store_unsigned_integer (buf, 8, total_sse_args);
+ regcache_cooked_write (regcache, X86_64_RAX_REGNUM, buf);
return sp;
}
--
Andreas Jaeger, SuSE Linux AG, aj@suse.de, http://www.suse.de/~aj
GPG fingerprint = 93A3 365E CE47 B889 DF7F FED1 389A 563C C272 A126
[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]
next reply other threads:[~2003-06-26 6:38 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-06-26 6:38 Andreas Jaeger [this message]
2003-06-26 15:09 ` Mark Kettenis
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=u8y8zpcphe.fsf@gromit.moeb \
--to=aj@suse.de \
--cc=gdb-patches@sources.redhat.com \
/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