Associate dummy_frame with ptid
[deliverable/binutils-gdb.git] / gdb / inf-ptrace.c
index 27bbf4d7deca521beaa6f602d59b2d2db336f5ad..e1d64f8cd7eec08e7e88a40bd2535acc0076ab91 100644 (file)
@@ -1,6 +1,6 @@
 /* Low-level child interface to ptrace.
 
-   Copyright (C) 1988-2013 Free Software Foundation, Inc.
+   Copyright (C) 1988-2014 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -26,7 +26,7 @@
 #include "regcache.h"
 
 #include "gdb_assert.h"
-#include "gdb_string.h"
+#include <string.h>
 #include "gdb_ptrace.h"
 #include "gdb_wait.h"
 #include <signal.h>
@@ -40,7 +40,8 @@
 #ifdef PT_GET_PROCESS_STATE
 
 static int
-inf_ptrace_follow_fork (struct target_ops *ops, int follow_child)
+inf_ptrace_follow_fork (struct target_ops *ops, int follow_child,
+                       int detach_fork)
 {
   pid_t pid, fpid;
   ptrace_state_t pe;
@@ -122,24 +123,20 @@ inf_ptrace_create_inferior (struct target_ops *ops,
   /* Do not change either targets above or the same target if already present.
      The reason is the target stack is shared across multiple inferiors.  */
   int ops_already_pushed = target_is_pushed (ops);
-  struct cleanup *back_to = NULL;
+  struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
 
   if (! ops_already_pushed)
     {
       /* Clear possible core file with its process_stratum.  */
       push_target (ops);
-      back_to = make_cleanup_unpush_target (ops);
+      make_cleanup_unpush_target (ops);
     }
 
   pid = fork_inferior (exec_file, allargs, env, inf_ptrace_me, NULL,
                       NULL, NULL, NULL);
 
-  if (! ops_already_pushed)
-    discard_cleanups (back_to);
+  discard_cleanups (back_to);
 
-  /* START_INFERIOR_TRAPS_EXPECTED is defined in inferior.h, and will
-     be 1 or 2 depending on whether we're starting without or with a
-     shell.  */
   startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
 
   /* On some targets, there must be some explicit actions taken after
@@ -150,7 +147,7 @@ inf_ptrace_create_inferior (struct target_ops *ops,
 #ifdef PT_GET_PROCESS_STATE
 
 static void
-inf_ptrace_post_startup_inferior (ptid_t pid)
+inf_ptrace_post_startup_inferior (struct target_ops *self, ptid_t pid)
 {
   ptrace_event_t pe;
 
@@ -177,17 +174,14 @@ inf_ptrace_mourn_inferior (struct target_ops *ops)
      only report its exit status to its original parent.  */
   waitpid (ptid_get_pid (inferior_ptid), &status, 0);
 
-  generic_mourn_inferior ();
-
-  if (!have_inferiors ())
-    unpush_target (ops);
+  inf_child_mourn_inferior (ops);
 }
 
 /* Attach to the process specified by ARGS.  If FROM_TTY is non-zero,
    be chatty about it.  */
 
 static void
-inf_ptrace_attach (struct target_ops *ops, char *args, int from_tty)
+inf_ptrace_attach (struct target_ops *ops, const char *args, int from_tty)
 {
   char *exec_file;
   pid_t pid;
@@ -196,7 +190,7 @@ inf_ptrace_attach (struct target_ops *ops, char *args, int from_tty)
   /* Do not change either targets above or the same target if already present.
      The reason is the target stack is shared across multiple inferiors.  */
   int ops_already_pushed = target_is_pushed (ops);
-  struct cleanup *back_to = NULL;
+  struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
 
   pid = parse_pid_to_attach (args);
 
@@ -208,7 +202,7 @@ inf_ptrace_attach (struct target_ops *ops, char *args, int from_tty)
       /* target_pid_to_str already uses the target.  Also clear possible core
         file with its process_stratum.  */
       push_target (ops);
-      back_to = make_cleanup_unpush_target (ops);
+      make_cleanup_unpush_target (ops);
     }
 
   if (from_tty)
@@ -243,14 +237,13 @@ inf_ptrace_attach (struct target_ops *ops, char *args, int from_tty)
      target, it should decorate the ptid later with more info.  */
   add_thread_silent (inferior_ptid);
 
-  if (! ops_already_pushed)
-    discard_cleanups (back_to);
+  discard_cleanups (back_to);
 }
 
 #ifdef PT_GET_PROCESS_STATE
 
 static void
