import gdb-19990504 snapshot
[deliverable/binutils-gdb.git] / gdb / procfs.c
index e8215a523be5556af98bfadf8d85d14708db9e45..8a68a8964976f485d487ca2231cb845310989872 100644 (file)
@@ -1,5 +1,5 @@
 /* Machine independent support for SVR4 /proc (process file system) for GDB.
-   Copyright 1991, 1992-96, 1997 Free Software Foundation, Inc.
+   Copyright 1991, 1992-98, 1999 Free Software Foundation, Inc.
    Written by Fred Fish at Cygnus Support.  Changes for sysv4.2mp procfs
    compatibility by Geoffrey Noer at Cygnus Solutions.
 
@@ -54,12 +54,60 @@ regardless of whether or not the actual target has floating point hardware.
 #include "gdbcore.h"
 #include "gdbthread.h"
 
+#if !defined(SYS_lwp_create) && defined(SYS_lwpcreate)
+# define SYS_lwp_create SYS_lwpcreate
+#endif
+
+#if !defined(SYS_lwp_exit) && defined(SYS_lwpexit)
+# define SYS_lwp_exit SYS_lwpexit
+#endif
+
+#if !defined(SYS_lwp_wait) && defined(SYS_lwpwait)
+# define SYS_lwp_wait SYS_lwpwait
+#endif
+
+#if !defined(SYS_lwp_self) && defined(SYS_lwpself)
+# define SYS_lwp_self SYS_lwpself
+#endif
+
+#if !defined(SYS_lwp_info) && defined(SYS_lwpinfo)
+# define SYS_lwp_info SYS_lwpinfo
+#endif
+
+#if !defined(SYS_lwp_private) && defined(SYS_lwpprivate)
+# define SYS_lwp_private SYS_lwpprivate
+#endif
+
+#if !defined(SYS_lwp_kill) && defined(SYS_lwpkill)
+# define SYS_lwp_kill SYS_lwpkill
+#endif
+
+#if !defined(SYS_lwp_suspend) && defined(SYS_lwpsuspend)
+# define SYS_lwp_suspend SYS_lwpsuspend
+#endif
+
+#if !defined(SYS_lwp_continue) && defined(SYS_lwpcontinue)
+# define SYS_lwp_continue SYS_lwpcontinue
+#endif
+
 /* the name of the proc status struct depends on the implementation */
-#ifdef HAVE_PSTATUS_T
-  typedef pstatus_t gdb_prstatus_t;
-#else
+/* Wrap Light Weight Process member in THE_PR_LWP macro for clearer code */
+#ifndef HAVE_PSTATUS_T
   typedef prstatus_t gdb_prstatus_t;
+#define THE_PR_LWP(a)  a
+#else  /* HAVE_PSTATUS_T */
+  typedef pstatus_t gdb_prstatus_t;
+#define THE_PR_LWP(a)  a.pr_lwp
+#if !defined(HAVE_PRRUN_T) && defined(HAVE_MULTIPLE_PROC_FDS)
+  /* Fallback definitions - for using configure information directly */
+#ifndef UNIXWARE
+#define UNIXWARE       1
+#endif
+#if !defined(PROCFS_USE_READ_WRITE) && !defined(HAVE_PROCFS_PIOCSET)
+#define PROCFS_USE_READ_WRITE  1
 #endif
+#endif /* !HAVE_PRRUN_T && HAVE_MULTIPLE_PROC_FDS */
+#endif /* HAVE_PSTATUS_T */
 
 #define MAX_SYSCALLS   256     /* Maximum number of syscalls for table */
 
@@ -80,9 +128,28 @@ regardless of whether or not the actual target has floating point hardware.
 #  endif
 #endif /* HAVE_MULTIPLE_PROC_FDS */
 
+
+/* These #ifdefs are for sol2.x in particular.  sol2.x has
+   both a "gregset_t" and a "prgregset_t", which have
+   similar uses but different layouts.  sol2.x gdb tries to
+   use prgregset_t (and prfpregset_t) everywhere. */
+
+#ifdef GDB_GREGSET_TYPE
+  typedef GDB_GREGSET_TYPE gdb_gregset_t;
+#else
+  typedef gregset_t gdb_gregset_t;
+#endif
+
+#ifdef GDB_FPREGSET_TYPE
+  typedef GDB_FPREGSET_TYPE gdb_fpregset_t;
+#else
+  typedef fpregset_t gdb_fpregset_t;
+#endif
+
+
 #define MAX_PROC_NAME_SIZE sizeof("/proc/1234567890/status")
 
-extern struct target_ops procfs_ops;           /* Forward declaration */
+struct target_ops procfs_ops;
 
 int procfs_suppress_run = 0;   /* Non-zero if procfs should pretend not to
                                   be a runnable target.  Used by targets
@@ -113,13 +180,13 @@ struct proc_ctl {
 /* set general registers */
 struct greg_ctl {
         int             cmd;
-        gregset_t       gregset;
+        gdb_gregset_t  gregset;
 };
 
 /* set fp registers */
 struct fpreg_ctl {
         int             cmd;
-        fpregset_t      fpregset;
+        gdb_fpregset_t fpregset;
 };
 
 /* set signals to be traced */
