From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22385 invoked by alias); 26 Jun 2003 06:38:59 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 22333 invoked from network); 26 Jun 2003 06:38:57 -0000 Received: from unknown (HELO Cantor.suse.de) (213.95.15.193) by sources.redhat.com with SMTP; 26 Jun 2003 06:38:57 -0000 Received: from Hermes.suse.de (Hermes.suse.de [213.95.15.136]) by Cantor.suse.de (Postfix) with ESMTP id 4169E1463F for ; Thu, 26 Jun 2003 08:38:57 +0200 (MEST) Received: from aj by arthur.inka.de with local (Exim 4.12) id 19VQPG-0004VX-00 for gdb-patches@sources.redhat.com; Thu, 26 Jun 2003 08:38:54 +0200 To: gdb-patches@sources.redhat.com Subject: Fix push_arguments on x86-64 From: Andreas Jaeger Date: Thu, 26 Jun 2003 06:38:00 -0000 Message-ID: User-Agent: Gnus/5.1003 (Gnus v5.10.3) XEmacs/21.4 (Portable Code, linux) MIME-Version: 1.0 Content-Type: multipart/signed; boundary="=-=-="; micalg=pgp-sha1; protocol="application/pgp-signature" X-SW-Source: 2003-06/txt/msg00787.txt.bz2 --=-=-= Content-Transfer-Encoding: quoted-printable Content-length: 6301 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 * 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 =3D 0; int ssereg =3D 0; + /* For varargs functions we have to pass the total number of SSE argumen= ts + in %rax. So, let's count this number. */ + int total_sse_args =3D 0; + /* Once an SSE/int argument is passed on the stack, all subsequent + arguments are passed there. */ + int sse_stack =3D 0; + int int_stack =3D 0; int i; + char buf[8]; static int int_parameter_registers[INT_REGS] =3D { X86_64_RDI_REGNUM, 4, /* %rdi, %rsi */ @@ -623,9 +631,7 @@ x86_64_push_arguments (struct regcache * int needed_sseregs; =20 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++] =3D i; } @@ -633,6 +639,13 @@ x86_64_push_arguments (struct regcache * { int j; int offset =3D 0; + + if (intreg / 2 + needed_intregs > INT_REGS) + int_stack =3D 1; + if (ssereg / 2 + needed_sseregs > SSE_REGS) + sse_stack =3D 1; + total_sse_args +=3D needed_sseregs; + for (j =3D 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 +=3D 8; - intreg +=3D 2; + if (int_stack) + stack_values[stack_values_count++] =3D i; + else + { + regcache_cooked_write + (regcache, int_parameter_registers[(intreg + 1) / 2], + VALUE_CONTENTS_ALL (args[i]) + offset); + offset +=3D 8; + intreg +=3D 2; + } break; case X86_64_INTEGERSI_CLASS: - { - LONGEST val =3D extract_signed_integer - (VALUE_CONTENTS_ALL (args[i]) + offset, 4); - regcache_cooked_write_signed - (regcache, int_parameter_registers[intreg / 2], val); - - offset +=3D 8; - intreg++; - break; - } + if (int_stack) + stack_values[stack_values_count++] =3D i; + else + { + LONGEST val =3D extract_signed_integer + (VALUE_CONTENTS_ALL (args[i]) + offset, 4); + regcache_cooked_write_signed + (regcache, int_parameter_registers[intreg / 2], val); +=09=09=20=20=20=20=20=20 + offset +=3D 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 +=3D 8; - ssereg +=3D 2; + if (sse_stack) + stack_values[stack_values_count++] =3D i; + else + { + regcache_cooked_write + (regcache, sse_parameter_registers[(ssereg + 1) / 2], + VALUE_CONTENTS_ALL (args[i]) + offset); + offset +=3D 8; + ssereg +=3D 2; + } break; case X86_64_SSEUP_CLASS: - regcache_cooked_write - (regcache, sse_parameter_registers[ssereg / 2], - VALUE_CONTENTS_ALL (args[i]) + offset); - offset +=3D 8; - ssereg++; + if (sse_stack) + stack_values[stack_values_count++] =3D i; + else + { + regcache_cooked_write + (regcache, sse_parameter_registers[ssereg / 2], + VALUE_CONTENTS_ALL (args[i]) + offset); + offset +=3D 8; + ssereg++; + } break; case X86_64_X87_CLASS: case X86_64_MEMORY_CLASS: @@ -699,6 +730,11 @@ x86_64_push_arguments (struct regcache * sp -=3D (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); =20 return sp; } --=20 Andreas Jaeger, SuSE Linux AG, aj@suse.de, http://www.suse.de/~aj GPG fingerprint =3D 93A3 365E CE47 B889 DF7F FED1 389A 563C C272 A126 --=-=-= Content-Type: application/pgp-signature Content-length: 197 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.2-rc1-SuSE (GNU/Linux) iD8DBQA++pT+OJpWPMJyoSYRAu+nAJ4upFBbfmBnIL2n3yAv3VDpjs6Y+gCfcB0u yWt8w7m7WIbdXIj/shmAmSk= =sYCB -----END PGP SIGNATURE----- --=-=-=--