* utils.c (strcmp_iw): Add a hack to allow "FOO(ARGS)" to
[deliverable/binutils-gdb.git] / gdb / procfs.c
index 407c65fe90aae96b3c6ed9d9ce7e5e0943a394d3..b4b1201175e25ff2f6928d7020d4ad21cafbf70c 100644 (file)
@@ -1,5 +1,5 @@
 /* Machine independent support for SVR4 /proc (process file system) for GDB.
-   Copyright (C) 1991 Free Software Foundation, Inc.
+   Copyright 1991, 1992 Free Software Foundation, Inc.
    Written by Fred Fish at Cygnus Support.
 
 This file is part of GDB.
@@ -40,15 +40,16 @@ regardless of whether or not the actual target has floating point hardware.
 #include <sys/procfs.h>
 #include <fcntl.h>
 #include <errno.h>
+#include <string.h>
 
 #include "inferior.h"
 #include "target.h"
-#include "signame.h"
+#include "command.h"
 
 #define MAX_SYSCALLS   256     /* Maximum number of syscalls for table */
 
 #ifndef PROC_NAME_FMT
-#define PROC_NAME_FMT "/proc/%d"
+#define PROC_NAME_FMT "/proc/%05d"
 #endif
 
 #if 1  /* FIXME: Gross and ugly hack to resolve coredep.c global */
@@ -77,6 +78,7 @@ struct procinfo {
   int fd;                      /* File descriptor for /proc entry */
   char *pathname;              /* Pathname to /proc entry */
   int was_stopped;             /* Nonzero if was stopped prior to attach */
+  int nopass_next_sigstop;     /* Don't pass a sigstop on next resume */
   prrun_t prrun;               /* Control state when it is run */
   prstatus_t prstatus;         /* Current process status info */
   gregset_t gregset;           /* General register set */
@@ -136,6 +138,18 @@ static struct trans pr_flag_table[] =
 #endif
 #if defined (PR_ISSYS)
   PR_ISSYS, "PR_ISSYS", "Is a system process",
+#endif
+#if defined (PR_STEP)
+  PR_STEP, "PR_STEP", "Process has single step pending",
+#endif
+#if defined (PR_KLC)
+  PR_KLC, "PR_KLC", "Kill-on-last-close is in effect",
+#endif
+#if defined (PR_ASYNC)
+  PR_ASYNC, "PR_ASYNC", "Asynchronous stop is in effect",
+#endif
+#if defined (PR_PCOMPAT)
+  PR_PCOMPAT, "PR_PCOMPAT", "Ptrace compatibility mode in effect",
 #endif
  0, NULL, NULL
 };
@@ -161,6 +175,9 @@ static struct trans pr_why_table[] =
 #endif
 #if defined (PR_JOBCONTROL)
  PR_JOBCONTROL, "PR_JOBCONTROL", "Default job control stop signal action",
+#endif
+#if defined (PR_SUSPENDED)
+ PR_SUSPENDED, "PR_SUSPENDED", "Process suspended",
 #endif
  0, NULL, NULL
 };
@@ -322,380 +339,6 @@ static struct sigcode {
   0, 0, NULL, NULL
 };
 