@@ -166,7 +233,7 @@ struct procinfo {
   int had_event;               /* poll/select says something happened */
   int was_stopped;             /* Nonzero if was stopped prior to attach */
   int nopass_next_sigstop;     /* Don't pass a sigstop on next resume */
-#ifndef HAVE_NO_PRRUN_T
+#ifdef HAVE_PRRUN_T
   prrun_t prrun;               /* Control state when it is run */
 #endif
   gdb_prstatus_t prstatus;     /* Current process status info */
@@ -185,6 +252,8 @@ struct procinfo {
                                   currently installed */
                                /* Pointer to list of syscall trap handlers */
   struct procfs_syscall_handler *syscall_handlers; 
+  int saved_rtnval;            /* return value and status for wait(), */
+  int saved_statval;           /*  as supplied by a syscall handler. */
   int new_child;               /* Non-zero if it's a new thread */
 };
 
@@ -477,7 +546,7 @@ static void procfs_attach PARAMS ((char *, int));
 
 static void proc_set_exec_trap PARAMS ((void));
 
-static int procfs_init_inferior PARAMS ((int));
+static void  procfs_init_inferior PARAMS ((int));
 
 static struct procinfo *create_procinfo PARAMS ((int));
 
@@ -513,6 +582,10 @@ static int open_proc_file PARAMS ((int, struct procinfo *, int, int));
 
 static void close_proc_file PARAMS ((struct procinfo *));
 
+static void close_proc_file_cleanup PARAMS ((void*));
+
+static struct cleanup *make_cleanup_close_proc_file PARAMS ((struct procinfo *));
+
 static void unconditionally_kill_inferior PARAMS ((struct procinfo *));
 
 static NORETURN void proc_init_failed PARAMS ((struct procinfo *, char *, int)) ATTR_NORETURN;
@@ -596,17 +669,19 @@ struct procfs_syscall_handler
 static void procfs_resume PARAMS ((int pid, int step,
                                   enum target_signal signo));
 
+static void init_procfs_ops PARAMS ((void));
+
 /* External function prototypes that can't be easily included in any
    header file because the args are typedefs in system include files. */
 
-extern void supply_gregset PARAMS ((gregset_t *));
+extern void supply_gregset PARAMS ((gdb_gregset_t *));
 
-extern void fill_gregset PARAMS ((gregset_t *, int));
+extern void fill_gregset PARAMS ((gdb_gregset_t *, int));
 
 #ifdef FP0_REGNUM
-extern void supply_fpregset PARAMS ((fpregset_t *));
+extern void supply_fpregset PARAMS ((gdb_fpregset_t *));
 
-extern void fill_fpregset PARAMS ((fpregset_t *, int));
+extern void fill_fpregset PARAMS ((gdb_fpregset_t *, int));
 #endif
 
 /*
@@ -901,12 +976,19 @@ wait_fd ()
              if ((poll_list[i].revents & POLLHUP) != 0 ||
                  !procfs_read_status(pi))
                { /* The LWP has apparently terminated.  */
+                 if (num_poll_list <= 1)
+                   {
+                     pi->prstatus.pr_flags = 0;
+                     pi->had_event = 1;
+                     break;
+                   }
                  if (info_verbose)
                    printf_filtered ("LWP %d exited.\n", 
                                     (pi->pid >> 16) & 0xffff);
                  close_proc_file (pi);
+                 i--;                  /* don't skip deleted entry */
                  if (num_fds != 0)
-                   continue;           /* already another event to process */
+                   break;              /* already another event to process */
                  else
                    goto wait_again;    /* wait for another event */
                }
@@ -1689,13 +1771,67 @@ init_syscall_table ()
 #if defined (SYS_lwp_sema_trywait)
   syscall_table[SYS_lwp_sema_trywait] = "lwp_sema_trywait";
 #endif
