daily update
[deliverable/binutils-gdb.git] / gdb / inf-ptrace.c
index 9e2ea846e214a0a244fa2b9afd4a265c6e4ba2ee..8acc690eb5d83b22102c041dce93df0ed846fd77 100644 (file)
@@ -1,14 +1,14 @@
 /* Low-level child interface to ptrace.
 
-   Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
-   1998, 1999, 2000, 2001, 2002, 2004, 2005
+   Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998,
+   1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "command.h"
 #include "inferior.h"
 #include "inflow.h"
 #include "gdbcore.h"
-#include "observer.h"
 #include "regcache.h"
 
+#include "gdb_stdint.h"
 #include "gdb_assert.h"
 #include "gdb_string.h"
 #include "gdb_ptrace.h"
@@ -138,12 +136,6 @@ inf_ptrace_create_inferior (char *exec_file, char *allargs, char **env,
 {
   fork_inferior (exec_file, allargs, env, inf_ptrace_me, inf_ptrace_him,
                 NULL, NULL);
-
-  /* We are at the first instruction we care about.  */
-  observer_notify_inferior_created (&current_target, from_tty);
-
-  /* Pedal to the metal...  */
-  proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
 }
 
 #ifdef PT_GET_PROCESS_STATE
@@ -228,10 +220,6 @@ inf_ptrace_attach (char *args, int from_tty)
 
   inferior_ptid = pid_to_ptid (pid);
   push_target (ptrace_ops_hack);
-
-  /* Do this first, before anything has had a chance to query the
-     inferior's symbol table or similar.  */
-  observer_notify_inferior_created (&current_target, from_tty);
 }
 
 #ifdef PT_GET_PROCESS_STATE
@@ -515,7 +503,8 @@ inf_ptrace_xfer_partial (struct target_ops *ops, enum target_object object,
                    < rounded_offset + sizeof (PTRACE_TYPE_RET)))
              /* Need part of initial word -- fetch it.  */
              buffer.word = ptrace (PT_READ_I, pid,
-                                   (PTRACE_TYPE_ARG3)(long)rounded_offset, 0);
+                                   (PTRACE_TYPE_ARG3)(uintptr_t)
+                                   rounded_offset, 0);
 
            /* Copy data to be written over corresponding part of
               buffer.  */
@@ -524,14 +513,16 @@ inf_ptrace_xfer_partial (struct target_ops *ops, enum target_object object,
 
            errno = 0;
            ptrace (PT_WRITE_D, pid,
-                   (PTRACE_TYPE_ARG3)(long)rounded_offset, buffer.word);
+                   (PTRACE_TYPE_ARG3)(uintptr_t)rounded_offset,
+                   buffer.word);
            if (errno)
              {
                /* Using the appropriate one (I or D) is necessary for
                   Gould NP1, at least.  */
                errno = 0;
                ptrace (PT_WRITE_I, pid,
-                       (PTRACE_TYPE_ARG3)(long)rounded_offset, buffer.word);
+                       (PTRACE_TYPE_ARG3)(uintptr_t)rounded_offset,
+                       buffer.word);
                if (errno)
                  return 0;
              }
@@ -541,7 +532,8 @@ inf_ptrace_xfer_partial (struct target_ops *ops, enum target_object object,
          {
            errno = 0;
            buffer.word = ptrace (PT_READ_I, pid,
-                                 (PTRACE_TYPE_ARG3)(long)rounded_offset, 0);
+                                 (PTRACE_TYPE_ARG3)(uintptr_t)rounded_offset,
+                                 0);
            if (errno)
              return 0;
            /* Copy appropriate bytes out of the buffer.  */
@@ -618,21 +610,25 @@ inf_ptrace_target (void)
 
 /* Pointer to a function that returns the offset within the user area
    where a particular register is stored.  */
-static CORE_ADDR (*inf_ptrace_register_u_offset)(int);
+static CORE_ADDR (*inf_ptrace_register_u_offset)(struct gdbarch *, int, int);
 
 /* Fetch register REGNUM from the inferior.  */
 
 static void
-inf_ptrace_fetch_register (int regnum)
+inf_ptrace_fetch_register (struct regcache *regcache, int regnum)
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
   CORE_ADDR addr;
   size_t size;
   PTRACE_TYPE_RET *buf;
   int pid, i;
 
-  if (CANNOT_FETCH_REGISTER (regnum))
+  /* This isn't really an address, but ptrace thinks of it as one.  */
+  addr = inf_ptrace_register_u_offset (gdbarch, regnum, 0);
+  if (addr == (CORE_ADDR)-1
+      || gdbarch_cannot_fetch_register (gdbarch, regnum))
     {
-      regcache_raw_supply (current_regcache, regnum, NULL);
+      regcache_raw_supply (regcache, regnum, NULL);
       return;
     }
 
@@ -642,10 +638,7 @@ inf_ptrace_fetch_register (int regnum)
   if (pid == 0)
     pid = ptid_get_pid (inferior_ptid);
 
-  /* This isn't really an address, but ptrace thinks of it as one.  */
-  addr = inf_ptrace_register_u_offset (regnum);
-  size = register_size (current_gdbarch, regnum);
-
+  size = register_size (gdbarch, regnum);
   gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0);
   buf = alloca (size);
 