-/* Translation table for errno values.  See intro(2) in most UNIX systems
-   Programmers Reference Manuals.
-
-   Note that some systems provide a function (strerror) that returns the
-   error message string, or a global variable that is the base address of the
-   array of character pointers.  Perhaps we should try to make use of these
-   provided strings if they are present, but at least this is more portable.
-   (FIXME?) */
-
-static struct trans errno_table[] =
-{
-#if defined (EPERM)
-  EPERM, "EPERM", "Not super-user",
-#endif
-#if defined (ENOENT)
-  ENOENT, "ENOENT", "No such file or directory",
-#endif
-#if defined (ESRCH)
-  ESRCH, "ESRCH", "No such process",
-#endif
-#if defined (EINTR)
-  EINTR, "EINTR", "Interrupted system call",
-#endif
-#if defined (EIO)
-  EIO, "EIO", "I/O error",
-#endif
-#if defined (ENXIO)
-  ENXIO, "ENXIO", "No such device or address",
-#endif
-#if defined (E2BIG)
-  E2BIG, "E2BIG", "Arg list too long",
-#endif
-#if defined (ENOEXEC)
-  ENOEXEC, "ENOEXEC", "Exec format error",
-#endif
-#if defined (EBADF)
-  EBADF, "EBADF", "Bad file number",
-#endif
-#if defined (ECHILD)
-  ECHILD, "ECHILD", "No child process",
-#endif
-#if defined (EAGAIN)
-  EAGAIN, "EAGAIN", "No more processes",
-#endif
-#if defined (ENOMEM)
-  ENOMEM, "ENOMEM", "Not enough space",
-#endif
-#if defined (EACCES)
-  EACCES, "EACCES", "Permission denied",
-#endif
-#if defined (EFAULT)
-  EFAULT, "EFAULT", "Bad address",
-#endif
-#if defined (ENOTBLK)
-  ENOTBLK, "ENOTBLK", "Block device required",
-#endif
-#if defined (EBUSY)
-  EBUSY, "EBUSY", "Device busy",
-#endif
-#if defined (EEXIST)
-  EEXIST, "EEXIST", "File exists",
-#endif
-#if defined (EXDEV)
-  EXDEV, "EXDEV", "Cross-device link",
-#endif
-#if defined (ENODEV)
-  ENODEV, "ENODEV", "No such device",
-#endif
-#if defined (ENOTDIR)
-  ENOTDIR, "ENOTDIR", "Not a directory",
-#endif
-#if defined (EISDIR)
-  EISDIR, "EISDIR", "Is a directory",
-#endif
-#if defined (EINVAL)
-  EINVAL, "EINVAL", "Invalid argument",
-#endif
-#if defined (ENFILE)
-  ENFILE, "ENFILE", "File table overflow",
-#endif
-#if defined (EMFILE)
-  EMFILE, "EMFILE", "Too many open files",
-#endif
-#if defined (ENOTTY)
-  ENOTTY, "ENOTTY", "Not a typewriter",
-#endif
-#if defined (ETXTBSY)
-  ETXTBSY, "ETXTBSY", "Text file busy",
-#endif
-#if defined (EFBIG)
-  EFBIG, "EFBIG", "File too large",
-#endif
-#if defined (ENOSPC)
-  ENOSPC, "ENOSPC", "No space left on device",
-#endif
-#if defined (ESPIPE)
-  ESPIPE, "ESPIPE", "Illegal seek",
-#endif
-#if defined (EROFS)
-  EROFS, "EROFS", "Read only file system",
-#endif
-#if defined (EMLINK)
-  EMLINK, "EMLINK", "Too many links",
-#endif
-#if defined (EPIPE)
-  EPIPE, "EPIPE", "Broken pipe",
-#endif
-#if defined (EDOM)
-  EDOM, "EDOM", "Math argument out of domain of func",
-#endif
-#if defined (ERANGE)
-  ERANGE, "ERANGE", "Math result not representable",
-#endif
-#if defined (ENOMSG)
-  ENOMSG, "ENOMSG", "No message of desired type",
-#endif
-#if defined (EIDRM)
-  EIDRM, "EIDRM", "Identifier removed",
-#endif
-#if defined (ECHRNG)
-  ECHRNG, "ECHRNG", "Channel number out of range",
-#endif
-#if defined (EL2NSYNC)
-  EL2NSYNC, "EL2NSYNC", "Level 2 not synchronized",
-#endif
-#if defined (EL3HLT)
-  EL3HLT, "EL3HLT", "Level 3 halted",
-#endif
-#if defined (EL3RST)
-  EL3RST, "EL3RST", "Level 3 reset",
-#endif
-#if defined (ELNRNG)
-  ELNRNG, "ELNRNG", "Link number out of range",
-#endif
-#if defined (EUNATCH)
-  EUNATCH, "EUNATCH", "Protocol driver not attached",
-#endif
-#if defined (ENOCSI)
-  ENOCSI, "ENOCSI", "No CSI structure available",
-#endif
-#if defined (EL2HLT)
-  EL2HLT, "EL2HLT", "Level 2 halted",
-#endif
-#if defined (EDEADLK)
-  EDEADLK, "EDEADLK", "Deadlock condition",
-#endif
-#if defined (ENOLCK)
-  ENOLCK, "ENOLCK", "No record locks available",
-#endif
-#if defined (EBADE)
-  EBADE, "EBADE", "Invalid exchange",
-#endif
-#if defined (EBADR)
-  EBADR, "EBADR", "Invalid request descriptor",
-#endif
-#if defined (EXFULL)
-  EXFULL, "EXFULL", "Exchange full",
-#endif
-#if defined (ENOANO)
-  ENOANO, "ENOANO", "No anode",
-#endif
-#if defined (EBADRQC)
-  EBADRQC, "EBADRQC", "Invalid request code",
-#endif
-#if defined (EBADSLT)
-  EBADSLT, "EBADSLT", "Invalid slot",
-#endif
-#if defined (EDEADLOCK)
-  EDEADLOCK, "EDEADLOCK", "File locking deadlock error",
-#endif
-#if defined (EBFONT)
-  EBFONT, "EBFONT", "Bad font file fmt",
-#endif
-#if defined (ENOSTR)
-  ENOSTR, "ENOSTR", "Device not a stream",
-#endif
-#if defined (ENODATA)
-  ENODATA, "ENODATA", "No data available",
-#endif
-#if defined (ETIME)
-  ETIME, "ETIME", "Timer expired",
-#endif
-#if defined (ENOSR)
-  ENOSR, "ENOSR", "Out of streams resources",
-#endif
-#if defined (ENONET)
-  ENONET, "ENONET", "Machine is not on the network",
-#endif
-#if defined (ENOPKG)
-  ENOPKG, "ENOPKG", "Package not installed",
-#endif
-#if defined (EREMOTE)
-  EREMOTE, "EREMOTE", "Object is remote",
-#endif
-#if defined (ENOLINK)
-  ENOLINK, "ENOLINK", "Link has been severed",
-#endif
-#if defined (EADV)
-  EADV, "EADV", "Advertise error",
-#endif
-#if defined (ESRMNT)
-  ESRMNT, "ESRMNT", "Srmount error",
-#endif
-#if defined (ECOMM)
-  ECOMM, "ECOMM", "Communication error on send",
-#endif
-#if defined (EPROTO)
-  EPROTO, "EPROTO", "Protocol error",
-#endif
-#if defined (EMULTIHOP)
-  EMULTIHOP, "EMULTIHOP", "Multihop attempted",
-#endif
-#if defined (EDOTDOT)
-  EDOTDOT, "EDOTDOT", "RFS specific error",
-#endif
-#if defined (EBADMSG)
-  EBADMSG, "EBADMSG", "Not a data message",
-#endif
-#if defined (ENAMETOOLONG)
-  ENAMETOOLONG, "ENAMETOOLONG", "File name too long",
-#endif
-#if defined (EOVERFLOW)
-  EOVERFLOW, "EOVERFLOW", "Value too large for defined data type",
-#endif
-#if defined (ENOTUNIQ)
-  ENOTUNIQ, "ENOTUNIQ", "Name not unique on network",
-#endif
-#if defined (EBADFD)
-  EBADFD, "EBADFD", "File descriptor in bad state",
-#endif
-#if defined (EREMCHG)
-  EREMCHG, "EREMCHG", "Remote address changed",
-#endif
-#if defined (ELIBACC)
-  ELIBACC, "ELIBACC", "Cannot access a needed shared library",
-#endif
-#if defined (ELIBBAD)
-  ELIBBAD, "ELIBBAD", "Accessing a corrupted shared library",
-#endif
-#if defined (ELIBSCN)
-  ELIBSCN, "ELIBSCN", ".lib section in a.out corrupted",
-#endif
-#if defined (ELIBMAX)
-  ELIBMAX, "ELIBMAX", "Attempting to link in too many shared libraries",
-#endif
-#if defined (ELIBEXEC)
-  ELIBEXEC, "ELIBEXEC", "Cannot exec a shared library directly",
-#endif
-#if defined (EILSEQ)
-  EILSEQ, "EILSEQ", "Illegal byte sequence",
-#endif
-#if defined (ENOSYS)
-  ENOSYS, "ENOSYS", "Operation not applicable",
-#endif
-#if defined (ELOOP)
-  ELOOP, "ELOOP", "Too many symbolic links encountered",
-#endif
-#if defined (ERESTART)
-  ERESTART, "ERESTART", "Interrupted system call should be restarted",
-#endif
-#if defined (ESTRPIPE)
-  ESTRPIPE, "ESTRPIPE", "Streams pipe error",
-#endif
-#if defined (ENOTEMPTY)
-  ENOTEMPTY, "ENOTEMPTY", "Directory not empty",
-#endif
-#if defined (EUSERS)
-  EUSERS, "EUSERS", "Too many users",
-#endif
-#if defined (ENOTSOCK)
-  ENOTSOCK, "ENOTSOCK", "Socket operation on non-socket",
-#endif
-#if defined (EDESTADDRREQ)
-  EDESTADDRREQ, "EDESTADDRREQ", "Destination address required",
-#endif
-#if defined (EMSGSIZE)
-  EMSGSIZE, "EMSGSIZE", "Message too long",
-#endif
-#if defined (EPROTOTYPE)
-  EPROTOTYPE, "EPROTOTYPE", "Protocol wrong type for socket",
-#endif
-#if defined (ENOPROTOOPT)
-  ENOPROTOOPT, "ENOPROTOOPT", "Protocol not available",
-#endif
-#if defined (EPROTONOSUPPORT)
-  EPROTONOSUPPORT, "EPROTONOSUPPORT", "Protocol not supported",
-#endif
-#if defined (ESOCKTNOSUPPORT)
-  ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT", "Socket type not supported",
-#endif
-#if defined (EOPNOTSUPP)
-  EOPNOTSUPP, "EOPNOTSUPP", "Operation not supported on transport endpoint ",
-#endif
-#if defined (EPFNOSUPPORT)
-  EPFNOSUPPORT, "EPFNOSUPPORT", "Protocol family not supported",
-#endif
-#if defined (EAFNOSUPPORT)
-  EAFNOSUPPORT, "EAFNOSUPPORT", "Address family not supported by protocol",
-#endif
-#if defined (EADDRINUSE)
-  EADDRINUSE, "EADDRINUSE", "Address already in use",
-#endif
-#if defined (EADDRNOTAVAIL)
-  EADDRNOTAVAIL, "EADDRNOTAVAIL","Cannot assign requested address",
-#endif
-#if defined (ENETDOWN)
-  ENETDOWN, "ENETDOWN", "Network is down",
-#endif
-#if defined (ENETUNREACH)
-  ENETUNREACH, "ENETUNREACH", "Network is unreachable",
-#endif
-#if defined (ENETRESET)
-  ENETRESET, "ENETRESET", "Network dropped connection because of reset",
-#endif
-#if defined (ECONNABORTED)
-  ECONNABORTED, "ECONNABORTED", "Software caused connection abort",
-#endif
-#if defined (ECONNRESET)
-  ECONNRESET, "ECONNRESET", "Connection reset by peer",
-#endif
-#if defined (ENOBUFS)
-  ENOBUFS, "ENOBUFS", "No buffer space available",
-#endif
-#if defined (EISCONN)
-  EISCONN, "EISCONN", "Transport endpoint is already connected",
-#endif
-#if defined (ENOTCONN)
-  ENOTCONN, "ENOTCONN", "Transport endpoint is not connected",
-#endif
-#if defined (ESHUTDOWN)
-  ESHUTDOWN, "ESHUTDOWN", "Cannot send after transport endpoint shutdown",
-#endif
-#if defined (ETOOMANYREFS)
-  ETOOMANYREFS, "ETOOMANYREFS", "Too many references: cannot splice",
-#endif
-#if defined (ETIMEDOUT)
-  ETIMEDOUT, "ETIMEDOUT", "Connection timed out",
-#endif
-#if defined (ECONNREFUSED)
-  ECONNREFUSED, "ECONNREFUSED", "Connection refused",
-#endif
-#if defined (EHOSTDOWN)
-  EHOSTDOWN, "EHOSTDOWN", "Host is down",
-#endif
-#if defined (EHOSTUNREACH)
-  EHOSTUNREACH, "EHOSTUNREACH", "No route to host",
-#endif
-#if defined (EWOULDBLOCK)
-  EWOULDBLOCK, "EWOULDBLOCK", "Operation already in progress",
-#endif
-#if defined (EINPROGRESS)
-  EINPROGRESS, "EINPROGRESS", "Operation now in progress",
-#endif
-#if defined (ESTALE)
-  ESTALE, "ESTALE", "Stale NFS file handle",
-#endif
-#if defined (EUCLEAN)
-  EUCLEAN, "EUCLEAN", "Structure needs cleaning",
-#endif
-#if defined (ENOTNAM)
-  ENOTNAM, "ENOTNAM", "Not a XENIX named type file",
-#endif
-#if defined (ENAVAIL)
-  ENAVAIL, "ENAVAIL", "No XENIX semaphores available",
-#endif
-#if defined (EISNAM)
-  EISNAM, "EISNAM", "Is a named type file",
-#endif
-#if defined (EREMOTEIO)
-  EREMOTEIO, "EREMOTEIO", "Remote I/O error",
-#endif
- 0, NULL, NULL
-};
-
 static char *syscall_table[MAX_SYSCALLS];
 
 /* Prototypes for local functions */
