* Fix push_arguments on x86-64
@ 2003-06-26 6:38 Andreas Jaeger
2003-06-26 15:09 ` Mark Kettenis
0 siblings, 1 reply; 2+ messages in thread
From: Andreas Jaeger @ 2003-06-26 6:38 UTC (permalink / raw)
To: gdb-patches
[-- 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 --]
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: Fix push_arguments on x86-64
2003-06-26 6:38 Fix push_arguments on x86-64 Andreas Jaeger
@ 2003-06-26 15:09 ` Mark Kettenis
0 siblings, 0 replies; 2+ messages in thread
From: Mark Kettenis @ 2003-06-26 15:09 UTC (permalink / raw)
To: Andreas Jaeger; +Cc: gdb-patches
Andreas Jaeger <aj@suse.de> writes:
> Ok to commit to both mainline and 6.0 branch?
>
> 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.
I believe that the whole argument classification functionality is more
complex than it needs to be based on reading the ABI, but it seems to
be an improvement and I trust you know what you're doing, so yes, this
is approved.
Mark
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2003-06-26 15:09 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-06-26 6:38 Fix push_arguments on x86-64 Andreas Jaeger
2003-06-26 15:09 ` Mark Kettenis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox