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]

[PATCH] More infptrace.c cleanup


This cleans up the code that fetches and stores registers from/into
the user-area using the PT_READ_U and PT_WRITE_U ptrace(2) requests.

Tested on alphaev6-unknown-linux-gnu and ia64-unknown-linux-gnu.

Committed,

Mark


Index: ChangeLog
from  Mark Kettenis  <kettenis@gnu.org>
 
	* infptrace.c: Include "gdb_assert.h".
	(PTRACE_XFER_TYPE): Remove define.
	(offsetof): Only define if U_REGS_OFFSET isn't defined.
	(fetch_register, store_register): Rewrite to use PTRACE_TYPE_RET.
	Tweak comment.
	(fetch_inferior_registers, store_inferior_registers): Remove
	redundant culry braces.  Tweak comment.  s/regno/regnum.
	* Makefile.in (infptrace.o): Update dependencies.

Index: infptrace.c
===================================================================
RCS file: /cvs/src/src/gdb/infptrace.c,v
retrieving revision 1.41
diff -u -p -r1.41 infptrace.c
--- infptrace.c 21 Aug 2004 08:56:38 -0000 1.41
+++ infptrace.c 22 Aug 2004 15:31:18 -0000
@@ -53,6 +53,8 @@
 #include "gdb_stat.h"
 #endif
 
+#include "gdb_assert.h"
+
 #if !defined (FETCH_INFERIOR_REGISTERS)
 #include <sys/user.h>		/* Probably need to poke the user structure */
 #endif /* !FETCH_INFERIOR_REGISTERS */
@@ -269,153 +271,130 @@ detach (int signal)
 #endif
 }
 
-/* Default the type of the ptrace transfer to int.  */
-#ifndef PTRACE_XFER_TYPE
-#define PTRACE_XFER_TYPE int
-#endif
 
-#if !defined (FETCH_INFERIOR_REGISTERS)
+#ifndef FETCH_INFERIOR_REGISTERS
 
-#if !defined (offsetof)
+/* U_REGS_OFFSET is the offset of the registers within the u area.  */
+#ifndef U_REGS_OFFSET
+
+#ifndef offsetof
 #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
 #endif
 
-/* U_REGS_OFFSET is the offset of the registers within the u area.  */
-#if !defined (U_REGS_OFFSET)
 #define U_REGS_OFFSET \
   ptrace (PT_READ_U, PIDGET (inferior_ptid), \
 	  (PTRACE_TYPE_ARG3) (offsetof (struct user, u_ar0)), 0) \
     - KERNEL_U_ADDR
 #endif
 
-/* Fetch one register.  */
+/* Fetch register REGNUM from the inferior.  */
 
 static void
-fetch_register (int regno)
+fetch_register (int regnum)
 {
-  /* This isn't really an address.  But ptrace thinks of it as one.  */
-  CORE_ADDR regaddr;
-  char mess[128];		/* For messages */
-  int i;
-  unsigned int offset;		/* Offset of registers within the u area.  */
-  char buf[MAX_REGISTER_SIZE];
-  int tid;
+  CORE_ADDR addr;
+  size_t size;
+  PTRACE_TYPE_RET *buf;
+  int tid, i;
 
-  if (CANNOT_FETCH_REGISTER (regno))
+  if (CANNOT_FETCH_REGISTER (regnum))
     {
-      regcache_raw_supply (current_regcache, regno, NULL);
+      regcache_raw_supply (current_regcache, regnum, NULL);
       return;
     }
 
-  /* Overload thread id onto process id */
-  if ((tid = TIDGET (inferior_ptid)) == 0)
-    tid = PIDGET (inferior_ptid);	/* no thread id, just use process id */
+  /* GNU/Linux LWP ID's are process ID's.  */
+  tid = TIDGET (inferior_ptid);
+  if (tid == 0)
+    tid = PIDGET (inferior_ptid); /* Not a threaded program.  */
+
+  /* This isn't really an address.  But ptrace thinks of it as one.  */
+  addr = register_addr (regnum, U_REGS_OFFSET);
+  size = register_size (current_gdbarch, regnum);
 
-  offset = U_REGS_OFFSET;
+  gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0);
+  buf = alloca (size);
 
-  regaddr = register_addr (regno, offset);
-  for (i = 0; i < register_size (current_gdbarch, regno); i += sizeof (PTRACE_XFER_TYPE))
+  /* Read the register contents from the inferior a chuck at the time.  */
+  for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
     {
       errno = 0;
-      *(PTRACE_XFER_TYPE *) & buf[i] = ptrace (PT_READ_U, tid,
-					       (PTRACE_TYPE_ARG3) regaddr, 0);
-      regaddr += sizeof (PTRACE_XFER_TYPE);
+      buf[i] = ptrace (PT_READ_U, tid, (PTRACE_TYPE_ARG3) addr, 0);
       if (errno != 0)
-	{
-	  sprintf (mess, "reading register %s (#%d)", 
-		   REGISTER_NAME (regno), regno);
-	  perror_with_name (mess);
-	}
+	error ("Couldn't read register %s (#%d): %s.", REGISTER_NAME (regnum),
+	       regnum, safe_strerror (errno));
+
+      addr += sizeof (PTRACE_TYPE_RET);
     }
-  regcache_raw_supply (current_regcache, regno, buf);
+  regcache_raw_supply (current_regcache, regnum, buf);
 }
 
-
-/* Fetch register values from the inferior.
-   If REGNO is negative, do this for all registers.
-   Otherwise, REGNO specifies which register (so we can save time). */
+/* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
+   for all registers.  */
 
 void
