aboutsummaryrefslogtreecommitdiff
path: root/gdb/procfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/procfs.c')
-rw-r--r--gdb/procfs.c1230
1 files changed, 1051 insertions, 179 deletions
diff --git a/gdb/procfs.c b/gdb/procfs.c
index 315110f..4ce9d98 100644
--- a/gdb/procfs.c
+++ b/gdb/procfs.c
@@ -1,6 +1,7 @@
/* Machine independent support for SVR4 /proc (process file system) for GDB.
- Copyright 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
- Written by Fred Fish at Cygnus Support.
+ Copyright 1991, 1992-96, 1997 Free Software Foundation, Inc.
+ Written by Fred Fish at Cygnus Support. Changes for sysv4.2mp procfs
+ compatibility by Geoffrey Noer at Cygnus Solutions.
This file is part of GDB.
@@ -24,8 +25,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
For information on the details of using /proc consult section proc(4)
in the UNIX System V Release 4 System Administrator's Reference Manual.
-The general register and floating point register sets are manipulated by
-separate ioctl's. This file makes the assumption that if FP0_REGNUM is
+The general register and floating point register sets are manipulated
+separately. This file makes the assumption that if FP0_REGNUM is
defined, then support for the floating point register set is desired,
regardless of whether or not the actual target has floating point hardware.
@@ -53,11 +54,33 @@ regardless of whether or not the actual target has floating point hardware.
#include "gdbcore.h"
#include "gdbthread.h"
+/* the name of the proc status struct depends on the implementation */
+#ifdef HAVE_PSTATUS_T
+ typedef pstatus_t gdb_prstatus_t;
+#else
+ typedef prstatus_t gdb_prstatus_t;
+#endif
+
#define MAX_SYSCALLS 256 /* Maximum number of syscalls for table */
-#ifndef PROC_NAME_FMT
-#define PROC_NAME_FMT "/proc/%05d"
-#endif
+/* proc name formats may vary depending on the proc implementation */
+#ifdef HAVE_MULTIPLE_PROC_FDS
+ #ifndef CTL_PROC_NAME_FMT
+ #define CTL_PROC_NAME_FMT "/proc/%d/ctl"
+ #define AS_PROC_NAME_FMT "/proc/%d/as"
+ #define MAP_PROC_NAME_FMT "/proc/%d/map"
+ #define STATUS_PROC_NAME_FMT "/proc/%d/status"
+ #endif
+#else /* HAVE_MULTIPLE_PROC_FDS */
+ #ifndef CTL_PROC_NAME_FMT
+ #define CTL_PROC_NAME_FMT "/proc/%05d"
+ #define AS_PROC_NAME_FMT "/proc/%05d"
+ #define MAP_PROC_NAME_FMT "/proc/%05d"
+ #define STATUS_PROC_NAME_FMT "/proc/%05d"
+ #endif
+#endif /* HAVE_MULTIPLE_PROC_FDS */
+
+#define MAX_PROC_NAME_SIZE sizeof("/proc/1234567890/status")
extern struct target_ops procfs_ops; /* Forward declaration */
@@ -77,6 +100,52 @@ CORE_ADDR kernel_u_addr;
#define si_uid _data._proc._pdata._kill.uid
#endif /* BROKEN_SIGINFO_H */
+/* Define structures for passing commands to /proc/pid/ctl file. Note that
+ while we create these for the PROCFS_USE_READ_WRITE world, we use them
+ and ignore the extra cmd int in other proc schemes.
+*/
+/* generic ctl msg */
+struct proc_ctl {
+ int cmd;
+ long data;
+};
+
+/* set general registers */
+struct greg_ctl {
+ int cmd;
+ gregset_t gregset;
+};
+
+/* set fp registers */
+struct fpreg_ctl {
+ int cmd;
+ fpregset_t fpregset;
+};
+
+/* set signals to be traced */
+struct sig_ctl {
+ int cmd;
+ sigset_t sigset;
+};
+
+/* set faults to be traced */
+struct flt_ctl {
+ int cmd;
+ fltset_t fltset;
+};
+
+/* set system calls to be traced */
+struct sys_ctl {
+ int cmd;
+ sysset_t sysset;
+};
+
+/* set current signal to be traced */
+struct sigi_ctl {
+ int cmd;
+ siginfo_t siginfo;
+};
+
/* All access to the inferior, either one started by gdb or one that has
been attached to, is controlled by an instance of a procinfo structure,
defined below. Since gdb currently only handles one inferior at a time,
@@ -89,24 +158,29 @@ CORE_ADDR kernel_u_addr;
struct procinfo {
struct procinfo *next;
int pid; /* Process ID of inferior */
- int fd; /* File descriptor for /proc entry */
+ int ctl_fd; /* File descriptor for /proc ctl file */
+ int status_fd; /* File descriptor for /proc status file */
+ int as_fd; /* File descriptor for /proc as file */
+ int map_fd; /* File descriptor for /proc map file */
char *pathname; /* Pathname to /proc entry */
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
prrun_t prrun; /* Control state when it is run */
- prstatus_t prstatus; /* Current process status info */
- gregset_t gregset; /* General register set */
- fpregset_t fpregset; /* Floating point register set */
- fltset_t fltset; /* Current traced hardware fault set */
- sigset_t trace; /* Current traced signal set */
- sysset_t exitset; /* Current traced system call exit set */
- sysset_t entryset; /* Current traced system call entry set */
- fltset_t saved_fltset; /* Saved traced hardware fault set */
- sigset_t saved_trace; /* Saved traced signal set */
- sigset_t saved_sighold; /* Saved held signal set */
- sysset_t saved_exitset; /* Saved traced system call exit set */
- sysset_t saved_entryset; /* Saved traced system call entry set */
+#endif
+ gdb_prstatus_t prstatus; /* Current process status info */
+ struct greg_ctl gregset; /* General register set */
+ struct fpreg_ctl fpregset; /* Floating point register set */
+ struct flt_ctl fltset; /* Current traced hardware fault set */
+ struct sig_ctl trace; /* Current traced signal set */
+ struct sys_ctl exitset; /* Current traced system call exit set */
+ struct sys_ctl entryset; /* Current traced system call entry set */
+ struct sig_ctl saved_sighold; /* Saved held signal set */
+ struct flt_ctl saved_fltset; /* Saved traced hardware fault set */
+ struct sig_ctl saved_trace; /* Saved traced signal set */
+ struct sys_ctl saved_exitset; /* Saved traced system call exit set */
+ struct sys_ctl saved_entryset;/* Saved traced system call entry set */
int num_syscall_handlers; /* Number of syscall handlers currently installed */
struct procfs_syscall_handler *syscall_handlers; /* Pointer to list of syscall trap handlers */
int new_child; /* Non-zero if it's a new thread */
@@ -422,7 +496,7 @@ static char *errnoname PARAMS ((int));
static int proc_address_to_fd PARAMS ((struct procinfo *, CORE_ADDR, int));
-static int open_proc_file PARAMS ((int, struct procinfo *, int));
+static int open_proc_file PARAMS ((int, struct procinfo *, int, int));
static void close_proc_file PARAMS ((struct procinfo *));
@@ -460,8 +534,14 @@ static void procfs_create_inferior PARAMS ((char *, char *, char **));
static void procfs_notice_signals PARAMS ((int pid));
+static void notice_signals PARAMS ((struct procinfo *, struct sig_ctl *));
+
static struct procinfo *find_procinfo PARAMS ((pid_t pid, int okfail));
+static int procfs_read_status PARAMS ((struct procinfo *));
+static int procfs_write_pcwstop PARAMS ((struct procinfo *));
+static void procfs_write_pckill PARAMS ((struct procinfo *));
+
typedef int syscall_func_t PARAMS ((struct procinfo *pi, int syscall_num,
int why, int *rtnval, int *statval));
@@ -510,9 +590,11 @@ extern void supply_gregset PARAMS ((gregset_t *));
extern void fill_gregset PARAMS ((gregset_t *, int));
+#ifdef FP0_REGNUM
extern void supply_fpregset PARAMS ((fpregset_t *));
extern void fill_fpregset PARAMS ((fpregset_t *, int));
+#endif
/*
@@ -592,8 +674,12 @@ add_fd (pi)
poll_list = (struct pollfd *) xrealloc (poll_list,
(num_poll_list + 1)
* sizeof (struct pollfd));
- poll_list[num_poll_list].fd = pi->fd;
+ poll_list[num_poll_list].fd = pi->ctl_fd;
+#ifdef UNIXWARE
+ poll_list[num_poll_list].events = POLLWRNORM;
+#else
poll_list[num_poll_list].events = POLLPRI;
+#endif
num_poll_list++;
}
@@ -606,7 +692,7 @@ remove_fd (pi)
for (i = 0; i < num_poll_list; i++)
{
- if (poll_list[i].fd == pi->fd)
+ if (poll_list[i].fd == pi->ctl_fd)
{
if (i != num_poll_list - 1)
memcpy (poll_list + i, poll_list + i + 1,
@@ -625,6 +711,103 @@ remove_fd (pi)
}
}
+/*
+
+LOCAL FUNCTION
+
+ procfs_read_status - get procfs fd status
+
+SYNOPSIS
+
+ static int procfs_read_status (pi) struct procinfo *pi;
+
+DESCRIPTION
+
+ Given a pointer to a procinfo struct, get the status of
+ the status_fd in the appropriate way. Returns 0 on failure,
+ 1 on success.
+ */
+
+static int
+procfs_read_status (pi)
+ struct procinfo *pi;
+{
+#ifdef PROCFS_USE_READ_WRITE
+ if ((lseek (pi->status_fd, 0, SEEK_SET) < 0) ||
+ (read (pi->status_fd, (char *) &pi->prstatus,
+ sizeof (gdb_prstatus_t)) != sizeof (gdb_prstatus_t)))
+#else
+ if (ioctl (pi->status_fd, PIOCSTATUS, &pi->prstatus) < 0)
+#endif
+ return 0;
+ else
+ return 1;
+}
+
+/*
+
+LOCAL FUNCTION
+
+ procfs_write_pcwstop - send a PCWSTOP to procfs fd
+
+SYNOPSIS
+
+ static int procfs_write_pcwstop (pi) struct procinfo *pi;
+
+DESCRIPTION
+
+ Given a pointer to a procinfo struct, send a PCWSTOP to
+ the ctl_fd in the appropriate way. Returns 0 on failure,
+ 1 on success.
+ */
+
+static int
+procfs_write_pcwstop (pi)
+ struct procinfo *pi;
+{
+#ifdef PROCFS_USE_READ_WRITE
+ long cmd = PCWSTOP;
+ if (write (pi->ctl_fd, (char *) &cmd, sizeof (long)) < 0)
+#else
+ if (ioctl (pi->ctl_fd, PIOCWSTOP, &pi->prstatus) < 0)
+#endif
+ return 0;
+ else
+ return 1;
+}
+
+/*
+
+LOCAL FUNCTION
+
+ procfs_write_pckill - send a kill to procfs fd
+
+SYNOPSIS
+
+ static void procfs_write_pckill (pi) struct procinfo *pi;
+
+DESCRIPTION
+
+ Given a pointer to a procinfo struct, send a kill to
+ the ctl_fd in the appropriate way. Returns 0 on failure,
+ 1 on success.
+ */
+
+static void
+procfs_write_pckill (pi)
+ struct procinfo *pi;
+{
+#ifdef PROCFS_USE_READ_WRITE
+ struct proc_ctl pctl;
+ pctl.cmd = PCKILL;
+ pctl.data = SIGKILL;
+ write (pi->ctl_fd, &pctl, sizeof (struct proc_ctl));
+#else
+ int signo = SIGKILL;
+ ioctl (pi->ctl_fd, PIOCKILL, &signo);
+#endif
+}
+
static struct procinfo *
wait_fd ()
{
@@ -649,10 +832,10 @@ wait_fd ()
print_sys_errmsg ("poll failed", errno);
error ("Poll failed, returned %d", num_fds);
}
-#else
+#else /* LOSING_POLL */
pi = current_procinfo;
- while (ioctl (pi->fd, PIOCWSTOP, &pi->prstatus) < 0)
+ while (!procfs_write_pcwstop (pi))
{
if (errno == ENOENT)
{
@@ -663,11 +846,11 @@ wait_fd ()
else if (errno != EINTR)
{
print_sys_errmsg (pi->pathname, errno);
- error ("PIOCWSTOP failed");
+ error ("procfs_write_pcwstop failed");
}
}
pi->had_event = 1;
-#endif
+#endif /* LOSING_POLL */
clear_sigint_trap ();
clear_sigio_trap ();
@@ -676,17 +859,18 @@ wait_fd ()
for (i = 0; i < num_poll_list && num_fds > 0; i++)
{
- if ((poll_list[i].revents & (POLLPRI|POLLERR|POLLHUP|POLLNVAL)) == 0)
+ if ((poll_list[i].revents & (POLLWRNORM|POLLPRI|POLLERR|POLLHUP|POLLNVAL)) == 0)
continue;
for (pi = procinfo_list; pi; pi = pi->next)
{
- if (poll_list[i].fd == pi->fd)
+ if (poll_list[i].fd == pi->ctl_fd)
{
- if (ioctl (pi->fd, PIOCSTATUS, &pi->prstatus) < 0)
+ if (!procfs_read_status(pi))
{
print_sys_errmsg (pi->pathname, errno);
- error ("PIOCSTATUS failed");
+ error ("procfs_read_status failed");
}
+
num_fds--;
pi->had_event = 1;
break;
@@ -1062,6 +1246,9 @@ init_syscall_table ()
#if defined (SYS_sys3b)
syscall_table[SYS_sys3b] = "sys3b";
#endif
+#if defined (SYS_sysi86)
+ syscall_table[SYS_sysi86] = "sysi86";
+#endif
#if defined (SYS_acct)
syscall_table[SYS_acct] = "acct";
#endif
@@ -1278,6 +1465,192 @@ init_syscall_table ()
#if defined (SYS_sproc)
syscall_table[SYS_sproc] = "sproc";
#endif
+#if defined (SYS_keyctl)
+ syscall_table[SYS_keyctl] = "keyctl";
+#endif
+#if defined (SYS_secsys)
+ syscall_table[SYS_secsys] = "secsys";
+#endif
+#if defined (SYS_filepriv)
+ syscall_table[SYS_filepriv] = "filepriv";
+#endif
+#if defined (SYS_procpriv)
+ syscall_table[SYS_procpriv] = "procpriv";
+#endif
+#if defined (SYS_devstat)
+ syscall_table[SYS_devstat] = "devstat";
+#endif
+#if defined (SYS_aclipc)
+ syscall_table[SYS_aclipc] = "aclipc";
+#endif
+#if defined (SYS_fdevstat)
+ syscall_table[SYS_fdevstat] = "fdevstat";
+#endif
+#if defined (SYS_flvlfile)
+ syscall_table[SYS_flvlfile] = "flvlfile";
+#endif
+#if defined (SYS_lvlfile)
+ syscall_table[SYS_lvlfile] = "lvlfile";
+#endif
+#if defined (SYS_lvlequal)
+ syscall_table[SYS_lvlequal] = "lvlequal";
+#endif
+#if defined (SYS_lvlproc)
+ syscall_table[SYS_lvlproc] = "lvlproc";
+#endif
+#if defined (SYS_lvlipc)
+ syscall_table[SYS_lvlipc] = "lvlipc";
+#endif
+#if defined (SYS_acl)
+ syscall_table[SYS_acl] = "acl";
+#endif
+#if defined (SYS_auditevt)
+ syscall_table[SYS_auditevt] = "auditevt";
+#endif
+#if defined (SYS_auditctl)
+ syscall_table[SYS_auditctl] = "auditctl";
+#endif
+#if defined (SYS_auditdmp)
+ syscall_table[SYS_auditdmp] = "auditdmp";
+#endif
+#if defined (SYS_auditlog)
+ syscall_table[SYS_auditlog] = "auditlog";
+#endif
+#if defined (SYS_auditbuf)
+ syscall_table[SYS_auditbuf] = "auditbuf";
+#endif
+#if defined (SYS_lvldom)
+ syscall_table[SYS_lvldom] = "lvldom";
+#endif
+#if defined (SYS_lvlvfs)
+ syscall_table[SYS_lvlvfs] = "lvlvfs";
+#endif
+#if defined (SYS_mkmld)
+ syscall_table[SYS_mkmld] = "mkmld";
+#endif
+#if defined (SYS_mldmode)
+ syscall_table[SYS_mldmode] = "mldmode";
+#endif
+#if defined (SYS_secadvise)
+ syscall_table[SYS_secadvise] = "secadvise";
+#endif
+#if defined (SYS_online)
+ syscall_table[SYS_online] = "online";
+#endif
+#if defined (SYS_setitimer)
+ syscall_table[SYS_setitimer] = "setitimer";
+#endif
+#if defined (SYS_getitimer)
+ syscall_table[SYS_getitimer] = "getitimer";
+#endif
+#if defined (SYS_gettimeofday)
+ syscall_table[SYS_gettimeofday] = "gettimeofday";
+#endif
+#if defined (SYS_settimeofday)
+ syscall_table[SYS_settimeofday] = "settimeofday";
+#endif
+#if defined (SYS_lwpcreate)
+ syscall_table[SYS_lwpcreate] = "lwpcreate";
+#endif
+#if defined (SYS_lwpexit)
+ syscall_table[SYS_lwpexit] = "lwpexit";
+#endif
+#if defined (SYS_lwpwait)
+ syscall_table[SYS_lwpwait] = "lwpwait";
+#endif
+#if defined (SYS_lwpself)
+ syscall_table[SYS_lwpself] = "lwpself";
+#endif
+#if defined (SYS_lwpinfo)
+ syscall_table[SYS_lwpinfo] = "lwpinfo";
+#endif
+#if defined (SYS_lwpprivate)
+ syscall_table[SYS_lwpprivate] = "lwpprivate";
+#endif
+#if defined (SYS_processor_bind)
+ syscall_table[SYS_processor_bind] = "processor_bind";
+#endif
+#if defined (SYS_processor_exbind)
+ syscall_table[SYS_processor_exbind] = "processor_exbind";
+#endif
+#if defined (SYS_prepblock)
+ syscall_table[SYS_prepblock] = "prepblock";
+#endif
+#if defined (SYS_block)
+ syscall_table[SYS_block] = "block";
+#endif
+#if defined (SYS_rdblock)
+ syscall_table[SYS_rdblock] = "rdblock";
+#endif
+#if defined (SYS_unblock)
+ syscall_table[SYS_unblock] = "unblock";
+#endif
+#if defined (SYS_cancelblock)
+ syscall_table[SYS_cancelblock] = "cancelblock";
+#endif
+#if defined (SYS_pread)
+ syscall_table[SYS_pread] = "pread";
+#endif
+#if defined (SYS_pwrite)
+ syscall_table[SYS_pwrite] = "pwrite";
+#endif
+#if defined (SYS_truncate)
+ syscall_table[SYS_truncate] = "truncate";
+#endif
+#if defined (SYS_ftruncate)
+ syscall_table[SYS_ftruncate] = "ftruncate";
+#endif
+#if defined (SYS_lwpkill)
+ syscall_table[SYS_lwpkill] = "lwpkill";
+#endif
+#if defined (SYS_sigwait)
+ syscall_table[SYS_sigwait] = "sigwait";
+#endif
+#if defined (SYS_fork1)
+ syscall_table[SYS_fork1] = "fork1";
+#endif
+#if defined (SYS_forkall)
+ syscall_table[SYS_forkall] = "forkall";
+#endif
+#if defined (SYS_modload)
+ syscall_table[SYS_modload] = "modload";
+#endif
+#if defined (SYS_moduload)
+ syscall_table[SYS_moduload] = "moduload";
+#endif
+#if defined (SYS_modpath)
+ syscall_table[SYS_modpath] = "modpath";
+#endif
+#if defined (SYS_modstat)
+ syscall_table[SYS_modstat] = "modstat";
+#endif
+#if defined (SYS_modadm)
+ syscall_table[SYS_modadm] = "modadm";
+#endif
+#if defined (SYS_getksym)
+ syscall_table[SYS_getksym] = "getksym";
+#endif
+#if defined (SYS_lwpsuspend)
+ syscall_table[SYS_lwpsuspend] = "lwpsuspend";
+#endif
+#if defined (SYS_lwpcontinue)
+ syscall_table[SYS_lwpcontinue] = "lwpcontinue";
+#endif
+#if defined (SYS_priocntllst)
+ syscall_table[SYS_priocntllst] = "priocntllst";
+#endif
+#if defined (SYS_sleep)
+ syscall_table[SYS_sleep] = "sleep";
+#endif
+#if defined (SYS_lwp_sema_wait)
+ syscall_table[SYS_lwp_sema_wait] = "lwp_sema_wait";
+#endif
+#if defined (SYS_lwp_sema_post)
+ syscall_table[SYS_lwp_sema_post] = "lwp_sema_post";
+#endif
+#if defined (SYS_lwp_sema_trywait)
+ syscall_table[SYS_lwp_sema_trywait] = "lwp_sema_trywait";
+#endif
}
/*
@@ -1335,18 +1708,16 @@ static void
unconditionally_kill_inferior (pi)
struct procinfo *pi;
{
- int signo;
int ppid;
+ struct proc_ctl pctl;
ppid = pi->prstatus.pr_ppid;
- signo = SIGKILL;
-
#ifdef PROCFS_NEED_CLEAR_CURSIG_FOR_KILL
/* Alpha OSF/1-3.x procfs needs a clear of the current signal
before the PIOCKILL, otherwise it might generate a corrupted core
file for the inferior. */
- ioctl (pi->fd, PIOCSSIG, NULL);
+ ioctl (pi->ctl_fd, PIOCSSIG, NULL);
#endif
#ifdef PROCFS_NEED_PIOCSSIG_FOR_KILL
/* Alpha OSF/1-2.x procfs needs a PIOCSSIG call with a SIGKILL signal
@@ -1358,16 +1729,16 @@ unconditionally_kill_inferior (pi)
struct siginfo newsiginfo;
memset ((char *) &newsiginfo, 0, sizeof (newsiginfo));
- newsiginfo.si_signo = signo;
+ newsiginfo.si_signo = SIGKILL;
newsiginfo.si_code = 0;
newsiginfo.si_errno = 0;
newsiginfo.si_pid = getpid ();
newsiginfo.si_uid = getuid ();
- ioctl (pi->fd, PIOCSSIG, &newsiginfo);
+ ioctl (pi->ctl_fd, PIOCSSIG, &newsiginfo);
}
-#else
- ioctl (pi->fd, PIOCKILL, &signo);
-#endif
+#else /* PROCFS_NEED_PIOCSSIG_FOR_KILL */
+ procfs_write_pckill (pi);
+#endif /* PROCFS_NEED_PIOCSSIG_FOR_KILL */
close_proc_file (pi);
@@ -1418,15 +1789,15 @@ procfs_xfer_memory (memaddr, myaddr, len, dowrite, target)
pi = current_procinfo;
- if (lseek(pi->fd, (off_t) memaddr, 0) == (off_t) memaddr)
+ if (lseek(pi->as_fd, (off_t) memaddr, SEEK_SET) == (off_t) memaddr)
{
if (dowrite)
{
- nbytes = write (pi->fd, myaddr, len);
+ nbytes = write (pi->as_fd, myaddr, len);
}
else
{
- nbytes = read (pi->fd, myaddr, len);
+ nbytes = read (pi->as_fd, myaddr, len);
}
if (nbytes < 0)
{
@@ -1479,15 +1850,32 @@ procfs_store_registers (regno)
int regno;
{
struct procinfo *pi;
+#ifdef PROCFS_USE_READ_WRITE
+ struct greg_ctl greg;
+ struct fpreg_ctl fpreg;
+#endif
pi = current_procinfo;
+#ifdef PROCFS_USE_READ_WRITE
if (regno != -1)
{
- ioctl (pi->fd, PIOCGREG, &pi->gregset);
+ procfs_read_status (pi);
+ memcpy ((char *) &greg.gregset,
+ (char *) &pi->prstatus.pr_lwp.pr_context.uc_mcontext.gregs,
+ sizeof (gregset_t));
}
- fill_gregset (&pi->gregset, regno);
- ioctl (pi->fd, PIOCSREG, &pi->gregset);
+ fill_gregset (&greg.gregset, regno);
+ greg.cmd = PCSREG;
+ write (pi->ctl_fd, &greg, sizeof (greg));
+#else /* PROCFS_USE_READ_WRITE */
+ if (regno != -1)
+ {
+ ioctl (pi->ctl_fd, PIOCGREG, &pi->gregset.gregset);
+ }
+ fill_gregset (&pi->gregset.gregset, regno);
+ ioctl (pi->ctl_fd, PIOCSREG, &pi->gregset.gregset);
+#endif /* PROCFS_USE_READ_WRITE */
#if defined (FP0_REGNUM)
@@ -1495,12 +1883,25 @@ procfs_store_registers (regno)
target has floating point hardware. Since we ignore the returned value,
we'll never know whether it worked or not anyway. */
+#ifdef PROCFS_USE_READ_WRITE
if (regno != -1)
{
- ioctl (pi->fd, PIOCGFPREG, &pi->fpregset);
+ procfs_read_status (pi);
+ memcpy ((char *) &fpreg.fpregset,
+ (char *) &pi->prstatus.pr_lwp.pr_context.uc_mcontext.fpregs,
+ sizeof (fpregset_t));
}
- fill_fpregset (&pi->fpregset, regno);
- ioctl (pi->fd, PIOCSFPREG, &pi->fpregset);
+ fill_fpregset (&fpreg.fpregset, regno);
+ fpreg.cmd = PCSFPREG;
+ write (pi->ctl_fd, &fpreg, sizeof (fpreg));
+#else /* PROCFS_USE_READ_WRITE */
+ if (regno != -1)
+ {
+ ioctl (pi->ctl_fd, PIOCGFPREG, &pi->fpregset.fpregset);
+ }
+ fill_fpregset (&pi->fpregset.fpregset, regno);
+ ioctl (pi->ctl_fd, PIOCSFPREG, &pi->fpregset.fpregset);
+#endif /* PROCFS_USE_READ_WRITE */
#endif /* FP0_REGNUM */
@@ -1534,6 +1935,8 @@ create_procinfo (pid)
int pid;
{
struct procinfo *pi;
+ struct sig_ctl sctl;
+ struct flt_ctl fctl;
pi = find_procinfo (pid, 1);
if (pi != NULL)
@@ -1541,7 +1944,7 @@ create_procinfo (pid)
pi = (struct procinfo *) xmalloc (sizeof (struct procinfo));
- if (!open_proc_file (pid, pi, O_RDWR))
+ if (!open_proc_file (pid, pi, O_RDWR, 1))
proc_init_failed (pi, "can't open process file");
/* open_proc_file may modify pid. */
@@ -1557,28 +1960,42 @@ create_procinfo (pid)
pi->num_syscall_handlers = 0;
pi->syscall_handlers = NULL;
+#ifdef UNIXWARE
+ prfillset (&sctl.sigset);
+ notice_signals (pi, &sctl);
+ prfillset (&fctl.fltset);
+ prdelset (&fctl.fltset, FLTPAGE);
+#else /* UNIXWARE */
memset ((char *) &pi->prrun, 0, sizeof (pi->prrun));
prfillset (&pi->prrun.pr_trace);
procfs_notice_signals (pid);
prfillset (&pi->prrun.pr_fault);
prdelset (&pi->prrun.pr_fault, FLTPAGE);
-
#ifdef PROCFS_DONT_TRACE_FAULTS
premptyset (&pi->prrun.pr_fault);
#endif
+#endif /* UNIXWARE */
- if (ioctl (pi->fd, PIOCSTATUS, &pi->prstatus) < 0)
- proc_init_failed (pi, "PIOCSTATUS failed");
+ if (!procfs_read_status (pi))
+ proc_init_failed (pi, "procfs_read_status failed");
/* A bug in Solaris (2.5 at least) causes PIOCWSTOP to hang on LWPs that are
already stopped, even if they all have PR_ASYNC set. */
+#ifndef UNIXWARE
if (!(pi->prstatus.pr_flags & PR_STOPPED))
- if (ioctl (pi->fd, PIOCWSTOP, &pi->prstatus) < 0)
- proc_init_failed (pi, "PIOCWSTOP failed");
+#endif
+ if (!procfs_write_pcwstop (pi))
+ proc_init_failed (pi, "procfs_write_pcwstop failed");
- if (ioctl (pi->fd, PIOCSFAULT, &pi->prrun.pr_fault) < 0)
+#ifdef PROCFS_USE_READ_WRITE
+ fctl.cmd = PCSFAULT;
+ if (write (pi->ctl_fd, (char *) &fctl, sizeof (struct flt_ctl)) < 0)
+ proc_init_failed (pi, "PCSFAULT failed");
+#else
+ if (ioctl (pi->ctl_fd, PIOCSFAULT, &pi->prrun.pr_fault) < 0)
proc_init_failed (pi, "PIOCSFAULT failed");
+#endif
return pi;
}
@@ -1615,7 +2032,7 @@ procfs_exit_handler (pi, syscall_num, why, rtnvalp, statvalp)
{
pi->prrun.pr_flags = PRCFAULT;
- if (ioctl (pi->fd, PIOCRUN, &pi->prrun) != 0)
+ if (ioctl (pi->ctl_fd, PIOCRUN, &pi->prrun) != 0)
perror_with_name (pi->pathname);
*rtnvalp = wait (statvalp);
@@ -1661,7 +2078,8 @@ procfs_exec_handler (pi, syscall_num, why, rtnvalp, statvalp)
return 1;
}
-#ifdef SYS_sproc /* IRIX lwp creation system call */
+#if defined(SYS_sproc) && !defined(UNIXWARE)
+/* IRIX lwp creation system call */
/*
@@ -1711,7 +2129,7 @@ procfs_sproc_handler (pi, syscall_num, why, rtnvalp, statvalp)
pi->prrun.pr_flags &= PRSTEP;
pi->prrun.pr_flags |= PRCFAULT;
- if (ioctl (pi->fd, PIOCRUN, &pi->prrun) != 0)
+ if (ioctl (pi->ctl_fd, PIOCRUN, &pi->prrun) != 0)
perror_with_name (pi->pathname);
return 0;
@@ -1777,12 +2195,12 @@ procfs_fork_handler (pi, syscall_num, why, rtnvalp, statvalp)
if (pitemp)
close_proc_file (pitemp);
- if (ioctl (pi->fd, PIOCRUN, &pi->prrun) != 0)
+ if (ioctl (pi->ctl_fd, PIOCRUN, &pi->prrun) != 0)
perror_with_name (pi->pathname);
return 0;
}
-#endif /* SYS_sproc */
+#endif /* SYS_sproc && !UNIXWARE */
/*
@@ -1855,7 +2273,7 @@ procfs_init_inferior (pid)
that we also have to trap on fork and vfork in order to disable all tracing
in the targets child processes. */
- modify_inherit_on_fork_flag (pip->fd, 1);
+ modify_inherit_on_fork_flag (pip->ctl_fd, 1);
#endif
#ifdef SYS_lwp_create
@@ -1910,25 +2328,46 @@ static void
procfs_notice_signals (pid)
int pid;
{
- int signo;
struct procinfo *pi;
+ struct sig_ctl sctl;
pi = find_procinfo (pid, 0);
+#ifdef UNIXWARE
+ premptyset (&sctl.sigset);
+#else
+ sctl.sigset = &pi->prrun.pr_trace;
+#endif
+
+ notice_signals (pi, &sctl);
+}
+
+static void
+notice_signals (pi, sctl)
+ struct procinfo *pi;
+ struct sig_ctl *sctl;
+{
+ int signo;
+
for (signo = 0; signo < NSIG; signo++)
{
if (signal_stop_state (target_signal_from_host (signo)) == 0 &&
signal_print_state (target_signal_from_host (signo)) == 0 &&
signal_pass_state (target_signal_from_host (signo)) == 1)
{
- prdelset (&pi->prrun.pr_trace, signo);
+ prdelset (&sctl->sigset, signo);
}
else
{
- praddset (&pi->prrun.pr_trace, signo);
+ praddset (&sctl->sigset, signo);
}
}
- if (ioctl (pi->fd, PIOCSTRACE, &pi->prrun.pr_trace))
+#ifdef PROCFS_USE_READ_WRITE
+ sctl->cmd = PCSTRACE;
+ if (write (pi->ctl_fd, (char *) sctl, sizeof (struct sig_ctl)) < 0)
+#else
+ if (ioctl (pi->ctl_fd, PIOCSTRACE, &sctl->sigset))
+#endif
{
print_sys_errmsg ("PIOCSTRACE failed", errno);
}
@@ -1968,20 +2407,24 @@ NOTE
static void
proc_set_exec_trap ()
{
- sysset_t exitset;
- sysset_t entryset;
- auto char procname[32];
+ struct sys_ctl exitset;
+ struct sys_ctl entryset;
+ char procname[MAX_PROC_NAME_SIZE];
int fd;
- sprintf (procname, PROC_NAME_FMT, getpid ());
+ sprintf (procname, CTL_PROC_NAME_FMT, getpid ());
+#ifdef UNIXWARE
+ if ((fd = open (procname, O_WRONLY)) < 0)
+#else
if ((fd = open (procname, O_RDWR)) < 0)
+#endif
{
perror (procname);
gdb_flush (gdb_stderr);
_exit (127);
}
- premptyset (&exitset);
- premptyset (&entryset);
+ premptyset (&exitset.sysset);
+ premptyset (&entryset.sysset);
#ifdef PIOCSSPCACT
/* Under Alpha OSF/1 we have to use a PIOCSSPCACT ioctl to trace
@@ -2013,25 +2456,35 @@ proc_set_exec_trap ()
*is* a SYS_execv. So, we try to account for that. */
#ifdef SYS_exec
- praddset (&exitset, SYS_exec);
+ praddset (&exitset.sysset, SYS_exec);
#endif
#ifdef SYS_execve
- praddset (&exitset, SYS_execve);
+ praddset (&exitset.sysset, SYS_execve);
#endif
#ifdef SYS_execv
- praddset (&exitset, SYS_execv);
+ praddset (&exitset.sysset, SYS_execv);
#endif
- if (ioctl (fd, PIOCSEXIT, &exitset) < 0)
+#ifdef PROCFS_USE_READ_WRITE
+ exitset.cmd = PCSEXIT;
+ if (write (fd, (char *) &exitset, sizeof (struct sys_ctl)) < 0)
+#else
+ if (ioctl (fd, PIOCSEXIT, &exitset.sysset) < 0)
+#endif
{
perror (procname);
gdb_flush (gdb_stderr);
_exit (127);
}
- praddset (&entryset, SYS_exit);
+ praddset (&entryset.sysset, SYS_exit);
- if (ioctl (fd, PIOCSENTRY, &entryset) < 0)
+#ifdef PROCFS_USE_READ_WRITE
+ entryset.cmd = PCSENTRY;
+ if (write (fd, (char *) &entryset, sizeof (struct sys_ctl)) < 0)
+#else
+ if (ioctl (fd, PIOCSENTRY, &entryset.sysset) < 0)
+#endif
{
perror (procname);
gdb_flush (gdb_stderr);
@@ -2052,14 +2505,20 @@ proc_set_exec_trap ()
#ifdef PR_ASYNC
{
long pr_flags;
+ struct proc_ctl pctl;
/* Solaris needs this to make procfs treat all threads seperately. Without
this, all threads halt whenever something happens to any thread. Since
GDB wants to control all this itself, it needs to set PR_ASYNC. */
pr_flags = PR_ASYNC;
-
+#ifdef PROCFS_USE_READ_WRITE
+ pctl.cmd = PCSET;
+ pctl.data = PR_FORK|PR_ASYNC;
+ write (fd, (char *) &pctl, sizeof (struct proc_ctl));
+#else
ioctl (fd, PIOCSET, &pr_flags);
+#endif
}
#endif /* PR_ASYNC */
}
@@ -2083,6 +2542,48 @@ DESCRIPTION
the end of the mappings or the function returns nonzero.
*/
+#ifdef UNIXWARE
+int
+proc_iterate_over_mappings (func)
+ int (*func) PARAMS ((int, CORE_ADDR));
+{
+ int nmap;
+ int fd;
+ int funcstat = 0;
+ prmap_t *prmaps;
+ prmap_t *prmap;
+ struct procinfo *pi;
+ struct stat sbuf;
+
+ pi = current_procinfo;
+
+ if (fstat (pi->map_fd, &sbuf) < 0)
+ return 0;
+
+ nmap = sbuf.st_size / sizeof (prmap_t);
+ prmaps = (prmap_t *) alloca (nmap * sizeof(prmap_t));
+ if ((lseek (pi->map_fd, 0, SEEK_SET) == 0) &&
+ (read (pi->map_fd, (char *) prmaps, nmap * sizeof (prmap_t)) ==
+ (nmap * sizeof (prmap_t))))
+ {
+ int i = 0;
+ for (prmap = prmaps; i < nmap && funcstat == 0; ++prmap, ++i)
+ {
+ char name[sizeof ("/proc/1234567890/object") +
+ sizeof (prmap->pr_mapname)];
+ sprintf (name, "/proc/%d/object/%s", pi->pid, prmap->pr_mapname);
+ if ((fd = open (name, O_RDONLY)) == -1)
+ {
+ funcstat = 1;
+ break;
+ }
+ funcstat = (*func) (fd, (CORE_ADDR) prmap->pr_vaddr);
+ close (fd);
+ }
+ }
+ return (funcstat);
+}
+#else /* UNIXWARE */
int
proc_iterate_over_mappings (func)
int (*func) PARAMS ((int, CORE_ADDR));
@@ -2096,10 +2597,10 @@ proc_iterate_over_mappings (func)
pi = current_procinfo;
- if (ioctl (pi->fd, PIOCNMAP, &nmap) == 0)
+ if (ioctl (pi->map_fd, PIOCNMAP, &nmap) == 0)
{
prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
- if (ioctl (pi->fd, PIOCMAP, prmaps) == 0)
+ if (ioctl (pi->map_fd, PIOCMAP, prmaps) == 0)
{
for (prmap = prmaps; prmap -> pr_size && funcstat == 0; ++prmap)
{
@@ -2111,6 +2612,7 @@ proc_iterate_over_mappings (func)
}
return (funcstat);
}
+#endif /* UNIXWARE */
#if 0 /* Currently unused */
/*
@@ -2146,10 +2648,10 @@ proc_base_address (addr)
pi = current_procinfo;
- if (ioctl (pi->fd, PIOCNMAP, &nmap) == 0)
+ if (ioctl (pi->map_fd, PIOCNMAP, &nmap) == 0)
{
prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
- if (ioctl (pi->fd, PIOCMAP, prmaps) == 0)
+ if (ioctl (pi->map_fd, PIOCMAP, prmaps) == 0)
{
for (prmap = prmaps; prmap -> pr_size; ++prmap)
{
@@ -2195,7 +2697,7 @@ proc_address_to_fd (pi, addr, complain)
{
int fd = -1;
- if ((fd = ioctl (pi->fd, PIOCOPENM, (caddr_t *) &addr)) < 0)
+ if ((fd = ioctl (pi->ctl_fd, PIOCOPENM, (caddr_t *) &addr)) < 0)
{
if (complain)
{
@@ -2338,10 +2840,12 @@ do_attach (pid)
int pid;
{
struct procinfo *pi;
+ struct sig_ctl sctl;
+ struct flt_ctl fctl;
pi = (struct procinfo *) xmalloc (sizeof (struct procinfo));
- if (!open_proc_file (pid, pi, O_RDWR))
+ if (!open_proc_file (pid, pi, O_RDWR, 1))
{
free (pi);
perror_with_name (pi->pathname);
@@ -2360,14 +2864,17 @@ do_attach (pid)
/* Get current status of process and if it is not already stopped,
then stop it. Remember whether or not it was stopped when we first
examined it. */
-
- if (ioctl (pi->fd, PIOCSTATUS, &pi->prstatus) < 0)
+ if (!procfs_read_status (pi))
{
print_sys_errmsg (pi->pathname, errno);
close_proc_file (pi);
- error ("PIOCSTATUS failed");
+ error ("procfs_read_status failed");
}
+#ifdef UNIXWARE
+ if (pi->prstatus.pr_lwp.pr_flags & (PR_STOPPED | PR_ISTOP))
+#else
if (pi->prstatus.pr_flags & (PR_STOPPED | PR_ISTOP))
+#endif
{
pi->was_stopped = 1;
}
@@ -2376,16 +2883,30 @@ do_attach (pid)
pi->was_stopped = 0;
if (1 || query ("Process is currently running, stop it? "))
{
+ long cmd;
/* Make it run again when we close it. */
- modify_run_on_last_close_flag (pi->fd, 1);
+ modify_run_on_last_close_flag (pi->ctl_fd, 1);
- if (ioctl (pi->fd, PIOCSTOP, &pi->prstatus) < 0)
+#ifdef PROCFS_USE_READ_WRITE
+ cmd = PCSTOP;
+ if (write (pi->ctl_fd, (char *) &cmd, sizeof (long)) < 0)
+#else
+ if (ioctl (pi->ctl_fd, PIOCSTOP, &pi->prstatus) < 0)
+#endif
{
print_sys_errmsg (pi->pathname, errno);
close_proc_file (pi);
error ("PIOCSTOP failed");
}
+#ifdef UNIXWARE
+ if (!procfs_read_status (pi))
+ {
+ print_sys_errmsg (pi->pathname, errno);
+ close_proc_file (pi);
+ error ("procfs_read_status failed");
+ }
+#endif
pi->nopass_next_sigstop = 1;
}
else
@@ -2396,12 +2917,32 @@ do_attach (pid)
/* Remember some things about the inferior that we will, or might, change
so that we can restore them when we detach. */
-
- 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);
+#ifdef PROCFS_USE_READ_WRITE
+ memcpy ((char *) &pi->saved_trace.sigset,
+ (char *) &pi->prstatus.pr_sigtrace, sizeof (sigset_t));
+ memcpy ((char *) &pi->saved_fltset.fltset,
+ (char *) &pi->prstatus.pr_flttrace, sizeof (fltset_t));
+ memcpy ((char *) &pi->saved_entryset.sysset,
+ (char *) &pi->prstatus.pr_sysentry, sizeof (sysset_t));
+ memcpy ((char *) &pi->saved_exitset.sysset,
+ (char *) &pi->prstatus.pr_sysexit, sizeof (sysset_t));
+
+ /* Set up trace and fault sets, as gdb expects them. */
+
+ prfillset (&sctl.sigset);
+ notice_signals (pi, &sctl);
+ prfillset (&fctl.fltset);
+ prdelset (&fctl.fltset, FLTPAGE);
+
+ fctl.cmd = PCSFAULT;
+ if (write (pi->ctl_fd, (char *) &fctl, sizeof (struct flt_ctl)) < 0)
+ print_sys_errmsg ("PCSFAULT failed", errno);
+#else /* PROCFS_USE_READ_WRITE */
+ ioctl (pi->ctl_fd, PIOCGTRACE, &pi->saved_trace.sigset);
+ ioctl (pi->ctl_fd, PIOCGHOLD, &pi->saved_sighold.sigset);
+ ioctl (pi->ctl_fd, PIOCGFAULT, &pi->saved_fltset.fltset);
+ ioctl (pi->ctl_fd, PIOCGENTRY, &pi->saved_entryset.sysset);
+ ioctl (pi->ctl_fd, PIOCGEXIT, &pi->saved_exitset.sysset);
/* Set up trace and fault sets, as gdb expects them. */
@@ -2415,14 +2956,15 @@ do_attach (pid)
premptyset (&pi->prrun.pr_fault);
#endif
- if (ioctl (pi->fd, PIOCSFAULT, &pi->prrun.pr_fault))
+ if (ioctl (pi->ctl_fd, PIOCSFAULT, &pi->prrun.pr_fault))
{
print_sys_errmsg ("PIOCSFAULT failed", errno);
}
- if (ioctl (pi->fd, PIOCSTRACE, &pi->prrun.pr_trace))
+ if (ioctl (pi->ctl_fd, PIOCSTRACE, &pi->prrun.pr_trace))
{
print_sys_errmsg ("PIOCSTRACE failed", errno);
}
+#endif /* PROCFS_USE_READ_WRITE */
attach_flag = 1;
return (pid);
}
@@ -2468,40 +3010,73 @@ do_detach (signal)
{
set_proc_siginfo (pi, signal);
}
- if (ioctl (pi->fd, PIOCSEXIT, &pi->saved_exitset) < 0)
+#ifdef PROCFS_USE_READ_WRITE
+ pi->saved_exitset.cmd = PCSEXIT;
+ if (write (pi->ctl_fd, (char *) &pi->saved_exitset,
+ sizeof (struct sys_ctl)) < 0)
+#else
+ if (ioctl (pi->ctl_fd, PIOCSEXIT, &pi->saved_exitset.sysset) < 0)
+#endif
{
print_sys_errmsg (pi->pathname, errno);
printf_unfiltered ("PIOCSEXIT failed.\n");
}
- if (ioctl (pi->fd, PIOCSENTRY, &pi->saved_entryset) < 0)
+#ifdef PROCFS_USE_READ_WRITE
+ pi->saved_entryset.cmd = PCSENTRY;
+ if (write (pi->ctl_fd, (char *) &pi->saved_entryset,
+ sizeof (struct sys_ctl)) < 0)
+#else
+ if (ioctl (pi->ctl_fd, PIOCSENTRY, &pi->saved_entryset.sysset) < 0)
+#endif
{
print_sys_errmsg (pi->pathname, errno);
printf_unfiltered ("PIOCSENTRY failed.\n");
}
- if (ioctl (pi->fd, PIOCSTRACE, &pi->saved_trace) < 0)
+#ifdef PROCFS_USE_READ_WRITE
+ pi->saved_trace.cmd = PCSTRACE;
+ if (write (pi->ctl_fd, (char *) &pi->saved_trace,
+ sizeof (struct sig_ctl)) < 0)
+#else
+ if (ioctl (pi->ctl_fd, PIOCSTRACE, &pi->saved_trace.sigset) < 0)
+#endif
{
print_sys_errmsg (pi->pathname, errno);
printf_unfiltered ("PIOCSTRACE failed.\n");
}
- if (ioctl (pi->fd, PIOCSHOLD, &pi->saved_sighold) < 0)
+#ifndef UNIXWARE
+ if (ioctl (pi->ctl_fd, PIOCSHOLD, &pi->saved_sighold.sigset) < 0)
{
print_sys_errmsg (pi->pathname, errno);
printf_unfiltered ("PIOSCHOLD failed.\n");
}
- if (ioctl (pi->fd, PIOCSFAULT, &pi->saved_fltset) < 0)
+#endif
+#ifdef PROCFS_USE_READ_WRITE
+ pi->saved_fltset.cmd = PCSFAULT;
+ if (write (pi->ctl_fd, (char *) &pi->saved_fltset,
+ sizeof (struct flt_ctl)) < 0)
+#else
+ if (ioctl (pi->ctl_fd, PIOCSFAULT, &pi->saved_fltset.fltset) < 0)
+#endif
{
print_sys_errmsg (pi->pathname, errno);
printf_unfiltered ("PIOCSFAULT failed.\n");
}
- if (ioctl (pi->fd, PIOCSTATUS, &pi->prstatus) < 0)
+ if (!procfs_read_status (pi))
{
print_sys_errmsg (pi->pathname, errno);
- printf_unfiltered ("PIOCSTATUS failed.\n");
+ printf_unfiltered ("procfs_read_status failed.\n");
}
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
{
+ long cmd;
+ struct proc_ctl pctl;
+
if (signal || !pi->was_stopped ||
query ("Was stopped when attached, make it runnable again? "))
{
@@ -2511,7 +3086,12 @@ do_detach (signal)
set_proc_siginfo (pi, signal);
/* Clear any fault that might have stopped it. */
- if (ioctl (pi->fd, PIOCCFAULT, 0))
+#ifdef PROCFS_USE_READ_WRITE
+ cmd = PCCFAULT;
+ if (write (pi->ctl_fd, (char *) &cmd, sizeof (long)) < 0)
+#else
+ if (ioctl (pi->ctl_fd, PIOCCFAULT, 0))
+#endif
{
print_sys_errmsg (pi->pathname, errno);
printf_unfiltered ("PIOCCFAULT failed.\n");
@@ -2519,7 +3099,7 @@ do_detach (signal)
/* Make it run again when we close it. */
- modify_run_on_last_close_flag (pi->fd, 1);
+ modify_run_on_last_close_flag (pi->ctl_fd, 1);
}
}
}
@@ -2563,7 +3143,9 @@ procfs_wait (pid, ourstatus)
int checkerr = 0;
int rtnval = -1;
struct procinfo *pi;
+ struct proc_ctl pctl;
+#ifndef UNIXWARE
if (pid != -1) /* Non-specific process? */
pi = NULL;
else
@@ -2585,13 +3167,18 @@ procfs_wait (pid, ourstatus)
for (pi = procinfo_list; pi; pi = pi->next)
if (pi->pid == pid && pi->had_event)
break;
+#endif
if (!pi && !checkerr)
goto wait_again;
+#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 (ioctl (pi->fd, PIOCWSTOP, &pi->prstatus) < 0)
+ if (!procfs_write_pcwstop (pi))
{
checkerr++;
}
@@ -2604,7 +3191,7 @@ procfs_wait (pid, ourstatus)
if (rtnval != inferior_pid)
{
print_sys_errmsg (pi->pathname, errno);
- error ("PIOCWSTOP, wait failed, returned %d", rtnval);
+ error ("procfs_write_pcwstop, wait failed, returned %d", rtnval);
/* NOTREACHED */
}
}
@@ -2617,9 +3204,15 @@ procfs_wait (pid, ourstatus)
}
else if (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
switch (why)
{
@@ -2660,9 +3253,14 @@ procfs_wait (pid, ourstatus)
A PIOCRUN ioctl must be used to restart the process so it
can finish exiting. */
+#ifdef PROCFS_USE_READ_WRITE
+ pctl.cmd = PCRUN;
+ pctl.data = PRCFAULT;
+ if (write (pi->ctl_fd, (char *) &pctl, sizeof (struct proc_ctl)) < 0)
+#else
pi->prrun.pr_flags = PRCFAULT;
-
- if (ioctl (pi->fd, PIOCRUN, &pi->prrun) != 0)
+ if (ioctl (pi->ctl_fd, PIOCRUN, &pi->prrun) != 0)
+#endif
perror_with_name (pi->pathname);
if (wait (&dummy) < 0)
@@ -2717,7 +3315,11 @@ 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
break;
}
break;
@@ -2733,20 +3335,30 @@ procfs_wait (pid, ourstatus)
{
if (!procinfo->had_event)
{
+#ifdef PROCFS_USE_READ_WRITE
+ cmd = PCSTOP;
+ if (write (pi->ctl_fd, (char *) &cmd, sizeof (long)) < 0)
+ {
+ print_sys_errmsg (procinfo->pathname, errno);
+ error ("PCSTOP failed");
+ }
+#else
/* A bug in Solaris (2.5) causes us to hang when trying to
stop a stopped process. So, we have to check first in
order to avoid the hang. */
- if (ioctl (procinfo->fd, PIOCSTATUS, &procinfo->prstatus) < 0)
+ if (!procfs_read_status (procinfo))
{
print_sys_errmsg (procinfo->pathname, errno);
- error ("PIOCSTATUS failed");
+ error ("procfs_read_status failed");
}
+
if (!(procinfo->prstatus.pr_flags & PR_STOPPED))
- if (ioctl (procinfo->fd, PIOCSTOP, &procinfo->prstatus) < 0)
+ if (ioctl (procinfo->ctl_fd, PIOCSTOP, &procinfo->prstatus) < 0)
{
print_sys_errmsg (procinfo->pathname, errno);
error ("PIOCSTOP failed");
}
+#endif
}
}
}
@@ -2817,30 +3429,53 @@ set_proc_siginfo (pip, signo)
{
struct siginfo newsiginfo;
struct siginfo *sip;
+ struct sigi_ctl sictl;
#ifdef PROCFS_DONT_PIOCSSIG_CURSIG
/* 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
return;
#endif
+#ifdef UNIXWARE
+ if (signo == pip->prstatus.pr_lwp.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)
{
sip = &pip -> prstatus.pr_info;
}
+#endif
else
{
+#ifdef UNIXWARE
+ siginfo_t *sip = &sictl.siginfo;
+ memset ((char *) sip, 0, sizeof (siginfo_t));
+#else
memset ((char *) &newsiginfo, 0, sizeof (newsiginfo));
sip = &newsiginfo;
+#endif
sip -> si_signo = signo;
sip -> si_code = 0;
sip -> si_errno = 0;
sip -> si_pid = getpid ();
sip -> si_uid = getuid ();
}
- if (ioctl (pip -> fd, PIOCSSIG, sip) < 0)
+#ifdef PROCFS_USE_READ_WRITE
+ sictl.cmd = PCSSIG;
+ if (write (pip->ctl_fd, (char *) &sictl, sizeof (struct sigi_ctl)) < 0)
+#else
+ if (ioctl (pip->ctl_fd, PIOCSSIG, sip) < 0)
+#endif
{
print_sys_errmsg (pip -> pathname, errno);
warning ("PIOCSSIG failed");
@@ -2859,11 +3494,17 @@ procfs_resume (pid, step, signo)
{
int signal_to_pass;
struct procinfo *pi, *procinfo;
+ struct proc_ctl pctl;
pi = find_procinfo (pid == -1 ? inferior_pid : pid, 0);
errno = 0;
+#ifdef UNIXWARE
+ pctl.cmd = PCRUN;
+ pctl.data = PRCFAULT;
+#else
pi->prrun.pr_flags = PRSTRACE | PRSFAULT | PRCFAULT;
+#endif
#if 0
/* It should not be necessary. If the user explicitly changes the value,
@@ -2898,8 +3539,13 @@ 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
/* We are about to pass the inferior a SIGTSTP whose action is
SIG_DFL. The SIG_DFL action for a SIGTSTP is to stop
@@ -2925,19 +3571,31 @@ procfs_resume (pid, step, signo)
}
else
{
+#ifdef UNIXWARE
+ pctl.data |= PRCSIG;
+#else
pi->prrun.pr_flags |= PRCSIG;
+#endif
}
pi->nopass_next_sigstop = 0;
if (step)
{
+#ifdef UNIXWARE
+ pctl.data |= PRSTEP;
+#else
pi->prrun.pr_flags |= PRSTEP;
+#endif
}
/* Don't try to start a process unless it's stopped on an
`event of interest'. Doing so will cause errors. */
+#ifdef PROCFS_USE_READ_WRITE
+ if (write (pi->ctl_fd, (char *) &pctl, sizeof (struct proc_ctl)) < 0)
+#else
if ((pi->prstatus.pr_flags & PR_ISTOP)
- && ioctl (pi->fd, PIOCRUN, &pi->prrun) != 0)
+ && ioctl (pi->ctl_fd, PIOCRUN, &pi->prrun) != 0)
+#endif
{
perror_with_name (pi->pathname);
/* NOTREACHED */
@@ -2953,24 +3611,39 @@ procfs_resume (pid, step, signo)
{
if (pi != procinfo && !procinfo->had_event)
{
+#ifdef PROCFS_USE_READ_WRITE
+ pctl.data = PRCFAULT | PRCSIG;
+ if (write (procinfo->ctl_fd, (char *) &pctl,
+ sizeof (struct proc_ctl)) < 0)
+ {
+ if (!procfs_read_status (procinfo))
+ {
+ fprintf_unfiltered(gdb_stderr, "procfs_read_status failed, errno=%d\n", errno);
+ }
+ 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;
- ioctl (procinfo->fd, PIOCSTATUS, &procinfo->prstatus);
+ procfs_read_status (procinfo);
/* Don't try to start a process unless it's stopped on an
`event of interest'. Doing so will cause errors. */
if ((procinfo->prstatus.pr_flags & PR_ISTOP)
- && ioctl (procinfo->fd, PIOCRUN, &procinfo->prrun) < 0)
+ && ioctl (procinfo->ctl_fd, PIOCRUN, &procinfo->prrun) < 0)
{
- if (ioctl (procinfo->fd, PIOCSTATUS, &procinfo->prstatus) < 0)
+ if (!procfs_read_status (procinfo))
{
- fprintf_unfiltered(gdb_stderr, "PIOCSTATUS failed, errno=%d\n", errno);
+ fprintf_unfiltered(gdb_stderr, "procfs_read_status failed, errno=%d\n", errno);
}
print_sys_errmsg (procinfo->pathname, errno);
error ("PIOCRUN failed");
}
- ioctl (procinfo->fd, PIOCSTATUS, &procinfo->prstatus);
+ procfs_read_status (procinfo);
+#endif
}
}
}
@@ -3001,16 +3674,26 @@ procfs_fetch_registers (regno)
pi = current_procinfo;
- if (ioctl (pi->fd, PIOCGREG, &pi->gregset) != -1)
+#ifdef UNIXWARE
+ if (procfs_read_status (pi))
+ {
+ supply_gregset (&pi->prstatus.pr_lwp.pr_context.uc_mcontext.gregs);
+#if defined (FP0_REGNUM)
+ supply_fpregset (&pi->prstatus.pr_lwp.pr_context.uc_mcontext.fpregs);
+#endif
+ }
+#else /* UNIXWARE */
+ if (ioctl (pi->ctl_fd, PIOCGREG, &pi->gregset.gregset) != -1)
{
- supply_gregset (&pi->gregset);
+ supply_gregset (&pi->gregset.gregset);
}
#if defined (FP0_REGNUM)
- if (ioctl (pi->fd, PIOCGFPREG, &pi->fpregset) != -1)
+ if (ioctl (pi->ctl_fd, PIOCGFPREG, &pi->fpregset.fpregset) != -1)
{
- supply_fpregset (&pi->fpregset);
+ supply_fpregset (&pi->fpregset.fpregset);
}
#endif
+#endif /* UNIXWARE */
}
/*
@@ -3071,7 +3754,12 @@ close_proc_file (pip)
remove_fd (pip); /* Remove fd from poll/select list */
- close (pip -> fd);
+ close (pip->ctl_fd);
+#ifdef HAVE_MULTIPLE_PROC_FDS
+ close (pip->as_fd);
+ close (pip->status_fd);
+ close (pip->map_fd);
+#endif
free (pip -> pathname);
@@ -3080,11 +3768,17 @@ close_proc_file (pip)
if (procinfo_list == pip)
procinfo_list = pip->next;
else
- for (procinfo = procinfo_list; procinfo; procinfo = procinfo->next)
- if (procinfo->next == pip)
- procinfo->next = pip->next;
-
- free (pip);
+ {
+ for (procinfo = procinfo_list; procinfo; procinfo = procinfo->next)
+ {
+ if (procinfo->next == pip)
+ {
+ procinfo->next = pip->next;
+ break;
+ }
+ }
+ free (pip);
+ }
}
/*
@@ -3117,16 +3811,17 @@ DESCRIPTION
*/
static int
-open_proc_file (pid, pip, mode)
+open_proc_file (pid, pip, mode, control)
int pid;
struct procinfo *pip;
int mode;
+ int control;
{
int tmp, tmpfd;
pip -> next = NULL;
pip -> had_event = 0;
- pip -> pathname = xmalloc (32);
+ pip -> pathname = xmalloc (MAX_PROC_NAME_SIZE);
pip -> pid = pid;
#ifndef PIOCOPENLWP
@@ -3135,12 +3830,59 @@ open_proc_file (pid, pip, mode)
tmp = pid & 0xffff;
#endif
- sprintf (pip -> pathname, PROC_NAME_FMT, tmp);
+#ifdef HAVE_MULTIPLE_PROC_FDS
+ sprintf (pip->pathname, STATUS_PROC_NAME_FMT, tmp);
+ if ((pip->status_fd = open (pip->pathname, O_RDONLY)) < 0)
+ {
+ return 0;
+ }
+
+ sprintf (pip->pathname, AS_PROC_NAME_FMT, tmp);
+ if ((pip->as_fd = open (pip->pathname, O_RDWR)) < 0)
+ {
+ close (pip->status_fd);
+ 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;
+ }
+
+ 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);
+ if ((pip->ctl_fd = open (pip->pathname, O_WRONLY)) < 0)
+ {
+ close (pip->status_fd);
+ close (pip->as_fd);
+ close (pip->map_fd);
+ return 0;
+ }
+ }
+
+#else /* HAVE_MULTIPLE_PROC_FDS */
+ sprintf (pip -> pathname, CTL_PROC_NAME_FMT, tmp);
+
if ((tmpfd = open (pip -> pathname, mode)) < 0)
return 0;
#ifndef PIOCOPENLWP
- pip -> fd = tmpfd;
+ pip -> ctl_fd = tmpfd;
+ pip -> as_fd = tmpfd;
+ pip -> map_fd = tmpfd;
+ pip -> status_fd = tmpfd;
#else
tmp = (pid >> 16) & 0xffff; /* Extract thread id */
@@ -3157,7 +3899,7 @@ open_proc_file (pid, pip, mode)
pip -> pid = (tmp << 16) | pid; /* Update pip */
}
- if ((pip -> fd = ioctl (tmpfd, PIOCOPENLWP, &tmp)) < 0)
+ if ((pip -> ctl_fd = ioctl (tmpfd, PIOCOPENLWP, &tmp)) < 0)
{
close (tmpfd);
return 0;
@@ -3167,13 +3909,20 @@ open_proc_file (pid, pip, mode)
{
long pr_flags;
pr_flags = PR_ASYNC;
- ioctl (pip -> fd, PIOCSET, &pr_flags);
+ ioctl (pip -> ctl_fd, PIOCSET, &pr_flags);
}
#endif
+ /* keep extra fds in sync */
+ pip->as_fd = pip->ctl_fd;
+ pip->map_fd = pip->ctl_fd;
+ pip->status_fd = pip->ctl_fd;
+
close (tmpfd); /* All done with main pid */
#endif /* PIOCOPENLWP */
+#endif /* HAVE_MULTIPLE_PROC_FDS */
+
return 1;
}
@@ -3202,6 +3951,11 @@ info_proc_flags (pip, summary)
int summary;
{
struct trans *transp;
+#ifdef UNIXWARE
+ long flags = pip->prstatus.pr_flags | pip->prstatus.pr_lwp.pr_flags;
+#else
+ long flags = pip->prstatus.pr_flags;
+#endif
printf_filtered ("%-32s", "Process status flags:");
if (!summary)
@@ -3210,7 +3964,7 @@ info_proc_flags (pip, summary)
}
for (transp = pr_flag_table; transp -> name != NULL; transp++)
{
- if (pip -> prstatus.pr_flags & transp -> value)
+ if (flags & transp -> value)
{
if (summary)
{
@@ -3234,10 +3988,19 @@ 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
+#ifdef UNIXWARE
+ if (pip -> prstatus.pr_lwp.pr_flags & PR_STOPPED)
+#else
if (pip -> prstatus.pr_flags & PR_STOPPED)
+#endif
{
printf_filtered ("%-32s", "Reason for stopping:");
if (!summary)
@@ -3328,12 +4091,22 @@ 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
{
printf_filtered ("%-32s", "Additional signal/fault info:");
+#ifdef UNIXWARE
+ sip = &pip -> prstatus.pr_lwp.pr_info;
+#else
sip = &pip -> prstatus.pr_info;
+#endif
if (summary)
{
printf_filtered ("%s ", signalname (sip -> si_signo));
@@ -3451,17 +4224,19 @@ info_proc_syscalls (pip, summary)
}
#endif
- if (ioctl (pip -> fd, PIOCGENTRY, &pip -> entryset) < 0)
+#ifndef UNIXWARE
+ if (ioctl (pip -> ctl_fd, PIOCGENTRY, &pip -> entryset) < 0)
{
print_sys_errmsg (pip -> pathname, errno);
error ("PIOCGENTRY failed");
}
- if (ioctl (pip -> fd, PIOCGEXIT, &pip -> exitset) < 0)
+ if (ioctl (pip -> ctl_fd, PIOCGEXIT, &pip -> exitset) < 0)
{
print_sys_errmsg (pip -> pathname, errno);
error ("PIOCGEXIT failed");
}
+#endif
printf_filtered ("System call tracing information:\n\n");
@@ -3477,12 +4252,21 @@ info_proc_syscalls (pip, summary)
else
printf_filtered ("\t%-12d ", syscallnum);
+#ifdef UNIXWARE
+ printf_filtered ("%-8s ",
+ prismember (&pip->prstatus.pr_sysentry, syscallnum)
+ ? "on" : "off");
+ printf_filtered ("%-8s ",
+ prismember (&pip->prstatus.pr_sysexit, syscallnum)
+ ? "on" : "off");
+#else
printf_filtered ("%-8s ",
prismember (&pip -> entryset, syscallnum)
? "on" : "off");
printf_filtered ("%-8s ",
prismember (&pip -> exitset, syscallnum)
? "on" : "off");
+#endif
printf_filtered ("\n");
}
printf_filtered ("\n");
@@ -3536,11 +4320,13 @@ info_proc_signals (pip, summary)
if (!summary)
{
- if (ioctl (pip -> fd, PIOCGTRACE, &pip -> trace) < 0)
+#ifndef PROCFS_USE_READ_WRITE
+ if (ioctl (pip -> ctl_fd, PIOCGTRACE, &pip -> trace) < 0)
{
print_sys_errmsg (pip -> pathname, errno);
error ("PIOCGTRACE failed");
}
+#endif
printf_filtered ("Disposition of signals:\n\n");
printf_filtered ("\t%-15s %-8s %-8s %-8s %s\n\n",
@@ -3549,13 +4335,29 @@ info_proc_signals (pip, summary)
{
QUIT;
printf_filtered ("\t%-15s ", signalname (signo));
+#ifdef UNIXWARE
+ printf_filtered ("%-8s ",
+ prismember (&pip -> prstatus.pr_sigtrace, signo)
+ ? "on" : "off");
+ printf_filtered ("%-8s ",
+ prismember (&pip -> prstatus.pr_lwp.pr_context.uc_sigmask, signo)
+ ? "on" : "off");
+#else
printf_filtered ("%-8s ",
prismember (&pip -> trace, signo)
? "on" : "off");
printf_filtered ("%-8s ",
prismember (&pip -> prstatus.pr_sighold, signo)
? "on" : "off");
+#endif
+#ifdef UNIXWARE
+ if (prismember (&pip->prstatus.pr_sigpend, signo) ||
+ prismember (&pip->prstatus.pr_lwp.pr_lwppend, signo))
+ printf_filtered("%-8s ", "yes");
+ else
+ printf_filtered("%-8s ", "no");
+#else /* UNIXWARE */
#ifdef PROCFS_SIGPEND_OFFSET
/* Alpha OSF/1 numbers the pending signals from 1. */
printf_filtered ("%-8s ",
@@ -3568,6 +4370,7 @@ info_proc_signals (pip, summary)
prismember (&pip -> prstatus.pr_sigpend, signo)
? "yes" : "no");
#endif
+#endif /* UNIXWARE */
printf_filtered (" %s\n", safe_strsignal (signo));
}
printf_filtered ("\n");
@@ -3583,11 +4386,13 @@ info_proc_faults (pip, summary)
if (!summary)
{
- if (ioctl (pip -> fd, PIOCGFAULT, &pip -> fltset) < 0)
+#ifndef UNIXWARE
+ if (ioctl (pip -> ctl_fd, PIOCGFAULT, &pip->fltset.fltset) < 0)
{
print_sys_errmsg (pip -> pathname, errno);
error ("PIOCGFAULT failed");
}
+#endif
printf_filtered ("Current traced hardware fault set:\n\n");
printf_filtered ("\t%-12s %-8s\n", "Fault", "Trace");
@@ -3596,8 +4401,13 @@ info_proc_faults (pip, summary)
{
QUIT;
printf_filtered ("\t%-12s ", transp -> name);
- printf_filtered ("%-8s", prismember (&pip -> fltset, transp -> value)
+#ifdef UNIXWARE
+ printf_filtered ("%-8s", prismember (&pip->prstatus.pr_flttrace, transp -> value)
+ ? "on" : "off");
+#else
+ printf_filtered ("%-8s", prismember (&pip->fltset.fltset, transp -> value)
? "on" : "off");
+#endif
printf_filtered ("\n");
}
printf_filtered ("\n");
@@ -3612,6 +4422,7 @@ info_proc_mappings (pip, summary)
int nmap;
struct prmap *prmaps;
struct prmap *prmap;
+ struct stat sbuf;
if (!summary)
{
@@ -3626,12 +4437,25 @@ info_proc_mappings (pip, summary)
" Size",
" Offset",
"Flags");
- if (ioctl (pip -> fd, PIOCNMAP, &nmap) == 0)
+#ifdef PROCFS_USE_READ_WRITE
+ if (fstat (pip->map_fd, &sbuf) == 0)
+ {
+ nmap = sbuf.st_size / sizeof (prmap_t);
+ prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
+ if ((lseek (pip->map_fd, 0, SEEK_SET) == 0) &&
+ (read (pip->map_fd, (char *) prmaps,
+ nmap * sizeof (*prmaps)) == (nmap * sizeof (*prmaps))))
+ {
+ int i = 0;
+ for (prmap = prmaps; i < nmap; ++prmap, ++i)
+#else
+ if (ioctl (pip -> ctl_fd, PIOCNMAP, &nmap) == 0)
{
prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
- if (ioctl (pip -> fd, PIOCMAP, prmaps) == 0)
+ if (ioctl (pip -> ctl_fd, PIOCMAP, prmaps) == 0)
{
for (prmap = prmaps; prmap -> pr_size; ++prmap)
+#endif /* PROCFS_USE_READ_WRITE */
{
#ifdef BFD_HOST_64_BIT
printf_filtered (" %#18lx %#18lx %#10x %#10x %7s\n",
@@ -3773,7 +4597,7 @@ info_proc (args, from_tty)
memset (pip, 0, sizeof (*pip));
pip->pid = pid;
- if (!open_proc_file (pid, pip, O_RDONLY))
+ if (!open_proc_file (pid, pip, O_RDONLY, 0))
{
perror_with_name (pip -> pathname);
/* NOTREACHED */
@@ -3797,20 +4621,22 @@ info_proc (args, from_tty)
error ("\
No process. Start debugging a program or specify an explicit process ID.");
}
- if (ioctl (pip -> fd, PIOCSTATUS, &(pip -> prstatus)) < 0)
+
+ if (!procfs_read_status (pip))
{
print_sys_errmsg (pip -> pathname, errno);
- error ("PIOCSTATUS failed");
+ error ("procfs_read_status failed");
}
+#ifndef PROCFS_USE_READ_WRITE
#ifdef PIOCLWPIDS
nlwp = pip->prstatus.pr_nlwp;
lwps = alloca ((2 * nlwp + 2) * sizeof (id_t));
- if (ioctl (pip->fd, PIOCLWPIDS, lwps))
+ if (ioctl (pip->ctl_fd, PIOCLWPIDS, lwps))
{
print_sys_errmsg (pip -> pathname, errno);
- error ("PIOCSTATUS failed");
+ error ("PIOCLWPIDS failed");
}
#else /* PIOCLWPIDS */
nlwp = 1;
@@ -3826,18 +4652,20 @@ No process. Start debugging a program or specify an explicit process ID.");
{
pip = (struct procinfo *) xmalloc (sizeof (struct procinfo));
memset (pip, 0, sizeof (*pip));
- if (!open_proc_file ((*lwps << 16) | pid, pip, O_RDONLY))
+ if (!open_proc_file ((*lwps << 16) | pid, pip, O_RDONLY, 0))
continue;
make_cleanup (close_proc_file, pip);
- if (ioctl (pip -> fd, PIOCSTATUS, &(pip -> prstatus)) < 0)
+ if (!procfs_read_status (pip))
{
print_sys_errmsg (pip -> pathname, errno);
- error ("PIOCSTATUS failed");
+ error ("procfs_read_status failed");
}
}
+#endif /* PROCFS_USE_READ_WRITE */
+
/* Print verbose information of the requested type(s), or just a summary
of the information for all types. */
@@ -3876,7 +4704,9 @@ No process. Start debugging a program or specify an explicit process ID.");
freeing temporary memory , etc. */
do_cleanups (old_chain);
+#ifndef PROCFS_USE_READ_WRITE
}
+#endif
}
/*
@@ -3902,24 +4732,47 @@ modify_inherit_on_fork_flag (fd, flag)
int fd;
int flag;
{
-#ifdef PIOCSET
+#if defined (PIOCSET) || defined (PCSET)
long pr_flags;
#endif
- int retval;
+ int retval = 0;
+ struct proc_ctl pctl;
-#ifdef PIOCSET /* New method */
+#if defined (PIOCSET) || defined (PCSET) /* New method */
pr_flags = PR_FORK;
if (flag)
- retval = ioctl (fd, PIOCSET, &pr_flags);
+ {
+#ifdef PROCFS_USE_READ_WRITE
+ pctl.cmd = PCSET;
+ pctl.data = PR_FORK;
+ if (write (fd, (char *) &pctl, sizeof (struct proc_ctl)) < 0)
+ retval = -1;
+#else
+ retval = ioctl (fd, PIOCSET, &pr_flags);
+#endif
+ }
else
- retval = ioctl (fd, PIOCRESET, &pr_flags);
+ {
+#ifdef PROCFS_USE_READ_WRITE
+ pctl.cmd = PCRESET;
+ pctl.data = PR_FORK;
+ if (write (fd, (char *) &pctl, sizeof (struct proc_ctl)) < 0)
+ retval = -1;
+#else
+ retval = ioctl (fd, PIOCRESET, &pr_flags);
+#endif
+ }
#else
#ifdef PIOCSFORK /* Original method */
if (flag)
- retval = ioctl (fd, PIOCSFORK, NULL);
+ {
+ retval = ioctl (fd, PIOCSFORK, NULL);
+ }
else
- retval = ioctl (fd, PIOCRFORK, NULL);
+ {
+ retval = ioctl (fd, PIOCRFORK, NULL);
+ }
#else
Neither PR_FORK nor PIOCSFORK exist!!!
#endif
@@ -3955,17 +4808,36 @@ modify_run_on_last_close_flag (fd, flag)
int fd;
int flag;
{
-#ifdef PIOCSET
+#if defined (PIOCSET) || defined (PCSET)
long pr_flags;
#endif
- int retval;
+ int retval = 0;
+ struct proc_ctl pctl;
-#ifdef PIOCSET /* New method */
+#if defined (PIOCSET) || defined (PCSET) /* New method */
pr_flags = PR_RLC;
if (flag)
- retval = ioctl (fd, PIOCSET, &pr_flags);
+ {
+#ifdef PROCFS_USE_READ_WRITE
+ pctl.cmd = PCSET;
+ pctl.data = PR_RLC;
+ if (write (fd, (char *) &pctl, sizeof (struct proc_ctl)) < 0)
+ retval = -1;
+#else
+ retval = ioctl (fd, PIOCSET, &pr_flags);
+#endif
+ }
else
- retval = ioctl (fd, PIOCRESET, &pr_flags);
+ {
+#ifdef PROCFS_USE_READ_WRITE
+ pctl.cmd = PCRESET;
+ pctl.data = PR_RLC;
+ if (write (fd, (char *) &pctl, sizeof (struct proc_ctl)) < 0)
+ retval = -1;
+#else
+ retval = ioctl (fd, PIOCRESET, &pr_flags);
+#endif
+ }
#else
#ifdef PIOCSRLC /* Original method */
@@ -4010,7 +4882,7 @@ procfs_clear_syscall_trap (pi, syscall_num, errok)
sysset_t sysset;
int goterr, i;
- goterr = ioctl (pi->fd, PIOCGENTRY, &sysset) < 0;
+ goterr = ioctl (pi->ctl_fd, PIOCGENTRY, &sysset) < 0;
if (goterr && !errok)
{
@@ -4022,14 +4894,14 @@ procfs_clear_syscall_trap (pi, syscall_num, errok)
{
prdelset (&sysset, syscall_num);
- if ((ioctl (pi->fd, PIOCSENTRY, &sysset) < 0) && !errok)
+ if ((ioctl (pi->ctl_fd, PIOCSENTRY, &sysset) < 0) && !errok)
{
print_sys_errmsg (pi->pathname, errno);
error ("PIOCSENTRY failed");
}
}
- goterr = ioctl (pi->fd, PIOCGEXIT, &sysset) < 0;
+ goterr = ioctl (pi->ctl_fd, PIOCGEXIT, &sysset) < 0;
if (goterr && !errok)
{
@@ -4042,7 +4914,7 @@ procfs_clear_syscall_trap (pi, syscall_num, errok)
{
praddset (&sysset, syscall_num);
- if ((ioctl (pi->fd, PIOCSEXIT, &sysset) < 0) && !errok)
+ if ((ioctl (pi->ctl_fd, PIOCSEXIT, &sysset) < 0) && !errok)
{
procfs_clear_syscall_trap (pi, syscall_num, 1);
print_sys_errmsg (pi->pathname, errno);
@@ -4115,7 +4987,7 @@ procfs_set_syscall_trap (pi, syscall_num, flags, func)
if (flags & PROCFS_SYSCALL_ENTRY)
{
- if (ioctl (pi->fd, PIOCGENTRY, &sysset) < 0)
+ if (ioctl (pi->ctl_fd, PIOCGENTRY, &sysset) < 0)
{
print_sys_errmsg (pi->pathname, errno);
error ("PIOCGENTRY failed");
@@ -4123,7 +4995,7 @@ procfs_set_syscall_trap (pi, syscall_num, flags, func)
praddset (&sysset, syscall_num);
- if (ioctl (pi->fd, PIOCSENTRY, &sysset) < 0)
+ if (ioctl (pi->ctl_fd, PIOCSENTRY, &sysset) < 0)
{
print_sys_errmsg (pi->pathname, errno);
error ("PIOCSENTRY failed");
@@ -4132,7 +5004,7 @@ procfs_set_syscall_trap (pi, syscall_num, flags, func)
if (flags & PROCFS_SYSCALL_EXIT)
{
- if (ioctl (pi->fd, PIOCGEXIT, &sysset) < 0)
+ if (ioctl (pi->ctl_fd, PIOCGEXIT, &sysset) < 0)
{
procfs_clear_syscall_trap (pi, syscall_num, 1);
print_sys_errmsg (pi->pathname, errno);
@@ -4141,7 +5013,7 @@ procfs_set_syscall_trap (pi, syscall_num, flags, func)
praddset (&sysset, syscall_num);
- if (ioctl (pi->fd, PIOCSEXIT, &sysset) < 0)
+ if (ioctl (pi->ctl_fd, PIOCSEXIT, &sysset) < 0)
{
procfs_clear_syscall_trap (pi, syscall_num, 1);
print_sys_errmsg (pi->pathname, errno);
@@ -4230,7 +5102,7 @@ procfs_lwp_creation_handler (pi, syscall_num, why, rtnvalp, statvalp)
pi->prrun.pr_flags &= PRSTEP;
pi->prrun.pr_flags |= PRCFAULT;
- if (ioctl (pi->fd, PIOCRUN, &pi->prrun) != 0)
+ if (ioctl (pi->ctl_fd, PIOCRUN, &pi->prrun) != 0)
perror_with_name (pi->pathname);
return 0;
@@ -4245,7 +5117,7 @@ procfs_lwp_creation_handler (pi, syscall_num, why, rtnvalp, statvalp)
pi->prrun.pr_flags |= PRCFAULT;
if ((pi->prstatus.pr_flags & PR_ISTOP)
- && ioctl (pi->fd, PIOCRUN, &pi->prrun) != 0)
+ && ioctl (pi->ctl_fd, PIOCRUN, &pi->prrun) != 0)
perror_with_name (pi->pathname);
pi->new_child = 0; /* No longer new */
@@ -4411,7 +5283,7 @@ procfs_set_watchpoint(pid, addr, len, rw)
wpt.pr_vaddr = (caddr_t)addr;
wpt.pr_size = len;
wpt.pr_wflags = ((rw & 1) ? MA_READ : 0) | ((rw & 2) ? MA_WRITE : 0);
- if (ioctl (pi->fd, PIOCSWATCH, &wpt) < 0)
+ if (ioctl (pi->ctl_fd, PIOCSWATCH, &wpt) < 0)
{
if (errno == E2BIG)
return -1;
@@ -4454,7 +5326,7 @@ procfs_stopped_by_watchpoint(pid)
}
return 0;
}
-#endif
+#endif /* TARGET_HAS_HARDWARE_WATCHPOINTS */
/* Why is this necessary? Shouldn't dead threads just be removed from the
thread database? */
@@ -4542,13 +5414,13 @@ void
_initialize_procfs ()
{
#ifdef HAVE_OPTIONAL_PROC_FS
- char procname[32];
+ char procname[MAX_PROC_NAME_SIZE];
int fd;
/* If we have an optional /proc filesystem (e.g. under OSF/1),
don't add procfs support if we cannot access the running
GDB via /proc. */
- sprintf (procname, PROC_NAME_FMT, getpid ());
+ sprintf (procname, STATUS_PROC_NAME_FMT, getpid ());
if ((fd = open (procname, O_RDONLY)) < 0)
return;
close (fd);