Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
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 --]

             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