-fetch_inferior_registers (int regno)
+fetch_inferior_registers (int regnum)
 {
-  if (regno >= 0)
-    {
-      fetch_register (regno);
-    }
+  if (regnum == -1)
+    for (regnum = 0; regnum < NUM_REGS; regnum++)
+      fetch_register (regnum);
   else
-    {
-      for (regno = 0; regno < NUM_REGS; regno++)
-	{
-	  fetch_register (regno);
-	}
-    }
+    fetch_register (regnum);
 }
 
-/* Store one register. */
+/* Store register REGNUM into the inferior.  */
 
 static void
-store_register (int regno)
+store_register (int regnum)
 {
-  /* This isn't really an address.  But ptrace thinks of it as one.  */
-  CORE_ADDR regaddr;
-  char mess[128];		/* For messages */
-  int i;
-  unsigned int offset;		/* Offset of registers within the u area.  */
-  int tid;
-  char buf[MAX_REGISTER_SIZE];
+  CORE_ADDR addr;
+  size_t size;
+  PTRACE_TYPE_RET *buf;
+  int tid, i;
 
-  if (CANNOT_STORE_REGISTER (regno))
-    {
-      return;
-    }
-
-  /* Overload thread id onto process id */
-  if ((tid = TIDGET (inferior_ptid)) == 0)
-    tid = PIDGET (inferior_ptid);	/* no thread id, just use process id */
+  if (CANNOT_STORE_REGISTER (regnum))
+    return;
 
-  offset = U_REGS_OFFSET;
+  /* GNU/Linux LWP ID's are process ID's.  */
+  tid = TIDGET (inferior_ptid);
+  if (tid == 0)
+    tid = PIDGET (inferior_ptid); /* Not a threaded program.  */
 
-  regaddr = register_addr (regno, offset);
+  /* This isn't really an address.  But ptrace thinks of it as one.  */
+  addr = register_addr (regnum, U_REGS_OFFSET);
+  size = register_size (current_gdbarch, regnum);
 
-  /* Put the contents of regno into a local buffer */
-  regcache_raw_collect (current_regcache, regno, buf);
+  gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0);
+  buf = alloca (size);
 
-  /* Store the local buffer into the inferior a chunk at the time. */
-  for (i = 0; i < register_size (current_gdbarch, regno); i += sizeof (PTRACE_XFER_TYPE))
+  /* Write the register contents into the inferior a chunk at the time.  */
+  regcache_raw_collect (current_regcache, regnum, buf);
+  for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
     {
       errno = 0;
-      ptrace (PT_WRITE_U, tid, (PTRACE_TYPE_ARG3) regaddr,
-	      *(PTRACE_XFER_TYPE *) (buf + i));
-      regaddr += sizeof (PTRACE_XFER_TYPE);
+      ptrace (PT_WRITE_U, tid, (PTRACE_TYPE_ARG3) addr, buf[i]);
       if (errno != 0)
-	{
-	  sprintf (mess, "writing register %s (#%d)", 
-		   REGISTER_NAME (regno), regno);
-	  perror_with_name (mess);
-	}
+	error ("Couldn't write register %s (#%d): %s.", REGISTER_NAME (regnum),
+	       regnum, safe_strerror (errno));
+
+      addr += sizeof (PTRACE_TYPE_RET);
     }
 }
 
-/* Store our register values back into the inferior.
-   If REGNO is negative, do this for all registers.
-   Otherwise, REGNO specifies which register (so we can save time).  */
+/* Store register REGNUM back into the inferior.  If REGNUM is -1, do
+   this for all registers (including the floating point registers).  */
 
 void
-store_inferior_registers (int regno)
+store_inferior_registers (int regnum)
 {
-  if (regno >= 0)
-    {
-      store_register (regno);
-    }
+  if (regnum == -1)
+    for (regnum = 0; regnum < NUM_REGS; regnum++)
+      store_register (regnum);
   else
-    {
-      for (regno = 0; regno < NUM_REGS; regno++)
-	{
-	  store_register (regno);
-	}
-    }
+    store_register (regnum);
 }
-#endif /* !defined (FETCH_INFERIOR_REGISTERS).  */
+
+#endif /* not FETCH_INFERIOR_REGISTERS.  */
 
 
 /* Set an upper limit on alloca.  */
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.609
diff -u -p -r1.609 Makefile.in
--- Makefile.in 21 Aug 2004 08:56:38 -0000 1.609
+++ Makefile.in 22 Aug 2004 15:31:21 -0000
@@ -2051,7 +2051,8 @@ inflow.o: inflow.c $(defs_h) $(frame_h) 
 	$(inflow_h)
 infptrace.o: infptrace.c $(defs_h) $(frame_h) $(inferior_h) $(target_h) \
 	$(gdb_string_h) $(regcache_h) $(gdb_wait_h) $(command_h) \
-	$(gdb_dirent_h) $(gdb_ptrace_h) $(gdbcore_h) $(gdb_stat_h)
+	$(gdb_dirent_h) $(gdb_ptrace_h) $(gdbcore_h) $(gdb_stat_h) \
+	$(gdb_assert_h)
 infrun.o: infrun.c $(defs_h) $(gdb_string_h) $(symtab_h) $(frame_h) \
 	$(inferior_h) $(breakpoint_h) $(gdb_wait_h) $(gdbcore_h) $(gdbcmd_h) \
 	$(cli_script_h) $(target_h) $(gdbthread_h) $(annotate_h) \


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