20000-05-18 H.J. Lu (hjl@gnu.org)
[binutils-gdb.git] / gdb / procfs.c
index d1763869eff7c789f11a543b21ce3ae49dded904..2fa825b41bc3a6b8a567d3f8b85fbb821e437b53 100644 (file)
@@ -24,6 +24,7 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "target.h"
 #include "gdbcore.h"
 #include "gdbcmd.h"
+#include "gdbthread.h"
 
 #if defined (NEW_PROC_API)
 #define _STRUCTURED_PROC 1     /* Should be done by configure script. */
@@ -33,6 +34,9 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include <sys/fault.h>
 #include <sys/syscall.h>
 #include <sys/errno.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <ctype.h>
 
 /* 
  * PROCFS.C
@@ -79,6 +83,12 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include <unistd.h>    /* for "X_OK" */
 #include "gdb_stat.h"  /* for struct stat */
 
+/* Note: procfs-utils.h must be included after the above system header
+   files, because it redefines various system calls using macros.
+   This may be incompatible with the prototype declarations.  */
+
+#include "proc-utils.h"
+
 /* =================== TARGET_OPS "MODULE" =================== */
 
 /*
@@ -148,6 +158,8 @@ init_procfs_ops ()
   procfs_ops.to_thread_alive       = procfs_thread_alive;
   procfs_ops.to_pid_to_str         = procfs_pid_to_str;
 
+  procfs_ops.to_has_all_memory     = 1;
+  procfs_ops.to_has_memory         = 1;
   procfs_ops.to_has_execution      = 1;
   procfs_ops.to_has_stack          = 1;
   procfs_ops.to_has_registers      = 1;
@@ -158,36 +170,6 @@ init_procfs_ops ()
 
 /* =================== END, TARGET_OPS "MODULE" =================== */
 
-/*
- * Temporary debugging code:
- *
- * These macros allow me to trace the system calls that we make
- * to control the child process.  This is quite handy for comparing
- * with the older version of procfs.
- */
-
-#ifdef TRACE_PROCFS
-#ifdef NEW_PROC_API
-extern  int   write_with_trace PARAMS ((int, void *, size_t, char *, int));
-extern  off_t lseek_with_trace PARAMS ((int, off_t,  int,    char *, int));
-#define write(X,Y,Z)   write_with_trace (X, Y, Z, __FILE__, __LINE__)
-#define lseek(X,Y,Z)   lseek_with_trace (X, Y, Z, __FILE__, __LINE__)
-#else
-extern  int ioctl_with_trace PARAMS ((int, long, void *, char *, int));
-#define ioctl(X,Y,Z)   ioctl_with_trace (X, Y, Z, __FILE__, __LINE__)
-#endif
-#define open(X,Y)      open_with_trace  (X, Y,    __FILE__, __LINE__)
-#define close(X)       close_with_trace (X,       __FILE__, __LINE__)
-#define wait(X)        wait_with_trace  (X,       __FILE__, __LINE__)
-#define PROCFS_NOTE(X) procfs_note      (X,       __FILE__, __LINE__)
-#define PROC_PRETTYFPRINT_STATUS(X,Y,Z,T) \
-proc_prettyfprint_status (X, Y, Z, T)
-#else
-#define PROCFS_NOTE(X)
-#define PROC_PRETTYFPRINT_STATUS(X,Y,Z,T)
-#endif
-
-
 /*
  * World Unification:
  *
@@ -287,6 +269,8 @@ typedef prstatus_t gdb_lwpstatus_t;
 #ifndef PIDGET
 #define PIDGET(PID)            (PID)
 #define TIDGET(PID)            (PID)
+#endif
+#ifndef MERGEPID
 #define MERGEPID(PID, TID)     (PID)
 #endif
 
@@ -403,11 +387,13 @@ find_procinfo_or_die (pid, tid)
   procinfo *pi = find_procinfo (pid, tid);
 
   if (pi == NULL)
-    if (tid)
-      error ("procfs: couldn't find pid %d (kernel thread %d) in procinfo list.", 
-            pid, tid);
-    else
-      error ("procfs: couldn't find pid %d in procinfo list.", pid);
+    {
+      if (tid)
+       error ("procfs: couldn't find pid %d (kernel thread %d) in procinfo list.", 
+              pid, tid);
+      else
+       error ("procfs: couldn't find pid %d in procinfo list.", pid);
+    }
   return pi;
 }
 
@@ -431,7 +417,9 @@ open_procinfo_files (pi, which)
      procinfo *pi;
      int       which;
 {
+#ifdef NEW_PROC_API
   char tmp[MAX_PROC_NAME_SIZE];
+#endif
   int  fd;
 
   /* 
@@ -576,7 +564,7 @@ open_procinfo_files (pi, which)
  * Function: create_procinfo
  *
  * Allocate a data structure and link it into the procinfo list.
- * (First tries to find a pre-existing one (FIXME: why???)
+ * (First tries to find a pre-existing one (FIXME: why?)
  *
  * Return: pointer to new procinfo struct.
  */
