Make the /proc support a target-struct in its own right.
authorJohn Gilmore <gnu@cygnus>
Sat, 26 Sep 1992 09:06:30 +0000 (09:06 +0000)
committerJohn Gilmore <gnu@cygnus>
Sat, 26 Sep 1992 09:06:30 +0000 (09:06 +0000)
* inferior.h (proc_wait, inferior_proc_init, proc_set_exec_trap):
No longer global functions.
(fork_inferior):  New global function from fork-child.c.
* inftarg.c (child_wait):  Remove USE_PROC_FS conditional.
(ptrace_me, ptrace_him):  New stub functions for fork_inferior().
(child_create_inferior):  Moved to fork-child.c as fork_inferior.
(child_create_inferior):  New tiny function that calls fork_inferior.
* fork-child.c:  New file, containing fork_inferior, which is
built from slight mods to inftarg.c's child_create_inferior.

* procfs.c (procfs_ops):  Add target vector.
(attach):  Rename as static do_attach.
(procfs_create_inferior):  New tiny function that calls fork_inferior.
(child_xfer_memory):  Rename to static procfs_xfer_memory.
(store_inferior_registers):  Rename to static procfs_store_registers.
(inferior_proc_init):  Rename to static procfs_init_inferior.
(procfs_attach, procfs_detach, procfs_prepare_to_store,
procfs_files_info, procfs_open, procfs_mourn_inferior,
procfs_can_run):  Slightly mangled copies of the corresponding
child_XXX routines from inftarg.c.
(proc_wait):  Renamed to static procfs_wait.
(child_resume):  Rename to static procfs_resume.
(fetch_inferior_registers):  Rename to static procfs_fetch_registers.
(initialize_proc_fs):  Rename to initialize_procfs.  Set up
procfs_ops, too.
* xm-irix4.h, xm-sysv4.h (CREATE_INFERIOR_HOOK):  No longer needed.

gdb/ChangeLog
gdb/fork-child.c [new file with mode: 0644]
gdb/procfs.c
gdb/xm-irix4.h
gdb/xm-sysv4.h

index 3fa70183c5d4a781681f3216cdc0f48cc4a6d64c..2b0e8c7dd758d4ba7a2cf489bc265c394451b197 100644 (file)
@@ -1,11 +1,47 @@
 Sat Sep 26 00:25:15 1992  John Gilmore  (gnu@cygnus.com)
 
