This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA] Fix ppc_sysv_abi_broken_return_value


I noticed a few failures on NetBSD 2.0 that were similar to those I
see on OpenBSD 3.7.  Both use GCC 3.3.x.  I noticed a pattern, and
came up with the attached fix for OpenBSD.  The same fix works for
NetBSD if I make it use ppc_sysv_abi_broken_return_value.  Now it
seems that the brokenness changes with every GCC release, but I think
nevertheless that we should make the change below.  There are a couple
of reasons:

1. I somehow doubt that the old code was completely correct.  It
   doesn't really make sense, and perhaps predates the additional
   checks that Andrew added some time ago which made me find what was
   really going on.

2. The new code is quite a bit simpler.

3. This makes things work on the most up-to-date release of OpenBSD
   and NetBSD.

Of course the last reason is the most important one.

OK?

Mark

Index: ChangeLog
from  Mark Kettenis  <kettenis@gnu.org>

	* ppc-sysv-tdep.c (do_ppc_sysv_return_value): Fix the code that
	deals with the broken GCC convention.

2005-06-19  Mark Kettenis  <kettenis@gnu.org>

Index: ppc-sysv-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-sysv-tdep.c,v
retrieving revision 1.29
diff -u -p -r1.29 ppc-sysv-tdep.c
--- ppc-sysv-tdep.c 25 May 2005 03:12:13 -0000 1.29
+++ ppc-sysv-tdep.c 19 Jun 2005 20:50:44 -0000
@@ -433,52 +451,33 @@ do_ppc_sysv_return_value (struct gdbarch
     }
   if (broken_gcc && TYPE_LENGTH (type) <= 8)
     {
+      /* GCC screwed up for structures or unions whose size is less
+	 than or equal to 8 bytes..  Instead of left-aligning, it
+	 right-aligns the data into the buffer formed by r3, r4.  */
+      gdb_byte regvals[MAX_REGISTER_SIZE * 2];
+      int len = TYPE_LENGTH (type);
+      int offset = (2 * tdep->wordsize - len) % tdep->wordsize;
+
       if (readbuf)
 	{
-	  /* GCC screwed up.  The last register isn't "left" aligned.
-	     Need to extract the least significant part of each
-	     register and then store that.  */
-	  /* Transfer any full words.  */
-	  int word = 0;
-	  while (1)
-	    {
-	      ULONGEST reg;
-	      int len = TYPE_LENGTH (type) - word * tdep->wordsize;
-	      if (len <= 0)
-		break;
-	      if (len > tdep->wordsize)
-		len = tdep->wordsize;
-	      regcache_cooked_read_unsigned (regcache,
-					     tdep->ppc_gp0_regnum + 3 + word,
-					     &reg);
-	      store_unsigned_integer (((bfd_byte *) readbuf
-				       + word * tdep->wordsize), len, reg);
-	      word++;
-	    }
+	  regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3,
+				regvals + 0 * tdep->wordsize);
+	  if (len > tdep->wordsize)
+	    regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 4,
+				  regvals + 1 * tdep->wordsize);
+	  memcpy (readbuf, regvals + offset, len);
 	}
       if (writebuf)
 	{
-	  /* GCC screwed up.  The last register isn't "left" aligned.
-	     Need to extract the least significant part of each
-	     register and then store that.  */
-	  /* Transfer any full words.  */
-	  int word = 0;
-	  while (1)
-	    {
-	      ULONGEST reg;
-	      int len = TYPE_LENGTH (type) - word * tdep->wordsize;
-	      if (len <= 0)
-		break;
-	      if (len > tdep->wordsize)
-		len = tdep->wordsize;
-	      reg = extract_unsigned_integer (((const bfd_byte *) writebuf
-					       + word * tdep->wordsize), len);
-	      regcache_cooked_write_unsigned (regcache,
-					      tdep->ppc_gp0_regnum + 3 + word,
-					      reg);
-	      word++;
-	    }
+	  memset (regvals, 0, sizeof regvals);
+	  memcpy (regvals + offset, writebuf, len);
+	  regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3,
+				 regvals + 0 * tdep->wordsize);
+	  if (len > tdep->wordsize)
+	    regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 4,
+				   regvals + 1 * tdep->wordsize);
 	}
+
       return RETURN_VALUE_REGISTER_CONVENTION;
     }
   if (TYPE_LENGTH (type) <= 8)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]