@@ -1377,7 +1365,7 @@ proc_stop_process (pi)
   else
     {
 #ifdef NEW_PROC_API
-      int cmd = PCSTOP;
+      long cmd = PCSTOP;
       win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd));
 #else  /* ioctl method */
       win = (ioctl (pi->ctl_fd, PIOCSTOP, &pi->prstatus) >= 0);
@@ -1421,7 +1409,7 @@ proc_wait_for_stop (pi)
 
 #ifdef NEW_PROC_API
   {
-    int cmd = PCWSTOP;
+    long cmd = PCWSTOP;
     win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd));
     /* We been runnin' and we stopped -- need to update status.  */
     pi->status_valid = 0;
@@ -1498,7 +1486,7 @@ proc_run_process (pi, step, signo)
 
 #ifdef NEW_PROC_API
   {
-    int cmd[2];
+    long cmd[2];
 
     cmd[0]  = PCRUN;
     cmd[1]  = runflags;
@@ -1544,7 +1532,7 @@ proc_set_traced_signals (pi, sigset)
 #ifdef NEW_PROC_API
   {
     struct {
-      int cmd;
+      long cmd;
       /* Use char array to avoid alignment issues.  */
       char sigset[sizeof (sigset_t)];
     } arg;
@@ -1592,7 +1580,7 @@ proc_set_traced_faults (pi, fltset)
 #ifdef NEW_PROC_API
   {
     struct {
-      int cmd;
+      long cmd;
       /* Use char array to avoid alignment issues.  */
       char fltset[sizeof (fltset_t)];
     } arg;
@@ -1638,7 +1626,7 @@ proc_set_traced_sysentry (pi, sysset)
 #ifdef NEW_PROC_API
   {
     struct {
-      int cmd;
+      long cmd;
       /* Use char array to avoid alignment issues.  */
       char sysset[sizeof (sysset_t)];
     } arg;
@@ -1684,7 +1672,7 @@ proc_set_traced_sysexit (pi, sysset)
 #ifdef NEW_PROC_API
   {
     struct {
-      int cmd;
+      long cmd;
       /* Use char array to avoid alignment issues.  */
       char sysset[sizeof (sysset_t)];
     } arg;
@@ -1730,7 +1718,7 @@ proc_set_held_signals (pi, sighold)
 #ifdef NEW_PROC_API
   {
     struct {
-      int cmd;
+      long cmd;
       /* Use char array to avoid alignment issues.  */
       char hold[sizeof (sigset_t)];
     } arg;
@@ -2148,7 +2136,7 @@ proc_clear_current_fault (pi)
 
 #ifdef NEW_PROC_API
   {
-    int cmd = PCCFAULT;
+    long cmd = PCCFAULT;
     win = (write (pi->ctl_fd, (void *) &cmd, sizeof (cmd)) == sizeof (cmd));
   }
 #else
@@ -2178,7 +2166,7 @@ proc_set_current_signal (pi, signo)
 {
   int win;
   struct {
-    int cmd;
+    long cmd;
     /* Use char array to avoid alignment issues.  */
     char sinfo[sizeof (struct siginfo)];
   } arg;
@@ -2248,7 +2236,7 @@ proc_clear_current_signal (pi)
 #ifdef NEW_PROC_API
   {
     struct {
-      int cmd;
+      long cmd;
       /* Use char array to avoid alignment issues.  */
       char sinfo[sizeof (struct siginfo)];
     } arg;
@@ -2408,7 +2396,7 @@ proc_set_gregs (pi)
     {
 #ifdef NEW_PROC_API
       struct {
-       int cmd;
+       long cmd;
        /* Use char array to avoid alignment issues.  */
        char gregs[sizeof (gdb_gregset_t)];
       } arg;
@@ -2452,7 +2440,7 @@ proc_set_fpregs (pi)
     {
 #ifdef NEW_PROC_API
       struct {
-       int cmd;
+       long cmd;
        /* Use char array to avoid alignment issues.  */
        char fpregs[sizeof (gdb_fpregset_t)];
       } arg;
@@ -2516,7 +2504,7 @@ proc_kill (pi, signo)
   else
     {
 #ifdef NEW_PROC_API
-      int cmd[2];
+      long cmd[2];
 
       cmd[0] = PCKILL;
       cmd[1] = signo;
@@ -2567,8 +2555,8 @@ proc_parent_pid (pi)
 
 int
 proc_set_watchpoint (pi, addr, len, wflags)
-     procinfo *pi;
-     void     *addr;
+     procinfo  *pi;
+     CORE_ADDR addr;
      int       len;
      int       wflags;
 {
@@ -2580,7 +2568,7 @@ proc_set_watchpoint (pi, addr, len, wflags)
   return 0;
 #else
   struct {
-    int cmd;
+    long cmd;
     char watch[sizeof (prwatch_t)];
   } arg;
   prwatch_t *pwatch;
@@ -2627,11 +2615,14 @@ proc_iterate_over_mappings (func)
   struct prmap *map;
   procinfo *pi;
 #ifndef NEW_PROC_API   /* avoid compiler warning */
-  int nmaps = 0, i;
+  int nmaps = 0;
+  int i;
+#else
+  int map_fd;
+  char pathname[MAX_PROC_NAME_SIZE];
 #endif
   int funcstat = 0;
-  int fd, map_fd;
-  char pathname[MAX_PROC_NAME_SIZE];
+  int fd;
 
   pi = find_procinfo_or_die (PIDGET (inferior_pid), 0);
 
@@ -3466,6 +3457,19 @@ do_detach (signo)
  * is resumed.
  */
 
+/* These could go in a header file, but the many and various
+   definitions of gregset_t would make it tricky and ugly.  Several
+   different native operating systems (notably Solaris and Linux) have
+   various different definitions for gregset_t and fpregset_t.  We
+   have been kludging around this problem for a while, it would be
+   nice if someday we came up with a prettier way of handling it
+   (FIXME).  */
+
+extern void fill_gregset (gdb_gregset_t *, int);
+extern void fill_fpregset (gdb_fpregset_t *, int);
+extern void supply_gregset (gdb_gregset_t *);
+extern void supply_fpregset (gdb_fpregset_t *);
+
 static void
 procfs_fetch_registers (regno)
      int regno;
@@ -3498,21 +3502,20 @@ procfs_fetch_registers (regno)
 
   supply_gregset (gregs);
 
-#if defined (FP0_REGNUM)       /* need floating point? */
-  if ((regno >= 0 && regno < FP0_REGNUM) ||
-      regno == PC_REGNUM  ||
-#ifdef NPC_REGNUM
-      regno == NPC_REGNUM ||
-#endif
-      regno == FP_REGNUM  ||
-      regno == SP_REGNUM)
-    return;                    /* not a floating point register */
+  if (FP0_REGNUM >= 0) /* need floating point? */
+    {
+      if ((regno >= 0 && regno < FP0_REGNUM) ||
+         regno == PC_REGNUM  ||
+         (NPC_REGNUM >= 0 && regno == NPC_REGNUM) ||
+         regno == FP_REGNUM  ||
+         regno == SP_REGNUM)
+       return;                 /* not a floating point register */
 
-  if ((fpregs = proc_get_fpregs (pi)) == NULL)
-    proc_error (pi, "fetch_registers, get_fpregs", __LINE__);
+      if ((fpregs = proc_get_fpregs (pi)) == NULL)
+       proc_error (pi, "fetch_registers, get_fpregs", __LINE__);
 
-  supply_fpregset (fpregs);
-#endif
+      supply_fpregset (fpregs);
+    }
 }
 
 /* Get ready to modify the registers array.  On machines which store
@@ -3574,23 +3577,22 @@ procfs_store_registers (regno)
   if (!proc_set_gregs (pi))
     proc_error (pi, "store_registers, set_gregs", __LINE__);
 
-#if defined (FP0_REGNUM)       /* need floating point? */
-  if ((regno >= 0 && regno < FP0_REGNUM) ||
-      regno == PC_REGNUM  ||
-#ifdef NPC_REGNUM
-      regno == NPC_REGNUM ||
-#endif
-      regno == FP_REGNUM  ||
-      regno == SP_REGNUM)
-    return;                    /* not a floating point register */
-
-  if ((fpregs = proc_get_fpregs (pi)) == NULL)
-    proc_error (pi, "store_registers, get_fpregs", __LINE__);
-
-  fill_fpregset (fpregs, regno);
-  if (!proc_set_fpregs (pi))
-    proc_error (pi, "store_registers, set_fpregs", __LINE__);
-#endif
+  if (FP0_REGNUM >= 0)         /* need floating point? */
+    {
+      if ((regno >= 0 && regno < FP0_REGNUM) ||
+         regno == PC_REGNUM  ||
+         (NPC_REGNUM >= 0 && regno == NPC_REGNUM) ||
+         regno == FP_REGNUM  ||
+         regno == SP_REGNUM)
+       return;                 /* not a floating point register */
+
+      if ((fpregs = proc_get_fpregs (pi)) == NULL)
+       proc_error (pi, "store_registers, get_fpregs", __LINE__);
+
+      fill_fpregset (fpregs, regno);
+      if (!proc_set_fpregs (pi))
+       proc_error (pi, "store_registers, set_fpregs", __LINE__);
+    }
 }
 
 /*
@@ -3733,7 +3735,7 @@ wait_again:
                         return a "success" exit code.  Bogus: what if
                         it returns something else?  */
                      wstat = 0;
-                     retval = inferior_pid;  /* ??? */
+                     retval = inferior_pid;  /* ? ? ? */
                    }
                  else
                    {
@@ -3762,9 +3764,9 @@ wait_again:
                    if ((nsysargs = proc_nsysarg (pi)) > 0 &&
                        (sysargs  = proc_sysargs (pi)) != NULL)
                      {
-                       printf_filtered ("%d syscall arguments:\n", nsysargs);
+                       printf_filtered ("%ld syscall arguments:\n", nsysargs);
                        for (i = 0; i < nsysargs; i++)
-                         printf_filtered ("#%d: 0x%08x\n", 
+                         printf_filtered ("#%ld: 0x%08lx\n", 
                                           i, sysargs[i]);
                      }
 
@@ -3876,9 +3878,9 @@ wait_again:
                    if ((nsysargs = proc_nsysarg (pi)) > 0 &&
                        (sysargs  = proc_sysargs (pi)) != NULL)
                      {
-                       printf_filtered ("%d syscall arguments:\n", nsysargs);
+                       printf_filtered ("%ld syscall arguments:\n", nsysargs);
                        for (i = 0; i < nsysargs; i++)
-                         printf_filtered ("#%d: 0x%08x\n", 
+                         printf_filtered ("#%ld: 0x%08lx\n", 
                                           i, sysargs[i]);
                      }
                  }
@@ -4111,14 +4113,13 @@ invalidate_cache (parent, pi, ptr)
       if (!proc_set_gregs (pi))        /* flush gregs cache */
        proc_warn (pi, "target_resume, set_gregs",
                   __LINE__);
-#ifdef FP0_REGNUM
-  if (pi->fpregs_dirty)
-    if (parent == NULL ||
-       proc_get_current_thread (parent) != pi->tid)
-      if (!proc_set_fpregs (pi))       /* flush fpregs cache */
-       proc_warn (pi, "target_resume, set_fpregs", 
-                  __LINE__);
-#endif
+  if (FP0_REGNUM >= 0)
+    if (pi->fpregs_dirty)
+      if (parent == NULL ||
+         proc_get_current_thread (parent) != pi->tid)
+       if (!proc_set_fpregs (pi))      /* flush fpregs cache */
+         proc_warn (pi, "target_resume, set_fpregs", 
+                    __LINE__);
 #endif
 
   if (parent != NULL)
@@ -4141,6 +4142,7 @@ invalidate_cache (parent, pi, ptr)
   return 0;
 }
 
+#if 0
 /*
  * Function: make_signal_thread_runnable
  *
@@ -4165,6 +4167,7 @@ make_signal_thread_runnable (process, pi, ptr)
 #endif
   return 0;
 }
+#endif
 
 /*
  * Function: target_resume
@@ -4216,7 +4219,7 @@ procfs_resume (pid, step, signo)
 
   /* Convert signal to host numbering.  */
   if (signo == 0 ||
-      signo == TARGET_SIGNAL_STOP && pi->ignore_next_sigstop)
+      (signo == TARGET_SIGNAL_STOP && pi->ignore_next_sigstop))
     native_signo = 0;
   else
     native_signo = target_signal_to_host (signo);
@@ -4432,7 +4435,7 @@ unconditionally_kill_inferior (pi)
   }
 #else /* PROCFS_NEED_PIOCSSIG_FOR_KILL */
   if (!proc_kill (pi, SIGKILL))
-    proc_warn (pi, "unconditionally_kill, proc_kill", __LINE__);
+    proc_error (pi, "unconditionally_kill, proc_kill", __LINE__);
 #endif /* PROCFS_NEED_PIOCSSIG_FOR_KILL */
   destroy_procinfo (pi);
 
@@ -4603,7 +4606,6 @@ procfs_set_exec_trap ()
 
   procinfo *pi;
   sysset_t exitset;
-  sysset_t entryset;
 
   if ((pi = create_procinfo (getpid (), 0)) == NULL)
     perror_with_name ("procfs: create_procinfo failed in child.");
@@ -5027,11 +5029,12 @@ info_proc_cmd (args, from_tty)
 
   old_chain = make_cleanup (null_cleanup, 0);
   if (args)
-    if ((argv = buildargv (args)) == NULL)
-      nomem (0);
-    else
-      make_cleanup ((make_cleanup_func) freeargv, argv);
-
+    {
+      if ((argv = buildargv (args)) == NULL)
+       nomem (0);
+      else
+       make_cleanup ((make_cleanup_func) freeargv, argv);
+    }
   while (argv != NULL && *argv != NULL)
     {
       if (isdigit (argv[0][0]))
@@ -5173,27 +5176,6 @@ proc_untrace_sysexit_cmd (args, from_tty)
 }
 
 
-int
-mapping_test (fd, core_addr)
-     int fd;
-     CORE_ADDR core_addr;
-{
-  printf ("File descriptor %d, base address 0x%08x\n", fd, core_addr);
-  if (fd > 0)
-    close (fd);
-  return 0;
-}
-
-void
-test_mapping_cmd (args, from_tty)
-     char *args;
-     int from_tty;
-{
-  int ret;
-  ret = proc_iterate_over_mappings (mapping_test);
-  printf ("iterate_over_mappings returned %d.\n", ret);
-}
-
 void
 _initialize_procfs ()
 {
@@ -5210,9 +5192,6 @@ Default is the process being debugged.");
           "Cancel a trace of entries into the syscall.");
   add_com ("proc-untrace-exit", no_class, proc_untrace_sysexit_cmd, 
           "Cancel a trace of exits from the syscall.");
-
-  add_com ("test-mapping", no_class, test_mapping_cmd, 
-          "test iterate-over-mappings");
 }
 
 /* =================== END, GDB  "MODULE" =================== */
@@ -5237,20 +5216,3 @@ procfs_first_available ()
   else
     return -1;
 }
-
-int
-procfs_get_pid_fd (pid)
-     int pid;
-{
-  procinfo *pi;
-
-  if (pid == -1 && inferior_pid != 0)
-    pi = find_procinfo (PIDGET (inferior_pid), 0);
-  else
-    pi = find_procinfo (PIDGET (pid), 0);
-
-  if (pi)
-    return pi->ctl_fd;
-  else
-    return -1;
-}