-inf_ptrace_post_attach (int pid)
+inf_ptrace_post_attach (struct target_ops *self, int pid)
 {
   ptrace_event_t pe;
 
@@ -268,7 +261,7 @@ inf_ptrace_post_attach (int pid)
    specified by ARGS.  If FROM_TTY is non-zero, be chatty about it.  */
 
 static void
-inf_ptrace_detach (struct target_ops *ops, char *args, int from_tty)
+inf_ptrace_detach (struct target_ops *ops, const char *args, int from_tty)
 {
   pid_t pid = ptid_get_pid (inferior_ptid);
   int sig = 0;
@@ -301,8 +294,7 @@ inf_ptrace_detach (struct target_ops *ops, char *args, int from_tty)
   inferior_ptid = null_ptid;
   detach_inferior (pid);
 
-  if (!have_inferiors ())
-    unpush_target (ops);
+  inf_child_maybe_unpush_target (ops);
 }
 
 /* Kill the inferior.  */
@@ -325,7 +317,7 @@ inf_ptrace_kill (struct target_ops *ops)
 /* Stop the inferior.  */
 
 static void
-inf_ptrace_stop (ptid_t ptid)
+inf_ptrace_stop (struct target_ops *self, ptid_t ptid)
 {
   /* Send a SIGINT to the process group.  This acts just like the user
      typed a ^C on the controlling terminal.  Note that using a
@@ -459,15 +451,13 @@ inf_ptrace_wait (struct target_ops *ops,
   return pid_to_ptid (pid);
 }
 
-/* Attempt a transfer all LEN bytes starting at OFFSET between the
-   inferior's OBJECT:ANNEX space and GDB's READBUF/WRITEBUF buffer.
-   Return the number of bytes actually transferred.  */
+/* Implement the to_xfer_partial target_ops method.  */
 
-static LONGEST
+static enum target_xfer_status
 inf_ptrace_xfer_partial (struct target_ops *ops, enum target_object object,
                         const char *annex, gdb_byte *readbuf,
                         const gdb_byte *writebuf,
-                        ULONGEST offset, LONGEST len)
+                        ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
 {
   pid_t pid = ptid_get_pid (inferior_ptid);
 
@@ -494,13 +484,16 @@ inf_ptrace_xfer_partial (struct target_ops *ops, enum target_object object,
 
        errno = 0;
        if (ptrace (PT_IO, pid, (caddr_t)&piod, 0) == 0)
-         /* Return the actual number of bytes read or written.  */
-         return piod.piod_len;
+         {
+           /* Return the actual number of bytes read or written.  */
+           *xfered_len = piod.piod_len;
+           return (piod.piod_len == 0) ? TARGET_XFER_EOF : TARGET_XFER_OK;
+         }
        /* If the PT_IO request is somehow not supported, fallback on
           using PT_WRITE_D/PT_READ_D.  Otherwise we will return zero
           to indicate failure.  */
        if (errno != EINVAL)
-         return 0;
+         return TARGET_XFER_EOF;
       }
 #endif
       {
@@ -510,7 +503,7 @@ inf_ptrace_xfer_partial (struct target_ops *ops, enum target_object object,
          gdb_byte byte[sizeof (PTRACE_TYPE_RET)];
        } buffer;
        ULONGEST rounded_offset;
-       LONGEST partial_len;
+       ULONGEST partial_len;
 
        /* Round the start offset down to the next long word
           boundary.  */
@@ -556,7 +549,7 @@ inf_ptrace_xfer_partial (struct target_ops *ops, enum target_object object,
                        (PTRACE_TYPE_ARG3)(uintptr_t)rounded_offset,
                        buffer.word);
                if (errno)
-                 return 0;
+                 return TARGET_XFER_EOF;
              }
          }
 
@@ -567,17 +560,18 @@ inf_ptrace_xfer_partial (struct target_ops *ops, enum target_object object,
                                  (PTRACE_TYPE_ARG3)(uintptr_t)rounded_offset,
                                  0);
            if (errno)
-             return 0;
+             return TARGET_XFER_EOF;
            /* Copy appropriate bytes out of the buffer.  */
            memcpy (readbuf, buffer.byte + (offset - rounded_offset),
                    partial_len);
          }
 
-       return partial_len;
+       *xfered_len = partial_len;
+       return TARGET_XFER_OK;
       }
 
     case TARGET_OBJECT_UNWIND_TABLE:
-      return -1;
+      return TARGET_XFER_E_IO;
 
     case TARGET_OBJECT_AUXV:
 #if defined (PT_IO) && defined (PIOD_READ_AUXV)
@@ -588,7 +582,7 @@ inf_ptrace_xfer_partial (struct target_ops *ops, enum target_object object,
        struct ptrace_io_desc piod;
 
        if (writebuf)
-         return -1;
+         return TARGET_XFER_E_IO;
        piod.piod_op = PIOD_READ_AUXV;
        piod.piod_addr = readbuf;
        piod.piod_offs = (void *) (long) offset;
@@ -596,17 +590,20 @@ inf_ptrace_xfer_partial (struct target_ops *ops, enum target_object object,
 
        errno = 0;
        if (ptrace (PT_IO, pid, (caddr_t)&piod, 0) == 0)
-         /* Return the actual number of bytes read or written.  */
-         return piod.piod_len;
+         {
+           /* Return the actual number of bytes read or written.  */
+           *xfered_len = piod.piod_len;
+           return (piod.piod_len == 0) ? TARGET_XFER_EOF : TARGET_XFER_OK;
+         }
       }
 #endif
-      return -1;
+      return TARGET_XFER_E_IO;
 
     case TARGET_OBJECT_WCOOKIE:
-      return -1;
+      return TARGET_XFER_E_IO;
 
     default:
-      return -1;
+      return TARGET_XFER_E_IO;
     }
 }
 
This page took 0.029505 seconds and 4 git commands to generate.