+       Make the /proc support a target-struct in its own right.
+
        * Makefile.in: Remove inftarg.[co], since it is now included via
        config/*.mh files.
        * config/*.mh:  Add inftarg.o and fork-child.o to all *.mh that
        reference infptrace.o.  Add fork-child.o to all *.mh that
        reference procfs.o.
 
+       * inferior.h (proc_wait, inferior_proc_init, proc_set_exec_trap):
+       No longer global functions.
+       (fork_inferior):  New global function from fork-child.c.
+       * inftarg.c (child_wait):  Remove USE_PROC_FS conditional.
+       (ptrace_me, ptrace_him):  New stub functions for fork_inferior().
+       (child_create_inferior):  Moved to fork-child.c as fork_inferior.
+       (child_create_inferior):  New tiny function that calls fork_inferior.
+       * fork-child.c:  New file, containing fork_inferior, which is
+       built from slight mods to inftarg.c's child_create_inferior.
+
+       * procfs.c (procfs_ops):  Add target vector.
+       (attach):  Rename as static do_attach.
+       (procfs_create_inferior):  New tiny function that calls fork_inferior.
+       (child_xfer_memory):  Rename to static procfs_xfer_memory.
+       (store_inferior_registers):  Rename to static procfs_store_registers.
+       (inferior_proc_init):  Rename to static procfs_init_inferior.
+       (procfs_attach, procfs_detach, procfs_prepare_to_store,
+       procfs_files_info, procfs_open, procfs_mourn_inferior,
+       procfs_can_run):  Slightly mangled copies of the corresponding
+       child_XXX routines from inftarg.c.
+       (proc_wait):  Renamed to static procfs_wait.
+       (child_resume):  Rename to static procfs_resume.
+       (fetch_inferior_registers):  Rename to static procfs_fetch_registers.
+       (initialize_proc_fs):  Rename to initialize_procfs.  Set up
+       procfs_ops, too.
+
+       * putenv.c:  index -> strchr.
+       * regex.c:  Always rename bcopy to memcpy, etc.
+       FIXME:  Eventually do the renames rather than use #define's.
+       * sparc-tdep.c (deferred_stores):  Moved from sparc-xdep.c.
+       Fix bcopy->memcpy.
+       * sparc-xdep.c:  Move deferred_stores to target dependent.
+       * xm-irix4.h, xm-sysv4.h (CREATE_INFERIOR_HOOK):  No longer needed.
+
 Fri Sep 25 21:59:27 1992  John Gilmore  (gnu@cygnus.com)
 
        Split non-target-dependent code out of target_attach routines.
diff --git a/gdb/fork-child.c b/gdb/fork-child.c
new file mode 100644 (file)
index 0000000..1ec7e7a
--- /dev/null
@@ -0,0 +1,254 @@
+/* Fork a Unix child process, and set up to debug it, for GDB.
+   Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
+   Contributed by Cygnus Support.
+
+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
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "defs.h"
+#include "frame.h"  /* required by inferior.h */
+#include "inferior.h"
+#include "target.h"
+#include "wait.h"
+#include "gdbcore.h"
+#include "terminal.h"          /* For #ifdef TIOCGPGRP and new_tty */
+
+#include <signal.h>
+
+#ifdef SET_STACK_LIMIT_HUGE
+#include <sys/time.h>
+#include <sys/resource.h>
+
+extern int original_stack_limit;
+#endif /* SET_STACK_LIMIT_HUGE */
+
+extern char **environ;
+
+/* Start an inferior Unix child process and sets inferior_pid to its pid.
+   EXEC_FILE is the file to run.
+   ALLARGS is a string containing the arguments to the program.
+   ENV is the environment vector to pass.  Errors reported with error().  */
+
+#ifndef SHELL_FILE
+#define SHELL_FILE "/bin/sh"
+#endif
+
+void
+fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun)
+     char *exec_file;
+     char *allargs;
+     char **env;
+     void (*traceme_fun) PARAMS ((void));
+     void (*init_trace_fun) PARAMS ((int));
+{
+  int pid;
+  char *shell_command;
+  char *shell_file;
+  static char default_shell_file[] = SHELL_FILE;
+  int len;
+  int pending_execs;
+  /* Set debug_fork then attach to the child while it sleeps, to debug. */
+  static int debug_fork = 0;
+  /* This is set to the result of setpgrp, which if vforked, will be visible
+     to you in the parent process.  It's only used by humans for debugging.  */
+  static int debug_setpgrp = 657473;
+  char **save_our_env;
+
+  /* If no exec file handed to us, get it from the exec-file command -- with
+     a good, common error message if none is specified.  */
+  if (exec_file == 0)
+    exec_file = get_exec_file(1);
+
+  /* The user might want tilde-expansion, and in general probably wants
+     the program to behave the same way as if run from
+     his/her favorite shell.  So we let the shell run it for us.
+     FIXME, this should probably search the local environment (as
+     modified by the setenv command), not the env gdb inherited.  */
+  shell_file = getenv ("SHELL");
+  if (shell_file == NULL)
+    shell_file = default_shell_file;
+  
+  len = 5 + strlen (exec_file) + 1 + strlen (allargs) + 1 + /*slop*/ 10;
+  /* If desired, concat something onto the front of ALLARGS.
+     SHELL_COMMAND is the result.  */
+#ifdef SHELL_COMMAND_CONCAT
+  shell_command = (char *) alloca (strlen (SHELL_COMMAND_CONCAT) + len);
+  strcpy (shell_command, SHELL_COMMAND_CONCAT);
+#else
+  shell_command = (char *) alloca (len);
+  shell_command[0] = '\0';
+#endif
+  strcat (shell_command, "exec ");
+  strcat (shell_command, exec_file);
+  strcat (shell_command, " ");
+  strcat (shell_command, allargs);
+
+  /* exec is said to fail if the executable is open.  */
+  close_exec_file ();
+
+  /* Retain a copy of our environment variables, since the child will
+     replace the value of  environ  and if we're vforked, we have to 
+     restore it.  */
+  save_our_env = environ;
+
+  /* Tell the terminal handling subsystem what tty we plan to run on;
+     it will just record the information for later.  */
+
+  new_tty_prefork (inferior_io_terminal);
+
+  /* It is generally good practice to flush any possible pending stdio
+     output prior to doing a fork, to avoid the possibility of both the
+     parent and child flushing the same data after the fork. */
+
+  fflush (stdout);
+  fflush (stderr);
+
+#if defined(USG) && !defined(HAVE_VFORK)
+  pid = fork ();
+#else
+  if (debug_fork)
+    pid = fork ();
+  else
+    pid = vfork ();
+#endif
+
+  if (pid < 0)
+    perror_with_name ("vfork");
+
+  if (pid == 0)
+    {
+      if (debug_fork) 
+       sleep (debug_fork);
+
+#ifdef TIOCGPGRP
+      /* Run inferior in a separate process group.  */
+#ifdef NEED_POSIX_SETPGID
+      debug_setpgrp = setpgid (0, 0);
+#else
+#if defined(USG) && !defined(SETPGRP_ARGS)
+      debug_setpgrp = setpgrp ();
+#else
+      debug_setpgrp = setpgrp (getpid (), getpid ());
+#endif /* USG */
+#endif /* NEED_POSIX_SETPGID */
+      if (debug_setpgrp == -1)
+        perror("setpgrp failed in child");
+#endif /* TIOCGPGRP */
+
+#ifdef SET_STACK_LIMIT_HUGE
+      /* Reset the stack limit back to what it was.  */
+      {
+       struct rlimit rlim;
+
+       getrlimit (RLIMIT_STACK, &rlim);
+       rlim.rlim_cur = original_stack_limit;
+       setrlimit (RLIMIT_STACK, &rlim);
+      }
+#endif /* SET_STACK_LIMIT_HUGE */
+
+      /* Ask the tty subsystem to switch to the one we specified earlier
+        (or to share the current terminal, if none was specified).  */
+
+      new_tty ();
+
+      /* Changing the signal handlers for the inferior after
+        a vfork can also change them for the superior, so we don't mess
+        with signals here.  See comments in
+        initialize_signals for how we get the right signal handlers
+        for the inferior.  */
+
+      /* "Trace me, Dr. Memory!" */
+      (*traceme_fun) ();
+
+      /* There is no execlpe call, so we have to set the environment
+        for our child in the global variable.  If we've vforked, this
+        clobbers the parent, but environ is restored a few lines down
+        in the parent.  By the way, yes we do need to look down the
+        path to find $SHELL.  Rich Pixley says so, and I agree.  */
+      environ = env;
+      execlp (shell_file, shell_file, "-c", shell_command, (char *)0);
+
+      fprintf (stderr, "Cannot exec %s: %s.\n", shell_file,
+              safe_strerror (errno));
+      fflush (stderr);
+      _exit (0177);
+    }
+
+  /* Restore our environment in case a vforked child clob'd it.  */
+  environ = save_our_env;
+
+  /* Now that we have a child process, make it our target, and
+     initialize anything target-vector-specific that needs initializing.  */
+  (*init_trace_fun)(pid);
+
+#ifdef CREATE_INFERIOR_HOOK
+  CREATE_INFERIOR_HOOK (pid);
+#endif  
+
+/* The process was started by the fork that created it,
+   but it will have stopped one instruction after execing the shell.
+   Here we must get it up to actual execution of the real program.  */
+
+  inferior_pid = pid;          /* Needed for wait_for_inferior stuff below */
+
+  clear_proceed_status ();
+
+  /* We will get a trace trap after one instruction.
+     Continue it automatically.  Eventually (after shell does an exec)
+     it will get another trace trap.  Then insert breakpoints and continue.  */
+
+#ifdef START_INFERIOR_TRAPS_EXPECTED
+  pending_execs = START_INFERIOR_TRAPS_EXPECTED;
+#else
+  pending_execs = 2;
+#endif
+
+  init_wait_for_inferior ();
+
+  /* Set up the "saved terminal modes" of the inferior
+     based on what modes we are starting it with.  */
+  target_terminal_init ();
+
+  /* Install inferior's terminal modes.  */
+  target_terminal_inferior ();
+
+  while (1)
+    {
+      stop_soon_quietly = 1;   /* Make wait_for_inferior be quiet */
+      wait_for_inferior ();
+      if (stop_signal != SIGTRAP)
+       {
+         /* Let shell child handle its own signals in its own way */
+         /* FIXME, what if child has exit()ed?  Must exit loop somehow */
+         resume (0, stop_signal);
+       }
+      else
+       {
+         /* We handle SIGTRAP, however; it means child did an exec.  */
+         if (0 == --pending_execs)
+           break;
+         resume (0, 0);                /* Just make it go on */
+       }
+    }
+  stop_soon_quietly = 0;
+
+  /* We are now in the child process of interest, having exec'd the
+     correct program, and are poised at the first instruction of the
+     new program.  */
+#ifdef SOLIB_CREATE_INFERIOR_HOOK
+  SOLIB_CREATE_INFERIOR_HOOK (pid);
+#endif
+}
index b39402ee2685c63097136af5c62bd7aeee920ee6..6254c9c421f8c16020ebf3c43e853bcd39aa630c 100644 (file)
@@ -34,8 +34,6 @@ regardless of whether or not the actual target has floating point hardware.
 
 #include "defs.h"
 