+#if defined(SYS_fstatvfs64)
+  syscall_table[SYS_fstatvfs64] = "fstatvfs64";
+#endif
+#if defined(SYS_statvfs64)
+  syscall_table[SYS_statvfs64] = "statvfs64";
+#endif
+#if defined(SYS_ftruncate64)
+  syscall_table[SYS_ftruncate64] = "ftruncate64";
+#endif
+#if defined(SYS_truncate64)
+  syscall_table[SYS_truncate64] = "truncate64";
+#endif
+#if defined(SYS_getrlimit64)
+  syscall_table[SYS_getrlimit64] = "getrlimit64";
+#endif
+#if defined(SYS_setrlimit64)
+  syscall_table[SYS_setrlimit64] = "setrlimit64";
+#endif
+#if defined(SYS_lseek64)
+  syscall_table[SYS_lseek64] = "lseek64";
+#endif
+#if defined(SYS_mmap64)
+  syscall_table[SYS_mmap64] = "mmap64";
+#endif
+#if defined(SYS_pread64)
+  syscall_table[SYS_pread64] = "pread64";
+#endif
+#if defined(SYS_creat64)
+  syscall_table[SYS_creat64] = "creat64";
+#endif
+#if defined(SYS_dshmsys)
+  syscall_table[SYS_dshmsys] = "dshmsys";
+#endif
+#if defined(SYS_invlpg)
+  syscall_table[SYS_invlpg] = "invlpg";
+#endif
+#if defined(SYS_cg_ids)
+  syscall_table[SYS_cg_ids] = "cg_ids";
+#endif
+#if defined(SYS_cg_processors)
+  syscall_table[SYS_cg_processors] = "cg_processors";
+#endif
+#if defined(SYS_cg_info)
+  syscall_table[SYS_cg_info] = "cg_info";
+#endif
+#if defined(SYS_cg_bind)
+  syscall_table[SYS_cg_bind] = "cg_bind";
+#endif
+#if defined(SYS_cg_current)
+  syscall_table[SYS_cg_current] = "cg_current";
+#endif
+#if defined(SYS_cg_memloc)
+  syscall_table[SYS_cg_memloc] = "cg_memloc";
+#endif
 }
 
 /*
 
 LOCAL FUNCTION
 
-       procfs_kill_inferior - kill any currently inferior
+       procfs_kill_inferior - kill any current inferior
 
 SYNOPSIS
 
@@ -1901,7 +2037,7 @@ procfs_store_registers (regno)
       procfs_read_status (pi);
       memcpy ((char *) &greg.gregset,
          (char *) &pi->prstatus.pr_lwp.pr_context.uc_mcontext.gregs,
-         sizeof (gregset_t));
+         sizeof (gdb_gregset_t));
     }
   fill_gregset (&greg.gregset, regno);
   greg.cmd = PCSREG;
@@ -1927,7 +2063,7 @@ procfs_store_registers (regno)
       procfs_read_status (pi);
       memcpy ((char *) &fpreg.fpregset,
           (char *) &pi->prstatus.pr_lwp.pr_context.uc_mcontext.fpregs,
-          sizeof (fpregset_t));
+          sizeof (gdb_fpregset_t));
     }
   fill_fpregset (&fpreg.fpregset, regno);
   fpreg.cmd = PCSFPREG;
@@ -1975,6 +2111,8 @@ init_procinfo (pid, kill)
 {
   struct procinfo *pi = (struct procinfo *) 
     xmalloc (sizeof (struct procinfo));
+  struct sig_ctl  sctl;
+  struct flt_ctl  fctl;
 
   memset ((char *) pi, 0, sizeof (*pi));
   if (!open_proc_file (pid, pi, O_RDWR, 1))
@@ -2123,10 +2261,20 @@ procfs_exit_handler (pi, syscall_num, why, rtnvalp, statvalp)
      int *statvalp;
 {
   struct procinfo *temp_pi, *next_pi;
+  struct proc_ctl pctl;
 
+#ifdef UNIXWARE
+  pctl.cmd = PCRUN;
+  pctl.data = PRCFAULT;
+#else
   pi->prrun.pr_flags = PRCFAULT;
+#endif
 
+#ifdef PROCFS_USE_READ_WRITE
+  if (write (pi->ctl_fd, (char *)&pctl, sizeof (struct proc_ctl)) < 0)
+#else
   if (ioctl (pi->ctl_fd, PIOCRUN, &pi->prrun) != 0)
+#endif
     perror_with_name (pi->pathname);
 
   if (attach_flag)
@@ -2390,7 +2538,7 @@ LOCAL FUNCTION
 
 SYNOPSIS
 
-       int procfs_init_inferior (int pid)
+       void procfs_init_inferior (int pid)
 
 DESCRIPTION
 
@@ -2408,7 +2556,7 @@ NOTES
 
  */
 
-static int
+static void 
 procfs_init_inferior (pid)
      int pid;
 {
@@ -2434,8 +2582,6 @@ procfs_init_inferior (pid)
   /* One trap to exec the shell, one to exec the program being debugged.  */
   startup_inferior (2);
 #endif
-
-  return pid;
 }
 
 /*
@@ -2472,7 +2618,7 @@ procfs_notice_signals (pid)
 
   pi = find_procinfo (pid, 0);
 
-#ifdef UNIXWARE
+#ifndef HAVE_PRRUN_T
   premptyset (&sctl.sigset);
 #else
   sctl.sigset = pi->prrun.pr_trace;
@@ -2480,7 +2626,7 @@ procfs_notice_signals (pid)
 
   notice_signals (pi, &sctl);
 
-#ifndef UNIXWARE
+#ifdef HAVE_PRRUN_T
   pi->prrun.pr_trace = sctl.sigset;
 #endif
 }
@@ -2642,6 +2788,8 @@ proc_set_exec_trap ()
 
   modify_run_on_last_close_flag (fd, 1);
 
+#ifndef UNIXWARE       /* since this is a solaris-ism, we don't want it */
+                       /* NOTE: revisit when doing thread support for UW */
 #ifdef PR_ASYNC
   {
     long pr_flags;
@@ -2661,6 +2809,7 @@ proc_set_exec_trap ()
 #endif
   }
 #endif /* PR_ASYNC */
+#endif /* !UNIXWARE */
 }
 
 /*
@@ -2809,6 +2958,7 @@ proc_base_address (addr)
 
 #endif /* 0 */
 
+#ifndef UNIXWARE
 /*
 
 LOCAL FUNCTION
@@ -2847,7 +2997,7 @@ proc_address_to_fd (pi, addr, complain)
     }
   return (fd);
 }
-
+#endif /* !UNIXWARE */
 
 /* Attach to process PID, then initialize for debugging it
    and wait for the trace-trap that results from attaching.  */
@@ -3006,11 +3156,7 @@ do_attach (pid)
       if ((pi = find_procinfo ((*lwps << 16) | pid, 1)) == 0)
        pi = init_procinfo ((*lwps << 16) | pid, 0);
 