@@ -712,11 +355,14 @@ syscallname PARAMS ((int));
 static char *
 signalname PARAMS ((int));
 
+static char *
+errnoname PARAMS ((int));
+
 static int
 proc_address_to_fd PARAMS ((CORE_ADDR, int));
 
 static int
-open_proc_file PARAMS ((int, struct procinfo *));
+open_proc_file PARAMS ((int, struct procinfo *, int));
 
 static void
 close_proc_file PARAMS ((struct procinfo *));
@@ -868,7 +514,7 @@ lookupname (transp, val, prefix)
          free (locbuf);
        }
       locbuf = xmalloc (strlen (prefix) + 16);
-      (void) sprintf (locbuf, "%s %u", prefix, val);
+      sprintf (locbuf, "%s %u", prefix, val);
       name = locbuf;
     }
   return (name);
@@ -893,7 +539,7 @@ sigcodename (sip)
     }
   if (name == NULL)
     {
-      (void) sprintf (locbuf, "sigcode %u", sip -> si_signo);
+      sprintf (locbuf, "sigcode %u", sip -> si_signo);
       name = locbuf;
     }
   return (name);
@@ -951,7 +597,7 @@ syscallname (syscallnum)
     }
   else
     {
-      (void) sprintf (locbuf, "syscall %u", syscallnum);
+      sprintf (locbuf, "syscall %u", syscallnum);
       rtnval = locbuf;
     }
   return (rtnval);
