This is the mail archive of the gdb-patches@sourceware.org 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]

Re: [patch] Can't build ppc32 GDB


Sorry if this is a dup, I seem to be having mailer problems...

On Tue, 2006-04-25 at 21:38 +0200, Mark Kettenis wrote:
> > From: PAUL GILLIAM <pgilliam@us.ibm.com>
> > Date: Mon, 24 Apr 2006 17:23:13 -0700
> > 
> > Darn!  I forgot to 'trim' the patch'.
> > 
> > I have attached the 'trimmed' version.
> 
> Get rid of the PTRACE_XFER_TYPE and PTRACE_ARG3_TYPE.  Replace them
> with PTRACE_TYPE_RET and PTRACE_TYPE_ARG3.  Or better yet, if the
> prototype for ptrace(2) is consistent for all powerpc Linux variants,
> simply replace them with the proper type (which is probably "long").
> 
> Oh and while you're there, get rid of PT_READ_U/PT_WRITE_U in favour
> of PTRACE_PEEKUSR/PTRACE_POKEUSR.
> 
> Mark
> 
Changeing the PTRACE_... stuff had kind of a wrinkle (see below) 
but the big problem is with this line in ppc_linux_nat.c:

  last_stopped_data_address = (CORE_ADDR) siginfo.si_addr;

in subroutine ppc_linux_stopped_by_watchpoint()

A 'CORE_ADDR' is a 'bfd_vma' and on ppc64 systems, a 'bfd_vma' is an
'unsigned long long'.  If gdb is built on such a system with CC='gcc
-m64', an 'unsigned long long' is 64 bits as are an 'unsigned long' and
a 'void *'.  No problem.

But if CC is just 'gcc', then an 'unsigned long long' is still 64 bits,
but an 'unsigned long' and a 'void *' are 32 bits.

Changing the line to:
  last_stopped_data_address = (CORE_ADDR) (unsigned long)
siginfo.si_addr;

Fixes the problem because the extra cast does nothing when CC='gcc -m64'
but when CC='gcc', siginfo.si_addr is cast from a 'void *' to an integer
of the same size, which is then cast to an integer of a larger size,
avoiding the warning.

I have attached the new patch, OK to commit?

-=# Paul #=-

PS:

Here is the wrinkle

On a ppc64 system:

This is from /usr/include/sys/ptrace.h:
extern long int ptrace (enum __ptrace_request __request, ...) __THROW;

So I think PTRACE_TYPE_RET should default to 'long' in ppc_linux_nat.c

Also from /usr/include/sys/ptrace.h:
enum __ptrace_request
{
...
  /* Return the word in the process's user area at offset ADDR.  */
  PTRACE_PEEKUSER = 3,
#define PT_READ_U PTRACE_PEEKUSER
...
  /* Write the word DATA into the process's user area at offset ADDR.
*/
  PTRACE_POKEUSER = 6,
#define PT_WRITE_U PTRACE_POKEUSER
...

Even though the man pages says PTRACE_PEEKUSR and PTRACE_POKEUSR





2006-04-26:  Paul Gilliam  <pgilliam@us.ibm.com>

	* ppc-linux-nat.c: Clean up types for ptrace.
	Insert an 'extra' cast to account for the size difference between
	a CORE_ADDR and a void* on ppc64 systems compiled for 32-bits.

Index: ppc-linux-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-linux-nat.c,v
retrieving revision 1.60
diff -a -u -r1.60 ppc-linux-nat.c
--- ppc-linux-nat.c	24 Mar 2006 23:08:16 -0000	1.60
+++ ppc-linux-nat.c	27 Apr 2006 01:35:37 -0000
@@ -44,16 +44,16 @@
 #include "gregset.h"
 #include "ppc-tdep.h"
 
-#ifndef PT_READ_U
-#define PT_READ_U PTRACE_PEEKUSR
+#ifndef PTRACE_PEEKUSR
+#define PTRACE_PEEKUSR PTRACE_PEEKUSER
 #endif
-#ifndef PT_WRITE_U
-#define PT_WRITE_U PTRACE_POKEUSR
+#ifndef PTRACE_POKEUSR
+#define PTRACE_POKEUSR PTRACE_POKEUSER
 #endif
 
-/* Default the type of the ptrace transfer to int.  */
-#ifndef PTRACE_XFER_TYPE
-#define PTRACE_XFER_TYPE int
+/* Default the type of the ptrace transfer to long.  */
+#ifndef PTRACE_TYPE_RET
+#define PTRACE_TYPE_RET long
 #endif
 