-#ifdef UNIXWARE
-      if (pi->prstatus.pr_lwp.pr_flags & (PR_STOPPED | PR_ISTOP))
-#else
-      if (pi->prstatus.pr_flags & (PR_STOPPED | PR_ISTOP))
-#endif
+      if (THE_PR_LWP(pi->prstatus).pr_flags & (PR_STOPPED | PR_ISTOP))
        {
          pi->was_stopped = 1;
        }
@@ -3065,8 +3211,8 @@ do_attach (pid)
        }
       add_thread (pi->pid);
       procfs_set_inferior_syscall_traps (pi);
-    }
 #endif /* PROCFS_USE_READ_WRITE */
+    }
   attach_flag = 1;
   return (pi->pid);
 }
@@ -3170,11 +3316,8 @@ do_detach (signal)
        }
       else
        {
-#ifdef UNIXWARE
-         if (signal || (pi->prstatus.pr_lwp.pr_flags & (PR_STOPPED | PR_ISTOP)))
-#else
-         if (signal || (pi->prstatus.pr_flags & (PR_STOPPED | PR_ISTOP)))
-#endif
+         if (signal
+         || (THE_PR_LWP(pi->prstatus).pr_flags & (PR_STOPPED | PR_ISTOP)))
            {
              long cmd;
              struct proc_ctl pctl;
@@ -3247,38 +3390,62 @@ procfs_wait (pid, ourstatus)
   struct procinfo *pi;
   struct proc_ctl pctl;
 
-#ifndef UNIXWARE
-  if (pid != -1)               /* Non-specific process? */
-    pi = NULL;
-  else
-    for (pi = procinfo_list; pi; pi = pi->next)
-      if (pi->had_event)
-       break;
+scan_again:
 
-  if (!pi)
+  /* handle all syscall events first, otherwise we might not
+     notice a thread was created until too late. */
+
+  for (pi = procinfo_list; pi; pi = pi->next)
     {
-    wait_again:
+      if (!pi->had_event)
+       continue;
+
+      if (! (THE_PR_LWP(pi->prstatus).pr_flags & (PR_STOPPED | PR_ISTOP)) )
+       continue;
+
+      why = THE_PR_LWP(pi->prstatus).pr_why;
+      what = THE_PR_LWP(pi->prstatus).pr_what;
+      if (why == PR_SYSENTRY || why == PR_SYSEXIT)
+       {
+         int i;
+         int found_handler = 0;
 
-      if (pi)
-       pi->had_event = 0;
+         for (i = 0; i < pi->num_syscall_handlers; i++)
+           if (pi->syscall_handlers[i].syscall_num == what)
+             {
+               found_handler = 1;
+               pi->saved_rtnval = pi->pid;
+               pi->saved_statval = 0;
+               if (!pi->syscall_handlers[i].func
+                   (pi, what, why, &pi->saved_rtnval, &pi->saved_statval))
+                 pi->had_event = 0;
+               break;
+             }
 
-      pi = wait_fd ();
+         if (!found_handler)
+           {
+             if (why == PR_SYSENTRY)
+               error ("PR_SYSENTRY, unhandled system call %d", what);
+             else
+               error ("PR_SYSEXIT, unhandled system call %d", what);
+           }
+       }
     }
 
-  if (pid != -1)
-    for (pi = procinfo_list; pi; pi = pi->next)
-      if (pi->pid == pid && pi->had_event)
-       break;
-#endif
+  /* find a relevant process with an event */
 
-  if (!pi && !checkerr)
-    goto wait_again;
+  for (pi = procinfo_list; pi; pi = pi->next)
+    if (pi->had_event && (pid == -1 || pi->pid == pid))
+      break;
 
-#ifdef UNIXWARE
-  if (!checkerr && !(pi->prstatus.pr_lwp.pr_flags & (PR_STOPPED | PR_ISTOP)))
-#else
-  if (!checkerr && !(pi->prstatus.pr_flags & (PR_STOPPED | PR_ISTOP)))
-#endif
+  if (!pi)
+    {
+      wait_fd ();
+      goto scan_again;
+    }
+
+  if (!checkerr
+  && !(THE_PR_LWP(pi->prstatus).pr_flags & (PR_STOPPED | PR_ISTOP)))
     {
       if (!procfs_write_pcwstop (pi))
        {
@@ -3291,7 +3458,7 @@ procfs_wait (pid, ourstatus)
        {
          /* XXX Fixme -- what to do if attached?  Can't call wait... */
          rtnval = wait (&statval);
-         if ((rtnval) != (inferior_pid))
+         if ((rtnval) != (PIDGET (inferior_pid)))
            {
              print_sys_errmsg (pi->pathname, errno);
              error ("procfs_wait: wait failed, returned %d", rtnval);
@@ -3305,17 +3472,15 @@ procfs_wait (pid, ourstatus)
          /* NOTREACHED */
        }
     }
-  else if (pi->prstatus.pr_flags & (PR_STOPPED | PR_ISTOP))
+  else if (THE_PR_LWP(pi->prstatus).pr_flags & (PR_STOPPED | PR_ISTOP))
     {
 #ifdef UNIXWARE
       rtnval = pi->prstatus.pr_pid;
-      why = pi->prstatus.pr_lwp.pr_why;
-      what = pi->prstatus.pr_lwp.pr_what;
 #else
       rtnval = pi->pid;
-      why = pi->prstatus.pr_why;
-      what = pi->prstatus.pr_what;
 #endif
+      why = THE_PR_LWP(pi->prstatus).pr_why;
+      what = THE_PR_LWP(pi->prstatus).pr_what;
 
       switch (why)
        {
@@ -3324,27 +3489,8 @@ procfs_wait (pid, ourstatus)
          break;
        case PR_SYSENTRY:
        case PR_SYSEXIT:
-         {
-           int i;
-           int found_handler = 0;
-
-           for (i = 0; i < pi->num_syscall_handlers; i++)
-             if (pi->syscall_handlers[i].syscall_num == what)
-               {
-                 found_handler = 1;
-                 if (!pi->syscall_handlers[i].func (pi, what, why,
-                                                    &rtnval, &statval))
-                   goto wait_again;
-
-                 break;
-               }
-
-           if (!found_handler)
-             if (why == PR_SYSENTRY)
-               error ("PR_SYSENTRY, unhandled system call %d", what);
-             else
-               error ("PR_SYSEXIT, unhandled system call %d", what);
-         }
+         rtnval = pi->saved_rtnval;
+         statval = pi->saved_statval;
          break;
        case PR_REQUESTED:
          statval = (SIGSTOP << 8) | 0177;
@@ -3392,11 +3538,8 @@ procfs_wait (pid, ourstatus)
              /* Use the signal which the kernel assigns.  This is better than
                 trying to second-guess it from the fault.  In fact, I suspect
                 that FLTACCESS can be either SIGSEGV or SIGBUS.  */
-#ifdef UNIXWARE
-              statval = ((pi->prstatus.pr_lwp.pr_info.si_signo) << 8) | 0177;
-#else
-             statval = ((pi->prstatus.pr_info.si_signo) << 8) | 0177;
-#endif
+              statval =
+                ((THE_PR_LWP(pi->prstatus).pr_info.si_signo) << 8) | 0177;
              break;
            }
          break;
@@ -3414,7 +3557,7 @@ procfs_wait (pid, ourstatus)
            if (!procinfo->had_event)
              {
 #ifdef PROCFS_USE_READ_WRITE
-               cmd = PCSTOP;
+               long cmd = PCSTOP;
                if (write (pi->ctl_fd, (char *) &cmd, sizeof (long)) < 0)
                  {
                    print_sys_errmsg (procinfo->pathname, errno);
@@ -3448,8 +3591,8 @@ procfs_wait (pid, ourstatus)
     }
   else
     {
-      error ("PIOCWSTOP, stopped for unknown/unhandled reason, flags %#x", 
-            pi->prstatus.pr_flags);
+      error ("PIOCWSTOP, stopped for unknown/unhandled reason, flags %#x",
+            THE_PR_LWP(pi->prstatus).pr_flags);
     }
 
   store_waitstatus (ourstatus, statval);
@@ -3488,7 +3631,7 @@ DESCRIPTION
 
        If we are not delivering the same signal that the prstatus siginfo
        struct contains information about, then synthesize a siginfo struct
-       to match the signal we are doing to deliver, make it of the type
+       to match the signal we are going to deliver, make it of the type
        "generated by a user process", and send this synthesized copy.  When
        used to set the inferior's signal state, this will be required if we
        are not currently stopped because of a traced signal, or if we decide
@@ -3518,22 +3661,18 @@ set_proc_siginfo (pip, signo)
   /* With Alpha OSF/1 procfs, the kernel gets really confused if it
      receives a PIOCSSIG with a signal identical to the current signal,
      it messes up the current signal. Work around the kernel bug.  */
-#ifdef UNIXWARE
-  if (signo == pip -> prstatus.pr_lwp.pr_cursig)
-#else
-  if (signo == pip -> prstatus.pr_cursig)
-#endif
+  if (signo == THE_PR_LWP(pip->prstatus).pr_cursig)
     return;
 #endif
 
 #ifdef UNIXWARE
-  if (signo == pip->prstatus.pr_lwp.pr_info.si_signo)
+  if (signo == THE_PR_LWP(pip->prstatus).pr_info.si_signo)
     {
       memcpy ((char *) &sictl.siginfo, (char *) &pip->prstatus.pr_lwp.pr_info,
                sizeof (siginfo_t));
     }
 #else
-  if (signo == pip -> prstatus.pr_info.si_signo)
+  if (signo == THE_PR_LWP(pip->prstatus).pr_info.si_signo)
     {
       sip = &pip -> prstatus.pr_info;
     }
@@ -3622,13 +3761,8 @@ procfs_resume (pid, step, signo)
        an inferior to continue running at the same time as gdb.  (FIXME?)  */
     signal_to_pass = 0;
   else if (signo == TARGET_SIGNAL_TSTP
-#ifdef UNIXWARE
-          && pi->prstatus.pr_lwp.pr_cursig == SIGTSTP
-          && pi->prstatus.pr_lwp.pr_action.sa_handler == SIG_DFL
-#else
-          && pi->prstatus.pr_cursig == SIGTSTP
-          && pi->prstatus.pr_action.sa_handler == SIG_DFL
-#endif
+          && THE_PR_LWP(pi->prstatus).pr_cursig == SIGTSTP
+          && THE_PR_LWP(pi->prstatus).pr_action.sa_handler == SIG_DFL
           )
 
     /* We are about to pass the inferior a SIGTSTP whose action is
@@ -3725,7 +3859,6 @@ procfs_resume (pid, step, signo)
                  print_sys_errmsg (procinfo->pathname, errno);
                  error ("PCRUN failed");
                }
-             procfs_read_status (procinfo);
 #else
              procinfo->prrun.pr_flags &= PRSTEP;
              procinfo->prrun.pr_flags |= PRCFAULT | PRCSIG;
@@ -3752,9 +3885,9 @@ procfs_resume (pid, step, signo)
                  print_sys_errmsg (procinfo->pathname, errno);
                  warning ("PIOCRUN failed");
                }
+#endif
            }
        procfs_read_status (procinfo);
-#endif
       }
 }
 
@@ -3895,6 +4028,20 @@ close_proc_file (pip)
     }
 }
 
+static void
+close_proc_file_cleanup (pip)
+     void *pip;
+{
+  close_proc_file ((struct procinfo *) pip);
+}
+
+static struct cleanup *
+make_cleanup_close_proc_file (pip)
+     struct procinfo *pip;
+{
+  return make_cleanup (close_proc_file_cleanup, pip);
+}
+
 /*
 
 LOCAL FUNCTION
@@ -3966,14 +4113,6 @@ open_proc_file (pid, pip, mode, control)
       return 0;
     }
 
-  sprintf (pip->pathname, MAP_PROC_NAME_FMT, tmp);
-  if ((pip->map_fd = open (pip->pathname, O_RDONLY)) < 0)
-    {
-      close (pip->status_fd);
-      close (pip->as_fd);
-      return 0;
-    }
-
   if (control)
     {
       sprintf (pip->pathname, CTL_PROC_NAME_FMT, tmp);
@@ -4102,19 +4241,10 @@ info_proc_stop (pip, summary)
   int why;
   int what;
 
-#ifdef UNIXWARE
-  why = pip -> prstatus.pr_lwp.pr_why;
-  what = pip -> prstatus.pr_lwp.pr_what;
-#else
-  why = pip -> prstatus.pr_why;
-  what = pip -> prstatus.pr_what;
-#endif
+  why = THE_PR_LWP(pip->prstatus).pr_why;
+  what = THE_PR_LWP(pip->prstatus).pr_what;
 
-#ifdef UNIXWARE
-  if (pip -> prstatus.pr_lwp.pr_flags & PR_STOPPED)
-#else
-  if (pip -> prstatus.pr_flags & PR_STOPPED)
-#endif
+  if (THE_PR_LWP(pip->prstatus).pr_flags & PR_STOPPED)
     {
       printf_filtered ("%-32s", "Reason for stopping:");
       if (!summary)
@@ -4205,22 +4335,12 @@ info_proc_siginfo (pip, summary)
 {
   struct siginfo *sip;
 
-#ifdef UNIXWARE
-  if ((pip -> prstatus.pr_lwp.pr_flags & PR_STOPPED) &&
-      (pip -> prstatus.pr_lwp.pr_why == PR_SIGNALLED ||
-       pip -> prstatus.pr_lwp.pr_why == PR_FAULTED))
-#else
-  if ((pip -> prstatus.pr_flags & PR_STOPPED) &&
-      (pip -> prstatus.pr_why == PR_SIGNALLED ||
-       pip -> prstatus.pr_why == PR_FAULTED))
-#endif
+  if ((THE_PR_LWP(pip->prstatus).pr_flags & PR_STOPPED) &&
+      (THE_PR_LWP(pip->prstatus).pr_why == PR_SIGNALLED ||
+       THE_PR_LWP(pip->prstatus).pr_why == PR_FAULTED))
     {
       printf_filtered ("%-32s", "Additional signal/fault info:");
-#ifdef UNIXWARE
-      sip = &pip -> prstatus.pr_lwp.pr_info;
-#else
-      sip = &pip -> prstatus.pr_info;
-#endif
+      sip = &(THE_PR_LWP(pip->prstatus).pr_info);
       if (summary)
        {
          printf_filtered ("%s ", signalname (sip -> si_signo));
@@ -4658,7 +4778,7 @@ info_proc (args, from_tty)
        {
          nomem (0);
        }
-      make_cleanup (freeargv, (char *) argv);
+      make_cleanup_freeargv (argv);
 
       while (*argv != NULL)
        {
@@ -4720,7 +4840,7 @@ info_proc (args, from_tty)
                  /* NOTREACHED */
                }
              pid = pip->pid;
-             make_cleanup (close_proc_file, pip);
+             make_cleanup_close_proc_file (pip);
            }
          else if (**argv != '\000')
            {
@@ -4772,7 +4892,7 @@ No process.  Start debugging a program or specify an explicit process ID.");
          if (!open_proc_file ((*lwps << 16) | pid, pip, O_RDONLY, 0))
            continue;
 
-         make_cleanup (close_proc_file, pip);
+         make_cleanup_close_proc_file (pip);
 
          if (!procfs_read_status (pip))
            {
@@ -4794,7 +4914,11 @@ No process.  Start debugging a program or specify an explicit process ID.");
       if (summary || all)
        {
          info_proc_stop (pip, summary);
+#ifdef UNIXWARE
+         supply_gregset (&pip->prstatus.pr_lwp.pr_context.uc_mcontext.gregs);
+#else
          supply_gregset (&pip->prstatus.pr_reg);
+#endif
          printf_filtered ("PC: ");
          print_address (read_pc (), gdb_stdout);
          printf_filtered ("\n");
@@ -5002,7 +5126,8 @@ procfs_clear_syscall_trap (pi, syscall_num, errok)
 {
   sysset_t sysset;
   int goterr, i;
-  
+
+#ifndef UNIXWARE
   goterr = ioctl (pi->ctl_fd, PIOCGENTRY, &sysset) < 0;
 
   if (goterr && !errok)
@@ -5042,6 +5167,7 @@ procfs_clear_syscall_trap (pi, syscall_num, errok)
          error ("PIOCSEXIT failed");
        }
     }
+#endif
 
   if (!pi->syscall_handlers)
     {
@@ -5106,6 +5232,7 @@ procfs_set_syscall_trap (pi, syscall_num, flags, func)
 {
   sysset_t sysset;
 
+#ifndef UNIXWARE
   if (flags & PROCFS_SYSCALL_ENTRY)
     {
       if (ioctl (pi->ctl_fd, PIOCGENTRY, &sysset) < 0)
@@ -5141,6 +5268,7 @@ procfs_set_syscall_trap (pi, syscall_num, flags, func)
          error ("PIOCSEXIT failed");
        }
     }
+#endif
 
   if (!pi->syscall_handlers)
     {
@@ -5210,6 +5338,7 @@ procfs_lwp_creation_handler (pi, syscall_num, why, rtnvalp, statvalp)
 {
   int lwp_id;
   struct procinfo *childpi;
+  struct proc_ctl pctl;
 
   /* We've just detected the completion of an lwp_create system call.  Now we
      need to setup a procinfo struct for this thread, and notify the thread
@@ -5218,7 +5347,20 @@ procfs_lwp_creation_handler (pi, syscall_num, why, rtnvalp, statvalp)
   /* If lwp_create failed, then nothing interesting happened.  Continue the
      process and go back to sleep. */
 
-  if (pi->prstatus.pr_reg[R_PSR] & PS_FLAG_CARRY)
+#ifdef UNIXWARE
+  /* Joel ... can you check this logic out please? JKJ */
+  if (pi->prstatus.pr_lwp.pr_context.uc_mcontext.gregs[R_EFL] & 1)
+    { /* _lwp_create failed */
+      pctl.cmd = PCRUN;
+      pctl.data = PRCFAULT;
+
+      if (write (pi->ctl_fd, (char *) &pctl, sizeof (struct proc_ctl)) < 0)
+       perror_with_name (pi->pathname);
+
+      return 0;
+    }
+#else /* UNIXWARE */
+  if (PROCFS_GET_CARRY (pi->prstatus.pr_reg))
     {                          /* _lwp_create failed */
       pi->prrun.pr_flags &= PRSTEP;
       pi->prrun.pr_flags |= PRCFAULT;
@@ -5228,17 +5370,25 @@ procfs_lwp_creation_handler (pi, syscall_num, why, rtnvalp, statvalp)
 
       return 0;
     }
+#endif
 
   /* At this point, the new thread is stopped at it's first instruction, and
      the parent is stopped at the exit from lwp_create.  */
 
   if (pi->new_child)           /* Child? */
     {                          /* Yes, just continue it */
+#ifdef UNIXWARE
+      pctl.cmd = PCRUN;
+      pctl.data = PRCFAULT;
+
+      if (write(pi->ctl_fd, (char *)&pctl, sizeof (struct proc_ctl)) < 0)
+#else /* !UNIXWARE */
       pi->prrun.pr_flags &= PRSTEP;
       pi->prrun.pr_flags |= PRCFAULT;
 
       if ((pi->prstatus.pr_flags & PR_ISTOP)
          && ioctl (pi->ctl_fd, PIOCRUN, &pi->prrun) != 0)
+#endif /* !UNIXWARE */
        perror_with_name (pi->pathname);
 
       pi->new_child = 0;       /* No longer new */
@@ -5250,7 +5400,8 @@ procfs_lwp_creation_handler (pi, syscall_num, why, rtnvalp, statvalp)
      in the child and continue the parent.  */
 
   /* Third arg is pointer to new thread id. */
-  lwp_id = read_memory_integer (pi->prstatus.pr_sysarg[2], sizeof (int));
+  lwp_id = read_memory_integer (
+     THE_PR_LWP(pi->prstatus).pr_sysarg[2], sizeof (int));
 
   lwp_id = (lwp_id << 16) | PIDGET (pi->pid);
 
@@ -5265,25 +5416,38 @@ procfs_lwp_creation_handler (pi, syscall_num, why, rtnvalp, statvalp)
   printf_filtered ("[New %s]\n", target_pid_to_str (lwp_id));
 
   /* Continue the parent */
+#ifdef UNIXWARE
+  pctl.cmd = PCRUN;
+  pctl.data = PRCFAULT;
 
+  if (write(pi->ctl_fd, (char *)&pctl, sizeof (struct proc_ctl)) < 0)
+#else
   pi->prrun.pr_flags &= PRSTEP;
   pi->prrun.pr_flags |= PRCFAULT;
   if (ioctl (pi->ctl_fd, PIOCRUN, &pi->prrun) != 0)
+#endif
     perror_with_name (pi->pathname);
 
   /* The new child may have been created in one of two states: 
      SUSPENDED or RUNNABLE.  If runnable, we will simply signal it to run.
      If suspended, we flag it to be continued later, when it has an event.  */
 
-  if (childpi->prstatus.pr_why == PR_SUSPENDED)
+  if (THE_PR_LWP(childpi->prstatus).pr_why == PR_SUSPENDED)
     childpi->new_child = 1;    /* Flag this as an unseen child process */
   else
     {
       /* Continue the child */
+#ifdef UNIXWARE
+      pctl.cmd = PCRUN;
+      pctl.data = PRCFAULT;
+
+      if (write(pi->ctl_fd, (char *)&pctl, sizeof (struct proc_ctl)) < 0)
+#else
       childpi->prrun.pr_flags &= PRSTEP;
       childpi->prrun.pr_flags |= PRCFAULT;
 
       if (ioctl (childpi->ctl_fd, PIOCRUN, &childpi->prrun) != 0)
+#endif
        perror_with_name (childpi->pathname);
     }
   return 0;
@@ -5368,7 +5532,7 @@ procfs_create_inferior (exec_file, allargs, env)
     }
 
   fork_inferior (exec_file, allargs, env,
-                proc_set_exec_trap, procfs_init_inferior, shell_file);
+                proc_set_exec_trap, procfs_init_inferior, NULL, shell_file);
 
   /* We are at the first instruction we care about.  */
   /* Pedal to the metal... */
@@ -5406,6 +5570,7 @@ procfs_can_run ()
   return !procfs_suppress_run;
 }
 #ifdef TARGET_HAS_HARDWARE_WATCHPOINTS
+#ifndef UNIXWARE
 \f
 /* Insert a watchpoint */
 int
@@ -5465,6 +5630,7 @@ procfs_stopped_by_watchpoint(pid)
     }
   return 0;
 }
+#endif /* !UNIXWARE */
 #endif /* TARGET_HAS_HARDWARE_WATCHPOINTS */
 
 /* Why is this necessary?  Shouldn't dead threads just be removed from the
@@ -5504,6 +5670,18 @@ procfs_first_available ()
   return -1;
 }
 
+int
+procfs_get_pid_fd (pid)
+     int pid;
+{
+  struct procinfo *pi = find_procinfo (pid, 1);
+
+  if (pi == NULL)
+    return -1;
+
+  return pi->ctl_fd;
+}
+
 /* Send a SIGINT to the process group.  This acts just like the user typed a
    ^C on the controlling terminal.
 
@@ -5532,49 +5710,46 @@ procfs_pid_to_str (pid)
   return buf;
 }
 #endif /* TIDGET */
+
 \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 */
-  procfs_notice_signals,       /* to_notice_signals */
-  procfs_thread_alive,         /* to_thread_alive */
-  procfs_stop,                 /* to_stop */
-  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 */
-};
+static void
+init_procfs_ops ()
+{
+  procfs_ops.to_shortname = "procfs";
+  procfs_ops.to_longname = "Unix /proc child process";
+  procfs_ops.to_doc = "Unix /proc child process (started by the \"run\" command).";
+  procfs_ops.to_open = procfs_open;
+  procfs_ops.to_attach = procfs_attach;
+  procfs_ops.to_detach = procfs_detach;
+  procfs_ops.to_resume = procfs_resume;
+  procfs_ops.to_wait = procfs_wait;
+  procfs_ops.to_fetch_registers = procfs_fetch_registers;
+  procfs_ops.to_store_registers = procfs_store_registers;
+  procfs_ops.to_prepare_to_store = procfs_prepare_to_store;
+  procfs_ops.to_xfer_memory = procfs_xfer_memory;
+  procfs_ops.to_files_info = procfs_files_info;
+  procfs_ops.to_insert_breakpoint = memory_insert_breakpoint;
+  procfs_ops.to_remove_breakpoint = memory_remove_breakpoint;
+  procfs_ops.to_terminal_init = terminal_init_inferior;
+  procfs_ops.to_terminal_inferior = terminal_inferior;
+  procfs_ops.to_terminal_ours_for_output = terminal_ours_for_output;
+  procfs_ops.to_terminal_ours = terminal_ours;
+  procfs_ops.to_terminal_info = child_terminal_info;
+  procfs_ops.to_kill = procfs_kill_inferior;
+  procfs_ops.to_create_inferior = procfs_create_inferior;
+  procfs_ops.to_mourn_inferior = procfs_mourn_inferior;
+  procfs_ops.to_can_run = procfs_can_run;
+  procfs_ops.to_notice_signals = procfs_notice_signals;
+  procfs_ops.to_thread_alive = procfs_thread_alive;
+  procfs_ops.to_stop = procfs_stop;
+  procfs_ops.to_stratum = process_stratum;
+  procfs_ops.to_has_all_memory = 1;
+  procfs_ops.to_has_memory = 1;
+  procfs_ops.to_has_stack = 1;
+  procfs_ops.to_has_registers = 1;
+  procfs_ops.to_has_execution = 1;
+  procfs_ops.to_magic = OPS_MAGIC;
+}
 
 void
 _initialize_procfs ()
@@ -5592,6 +5767,7 @@ _initialize_procfs ()
   close (fd);
 #endif
 
+  init_procfs_ops ();
   add_target (&procfs_ops);
 
   add_info ("processes", info_proc, 
This page took 0.035689 seconds and 4 git commands to generate.