From 234a732de0f8970e9ca58cfe1071585f9a5205ee Mon Sep 17 00:00:00 2001 From: Geoffrey Noer Date: Thu, 10 Apr 1997 20:24:42 +0000 Subject: [PATCH] Thu Apr 10 13:20:53 1997 Geoffrey Noer * procfs.c: Substantial (but incomplete) changes to support sysv4.2mp procfs as implemented in UnixWare 2.1. The procinfo struct now has substructs like struct flt_ctl instead of just a fltset_t and has a ctl_fd, status_fd, as_fd, and map_fd instead of a single fd. Non-sysv4.2mp procfs models still have the structs and multiple fds, but don't use the entire struct and the four fds all point to the same thing. We use PROCFS_USE_READ_WRITE to decide whether to talk to procfs with reads/writes or use ioctl instead. We use HAVE_MULTIPLE_PROC_FDS to determine whether procfs really has multiple fds or not. PROC_NAME_FMT is split out into CTL_PROC_NAME_FMT, AS_PROC_NAME_FMT, MAP_PROC_NAME_FMT, STATUS_PROC_NAME_FMT. (procfs_notice_signals): now a necessary wrapper around (notice_signals): which are the new guts for noticing signals (open_proc_file): gets a new flag arg used in sysv4.2mp to determine whether or not to attempt to open the ctl_fd. (procfs_read_status): new local function, reads procfs status (procfs_write_pcwstop): new local function, writes a PCWSTOP (procfs_write_pckill): new local function, writes a PCKILL (unconditionally_kill_inferior): remove signo since we now just call procfs_write_pckill(). (procfs_xfer_memory): call lseek with SEEK_SET rather than 0 (proc_iterate_over_mappings): the whole function is ifdefed on UNIXWARE to keep things readable. Expanded the syscall_table to include new potential sysv4.2mp members. Note that all ifdefs of UNIXWARE should be eliminated if possible or renamed to describe what's being selected for a bit better. Sysv4.2mp and IRIX both have SYS_sproc so the IRIX specific code now also checks it's not UNIXWARE. * config/i386/tm-i386v42mp.h: also define HAVE_PSTATUS_T, HAVE_NO_PRRUN_T, PROCFS_USE_READ_WRITE, and UNIXWARE * config/mips/nm-irix4.h: set CTL_PROC_NAME_FMT et al to "/debug/%d" as PROC_NAME_FMT used to be --- gdb/ChangeLog | 40 ++ gdb/config/i386/tm-i386v42mp.h | 21 +- gdb/config/mips/nm-irix4.h | 5 +- gdb/procfs.c | 1230 +++++++++++++++++++++++++++----- 4 files changed, 1113 insertions(+), 183 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 1dfa21f5ac6..e03cc21b189 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,43 @@ +Thu Apr 10 13:20:53 1997 Geoffrey Noer + + * procfs.c: Substantial (but incomplete) changes to support + sysv4.2mp procfs as implemented in UnixWare 2.1. The procinfo + struct now has substructs like struct flt_ctl instead of + just a fltset_t and has a ctl_fd, status_fd, as_fd, and + map_fd instead of a single fd. Non-sysv4.2mp procfs models + still have the structs and multiple fds, but don't use the + entire struct and the four fds all point to the same thing. + We use PROCFS_USE_READ_WRITE to decide whether to talk to + procfs with reads/writes or use ioctl instead. We use + HAVE_MULTIPLE_PROC_FDS to determine whether procfs really has + multiple fds or not. PROC_NAME_FMT is split out into + CTL_PROC_NAME_FMT, AS_PROC_NAME_FMT, MAP_PROC_NAME_FMT, + STATUS_PROC_NAME_FMT. + + (procfs_notice_signals): now a necessary wrapper around + (notice_signals): which are the new guts for noticing signals + (open_proc_file): gets a new flag arg used in sysv4.2mp to + determine whether or not to attempt to open the ctl_fd. + (procfs_read_status): new local function, reads procfs status + (procfs_write_pcwstop): new local function, writes a PCWSTOP + (procfs_write_pckill): new local function, writes a PCKILL + (unconditionally_kill_inferior): remove signo since we now + just call procfs_write_pckill(). + (procfs_xfer_memory): call lseek with SEEK_SET rather than 0 + (proc_iterate_over_mappings): the whole function is ifdefed + on UNIXWARE to keep things readable. + + Expanded the syscall_table to include new potential sysv4.2mp + members. Note that all ifdefs of UNIXWARE should be eliminated + if possible or renamed to describe what's being selected for a + bit better. Sysv4.2mp and IRIX both have SYS_sproc so the + IRIX specific code now also checks it's not UNIXWARE. + + * config/i386/tm-i386v42mp.h: also define HAVE_PSTATUS_T, + HAVE_NO_PRRUN_T, PROCFS_USE_READ_WRITE, and UNIXWARE + * config/mips/nm-irix4.h: set CTL_PROC_NAME_FMT et al to + "/debug/%d" as PROC_NAME_FMT used to be + Wed Apr 9 11:36:14 1997 Jeffrey A Law (law@cygnus.com) * mn10300-tdep.c: Almost completely rewritten based on mn10200 diff --git a/gdb/config/i386/tm-i386v42mp.h b/gdb/config/i386/tm-i386v42mp.h index 951a05a7441..b8b093d9fb1 100644 --- a/gdb/config/i386/tm-i386v42mp.h +++ b/gdb/config/i386/tm-i386v42mp.h @@ -25,10 +25,25 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "i386/tm-i386v4.h" -/* proc on this architecture has multiple fds (ctl, as, map, status) */ -/* including a control fd */ +/* procfs on this architecture has multiple fds (ctl, as, map, status) + including a control fd */ #define HAVE_MULTIPLE_PROC_FDS -#define HAVE_CONTROL_PROC_FD + +/* procfs on this architecture has a pstatus_t instead of prstatus_t */ + +#define HAVE_PSTATUS_T + +/* procfs on this architecture has no prrun_t */ +#define HAVE_NO_PRRUN_T + +/* procfs on this architecture communicates with read/write instead + of ioctl */ + +#define PROCFS_USE_READ_WRITE + +/* define to select for other sysv4.2mp weirdness */ + +#define UNIXWARE #endif /* ifndef TM_I386V42MP_H */ diff --git a/gdb/config/mips/nm-irix4.h b/gdb/config/mips/nm-irix4.h index c4227ba34e2..017695ca295 100644 --- a/gdb/config/mips/nm-irix4.h +++ b/gdb/config/mips/nm-irix4.h @@ -23,7 +23,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ * with ptrace(), which seems *extremely* fragile, anyway. */ #define USE_PROC_FS -#define PROC_NAME_FMT "/debug/%d" +#define CTL_PROC_NAME_FMT "/debug/%d" +#define AS_PROC_NAME_FMT "/debug/%d" +#define MAP_PROC_NAME_FMT "/debug/%d" +#define STATUS_PROC_NAME_FMT "/debug/%d" /* Don't need special routines for the SGI -- we can use infptrace.c */ #undef FETCH_INFERIOR_REGISTERS diff --git a/gdb/procfs.c b/gdb/procfs.c index 315110fa9e0..4ce9d983c09 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); -- 2.30.2