 /* Glibc's headers don't define PTRACE_GETVRREGS so we cannot use a
@@ -190,7 +190,7 @@
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
   /* NOTE: cagney/2003-11-25: This is the word size used by the ptrace
      interface, and not the wordsize of the program's ABI.  */
-  int wordsize = sizeof (PTRACE_XFER_TYPE);
+  int wordsize = sizeof (PTRACE_TYPE_RET);
 
   /* General purpose registers occupy 1 slot each in the buffer */
   if (regno >= tdep->ppc_gp0_regnum 
@@ -384,17 +384,17 @@
       return;
     }
 
-  /* Read the raw register using PTRACE_XFER_TYPE sized chunks.  On a
+  /* Read the raw register using PTRACE_TYPE_RET sized chunks.  On a
      32-bit platform, 64-bit floating-point registers will require two
      transfers.  */
   for (bytes_transferred = 0;
        bytes_transferred < register_size (current_gdbarch, regno);
-       bytes_transferred += sizeof (PTRACE_XFER_TYPE))
+       bytes_transferred += sizeof (PTRACE_TYPE_RET))
     {
       errno = 0;
-      *(PTRACE_XFER_TYPE *) & buf[bytes_transferred]
-        = ptrace (PT_READ_U, tid, (PTRACE_ARG3_TYPE) regaddr, 0);
-      regaddr += sizeof (PTRACE_XFER_TYPE);
+      *(PTRACE_TYPE_RET *) & buf[bytes_transferred]
+        = ptrace (PTRACE_PEEKUSR, tid, (PTRACE_TYPE_ARG3) regaddr, 0);
+      regaddr += sizeof (PTRACE_TYPE_RET);
       if (errno != 0)
 	{
           char message[128];
@@ -406,7 +406,7 @@
 
   /* Now supply the register.  Keep in mind that the regcache's idea
      of the register's size may not be a multiple of sizeof
-     (PTRACE_XFER_TYPE).  */
+     (PTRACE_TYPE_RET).  */
   if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_LITTLE)
     {
       /* Little-endian values are always found at the left end of the
@@ -668,10 +668,10 @@
 
   /* First collect the register.  Keep in mind that the regcache's
      idea of the register's size may not be a multiple of sizeof
-     (PTRACE_XFER_TYPE).  */
+     (PTRACE_TYPE_RET).  */
   memset (buf, 0, sizeof buf);
   bytes_to_transfer = align_up (register_size (current_gdbarch, regno),
-                                sizeof (PTRACE_XFER_TYPE));
+                                sizeof (PTRACE_TYPE_RET));
   if (TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
     {
       /* Little-endian values always sit at the left end of the buffer.  */
@@ -685,12 +685,12 @@
       regcache_raw_collect (current_regcache, regno, buf + padding);
     }
 
-  for (i = 0; i < bytes_to_transfer; i += sizeof (PTRACE_XFER_TYPE))
+  for (i = 0; i < bytes_to_transfer; i += sizeof (PTRACE_TYPE_RET))
     {
       errno = 0;
-      ptrace (PT_WRITE_U, tid, (PTRACE_ARG3_TYPE) regaddr,
-	      *(PTRACE_XFER_TYPE *) & buf[i]);
-      regaddr += sizeof (PTRACE_XFER_TYPE);
+      ptrace (PTRACE_POKEUSR, tid, (PTRACE_TYPE_ARG3) regaddr,
+	      *(PTRACE_TYPE_RET *) & buf[i]);
+      regaddr += sizeof (PTRACE_TYPE_RET);
 
       if (errno == EIO 
           && regno == tdep->ppc_fpscr_regnum)
@@ -901,7 +901,7 @@
       (siginfo.si_code & 0xffff) != 0x0004)
     return 0;
 
-  last_stopped_data_address = (CORE_ADDR) siginfo.si_addr;
+  last_stopped_data_address = (CORE_ADDR) (unsigned long) siginfo.si_addr;
   return 1;
 }
 
@@ -926,7 +926,7 @@
 {
   /* NOTE: cagney/2003-11-25: This is the word size used by the ptrace
      interface, and not the wordsize of the program's ABI.  */
-  int wordsize = sizeof (PTRACE_XFER_TYPE);
+  int wordsize = sizeof (PTRACE_TYPE_RET);
   ppc_linux_supply_gregset (current_regcache, -1, gregsetp,
 			    sizeof (gdb_gregset_t), wordsize);
 }
@@ -936,7 +936,7 @@
 {
   /* NOTE: cagney/2003-11-25: This is the word size used by the ptrace
      interface, and not the wordsize of the program's ABI.  */
-  int wordsize = sizeof (PTRACE_XFER_TYPE);
+  int wordsize = sizeof (PTRACE_TYPE_RET);
   /* Right fill the register.  */
   regcache_raw_collect (current_regcache, regnum,
 			((bfd_byte *) reg

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