-#ifdef USE_PROC_FS     /* Entire file goes away if not using /proc */
-
 #include <time.h>
 #include <sys/procfs.h>
 #include <fcntl.h>
@@ -45,6 +43,7 @@ regardless of whether or not the actual target has floating point hardware.
 #include "inferior.h"
 #include "target.h"
 #include "command.h"
+#include "gdbcore.h"
 
 #define MAX_SYSCALLS   256     /* Maximum number of syscalls for table */
 
@@ -52,6 +51,8 @@ regardless of whether or not the actual target has floating point hardware.
 #define PROC_NAME_FMT "/proc/%05d"
 #endif
 
+extern struct target_ops procfs_ops;           /* Forward declaration */
+
 #if 1  /* FIXME: Gross and ugly hack to resolve coredep.c global */
 CORE_ADDR kernel_u_addr;
 #endif
@@ -406,6 +407,15 @@ lookupname PARAMS ((struct trans *, unsigned int, char *));
 static char *
 lookupdesc PARAMS ((struct trans *, unsigned int));
 
+static int
+do_attach PARAMS ((int pid));
+
+static void
+do_detach PARAMS ((int siggnal));
+
+static void
+procfs_create_inferior PARAMS ((char *, char *, char **));
+
 /* External function prototypes that can't be easily included in any
    header file because the args are typedefs in system include files. */
 