@@ -653,40 +646,47 @@ inf_ptrace_fetch_register (int regnum)
   for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
     {
       errno = 0;
-      buf[i] = ptrace (PT_READ_U, pid, (PTRACE_TYPE_ARG3)addr, 0);
+      buf[i] = ptrace (PT_READ_U, pid, (PTRACE_TYPE_ARG3)(uintptr_t)addr, 0);
       if (errno != 0)
        error (_("Couldn't read register %s (#%d): %s."),
-              REGISTER_NAME (regnum), regnum, safe_strerror (errno));
+              gdbarch_register_name (gdbarch, regnum),
+              regnum, safe_strerror (errno));
 
       addr += sizeof (PTRACE_TYPE_RET);
     }
-  regcache_raw_supply (current_regcache, regnum, buf);
+  regcache_raw_supply (regcache, regnum, buf);
 }
 
 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
    for all registers.  */
 
 static void
-inf_ptrace_fetch_registers (int regnum)
+inf_ptrace_fetch_registers (struct regcache *regcache, int regnum)
 {
   if (regnum == -1)
-    for (regnum = 0; regnum < NUM_REGS; regnum++)
-      inf_ptrace_fetch_register (regnum);
+    for (regnum = 0;
+        regnum < gdbarch_num_regs (get_regcache_arch (regcache));
+        regnum++)
+      inf_ptrace_fetch_register (regcache, regnum);
   else
-    inf_ptrace_fetch_register (regnum);
+    inf_ptrace_fetch_register (regcache, regnum);
 }
 
 /* Store register REGNUM into the inferior.  */
 
 static void
-inf_ptrace_store_register (int regnum)
+inf_ptrace_store_register (const struct regcache *regcache, int regnum)
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
   CORE_ADDR addr;
   size_t size;
   PTRACE_TYPE_RET *buf;
   int pid, i;
 
-  if (CANNOT_STORE_REGISTER (regnum))
+  /* This isn't really an address, but ptrace thinks of it as one.  */
+  addr = inf_ptrace_register_u_offset (gdbarch, regnum, 1);
+  if (addr == (CORE_ADDR)-1 
+      || gdbarch_cannot_store_register (gdbarch, regnum))
     return;
 
   /* Cater for systems like GNU/Linux, that implement threads as
@@ -695,22 +695,20 @@ inf_ptrace_store_register (int regnum)
   if (pid == 0)
     pid = ptid_get_pid (inferior_ptid);
 
-  /* This isn't really an address, but ptrace thinks of it as one.  */
-  addr = inf_ptrace_register_u_offset (regnum);
-  size = register_size (current_gdbarch, regnum);
-
+  size = register_size (gdbarch, regnum);
   gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0);
   buf = alloca (size);
 
   /* Write the register contents into the inferior a chunk at a time.  */
-  regcache_raw_collect (current_regcache, regnum, buf);
+  regcache_raw_collect (regcache, regnum, buf);
   for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
     {
       errno = 0;
-      ptrace (PT_WRITE_U, pid, (PTRACE_TYPE_ARG3)addr, buf[i]);
+      ptrace (PT_WRITE_U, pid, (PTRACE_TYPE_ARG3)(uintptr_t)addr, buf[i]);
       if (errno != 0)
        error (_("Couldn't write register %s (#%d): %s."),
-              REGISTER_NAME (regnum), regnum, safe_strerror (errno));
+              gdbarch_register_name (gdbarch, regnum),
+              regnum, safe_strerror (errno));
 
       addr += sizeof (PTRACE_TYPE_RET);
     }
@@ -720,13 +718,15 @@ inf_ptrace_store_register (int regnum)
    this for all registers.  */
 
 void
-inf_ptrace_store_registers (int regnum)
+inf_ptrace_store_registers (struct regcache *regcache, int regnum)
 {
   if (regnum == -1)
-    for (regnum = 0; regnum < NUM_REGS; regnum++)
-      inf_ptrace_store_register (regnum);
+    for (regnum = 0;
+        regnum < gdbarch_num_regs (get_regcache_arch (regcache));
+        regnum++)
+      inf_ptrace_store_register (regcache, regnum);
   else
-    inf_ptrace_store_register (regnum);
+    inf_ptrace_store_register (regcache, regnum);
 }
 
 /* Create a "traditional" ptrace target.  REGISTER_U_OFFSET should be
@@ -734,7 +734,8 @@ inf_ptrace_store_registers (int regnum)
    particular register is stored.  */
 
 struct target_ops *
-inf_ptrace_trad_target (CORE_ADDR (*register_u_offset)(int))
+inf_ptrace_trad_target (CORE_ADDR (*register_u_offset)
+                                       (struct gdbarch *, int, int))
 {
   struct target_ops *t = inf_ptrace_target();
 
This page took 0.025621 seconds and 4 git commands to generate.