@@ -982,8 +628,6 @@ NOTES
 static void
 init_syscall_table ()
 {
-  int syscallnum;
-  
 #if defined (SYS_exit)
   syscall_table[SYS_exit] = "exit";
 #endif
@@ -1363,7 +1007,7 @@ GLOBAL FUNCTION
 
 SYNOPSIS
 
-       int ptrace (int request, int pid, int arg3, int arg4)
+       int ptrace (int request, int pid, PTRACE_ARG3_TYPE arg3, int arg4)
 
 DESCRIPTION
 
@@ -1378,7 +1022,7 @@ int
 ptrace (request, pid, arg3, arg4)
      int request;
      int pid;
-     int arg3;
+     PTRACE_ARG3_TYPE arg3;
      int arg4;
 {
   error ("internal error - there is a call to ptrace() somewhere");
@@ -1479,7 +1123,7 @@ unconditionally_kill_inferior ()
   int signo;
   
   signo = SIGKILL;
-  (void) ioctl (pi.fd, PIOCKILL, &signo);
+  ioctl (pi.fd, PIOCKILL, &signo);
   close_proc_file (&pi);
   wait ((int *) 0);
 }
@@ -1584,10 +1228,10 @@ store_inferior_registers (regno)
 {
   if (regno != -1)
     {
-      (void) ioctl (pi.fd, PIOCGREG, &pi.gregset);
+      ioctl (pi.fd, PIOCGREG, &pi.gregset);
     }
   fill_gregset (&pi.gregset, regno);
-  (void) ioctl (pi.fd, PIOCSREG, &pi.gregset);
+  ioctl (pi.fd, PIOCSREG, &pi.gregset);
 
 #if defined (FP0_REGNUM)
 
@@ -1597,10 +1241,10 @@ store_inferior_registers (regno)
 
   if (regno != -1)
     {
-      (void) ioctl (pi.fd, PIOCGFPREG, &pi.fpregset);
+      ioctl (pi.fd, PIOCGFPREG, &pi.fpregset);
     }
   fill_fpregset (&pi.fpregset, regno);
-  (void) ioctl (pi.fd, PIOCSFPREG, &pi.fpregset);
+  ioctl (pi.fd, PIOCSFPREG, &pi.fpregset);
 
 #endif /* FP0_REGNUM */
 
@@ -1635,13 +1279,13 @@ void
 inferior_proc_init (pid)
      int pid;
 {
-  if (!open_proc_file (pid, &pi))
+  if (!open_proc_file (pid, &pi, O_RDWR))
     {
       proc_init_failed ("can't open process file");
     }
   else
     {
-      (void) memset ((char *) &pi.prrun, 0, sizeof (pi.prrun));
+      memset ((char *) &pi.prrun, 0, sizeof (pi.prrun));
       prfillset (&pi.prrun.pr_trace);
       proc_signal_handling_change ();
       prfillset (&pi.prrun.pr_fault);
@@ -1747,7 +1391,7 @@ proc_set_exec_trap ()
   auto char procname[32];
   int fd;
   
-  (void) sprintf (procname, PROC_NAME_FMT, getpid ());
+  sprintf (procname, PROC_NAME_FMT, getpid ());
   if ((fd = open (procname, O_RDWR)) < 0)
     {
       perror (procname);
@@ -1781,15 +1425,30 @@ proc_set_exec_trap ()
   /* Turn off inherit-on-fork flag so that all grand-children of gdb
      start with tracing flags cleared. */
 
-#ifdef PIOCRFORK       /* Standard SVR4 */
-  (void) ioctl (fd, PIOCRFORK, NULL);
-#else
-#ifdef PIOCRESET       /* iris (for example) */
+#if defined (PIOCRESET)        /* New method */
   {
       long pr_flags;
       pr_flags = PR_FORK;
-      (void) ioctl (fd, PIOCRESET, &pr_flags);
+      ioctl (fd, PIOCRESET, &pr_flags);
+  }
+#else
+#if defined (PIOCRFORK)        /* Original method */
+  ioctl (fd, PIOCRFORK, NULL);
+#endif
+#endif
+
+  /* Turn on run-on-last-close flag so that this process will not hang
+     if GDB goes away for some reason.  */
+
+#if defined (PIOCSET)  /* New method */
+  {
+      long pr_flags;
+      pr_flags = PR_RLC;
+      (void) ioctl (fd, PIOCSET, &pr_flags);
   }
+#else
+#if defined (PIOCSRLC) /* Original method */
+  (void) ioctl (fd, PIOCSRLC, 0);
 #endif
 #endif
 }
@@ -1822,7 +1481,6 @@ proc_iterate_over_mappings (func)
   int funcstat = 0;
   struct prmap *prmaps;
   struct prmap *prmap;
-  CORE_ADDR baseaddr = 0;
 
   if (pi.valid && (ioctl (pi.fd, PIOCNMAP, &nmap) == 0))
     {
@@ -1958,7 +1616,8 @@ NOTES
 
        The option of stopping at attach time is specific to the /proc
        versions of gdb.  Versions using ptrace force the attachee
-       to stop.
+       to stop.  (I have changed this version to do so, too.  All you
+       have to do is "continue" to make it go on. -- gnu@cygnus.com)
 
 */
 
@@ -1966,7 +1625,9 @@ int
 attach (pid)
      int pid;
 {
-  if (!open_proc_file (pid, &pi))
+  int result;
+
+  if (!open_proc_file (pid, &pi, O_RDWR))
     {
       perror_with_name (pi.pathname);
       /* NOTREACHED */
@@ -1989,29 +1650,52 @@ attach (pid)
   else
     {
       pi.was_stopped = 0;
-      if (query ("Process is currently running, stop it? "))
+      if (1 || query ("Process is currently running, stop it? "))
        {
+         /* Make it run again when we close it.  */
+#if defined (PIOCSET)  /* New method */
+         {
+             long pr_flags;
+             pr_flags = PR_RLC;
+             result = ioctl (pi.fd, PIOCSET, &pr_flags);
+         }
+#else
+#if defined (PIOCSRLC) /* Original method */
+         result = ioctl (pi.fd, PIOCSRLC, 0);
+#endif
+#endif
+         if (result < 0)
+           {
+             print_sys_errmsg (pi.pathname, errno);
+             close_proc_file (&pi);
+             error ("PIOCSRLC or PIOCSET failed");
+           }
          if (ioctl (pi.fd, PIOCSTOP, &pi.prstatus) < 0)
            {
              print_sys_errmsg (pi.pathname, errno);
              close_proc_file (&pi);
              error ("PIOCSTOP failed");
            }
+         pi.nopass_next_sigstop = 1;
+       }
+      else
+       {
+         printf ("Ok, gdb will wait for process %u to stop.\n", pid);
        }
     }
-  
+
   /*  Remember some things about the inferior that we will, or might, change
       so that we can restore them when we detach. */
   
-  (void) ioctl (pi.fd, PIOCGTRACE, &pi.saved_trace);
-  (void) ioctl (pi.fd, PIOCGHOLD, &pi.saved_sighold);
-  (void) ioctl (pi.fd, PIOCGFAULT, &pi.saved_fltset);
-  (void) ioctl (pi.fd, PIOCGENTRY, &pi.saved_entryset);
-  (void) ioctl (pi.fd, PIOCGEXIT, &pi.saved_exitset);
+  ioctl (pi.fd, PIOCGTRACE, &pi.saved_trace);
+  ioctl (pi.fd, PIOCGHOLD, &pi.saved_sighold);
+  ioctl (pi.fd, PIOCGFAULT, &pi.saved_fltset);
+  ioctl (pi.fd, PIOCGENTRY, &pi.saved_entryset);
+  ioctl (pi.fd, PIOCGEXIT, &pi.saved_exitset);
   
   /* Set up trace and fault sets, as gdb expects them. */
   
-  (void) memset (&pi.prrun, 0, sizeof (pi.prrun));
+  memset (&pi.prrun, 0, sizeof (pi.prrun));
   prfillset (&pi.prrun.pr_trace);
   proc_signal_handling_change ();
   prfillset (&pi.prrun.pr_fault);
@@ -2061,6 +1745,8 @@ void
 detach (signal)
      int signal;
 {
+  int result;
+
   if (signal)
     {
       set_proc_siginfo (&pi, signal);
@@ -2102,12 +1788,29 @@ detach (signal)
          if (signal || !pi.was_stopped ||
              query ("Was stopped when attached, make it runnable again? "))
            {
-             (void) memset (&pi.prrun, 0, sizeof (pi.prrun));
-             pi.prrun.pr_flags = PRCFAULT;
-             if (ioctl (pi.fd, PIOCRUN, &pi.prrun))
+             /* Clear any fault that might have stopped it.  */
+             if (ioctl (pi.fd, PIOCCFAULT, 0))
+               {
+                 print_sys_errmsg (pi.pathname, errno);
+                 printf ("PIOCCFAULT failed.\n");
+               }
+
+             /* Make it run again when we close it.  */
+#if defined (PIOCSET)  /* New method */
+             {
+                 long pr_flags;
+                 pr_flags = PR_RLC;
+                 result = ioctl (pi.fd, PIOCSET, &pr_flags);
+             }
+#else
+#if defined (PIOCSRLC) /* Original method */
+             result = ioctl (pi.fd, PIOCSRLC, 0);
+#endif
+#endif
+             if (result)
                {
                  print_sys_errmsg (pi.pathname, errno);
-                 printf ("PIOCRUN failed.\n");
+                 printf ("PIOCSRLC or PIOCSET failed.\n");
                }
            }
        }
@@ -2332,7 +2035,7 @@ set_proc_siginfo (pip, signo)
        }
       else
        {
-         (void) memset ((char *) &newsiginfo, 0, sizeof (newsiginfo));
+         memset ((char *) &newsiginfo, 0, sizeof (newsiginfo));
          sip = &newsiginfo;
          sip -> si_signo = signo;
          sip -> si_code = 0;
@@ -2371,6 +2074,17 @@ NOTE
        to be current.  One case where this might be necessary is if the
        user explicitly changes the PC value that gdb considers to be
        current.  FIXME:  Investigate if this is necessary or not.
+
+       When attaching to a child process, if we forced it to stop with
+       a PIOCSTOP, then we will have set the nopass_next_sigstop flag.
+       Upon resuming the first time after such a stop, we explicitly
+       inhibit sending it another SIGSTOP, which would be the normal
+       result of default signal handling.  One potential drawback to
+       this is that we will also ignore any attempt to by the user
+       to explicitly continue after the attach with a SIGSTOP.  Ultimately
+       this problem should be dealt with by making the routines that
+       deal with the inferior a little smarter, and possibly even allow
+       an inferior to continue running at the same time as gdb.  (FIXME?)
  */
 
 void
@@ -2379,9 +2093,19 @@ child_resume (step, signo)
      int signo;
 {
   errno = 0;
-  pi.prrun.pr_flags = PRSVADDR | PRSTRACE | PRSFAULT | PRCFAULT;
+  pi.prrun.pr_flags = PRSTRACE | PRSFAULT | PRCFAULT;
+
+#ifdef PRSVADDR_BROKEN
+/* Can't do this under Solaris running on a Sparc, as there seems to be no
+   place to put nPC.  In fact, if you use this, nPC seems to be set to some
+   random garbage.  We have to rely on the fact that PC and nPC have been
+   written previously via PIOCSREG during a register flush. */
+
   pi.prrun.pr_vaddr = (caddr_t) *(int *) &registers[REGISTER_BYTE (PC_REGNUM)];
-  if (signo)
+  pi.prrun.pr_flags != PRSVADDR;
+#endif
+
+  if (signo && !(signo == SIGSTOP && pi.nopass_next_sigstop))
     {
       set_proc_siginfo (&pi, signo);
     }
@@ -2389,6 +2113,7 @@ child_resume (step, signo)
     {
       pi.prrun.pr_flags |= PRCSIG;
     }
+  pi.nopass_next_sigstop = 0;
   if (step)
     {
       pi.prrun.pr_flags |= PRSTEP;
@@ -2474,8 +2199,7 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
        }
       else
        {
-         (void) memcpy ((char *) &pi.gregset, core_reg_sect,
-                        sizeof (pi.gregset));
+         memcpy ((char *) &pi.gregset, core_reg_sect, sizeof (pi.gregset));
          supply_gregset (&pi.gregset);
        }
     }
@@ -2487,8 +2211,7 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
        }
       else
        {
-         (void) memcpy ((char *) &pi.fpregset, core_reg_sect,
-                        sizeof (pi.fpregset));
+         memcpy ((char *) &pi.fpregset, core_reg_sect, sizeof (pi.fpregset));
 #if defined (FP0_REGNUM)
          supply_fpregset (&pi.fpregset);
 #endif
@@ -2519,7 +2242,7 @@ proc_init_failed (why)
      char *why;
 {
   print_sys_errmsg (pi.pathname, errno);
-  (void) kill (pi.pid, SIGKILL);
+  kill (pi.pid, SIGKILL);
   close_proc_file (&pi);
   error (why);
   /* NOTREACHED */
@@ -2551,7 +2274,7 @@ close_proc_file (pip)
   pip -> pid = 0;
   if (pip -> valid)
     {
-      (void) close (pip -> fd);
+      close (pip -> fd);
     }
   pip -> fd = -1;
   if (pip -> pathname)
@@ -2570,15 +2293,16 @@ LOCAL FUNCTION
 
 SYNOPSIS
 
-       static int open_proc_file (pid, struct procinfo *pip)
+       static int open_proc_file (int pid, struct procinfo *pip, int mode)
 
 DESCRIPTION
 
-       Given a process id, close the existing open /proc entry (if any)
-       and open one for the new process id.  Once it is open, then
-       mark the local process information structure as valid, which
-       guarantees that the pid, fd, and pathname fields match an open
-       /proc entry.  Returns zero if the open fails, nonzero otherwise.
+       Given a process id and a mode, close the existing open /proc
+       entry (if any) and open one for the new process id, in the
+       specified mode.  Once it is open, then mark the local process
+       information structure as valid, which guarantees that the pid,
+       fd, and pathname fields match an open /proc entry.  Returns
+       zero if the open fails, nonzero otherwise.
 
        Note that the pathname is left intact, even when the open fails,
        so that callers can use it to construct meaningful error messages
@@ -2586,21 +2310,22 @@ DESCRIPTION
  */
 
 static int
-open_proc_file (pid, pip)
+open_proc_file (pid, pip, mode)
      int pid;
      struct procinfo *pip;
+     int mode;
 {
-  pip -> valid = 0;
+  pip -> valid = 0;            /* FIXME, what is this? ?!  */
   if (pip -> valid)
     {
-      (void) close (pip -> fd);
+      close (pip -> fd);
     }
   if (pip -> pathname == NULL)
     {
       pip -> pathname = xmalloc (32);
     }
   sprintf (pip -> pathname, PROC_NAME_FMT, pid);
-  if ((pip -> fd = open (pip -> pathname, O_RDWR)) >= 0)
+  if ((pip -> fd = open (pip -> pathname, mode)) >= 0)
     {
       pip -> valid = 1;
       pip -> pid = pid;
@@ -2612,15 +2337,18 @@ static char *
 mappingflags (flags)
      long flags;
 {
-  static char asciiflags[7];
+  static char asciiflags[8];
   
-  strcpy (asciiflags, "------");
-  if (flags & MA_STACK)  asciiflags[0] = 's';
-  if (flags & MA_BREAK)  asciiflags[1] = 'b';
-  if (flags & MA_SHARED) asciiflags[2] = 's';
-  if (flags & MA_READ)   asciiflags[3] = 'r';
-  if (flags & MA_WRITE)  asciiflags[4] = 'w';
-  if (flags & MA_EXEC)   asciiflags[5] = 'x';
+  strcpy (asciiflags, "-------");
+#if defined (MA_PHYS)
+  if (flags & MA_PHYS)   asciiflags[0] = 'd';
+#endif
+  if (flags & MA_STACK)  asciiflags[1] = 's';
+  if (flags & MA_BREAK)  asciiflags[2] = 'b';
+  if (flags & MA_SHARED) asciiflags[3] = 's';
+  if (flags & MA_READ)   asciiflags[4] = 'r';
+  if (flags & MA_WRITE)  asciiflags[5] = 'w';
+  if (flags & MA_EXEC)   asciiflags[6] = 'x';
   return (asciiflags);
 }
 
@@ -2706,7 +2434,7 @@ info_proc_stop (pip, summary)
            else
              {
                printf_filtered ("\t%-16s %s.\n", signalname (what),
-                                sys_siglist[what]);
+                                safe_strsignal (what));
              }
            break;
          case PR_SYSENTRY:
@@ -2767,8 +2495,7 @@ info_proc_siginfo (pip, summary)
          printf_filtered ("%s ", signalname (sip -> si_signo));
          if (sip -> si_errno > 0)
            {
-             printf_filtered ("%s ", lookupname (errno_table,
-                                                 sip -> si_errno, "errno"));
+             printf_filtered ("%s ", errnoname (sip -> si_errno));
            }
          if (sip -> si_code <= 0)
            {
@@ -2801,13 +2528,12 @@ info_proc_siginfo (pip, summary)
        {
          printf_filtered ("\n\n");
          printf_filtered ("\t%-16s %s.\n", signalname (sip -> si_signo),
-                          sys_siglist[sip -> si_signo]);
+                          safe_strsignal (sip -> si_signo));
          if (sip -> si_errno > 0)
            {
              printf_filtered ("\t%-16s %s.\n",
-                              lookupname (errno_table,
-                                          sip -> si_errno, "errno"),
-                              lookupdesc (errno_table, sip -> si_errno));
+                              errnoname (sip -> si_errno),
+                              safe_strerror (sip -> si_errno));
            }
          if (sip -> si_code <= 0)
            {
@@ -2918,17 +2644,36 @@ static char *
 signalname (signo)
      int signo;
 {
-  char *abbrev;
+  char *name;
   static char locbuf[32];
 
-  abbrev = sig_abbrev (signo);
-  if (abbrev == NULL)
+  name = strsigno (signo);
+  if (name == NULL)
+    {
+      sprintf (locbuf, "Signal %d", signo);
+    }
+  else
+    {
+      sprintf (locbuf, "%s (%d)", name, signo);
+    }
+  return (locbuf);
+}
+
+static char *
+errnoname (errnum)
+     int errnum;
+{
+  char *name;
+  static char locbuf[32];
+
+  name = strerrno (errnum);
+  if (name == NULL)
     {
-      sprintf (locbuf, "signal %d", signo);
+      sprintf (locbuf, "Errno %d", errnum);
     }
   else
     {
-      sprintf (locbuf, "SIG%s (%d)", abbrev, signo);
+      sprintf (locbuf, "%s (%d)", name, errnum);
     }
   return (locbuf);
 }
@@ -2964,7 +2709,7 @@ info_proc_signals (pip, summary)
          printf_filtered ("%-8s ",
                           prismember (&pip -> prstatus.pr_sigpend, signo)
                           ? "yes" : "no");
-         printf_filtered (" %s\n", sys_siglist[signo]);
+         printf_filtered (" %s\n", safe_strsignal (signo));
        }
       printf_filtered ("\n");
     }
@@ -3012,7 +2757,7 @@ info_proc_mappings (pip, summary)
   if (!summary)
     {
       printf_filtered ("Mapped address spaces:\n\n");
-      printf_filtered ("\t%10s %10s %10s %10s %6s\n",
+      printf_filtered ("\t%10s %10s %10s %10s %7s\n",
                       "Start Addr",
                       "  End Addr",
                       "      Size",
@@ -3025,7 +2770,7 @@ info_proc_mappings (pip, summary)
            {
              for (prmap = prmaps; prmap -> pr_size; ++prmap)
                {
-                 printf_filtered ("\t%#10x %#10x %#10x %#10x %6s\n",
+                 printf_filtered ("\t%#10x %#10x %#10x %#10x %7s\n",
                                   prmap -> pr_vaddr,
                                   prmap -> pr_vaddr + prmap -> pr_size - 1,
                                   prmap -> pr_size,
@@ -3075,7 +2820,6 @@ info_proc (args, from_tty)
   struct procinfo pii;
   struct procinfo *pip;
   struct cleanup *old_chain;
-  char *nexttok;
   char **argv;
   int argsize;
   int summary = 1;
@@ -3155,8 +2899,8 @@ info_proc (args, from_tty)
            {
              pid = pii.pid;
              pip = &pii;
-             (void) memset (&pii, 0, sizeof (pii));
-             if (!open_proc_file (pid, pip))
+             memset (&pii, 0, sizeof (pii));
+             if (!open_proc_file (pid, pip, O_RDONLY))
                {
                  perror_with_name (pip -> pathname);
                  /* NOTREACHED */
This page took 0.035638 seconds and 4 git commands to generate.