* remote.c (struct remote_state): Add BUF and BUF_SIZE.
[deliverable/binutils-gdb.git] / gdb / inf-ptrace.c
index 033840a067ccc373ca932d3cc4184163099be8d2..04e6d477d2c027de44657ccc6603a06085c2ace9 100644 (file)
@@ -1,7 +1,7 @@
 /* Low-level child interface to ptrace.
 
-   Copyright 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
    Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    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., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include "defs.h"
 #include "command.h"
 #include "inferior.h"
 #include "inflow.h"
 #include "gdbcore.h"
-#include "observer.h"
 #include "regcache.h"
 
 #include "gdb_assert.h"
@@ -44,7 +43,7 @@ static struct target_ops *ptrace_ops_hack;
 #ifdef PT_GET_PROCESS_STATE
 
 static int
-inf_ptrace_follow_fork (int follow_child)
+inf_ptrace_follow_fork (struct target_ops *ops, int follow_child)
 {
   pid_t pid, fpid;
   ptrace_state_t pe;
@@ -108,19 +107,6 @@ inf_ptrace_me (void)
 static void
 inf_ptrace_him (int pid)
 {
-#ifdef PT_GET_PROCESS_STATE
-  {
-    ptrace_event_t pe;
-
-    /* Set the initial event mask.  */
-    memset (&pe, 0, sizeof pe);
-    pe.pe_set_event |= PTRACE_FORK;
-    if (ptrace (PT_SET_EVENT_MASK, pid,
-               (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
-      perror_with_name (("ptrace"));
-  }
-#endif
-
   push_target (ptrace_ops_hack);
 
   /* On some targets, there must be some explicit synchronization
@@ -151,14 +137,25 @@ 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);
+}
+
+#ifdef PT_GET_PROCESS_STATE
 
-  /* We are at the first instruction we care about.  */
-  observer_notify_inferior_created (&current_target, from_tty);
+static void
+inf_ptrace_post_startup_inferior (ptid_t pid)
+{
+  ptrace_event_t pe;
 
-  /* Pedal to the metal...  */
-  proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
+  /* Set the initial event mask.  */
+  memset (&pe, 0, sizeof pe);
+  pe.pe_set_event |= PTRACE_FORK;
+  if (ptrace (PT_SET_EVENT_MASK, ptid_get_pid (pid),
+             (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
+    perror_with_name (("ptrace"));
 }
 
+#endif
+
 /* Clean up a rotting corpse of an inferior after it died.  */
 
 static void
@@ -167,9 +164,9 @@ inf_ptrace_mourn_inferior (void)
   int status;
 
   /* Wait just one more time to collect the inferior's exit status.
-     Don not check whether this succeeds though, since we may be
+     Do not check whether this succeeds though, since we may be
      dealing with a process that we attached to.  Such a process will
-     only report its exit status to its origional parent.  */
+     only report its exit status to its original parent.  */
   waitpid (ptid_get_pid (inferior_ptid), &status, 0);
 
   unpush_target (ptrace_ops_hack);
@@ -222,29 +219,29 @@ inf_ptrace_attach (char *args, int from_tty)
   error (_("This system does not support attaching to a process"));
 #endif
 
-#ifdef PT_GET_PROCESS_STATE
-  {
-    ptrace_event_t pe;
-
-    /* Set the initial event mask.  */
-    memset (&pe, 0, sizeof pe);
-    pe.pe_set_event |= PTRACE_FORK;
-    if (ptrace (PT_SET_EVENT_MASK, pid,
-               (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
-      perror_with_name (("ptrace"));
-  }
-#endif
-
   inferior_ptid = pid_to_ptid (pid);
   push_target (ptrace_ops_hack);
+}
+
+#ifdef PT_GET_PROCESS_STATE
+
+void
+inf_ptrace_post_attach (int pid)
+{
+  ptrace_event_t pe;
 
-  /* 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);
+  /* Set the initial event mask.  */
+  memset (&pe, 0, sizeof pe);
+  pe.pe_set_event |= PTRACE_FORK;
+  if (ptrace (PT_SET_EVENT_MASK, pid,
+             (PTRACE_TYPE_ARG3)&pe, sizeof pe) == -1)
+    perror_with_name (("ptrace"));
 }
 
+#endif
+
 /* Detach from the inferior, optionally passing it the signal
-   specified ARGS.  If FROM_TTY is non-zero, be chatty about it.  */
+   specified by ARGS.  If FROM_TTY is non-zero, be chatty about it.  */
 
 static void
 inf_ptrace_detach (char *args, int from_tty)
@@ -266,7 +263,7 @@ inf_ptrace_detach (char *args, int from_tty)
 
 #ifdef PT_DETACH
   /* We'd better not have left any breakpoints in the program or it'll
-     die when it hits one.  Alsno note that this may only work if we
+     die when it hits one.  Also note that this may only work if we
      previously attached to the inferior.  It *might* work if we
      started the process ourselves.  */
   errno = 0;
@@ -454,8 +451,12 @@ inf_ptrace_xfer_partial (struct target_ops *ops, enum target_object object,
        struct ptrace_io_desc piod;
 
        /* NOTE: We assume that there are no distinct address spaces
-          for instruction and data.  */
-       piod.piod_op = writebuf ? PIOD_WRITE_D : PIOD_READ_D;
+          for instruction and data.  However, on OpenBSD 3.9 and
+          later, PIOD_WRITE_D doesn't allow changing memory that's
+          mapped read-only.  Since most code segments will be
+          read-only, using PIOD_WRITE_D will prevent us from
+          inserting breakpoints, so we use PIOD_WRITE_I instead.  */
+       piod.piod_op = writebuf ? PIOD_WRITE_I : PIOD_READ_D;
        piod.piod_addr = writebuf ? (void *) writebuf : readbuf;
        piod.piod_offs = (void *) (long) offset;
        piod.piod_len = len;
@@ -590,6 +591,8 @@ inf_ptrace_target (void)
   t->to_create_inferior = inf_ptrace_create_inferior;
 #ifdef PT_GET_PROCESS_STATE
   t->to_follow_fork = inf_ptrace_follow_fork;
+  t->to_post_startup_inferior = inf_ptrace_post_startup_inferior;
+  t->to_post_attach = inf_ptrace_post_attach;
 #endif
   t->to_mourn_inferior = inf_ptrace_mourn_inferior;
   t->to_thread_alive = inf_ptrace_thread_alive;
@@ -616,8 +619,14 @@ inf_ptrace_fetch_register (int regnum)
   PTRACE_TYPE_RET *buf;
   int pid, i;
 
+  if (CANNOT_FETCH_REGISTER (regnum))
+    {
+      regcache_raw_supply (current_regcache, regnum, NULL);
+      return;
+    }
+
   /* Cater for systems like GNU/Linux, that implement threads as
-     seperate processes.  */
+     separate processes.  */
   pid = ptid_get_lwp (inferior_ptid);
   if (pid == 0)
     pid = ptid_get_pid (inferior_ptid);
@@ -629,7 +638,7 @@ inf_ptrace_fetch_register (int regnum)
   gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0);
   buf = alloca (size);
 
-  /* Read the register contents from the inferior a chuck at the time.  */
+  /* Read the register contents from the inferior a chunk at a time.  */
   for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
     {
       errno = 0;
@@ -666,8 +675,11 @@ inf_ptrace_store_register (int regnum)
   PTRACE_TYPE_RET *buf;
   int pid, i;
 
+  if (CANNOT_STORE_REGISTER (regnum))
+    return;
+
   /* Cater for systems like GNU/Linux, that implement threads as
-     seperate processes.  */
+     separate processes.  */
   pid = ptid_get_lwp (inferior_ptid);
   if (pid == 0)
     pid = ptid_get_pid (inferior_ptid);
@@ -679,7 +691,7 @@ inf_ptrace_store_register (int regnum)
   gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0);
   buf = alloca (size);
 
-  /* Write the register contents into the inferior a chunk at the time.  */
+  /* Write the register contents into the inferior a chunk at a time.  */
   regcache_raw_collect (current_regcache, regnum, buf);
   for (i = 0; i < size / sizeof (PTRACE_TYPE_RET); i++)
     {
This page took 0.041371 seconds and 4 git commands to generate.