@@ -545,7 +555,8 @@ sigcodename (sip)
   return (name);
 }
 
-static char *sigcodedesc (sip)
+static char *
+sigcodedesc (sip)
      siginfo_t *sip;
 {
   struct sigcode *scp;
@@ -1031,13 +1042,13 @@ ptrace (request, pid, arg3, arg4)
 
 /*
 
-GLOBAL FUNCTION
+LOCAL FUNCTION
 
-       kill_inferior - kill any currently inferior
+       procfs_kill_inferior - kill any currently inferior
 
 SYNOPSIS
 
-       void kill_inferior (void)
+       void procfs_kill_inferior (void)
 
 DESCRIPTION
 
@@ -1051,8 +1062,8 @@ NOTES
 
 */
 
-void
-kill_inferior ()
+static void
+procfs_kill_inferior ()
 {
   if (inferior_pid != 0)
     {
@@ -1097,13 +1108,13 @@ unconditionally_kill_inferior ()
 
 /*
 
-GLOBAL FUNCTION
+LOCAL FUNCTION
 
-       child_xfer_memory -- copy data to or from inferior memory space
+       procfs_xfer_memory -- copy data to or from inferior memory space
 
 SYNOPSIS
 
-       int child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
+       int procfs_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
                int dowrite, struct target_ops target)
 
 DESCRIPTION
@@ -1113,7 +1124,7 @@ DESCRIPTION
        if DOWRITE is zero or to inferior if DOWRITE is nonzero.
   
        Returns the length copied, which is either the LEN argument or
-       zero.  This xfer function does not do partial moves, since child_ops
+       zero.  This xfer function does not do partial moves, since procfs_ops
        doesn't allow memory operations to cross below us in the target stack
        anyway.
 
@@ -1122,9 +1133,8 @@ NOTES
        The /proc interface makes this an almost trivial task.
  */
 
-
-int
-child_xfer_memory (memaddr, myaddr, len, dowrite, target)
+static int
+procfs_xfer_memory (memaddr, myaddr, len, dowrite, target)
      CORE_ADDR memaddr;
      char *myaddr;
      int len;
@@ -1153,13 +1163,13 @@ child_xfer_memory (memaddr, myaddr, len, dowrite, target)
 
 /*
 
-GLOBAL FUNCTION
+LOCAL FUNCTION
 
-       store_inferior_registers -- copy register values back to inferior
+       procfs_store_registers -- copy register values back to inferior
 
 SYNOPSIS
 
-       void store_inferior_registers (int regno)
+       void procfs_store_registers (int regno)
 
 DESCRIPTION
 
@@ -1189,8 +1199,8 @@ NOTES
 
  */
 
-void
-store_inferior_registers (regno)
+static void
+procfs_store_registers (regno)
      int regno;
 {
   if (regno != -1)
@@ -1219,13 +1229,13 @@ store_inferior_registers (regno)
 
 /*
 
-GLOBAL FUNCTION
+LOCAL FUNCTION
 
-       inferior_proc_init - initialize access to a /proc entry
+       procfs_init_inferior - initialize access to a /proc entry
 
 SYNOPSIS
 
-       void inferior_proc_init (int pid)
+       void procfs_init_inferior (int pid)
 
 DESCRIPTION
 
@@ -1242,10 +1252,13 @@ NOTES
 
  */
 
-void
-inferior_proc_init (pid)
+static void
+procfs_init_inferior (pid)
      int pid;
 {
+
+  push_target (&procfs_ops);
+
   if (!open_proc_file (pid, &pi, O_RDWR))
     {
       proc_init_failed ("can't open process file");
@@ -1322,7 +1335,7 @@ proc_signal_handling_change ()
 
 /*
 
-GLOBAL FUNCTION
+LOCAL FUNCTION
 
        proc_set_exec_trap -- arrange for exec'd child to halt at startup
 
@@ -1351,7 +1364,7 @@ NOTE
        tracing flags cleared.
  */
 
-void
+static void
 proc_set_exec_trap ()
 {
   sysset_t exitset;
@@ -1465,6 +1478,7 @@ proc_iterate_over_mappings (func)
   return (funcstat);
 }
 
+#if 0  /* Currently unused */
 /*
 
 GLOBAL FUNCTION
@@ -1486,9 +1500,6 @@ DESCRIPTION
        segment containing that address.
 */
 
-
-#if 0  /* Currently unused */
-
 CORE_ADDR
 proc_base_address (addr)
      CORE_ADDR addr;
@@ -1561,17 +1572,117 @@ proc_address_to_fd (addr, complain)
 }
 
 
-#ifdef ATTACH_DETACH
+/* Attach to process PID, then initialize for debugging it
+   and wait for the trace-trap that results from attaching.  */
+
+static void
+procfs_attach (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  char *exec_file;
+  int pid;
+
+  if (!args)
+    error_no_arg ("process-id to attach");
+
+  pid = atoi (args);
+
+  if (pid == getpid())         /* Trying to masturbate? */
+    error ("I refuse to debug myself!");
+
+  if (from_tty)
+    {
+      exec_file = (char *) get_exec_file (0);
+
+      if (exec_file)
+       printf ("Attaching program `%s', pid %d\n", exec_file, pid);
+      else
+       printf ("Attaching pid %d\n", pid);
+
+      fflush (stdout);
+    }
+
+  do_attach (pid);
+  inferior_pid = pid;
+  push_target (&procfs_ops);
+}
+
+
+/* Take a program previously attached to and detaches it.
+   The program resumes execution and will no longer stop
+   on signals, etc.  We'd better not have left any breakpoints
+   in the program or it'll die when it hits one.  For this
+   to work, it may be necessary for the process to have been
+   previously attached.  It *might* work if the program was
+   started via the normal ptrace (PTRACE_TRACEME).  */
+
+static void
+procfs_detach (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  int siggnal = 0;
+
+  if (from_tty)
+    {
+      char *exec_file = get_exec_file (0);
+      if (exec_file == 0)
+       exec_file = "";
+      printf ("Detaching program: %s pid %d\n",
+             exec_file, inferior_pid);
+      fflush (stdout);
+    }
+  if (args)
+    siggnal = atoi (args);
+  
+  do_detach (siggnal);
+  inferior_pid = 0;
+  unpush_target (&procfs_ops);         /* Pop out of handling an inferior */
+}
+
+/* Get ready to modify the registers array.  On machines which store
+   individual registers, this doesn't need to do anything.  On machines
+   which store all the registers in one fell swoop, this makes sure
+   that registers contains all the registers from the program being
+   debugged.  */
+
+static void
+procfs_prepare_to_store ()
+{
+#ifdef CHILD_PREPARE_TO_STORE
+  CHILD_PREPARE_TO_STORE ();
+#endif
+}
+
+/* Print status information about what we're accessing.  */
+
+static void
+procfs_files_info (ignore)
+     struct target_ops *ignore;
+{
+  printf ("\tUsing the running image of %s process %d via /proc.\n",
+         attach_flag? "attached": "child", inferior_pid);
+}
+
+/* ARGSUSED */
+static void
+procfs_open (arg, from_tty)
+     char *arg;
+     int from_tty;
+{
+  error ("Use the \"run\" command to start a Unix child process.");
+}
 
 /*
 
-GLOBAL FUNCTION
+LOCAL FUNCTION
 
-       attach -- attach to an already existing process
+       do_attach -- attach to an already existing process
 
 SYNOPSIS
 
-       int attach (int pid)
+       int do_attach (int pid)
 
 DESCRIPTION
 
@@ -1588,8 +1699,8 @@ NOTES
 
 */
 
-int
-attach (pid)
+static int
+do_attach (pid)
      int pid;
 {
   int result;
@@ -1681,13 +1792,13 @@ attach (pid)
 
 /*
 
-GLOBAL FUNCTION
+LOCAL FUNCTION
 
-       detach -- detach from an attached-to process
+       do_detach -- detach from an attached-to process
 
 SYNOPSIS
 
-       void detach (int signal)
+       void do_detach (int signal)
 
 DESCRIPTION
 
@@ -1708,8 +1819,8 @@ DESCRIPTION
        be the ideal situation.  (FIXME).
  */
 
-void
-detach (signal)
+static void
+do_detach (signal)
      int signal;
 {
   int result;
@@ -1786,17 +1897,18 @@ detach (signal)
   attach_flag = 0;
 }
 
-#endif /* ATTACH_DETACH */
-
 /*
 
-GLOBAL FUNCTION
+LOCAL FUNCTION
+
+       procfs_wait -- emulate wait() as much as possible
+       Wait for child to do something.  Return pid of child, or -1 in case
+       of error; store status through argument pointer STATUS.
 
-       proc_wait -- emulate wait() as much as possible
 
 SYNOPSIS
 
-       int proc_wait (int *statloc)
+       int procfs_wait (int *statloc)
 
 DESCRIPTION
 
@@ -1825,8 +1937,8 @@ NOTES
 
  */
 
-int
-proc_wait (statloc)
+static int
+procfs_wait (statloc)
      int *statloc;
 {
   short what;
@@ -1942,10 +2054,19 @@ proc_wait (statloc)
             pi.prstatus.pr_flags);
          /* NOTREACHED */
     }
+
   if (statloc)
     {
       *statloc = statval;
     }
+
+  if (rtnval == -1)            /* No more children to wait for */
+    {
+      fprintf (stderr, "Child process unexpectedly missing.\n");
+      *statloc = 42;   /* Claim it exited with signal 42 */
+      return rtnval;
+    }
+
   return (rtnval);
 }
 
@@ -2021,13 +2142,13 @@ set_proc_siginfo (pip, signo)
 
 /*
 
-GLOBAL FUNCTION
+LOCAL FUNCTION
 
-       child_resume -- resume execution of the inferior process
+       procfs_resume -- resume execution of the inferior process
 
 SYNOPSIS
 
-       void child_resume (int step, int signo)
+       void procfs_resume (int step, int signo)
 
 DESCRIPTION
 
@@ -2055,8 +2176,8 @@ NOTE
        an inferior to continue running at the same time as gdb.  (FIXME?)
  */
 
-void
-child_resume (step, signo)
+static void
+procfs_resume (step, signo)
      int step;
      int signo;
 {
@@ -2095,13 +2216,13 @@ child_resume (step, signo)
 
 /*
 
-GLOBAL FUNCTION
+LOCAL FUNCTION
 
-       fetch_inferior_registers -- fetch current registers from inferior
+       procfs_fetch_registers -- fetch current registers from inferior
 
 SYNOPSIS
 
-       void fetch_inferior_registers (int regno)
+       void procfs_fetch_registers (int regno)
 
 DESCRIPTION
 
@@ -2111,8 +2232,8 @@ DESCRIPTION
 
 */
 
-void
-fetch_inferior_registers (regno)
+static void
+procfs_fetch_registers (regno)
      int regno;
 {
   if (ioctl (pi.fd, PIOCGREG, &pi.gregset) != -1)
@@ -2773,7 +2894,9 @@ DESCRIPTION
        info proc mappings      (prints address mappings)
        info proc times         (prints process/children times)
        info proc id            (prints pid, ppid, gid, sid, etc)
+               FIXME:  i proc id not implemented.
        info proc status        (prints general process state info)
+               FIXME:  i proc status not implemented.
        info proc signals       (prints info about signal handling)
        info proc all           (prints all info)
 
@@ -2936,15 +3059,86 @@ info_proc (args, from_tty)
   do_cleanups (old_chain);
 }
 
+/* Fork an inferior process, and start debugging it with /proc.  */
+
+static void
+procfs_create_inferior (exec_file, allargs, env)
+     char *exec_file;
+     char *allargs;
+     char **env;
+{
+  fork_inferior (exec_file, allargs, env,
+                proc_set_exec_trap, procfs_init_inferior);
+  /* We are at the first instruction we care about.  */
+  /* Pedal to the metal... */
+  proceed ((CORE_ADDR) -1, 0, 0);
+}
+
+/* Clean up after the inferior dies.  */
+
+static void
+procfs_mourn_inferior ()
+{
+  unpush_target (&procfs_ops);
+  generic_mourn_inferior ();
+}
+
+/* Mark our target-struct as eligible for stray "run" and "attach" commands.  */
+static int
+procfs_can_run ()
+{
+  return(1);
+}
+\f
+struct target_ops procfs_ops = {
+  "procfs",                    /* to_shortname */
+  "Unix /proc child process",  /* to_longname */
+  "Unix /proc child process (started by the \"run\" command).",        /* to_doc */
+  procfs_open,                 /* to_open */
+  0,                           /* to_close */
+  procfs_attach,                       /* to_attach */
+  procfs_detach,               /* to_detach */
+  procfs_resume,                       /* to_resume */
+  procfs_wait,                 /* to_wait */
+  procfs_fetch_registers,      /* to_fetch_registers */
+  procfs_store_registers,      /* to_store_registers */
+  procfs_prepare_to_store,     /* to_prepare_to_store */
+  procfs_xfer_memory,          /* to_xfer_memory */
+  procfs_files_info,           /* to_files_info */
+  memory_insert_breakpoint,    /* to_insert_breakpoint */
+  memory_remove_breakpoint,    /* to_remove_breakpoint */
+  terminal_init_inferior,      /* to_terminal_init */
+  terminal_inferior,           /* to_terminal_inferior */
+  terminal_ours_for_output,    /* to_terminal_ours_for_output */
+  terminal_ours,               /* to_terminal_ours */
+  child_terminal_info,         /* to_terminal_info */
+  procfs_kill_inferior,                /* to_kill */
+  0,                           /* to_load */
+  0,                           /* to_lookup_symbol */
+  procfs_create_inferior,      /* to_create_inferior */
+  procfs_mourn_inferior,       /* to_mourn_inferior */
+  procfs_can_run,              /* to_can_run */
+  process_stratum,             /* to_stratum */
+  0,                           /* to_next */
+  1,                           /* to_has_all_memory */
+  1,                           /* to_has_memory */
+  1,                           /* to_has_stack */
+  1,                           /* to_has_registers */
+  1,                           /* to_has_execution */
+  0,                           /* sections */
+  0,                           /* sections_end */
+  OPS_MAGIC                    /* to_magic */
+};
+
 /*
 
 GLOBAL FUNCTION
 
-       _initialize_proc_fs -- initialize the process file system stuff
+       _initialize_procfs -- initialize the process file system stuff
 
 SYNOPSIS
 
-       void _initialize_proc_fs (void)
+       void _initialize_procfs (void)
 
 DESCRIPTION
 
@@ -2953,19 +3147,18 @@ DESCRIPTION
 
 */
 
-static char *proc_desc =
+void
+_initialize_procfs ()
+{
+  add_target (&procfs_ops);
+
+  add_info ("proc", info_proc, 
 "Show process status information using /proc entry.\n\
 Specify process id or use current inferior by default.\n\
 Specify keywords for detailed information; default is summary.\n\
 Keywords are: `all', `faults', `flags', `id', `mappings', `signals',\n\
 `status', `syscalls', and `times'.\n\
-Unambiguous abbreviations may be used.";
+Unambiguous abbreviations may be used.");
 
-void
-_initialize_proc_fs ()
-{
-  add_info ("proc", info_proc, proc_desc);
   init_syscall_table ();
 }
-
-#endif /* USE_PROC_FS */
index e25b6be7381a58cc5b6c46de2335402271f00f7d..1ecbd5cd6e2fd6a1ffee4f0a0485f75caf08ade5 100644 (file)
@@ -43,12 +43,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define USE_PROC_FS
 #define PROC_NAME_FMT "/debug/%d"
 
-/* If we are using SVR4 /proc instead of ptrace, use CREATE_INFERIOR_HOOK
-   to do internal /proc initialization. */
-#ifdef USE_PROC_FS
-#define CREATE_INFERIOR_HOOK(pid) inferior_proc_init(pid)
-#endif
-
 /* Irix defines psignal() in signal.h, which gets gcc rather angry at us
  * because their definition is markedly different.
  */
index 4968b5e88a43010ed047fd8171b2828a85f228d1..07cd547891abb88e9da240f6973f05b3edf3036c 100644 (file)
@@ -55,13 +55,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #define ATTACH_DETACH
 
-/* If we are using SVR4 /proc instead of ptrace, use CREATE_INFERIOR_HOOK
-   to do internal /proc initialization. */
-
-#ifdef USE_PROC_FS
-#define CREATE_INFERIOR_HOOK(pid) inferior_proc_init(pid)
-#endif
-
 /* Use setpgid(0,0) to run inferior in a separate process group */
 
 #define NEED_POSIX_SETPGID