- static void info_proc_stop PARAMS ((struct procinfo *, int));
-
- static void info_proc_siginfo PARAMS ((struct procinfo *, int));
-
- static void info_proc_syscalls PARAMS ((struct procinfo *, int));
-
- static void info_proc_mappings PARAMS ((struct procinfo *, int));
-
- static void info_proc_signals PARAMS ((struct procinfo *, int));
-
- static void info_proc_faults PARAMS ((struct procinfo *, int));
-
- static char *mappingflags PARAMS ((long));
-
- static char *lookupname PARAMS ((struct trans *, unsigned int, char *));
-
- static char *lookupdesc PARAMS ((struct trans *, unsigned int));
-
- static int do_attach PARAMS ((int pid));
-
- static void do_detach PARAMS ((int siggnal));
-
- 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_write_pcwstop PARAMS ((struct procinfo *));
- static int procfs_read_status 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));
-
- static void procfs_set_syscall_trap PARAMS ((struct procinfo * pi,
- int syscall_num, int flags,
- syscall_func_t * func));
-
- static void procfs_clear_syscall_trap PARAMS ((struct procinfo * pi,
- int syscall_num, int errok));
-
-#define PROCFS_SYSCALL_ENTRY 0x1 /* Trap on entry to sys call */
-#define PROCFS_SYSCALL_EXIT 0x2 /* Trap on exit from sys call */
-
- static syscall_func_t procfs_exit_handler;
-
- static syscall_func_t procfs_exec_handler;
-
-#ifdef SYS_sproc
- static syscall_func_t procfs_sproc_handler;
- static syscall_func_t procfs_fork_handler;
-#endif
-
-#ifdef SYS_lwp_create
- static syscall_func_t procfs_lwp_creation_handler;
-#endif
-
- static void modify_inherit_on_fork_flag PARAMS ((int fd, int flag));
- static void modify_run_on_last_close_flag PARAMS ((int fd, int flag));
-
-/* */
-
- struct procfs_syscall_handler
- {
- int syscall_num; /* The number of the system call being handled */
- /* The function to be called */
- syscall_func_t *func;
- };
-
- static void procfs_resume PARAMS ((int pid, int step,
- enum target_signal signo));
-
- static void init_procfs_ops PARAMS ((void));
-
-/* External function prototypes that can't be easily included in any
- header file because the args are typedefs in system include files. */
-
- extern void supply_gregset PARAMS ((gdb_gregset_t *));
-
- extern void fill_gregset PARAMS ((gdb_gregset_t *, int));
-
-#ifdef FP0_REGNUM
- extern void supply_fpregset PARAMS ((gdb_fpregset_t *));
-
- extern void fill_fpregset PARAMS ((gdb_fpregset_t *, int));
-#endif
-
-/*
-
- LOCAL FUNCTION
-
- find_procinfo -- convert a process id to a struct procinfo
-
- SYNOPSIS
-
- static struct procinfo * find_procinfo (pid_t pid, int okfail);
-
- DESCRIPTION
-
- Given a process id, look it up in the procinfo chain. Returns
- a struct procinfo *. If can't find pid, then call error(),
- unless okfail is set, in which case, return NULL;
- */
-
- static struct procinfo *
- find_procinfo (pid, okfail)
- pid_t pid;
- int okfail;
-{
- struct procinfo *procinfo;
-
- for (procinfo = procinfo_list; procinfo; procinfo = procinfo->next)
- if (procinfo->pid == pid)
- return procinfo;
-
- if (okfail)
- return NULL;
-
- error ("procfs (find_procinfo): Couldn't locate pid %d", pid);
-}
-
-/*
-
- LOCAL MACRO
-
- current_procinfo -- convert inferior_pid to a struct procinfo
-
- SYNOPSIS
-
- static struct procinfo * current_procinfo;
-
- DESCRIPTION
-
- Looks up inferior_pid in the procinfo chain. Always returns a
- struct procinfo *. If process can't be found, we error() out.
- */
-
-#define current_procinfo find_procinfo (inferior_pid, 0)
-
-/*
-
- LOCAL FUNCTION
-
- add_fd -- Add the fd to the poll/select list
-
- SYNOPSIS
-
- static void add_fd (struct procinfo *);
-
- DESCRIPTION
-
- Add the fd of the supplied procinfo to the list of fds used for
- poll/select operations.
- */
-
-static void
-add_fd (pi)
- struct procinfo *pi;
-{
- if (num_poll_list <= 0)
- poll_list = (struct pollfd *) xmalloc (sizeof (struct pollfd));
- else
- poll_list = (struct pollfd *) xrealloc (poll_list,
- (num_poll_list + 1)
- * sizeof (struct pollfd));
- 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++;
-}
-
-/*
-
- LOCAL FUNCTION
-
- remove_fd -- Remove the fd from the poll/select list
-
- SYNOPSIS
-
- static void remove_fd (struct procinfo *);
-
- DESCRIPTION
-
- Remove the fd of the supplied procinfo from the list of fds used
- for poll/select operations.
- */
-
-static void
-remove_fd (pi)
- struct procinfo *pi;
-{
- int i;
-
- for (i = 0; i < num_poll_list; i++)
- {
- if (poll_list[i].fd == pi->ctl_fd)
- {
- if (i != num_poll_list - 1)
- memcpy (poll_list + i, poll_list + i + 1,
- (num_poll_list - i - 1) * sizeof (struct pollfd));
-
- num_poll_list--;
-
- if (num_poll_list == 0)
- free (poll_list);
- else
- poll_list = (struct pollfd *) xrealloc (poll_list,
- num_poll_list
- * sizeof (struct pollfd));
- return;
- }
- }
-}
-
-/*
-
- 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 ()
-{
- struct procinfo *pi, *next_pi;
-#ifndef LOSING_POLL
- int num_fds;
- int i;
-#endif
-
- set_sigint_trap (); /* Causes SIGINT to be passed on to the
- attached process. */
- set_sigio_trap ();
-
-wait_again:
-#ifndef LOSING_POLL
- while (1)
- {
- num_fds = poll (poll_list, num_poll_list, -1);
- if (num_fds > 0)
- break;
- if (num_fds < 0 && errno == EINTR)
- continue;
- print_sys_errmsg ("poll failed", errno);
- error ("Poll failed, returned %d", num_fds);
- }
-#else /* LOSING_POLL */
- pi = current_procinfo;
-
- while (!procfs_write_pcwstop (pi))
- {
- if (errno == ENOENT)
- {
- /* Process exited. */
- pi->prstatus.pr_flags = 0;
- break;
- }
- else if (errno != EINTR)
- {
- print_sys_errmsg (pi->pathname, errno);
- error ("procfs_write_pcwstop failed");
- }
- }
- pi->had_event = 1;
-#endif /* LOSING_POLL */
-
- clear_sigint_trap ();
- clear_sigio_trap ();
-
-#ifndef LOSING_POLL
-
- for (i = 0; i < num_poll_list && num_fds > 0; i++)
- {
- if (0 == (poll_list[i].revents &
- (POLLWRNORM | POLLPRI | POLLERR | POLLHUP | POLLNVAL)))
- continue;
- for (pi = procinfo_list; pi; pi = next_pi)
- {
- next_pi = pi->next;
- if (poll_list[i].fd == pi->ctl_fd)
- {
- num_fds--;
- if ((poll_list[i].revents & POLLHUP) != 0 ||
- !procfs_read_status (pi))
- { /* The LWP has apparently terminated. */
- if (num_poll_list <= 1)
- {
- pi->prstatus.pr_flags = 0;
- pi->had_event = 1;
- break;
- }
- if (info_verbose)
- printf_filtered ("LWP %d exited.\n",
- (pi->pid >> 16) & 0xffff);
- close_proc_file (pi);
- i--; /* don't skip deleted entry */
- if (num_fds != 0)
- break; /* already another event to process */
- else
- goto wait_again; /* wait for another event */
- }
- pi->had_event = 1;
- break;
- }
- }
- if (!pi)
- error ("wait_fd: Couldn't find procinfo for fd %d\n",
- poll_list[i].fd);
- }
-#endif /* LOSING_POLL */
-
- return pi;
-}
-
-/*
-
- LOCAL FUNCTION
-
- lookupdesc -- translate a value to a summary desc string
-
- SYNOPSIS
-
- static char *lookupdesc (struct trans *transp, unsigned int val);
-
- DESCRIPTION
-
- Given a pointer to a translation table and a value to be translated,
- lookup the desc string and return it.
- */
-
-static char *
-lookupdesc (transp, val)
- struct trans *transp;
- unsigned int val;
-{
- char *desc;
-
- for (desc = NULL; transp->name != NULL; transp++)
- {
- if (transp->value == val)
- {
- desc = transp->desc;
- break;
- }
- }
-
- /* Didn't find a translation for the specified value, set a default one. */
-
- if (desc == NULL)
- {
- desc = "Unknown";
- }
- return (desc);
-}
-
-/*
-
- LOCAL FUNCTION
-
- lookupname -- translate a value to symbolic name
-
- SYNOPSIS
-
- static char *lookupname (struct trans *transp, unsigned int val,
- char *prefix);
-
- DESCRIPTION
-
- Given a pointer to a translation table, a value to be translated,
- and a default prefix to return if the value can't be translated,
- match the value with one of the translation table entries and
- return a pointer to the symbolic name.
-
- If no match is found it just returns the value as a printable string,
- with the given prefix. The previous such value, if any, is freed
- at this time.
- */
-
-static char *
-lookupname (transp, val, prefix)
- struct trans *transp;
- unsigned int val;
- char *prefix;
-{
- static char *locbuf;
- char *name;
-
- for (name = NULL; transp->name != NULL; transp++)
- {
- if (transp->value == val)
- {
- name = transp->name;
- break;
- }
- }
-
- /* Didn't find a translation for the specified value, build a default
- one using the specified prefix and return it. The lifetime of
- the value is only until the next one is needed. */
-
- if (name == NULL)
- {
- if (locbuf != NULL)
- {
- free (locbuf);
- }
- locbuf = xmalloc (strlen (prefix) + 16);
- sprintf (locbuf, "%s %u", prefix, val);
- name = locbuf;
- }
- return (name);
-}
-
-static char *
-sigcodename (sip)
- siginfo_t *sip;
-{
- struct sigcode *scp;
- char *name = NULL;
- static char locbuf[32];
-
- for (scp = siginfo_table; scp->codename != NULL; scp++)
- {
- if ((scp->signo == sip->si_signo) &&
- (scp->code == sip->si_code))
- {
- name = scp->codename;
- break;
- }
- }
- if (name == NULL)
- {
- sprintf (locbuf, "sigcode %u", sip->si_signo);
- name = locbuf;
- }
- return (name);
-}
-
-static char *
-sigcodedesc (sip)
- siginfo_t *sip;
-{
- struct sigcode *scp;
- char *desc = NULL;
-
- for (scp = siginfo_table; scp->codename != NULL; scp++)
- {
- if ((scp->signo == sip->si_signo) &&
- (scp->code == sip->si_code))
- {
- desc = scp->desc;
- break;
- }
- }
- if (desc == NULL)
- {
- desc = "Unrecognized signal or trap use";
- }
- return (desc);
-}
-
-/*
-
- LOCAL FUNCTION
-
- syscallname - translate a system call number into a system call name
-
- SYNOPSIS
-
- char *syscallname (int syscallnum)
-
- DESCRIPTION
-
- Given a system call number, translate it into the printable name
- of a system call, or into "syscall <num>" if it is an unknown
- number.
- */
-
-static char *
-syscallname (syscallnum)
- int syscallnum;
-{
- static char locbuf[32];
-
- if (syscallnum >= 0 && syscallnum < MAX_SYSCALLS
- && syscall_table[syscallnum] != NULL)
- return syscall_table[syscallnum];
- else
- {
- sprintf (locbuf, "syscall %u", syscallnum);
- return locbuf;
- }
-}
-
-/*
-
- LOCAL FUNCTION
-
- init_syscall_table - initialize syscall translation table
-
- SYNOPSIS
-
- void init_syscall_table (void)
-
- DESCRIPTION
-
- Dynamically initialize the translation table to convert system
- call numbers into printable system call names. Done once per
- gdb run, on initialization.
-
- NOTES
-
- This is awfully ugly, but preprocessor tricks to make it prettier
- tend to be nonportable.
- */
-
-static void
-init_syscall_table ()
-{
-#if defined (SYS_exit)
- syscall_table[SYS_exit] = "exit";
-#endif
-#if defined (SYS_fork)
- syscall_table[SYS_fork] = "fork";
-#endif
-#if defined (SYS_read)
- syscall_table[SYS_read] = "read";
-#endif
-#if defined (SYS_write)
- syscall_table[SYS_write] = "write";
-#endif
-#if defined (SYS_open)
- syscall_table[SYS_open] = "open";
-#endif
-#if defined (SYS_close)
- syscall_table[SYS_close] = "close";
-#endif
-#if defined (SYS_wait)
- syscall_table[SYS_wait] = "wait";
-#endif
-#if defined (SYS_creat)
- syscall_table[SYS_creat] = "creat";
-#endif
-#if defined (SYS_link)
- syscall_table[SYS_link] = "link";
-#endif
-#if defined (SYS_unlink)
- syscall_table[SYS_unlink] = "unlink";
-#endif
-#if defined (SYS_exec)
- syscall_table[SYS_exec] = "exec";
-#endif
-#if defined (SYS_execv)
- syscall_table[SYS_execv] = "execv";
-#endif
-#if defined (SYS_execve)
- syscall_table[SYS_execve] = "execve";
-#endif
-#if defined (SYS_chdir)
- syscall_table[SYS_chdir] = "chdir";
-#endif
-#if defined (SYS_time)
- syscall_table[SYS_time] = "time";
-#endif
-#if defined (SYS_mknod)
- syscall_table[SYS_mknod] = "mknod";
-#endif
-#if defined (SYS_chmod)
- syscall_table[SYS_chmod] = "chmod";
-#endif
-#if defined (SYS_chown)
- syscall_table[SYS_chown] = "chown";
-#endif
-#if defined (SYS_brk)
- syscall_table[SYS_brk] = "brk";
-#endif
-#if defined (SYS_stat)
- syscall_table[SYS_stat] = "stat";
-#endif
-#if defined (SYS_lseek)
- syscall_table[SYS_lseek] = "lseek";
-#endif
-#if defined (SYS_getpid)
- syscall_table[SYS_getpid] = "getpid";
-#endif
-#if defined (SYS_mount)
- syscall_table[SYS_mount] = "mount";
-#endif
-#if defined (SYS_umount)
- syscall_table[SYS_umount] = "umount";
-#endif
-#if defined (SYS_setuid)
- syscall_table[SYS_setuid] = "setuid";
-#endif
-#if defined (SYS_getuid)
- syscall_table[SYS_getuid] = "getuid";
-#endif
-#if defined (SYS_stime)
- syscall_table[SYS_stime] = "stime";
-#endif
-#if defined (SYS_ptrace)
- syscall_table[SYS_ptrace] = "ptrace";
-#endif
-#if defined (SYS_alarm)
- syscall_table[SYS_alarm] = "alarm";
-#endif
-#if defined (SYS_fstat)
- syscall_table[SYS_fstat] = "fstat";
-#endif
-#if defined (SYS_pause)
- syscall_table[SYS_pause] = "pause";
-#endif
-#if defined (SYS_utime)
- syscall_table[SYS_utime] = "utime";
-#endif
-#if defined (SYS_stty)
- syscall_table[SYS_stty] = "stty";
-#endif
-#if defined (SYS_gtty)
- syscall_table[SYS_gtty] = "gtty";
-#endif
-#if defined (SYS_access)
- syscall_table[SYS_access] = "access";
-#endif
-#if defined (SYS_nice)
- syscall_table[SYS_nice] = "nice";
-#endif
-#if defined (SYS_statfs)
- syscall_table[SYS_statfs] = "statfs";
-#endif
-#if defined (SYS_sync)
- syscall_table[SYS_sync] = "sync";
-#endif
-#if defined (SYS_kill)
- syscall_table[SYS_kill] = "kill";
-#endif
-#if defined (SYS_fstatfs)
- syscall_table[SYS_fstatfs] = "fstatfs";
-#endif
-#if defined (SYS_pgrpsys)
- syscall_table[SYS_pgrpsys] = "pgrpsys";
-#endif
-#if defined (SYS_xenix)
- syscall_table[SYS_xenix] = "xenix";
-#endif
-#if defined (SYS_dup)
- syscall_table[SYS_dup] = "dup";
-#endif
-#if defined (SYS_pipe)
- syscall_table[SYS_pipe] = "pipe";
-#endif
-#if defined (SYS_times)
- syscall_table[SYS_times] = "times";
-#endif
-#if defined (SYS_profil)
- syscall_table[SYS_profil] = "profil";
-#endif
-#if defined (SYS_plock)
- syscall_table[SYS_plock] = "plock";
-#endif
-#if defined (SYS_setgid)
- syscall_table[SYS_setgid] = "setgid";
-#endif
-#if defined (SYS_getgid)
- syscall_table[SYS_getgid] = "getgid";
-#endif
-#if defined (SYS_signal)
- syscall_table[SYS_signal] = "signal";
-#endif
-#if defined (SYS_msgsys)
- syscall_table[SYS_msgsys] = "msgsys";
-#endif
-#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
-#if defined (SYS_shmsys)
- syscall_table[SYS_shmsys] = "shmsys";
-#endif
-#if defined (SYS_semsys)
- syscall_table[SYS_semsys] = "semsys";
-#endif
-#if defined (SYS_ioctl)
- syscall_table[SYS_ioctl] = "ioctl";
-#endif
-#if defined (SYS_uadmin)
- syscall_table[SYS_uadmin] = "uadmin";
-#endif
-#if defined (SYS_utssys)
- syscall_table[SYS_utssys] = "utssys";
-#endif
-#if defined (SYS_fsync)
- syscall_table[SYS_fsync] = "fsync";
-#endif
-#if defined (SYS_umask)
- syscall_table[SYS_umask] = "umask";
-#endif
-#if defined (SYS_chroot)
- syscall_table[SYS_chroot] = "chroot";
-#endif
-#if defined (SYS_fcntl)
- syscall_table[SYS_fcntl] = "fcntl";
-#endif
-#if defined (SYS_ulimit)
- syscall_table[SYS_ulimit] = "ulimit";
-#endif
-#if defined (SYS_rfsys)
- syscall_table[SYS_rfsys] = "rfsys";
-#endif
-#if defined (SYS_rmdir)
- syscall_table[SYS_rmdir] = "rmdir";
-#endif
-#if defined (SYS_mkdir)
- syscall_table[SYS_mkdir] = "mkdir";
-#endif
-#if defined (SYS_getdents)
- syscall_table[SYS_getdents] = "getdents";
-#endif
-#if defined (SYS_sysfs)
- syscall_table[SYS_sysfs] = "sysfs";
-#endif
-#if defined (SYS_getmsg)
- syscall_table[SYS_getmsg] = "getmsg";
-#endif
-#if defined (SYS_putmsg)
- syscall_table[SYS_putmsg] = "putmsg";
-#endif
-#if defined (SYS_poll)
- syscall_table[SYS_poll] = "poll";
-#endif
-#if defined (SYS_lstat)
- syscall_table[SYS_lstat] = "lstat";
-#endif
-#if defined (SYS_symlink)
- syscall_table[SYS_symlink] = "symlink";
-#endif
-#if defined (SYS_readlink)
- syscall_table[SYS_readlink] = "readlink";
-#endif
-#if defined (SYS_setgroups)
- syscall_table[SYS_setgroups] = "setgroups";
-#endif
-#if defined (SYS_getgroups)
- syscall_table[SYS_getgroups] = "getgroups";
-#endif
-#if defined (SYS_fchmod)
- syscall_table[SYS_fchmod] = "fchmod";
-#endif
-#if defined (SYS_fchown)
- syscall_table[SYS_fchown] = "fchown";
-#endif
-#if defined (SYS_sigprocmask)
- syscall_table[SYS_sigprocmask] = "sigprocmask";
-#endif
-#if defined (SYS_sigsuspend)
- syscall_table[SYS_sigsuspend] = "sigsuspend";
-#endif
-#if defined (SYS_sigaltstack)
- syscall_table[SYS_sigaltstack] = "sigaltstack";
-#endif
-#if defined (SYS_sigaction)
- syscall_table[SYS_sigaction] = "sigaction";
-#endif
-#if defined (SYS_sigpending)
- syscall_table[SYS_sigpending] = "sigpending";
-#endif
-#if defined (SYS_context)
- syscall_table[SYS_context] = "context";
-#endif
-#if defined (SYS_evsys)
- syscall_table[SYS_evsys] = "evsys";
-#endif
-#if defined (SYS_evtrapret)
- syscall_table[SYS_evtrapret] = "evtrapret";
-#endif
-#if defined (SYS_statvfs)
- syscall_table[SYS_statvfs] = "statvfs";
-#endif
-#if defined (SYS_fstatvfs)
- syscall_table[SYS_fstatvfs] = "fstatvfs";
-#endif
-#if defined (SYS_nfssys)
- syscall_table[SYS_nfssys] = "nfssys";
-#endif
-#if defined (SYS_waitsys)
- syscall_table[SYS_waitsys] = "waitsys";
-#endif
-#if defined (SYS_sigsendsys)
- syscall_table[SYS_sigsendsys] = "sigsendsys";
-#endif
-#if defined (SYS_hrtsys)
- syscall_table[SYS_hrtsys] = "hrtsys";
-#endif
-#if defined (SYS_acancel)
- syscall_table[SYS_acancel] = "acancel";
-#endif
-#if defined (SYS_async)
- syscall_table[SYS_async] = "async";
-#endif
-#if defined (SYS_priocntlsys)
- syscall_table[SYS_priocntlsys] = "priocntlsys";
-#endif
-#if defined (SYS_pathconf)
- syscall_table[SYS_pathconf] = "pathconf";
-#endif
-#if defined (SYS_mincore)
- syscall_table[SYS_mincore] = "mincore";
-#endif
-#if defined (SYS_mmap)
- syscall_table[SYS_mmap] = "mmap";
-#endif
-#if defined (SYS_mprotect)
- syscall_table[SYS_mprotect] = "mprotect";
-#endif
-#if defined (SYS_munmap)
- syscall_table[SYS_munmap] = "munmap";
-#endif
-#if defined (SYS_fpathconf)
- syscall_table[SYS_fpathconf] = "fpathconf";
-#endif
-#if defined (SYS_vfork)
- syscall_table[SYS_vfork] = "vfork";
-#endif
-#if defined (SYS_fchdir)
- syscall_table[SYS_fchdir] = "fchdir";
-#endif
-#if defined (SYS_readv)
- syscall_table[SYS_readv] = "readv";
-#endif
-#if defined (SYS_writev)
- syscall_table[SYS_writev] = "writev";
-#endif
-#if defined (SYS_xstat)
- syscall_table[SYS_xstat] = "xstat";
-#endif
-#if defined (SYS_lxstat)
- syscall_table[SYS_lxstat] = "lxstat";
-#endif
-#if defined (SYS_fxstat)
- syscall_table[SYS_fxstat] = "fxstat";
-#endif
-#if defined (SYS_xmknod)
- syscall_table[SYS_xmknod] = "xmknod";
-#endif
-#if defined (SYS_clocal)
- syscall_table[SYS_clocal] = "clocal";
-#endif
-#if defined (SYS_setrlimit)
- syscall_table[SYS_setrlimit] = "setrlimit";
-#endif
-#if defined (SYS_getrlimit)
- syscall_table[SYS_getrlimit] = "getrlimit";
-#endif
-#if defined (SYS_lchown)
- syscall_table[SYS_lchown] = "lchown";
-#endif
-#if defined (SYS_memcntl)
- syscall_table[SYS_memcntl] = "memcntl";
-#endif
-#if defined (SYS_getpmsg)
- syscall_table[SYS_getpmsg] = "getpmsg";
-#endif
-#if defined (SYS_putpmsg)
- syscall_table[SYS_putpmsg] = "putpmsg";
-#endif
-#if defined (SYS_rename)
- syscall_table[SYS_rename] = "rename";
-#endif
-#if defined (SYS_uname)
- syscall_table[SYS_uname] = "uname";
-#endif
-#if defined (SYS_setegid)
- syscall_table[SYS_setegid] = "setegid";
-#endif
-#if defined (SYS_sysconfig)
- syscall_table[SYS_sysconfig] = "sysconfig";
-#endif
-#if defined (SYS_adjtime)
- syscall_table[SYS_adjtime] = "adjtime";
-#endif
-#if defined (SYS_systeminfo)
- syscall_table[SYS_systeminfo] = "systeminfo";
-#endif
-#if defined (SYS_seteuid)
- syscall_table[SYS_seteuid] = "seteuid";
-#endif
-#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_lwp_create)
- syscall_table[SYS_lwp_create] = "_lwp_create";
-#endif
-#if defined (SYS_lwp_exit)
- syscall_table[SYS_lwp_exit] = "_lwp_exit";
-#endif
-#if defined (SYS_lwp_wait)
- syscall_table[SYS_lwp_wait] = "_lwp_wait";
-#endif
-#if defined (SYS_lwp_self)
- syscall_table[SYS_lwp_self] = "_lwp_self";
-#endif
-#if defined (SYS_lwp_info)
- syscall_table[SYS_lwp_info] = "_lwp_info";
-#endif
-#if defined (SYS_lwp_private)
- syscall_table[SYS_lwp_private] = "_lwp_private";
-#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_lwp_kill)
- syscall_table[SYS_lwp_kill] = "_lwp_kill";
-#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_lwp_suspend)
- syscall_table[SYS_lwp_suspend] = "_lwp_suspend";
-#endif
-#if defined (SYS_lwp_continue)
- syscall_table[SYS_lwp_continue] = "_lwp_continue";
-#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
-#if defined(SYS_fstatvfs64)
- syscall_table[SYS_fstatvfs64] = "fstatvfs64";
-#endif
-#if defined(SYS_statvfs64)
- syscall_table[SYS_statvfs64] = "statvfs64";
-#endif
-#if defined(SYS_ftruncate64)
- syscall_table[SYS_ftruncate64] = "ftruncate64";
-#endif
-#if defined(SYS_truncate64)
- syscall_table[SYS_truncate64] = "truncate64";
-#endif
-#if defined(SYS_getrlimit64)
- syscall_table[SYS_getrlimit64] = "getrlimit64";
-#endif
-#if defined(SYS_setrlimit64)
- syscall_table[SYS_setrlimit64] = "setrlimit64";
-#endif
-#if defined(SYS_lseek64)
- syscall_table[SYS_lseek64] = "lseek64";
-#endif
-#if defined(SYS_mmap64)
- syscall_table[SYS_mmap64] = "mmap64";
-#endif
-#if defined(SYS_pread64)
- syscall_table[SYS_pread64] = "pread64";
-#endif
-#if defined(SYS_creat64)
- syscall_table[SYS_creat64] = "creat64";
-#endif
-#if defined(SYS_dshmsys)
- syscall_table[SYS_dshmsys] = "dshmsys";
-#endif
-#if defined(SYS_invlpg)
- syscall_table[SYS_invlpg] = "invlpg";
-#endif
-#if defined(SYS_cg_ids)
- syscall_table[SYS_cg_ids] = "cg_ids";
-#endif
-#if defined(SYS_cg_processors)
- syscall_table[SYS_cg_processors] = "cg_processors";
-#endif
-#if defined(SYS_cg_info)
- syscall_table[SYS_cg_info] = "cg_info";
-#endif
-#if defined(SYS_cg_bind)
- syscall_table[SYS_cg_bind] = "cg_bind";
-#endif
-#if defined(SYS_cg_current)
- syscall_table[SYS_cg_current] = "cg_current";
-#endif
-#if defined(SYS_cg_memloc)
- syscall_table[SYS_cg_memloc] = "cg_memloc";
-#endif
-}
-
-/*
-
- LOCAL FUNCTION
-
- procfs_kill_inferior - kill any current inferior
-
- SYNOPSIS
-
- void procfs_kill_inferior (void)
-
- DESCRIPTION
-
- Kill any current inferior.
-
- NOTES
-
- Kills even attached inferiors. Presumably the user has already
- been prompted that the inferior is an attached one rather than
- one started by gdb. (FIXME?)
-
- */
-
-static void
-procfs_kill_inferior ()
-{
- target_mourn_inferior ();
-}
-
-/*
-
- LOCAL FUNCTION
-
- unconditionally_kill_inferior - terminate the inferior
-
- SYNOPSIS
-
- static void unconditionally_kill_inferior (struct procinfo *)
-
- DESCRIPTION
-
- Kill the specified inferior.
-
- NOTE
-
- A possibly useful enhancement would be to first try sending
- the inferior a terminate signal, politely asking it to commit
- suicide, before we murder it (we could call that
- politely_kill_inferior()).
-
- */
-
-static void
-unconditionally_kill_inferior (pi)
- struct procinfo *pi;
-{
- int ppid;
- struct proc_ctl pctl;
-
- ppid = pi->prstatus.pr_ppid;
-
-#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->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
- to kill the inferior, otherwise it might remain stopped with a
- pending SIGKILL.
- We do not check the result of the PIOCSSIG, the inferior might have
- died already. */
- {
- struct siginfo newsiginfo;
-
- memset ((char *) &newsiginfo, 0, sizeof (newsiginfo));
- newsiginfo.si_signo = SIGKILL;
- newsiginfo.si_code = 0;
- newsiginfo.si_errno = 0;
- newsiginfo.si_pid = getpid ();
- newsiginfo.si_uid = getuid ();
- ioctl (pi->ctl_fd, PIOCSSIG, &newsiginfo);
- }
-#else /* PROCFS_NEED_PIOCSSIG_FOR_KILL */
- procfs_write_pckill (pi);
-#endif /* PROCFS_NEED_PIOCSSIG_FOR_KILL */
-
- close_proc_file (pi);
-
-/* Only wait() for our direct children. Our grandchildren zombies are killed
- by the death of their parents. */
-
- if (ppid == getpid ())
- wait ((int *) 0);
-}
-
-/*
-
- LOCAL FUNCTION
-
- procfs_xfer_memory -- copy data to or from inferior memory space
-
- SYNOPSIS
-
- int procfs_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
- int dowrite, struct target_ops target)
-
- DESCRIPTION
-
- Copy LEN bytes to/from inferior's memory starting at MEMADDR
- from/to debugger memory starting at MYADDR. Copy from inferior
- if DOWRITE is zero or to inferior if DOWRITE is nonzero.
-
- Returns the length copied, which is either the LEN argument or
- zero. This xfer function does not do partial moves, since procfs_ops
- doesn't allow memory operations to cross below us in the target stack
- anyway.
-
- NOTES
-
- The /proc interface makes this an almost trivial task.
- */
-
-static int
-procfs_xfer_memory (memaddr, myaddr, len, dowrite, target)
- CORE_ADDR memaddr;
- char *myaddr;
- int len;
- int dowrite;
- struct target_ops *target; /* ignored */
-{
- int nbytes = 0;
- struct procinfo *pi;
-
- pi = current_procinfo;
-
- if (lseek (pi->as_fd, (off_t) memaddr, SEEK_SET) == (off_t) memaddr)
- {
- if (dowrite)
- {
- nbytes = write (pi->as_fd, myaddr, len);
- }
- else
- {
- nbytes = read (pi->as_fd, myaddr, len);
- }
- if (nbytes < 0)
- {
- nbytes = 0;
- }
- }
- return (nbytes);
-}
-
-/*
-
- LOCAL FUNCTION
-
- procfs_store_registers -- copy register values back to inferior
-
- SYNOPSIS
-
- void procfs_store_registers (int regno)
-
- DESCRIPTION
-
- Store our current register values back into the inferior. If
- REGNO is -1 then store all the register, otherwise store just
- the value specified by REGNO.
-
- NOTES
-
- If we are storing only a single register, we first have to get all
- the current values from the process, overwrite the desired register
- in the gregset with the one we want from gdb's registers, and then
- send the whole set back to the process. For writing all the
- registers, all we have to do is generate the gregset and send it to
- the process.
-
- Also note that the process has to be stopped on an event of interest
- for this to work, which basically means that it has to have been
- run under the control of one of the other /proc ioctl calls and not
- ptrace. Since we don't use ptrace anyway, we don't worry about this
- fine point, but it is worth noting for future reference.
-
- Gdb is confused about what this function is supposed to return.
- Some versions return a value, others return nothing. Some are
- declared to return a value and actually return nothing. Gdb ignores
- anything returned. (FIXME)
-
- */
-
-static void
-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)
- {
- procfs_read_status (pi);
- memcpy ((char *) &greg.gregset,
- (char *) &pi->prstatus.pr_lwp.pr_context.uc_mcontext.gregs,
- sizeof (gdb_gregset_t));
- }
- 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)
-
- /* Now repeat everything using the floating point register set, if the
- 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)
- {
- procfs_read_status (pi);
- memcpy ((char *) &fpreg.fpregset,
- (char *) &pi->prstatus.pr_lwp.pr_context.uc_mcontext.fpregs,
- sizeof (gdb_fpregset_t));
- }
- 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 */
-
-}
-
-/*
-
- LOCAL FUNCTION
-
- init_procinfo - setup a procinfo struct and connect it to a process
-
- SYNOPSIS
-
- struct procinfo * init_procinfo (int pid)
-
- DESCRIPTION
-
- Allocate a procinfo structure, open the /proc file and then set up the
- set of signals and faults that are to be traced. Returns a pointer to
- the new procinfo structure.
-
- NOTES
-
- If proc_init_failed ever gets called, control returns to the command
- processing loop via the standard error handling code.
-
- */
-
-static struct procinfo *
-init_procinfo (pid, kill)
- int pid;
- int kill;
-{
- struct procinfo *pi = (struct procinfo *)
- xmalloc (sizeof (struct procinfo));
- struct sig_ctl sctl;
- struct flt_ctl fctl;
-
- memset ((char *) pi, 0, sizeof (*pi));
- if (!open_proc_file (pid, pi, O_RDWR, 1))
- proc_init_failed (pi, "can't open process file", kill);
-
- /* open_proc_file may modify pid. */
-
- pid = pi->pid;
-
- /* Add new process to process info list */
-
- pi->next = procinfo_list;
- procinfo_list = pi;
-
- add_fd (pi); /* Add to list for poll/select */
-
- /* Remember some things about the inferior that we will, or might, change
- so that we can restore them when we detach. */
-#ifdef UNIXWARE
- 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);
-
-#else /* ! UNIXWARE */
- 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. */
-
- 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 (!procfs_read_status (pi))
- proc_init_failed (pi, "procfs_read_status failed", kill);
-
- return pi;
-}
-
-/*
-
- LOCAL FUNCTION
-
- create_procinfo - initialize access to a /proc entry
-
- SYNOPSIS
-
- struct procinfo * create_procinfo (int pid)
-
- DESCRIPTION
-
- Allocate a procinfo structure, open the /proc file and then set up the
- set of signals and faults that are to be traced. Returns a pointer to
- the new procinfo structure.
-
- NOTES
-
- If proc_init_failed ever gets called, control returns to the command
- processing loop via the standard error handling code.
-
- */
-
-static struct procinfo *
-create_procinfo (pid)
- int pid;
-{
- struct procinfo *pi;
- struct sig_ctl sctl;
- struct flt_ctl fctl;
-
- pi = find_procinfo (pid, 1);
- if (pi != NULL)
- return pi; /* All done! It already exists */
-
- pi = init_procinfo (pid, 1);
-
-#ifndef UNIXWARE
-/* 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. */
- if (!(pi->prstatus.pr_flags & PR_STOPPED))
-#endif
- if (!procfs_write_pcwstop (pi))
- proc_init_failed (pi, "procfs_write_pcwstop failed", 1);
-
-#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", 1);
-#else
- if (ioctl (pi->ctl_fd, PIOCSFAULT, &pi->prrun.pr_fault) < 0)
- proc_init_failed (pi, "PIOCSFAULT failed", 1);
-#endif
-
- return pi;
-}
-
-/*
-
- LOCAL FUNCTION
-
- procfs_exit_handler - handle entry into the _exit syscall
-
- SYNOPSIS
-
- int procfs_exit_handler (pi, syscall_num, why, rtnvalp, statvalp)
-
- DESCRIPTION
-
- This routine is called when an inferior process enters the _exit()
- system call. It continues the process, and then collects the exit
- status and pid which are returned in *statvalp and *rtnvalp. After
- that it returns non-zero to indicate that procfs_wait should wake up.
-
- NOTES
- There is probably a better way to do this.
-
- */
-
-static int
-procfs_exit_handler (pi, syscall_num, why, rtnvalp, statvalp)
- struct procinfo *pi;
- int syscall_num;
- int why;
- int *rtnvalp;
- int *statvalp;
-{
- struct procinfo *temp_pi, *next_pi;
- struct proc_ctl pctl;
-
-#ifdef UNIXWARE
- pctl.cmd = PCRUN;
- pctl.data = PRCFAULT;
-#else
- pi->prrun.pr_flags = PRCFAULT;
-#endif
-
-#ifdef PROCFS_USE_READ_WRITE
- if (write (pi->ctl_fd, (char *) &pctl, sizeof (struct proc_ctl)) < 0)
-#else
- if (ioctl (pi->ctl_fd, PIOCRUN, &pi->prrun) != 0)
-#endif
- perror_with_name (pi->pathname);
-
- if (attach_flag)
- {
- /* Claim it exited (don't call wait). */
- if (info_verbose)
- printf_filtered ("(attached process has exited)\n");
- *statvalp = 0;
- *rtnvalp = inferior_pid;
- }
- else
- {
- *rtnvalp = wait (statvalp);
- if (*rtnvalp >= 0)
- *rtnvalp = pi->pid;
- }
-
- /* Close ALL open proc file handles,
- except the one that called SYS_exit. */
- for (temp_pi = procinfo_list; temp_pi; temp_pi = next_pi)
- {
- next_pi = temp_pi->next;
- if (temp_pi == pi)
- continue; /* Handled below */
- close_proc_file (temp_pi);
- }
- return 1;
-}
-
-/*
-
- LOCAL FUNCTION
-
- procfs_exec_handler - handle exit from the exec family of syscalls
-
- SYNOPSIS
-
- int procfs_exec_handler (pi, syscall_num, why, rtnvalp, statvalp)
-
- DESCRIPTION
-
- This routine is called when an inferior process is about to finish any
- of the exec() family of system calls. It pretends that we got a
- SIGTRAP (for compatibility with ptrace behavior), and returns non-zero
- to tell procfs_wait to wake up.
-
- NOTES
- This need for compatibility with ptrace is questionable. In the
- future, it shouldn't be necessary.
-
- */
-
-static int
-procfs_exec_handler (pi, syscall_num, why, rtnvalp, statvalp)
- struct procinfo *pi;
- int syscall_num;
- int why;
- int *rtnvalp;
- int *statvalp;
-{
- *statvalp = (SIGTRAP << 8) | 0177;
-
- return 1;
-}
-
-#if defined(SYS_sproc) && !defined(UNIXWARE)
-/* IRIX lwp creation system call */
-
-/*
-
- LOCAL FUNCTION
-
- procfs_sproc_handler - handle exit from the sproc syscall
-
- SYNOPSIS
-
- int procfs_sproc_handler (pi, syscall_num, why, rtnvalp, statvalp)
-
- DESCRIPTION
-
- This routine is called when an inferior process is about to finish an
- sproc() system call. This is the system call that IRIX uses to create
- a lightweight process. When the target process gets this event, we can
- look at rval1 to find the new child processes ID, and create a new
- procinfo struct from that.
-
- After that, it pretends that we got a SIGTRAP, and returns non-zero
- to tell procfs_wait to wake up. Subsequently, wait_for_inferior gets
- woken up, sees the new process and continues it.
-
- NOTES
- We actually never see the child exiting from sproc because we will
- shortly stop the child with PIOCSTOP, which is then registered as the
- event of interest.
- */
-
-static int
-procfs_sproc_handler (pi, syscall_num, why, rtnvalp, statvalp)
- struct procinfo *pi;
- int syscall_num;
- int why;
- int *rtnvalp;
- int *statvalp;
-{
-/* We've just detected the completion of an sproc system call. Now we need to
- setup a procinfo struct for this thread, and notify the thread system of the
- new arrival. */
-
-/* If sproc failed, then nothing interesting happened. Continue the process
- and go back to sleep. */
-
- if (pi->prstatus.pr_errno != 0)
- {
- pi->prrun.pr_flags &= PRSTEP;
- pi->prrun.pr_flags |= PRCFAULT;
-
- if (ioctl (pi->ctl_fd, PIOCRUN, &pi->prrun) != 0)
- perror_with_name (pi->pathname);
-
- return 0;
- }
-
- /* At this point, the new thread is stopped at it's first instruction, and
- the parent is stopped at the exit from sproc. */
-
- /* Notify the caller of the arrival of a new thread. */
- create_procinfo (pi->prstatus.pr_rval1);
-
- *rtnvalp = pi->prstatus.pr_rval1;
- *statvalp = (SIGTRAP << 8) | 0177;
-
- return 1;
-}
-
-/*
-
- LOCAL FUNCTION
-
- procfs_fork_handler - handle exit from the fork syscall
-
- SYNOPSIS
-
- int procfs_fork_handler (pi, syscall_num, why, rtnvalp, statvalp)
-
- DESCRIPTION
-
- This routine is called when an inferior process is about to finish a
- fork() system call. We will open up the new process, and then close
- it, which releases it from the clutches of the debugger.
-
- After that, we continue the target process as though nothing had
- happened.
-
- NOTES
- This is necessary for IRIX because we have to set PR_FORK in order
- to catch the creation of lwps (via sproc()). When an actual fork
- occurs, it becomes necessary to reset the forks debugger flags and
- continue it because we can't hack multiple processes yet.
- */
-
-static int
-procfs_fork_handler (pi, syscall_num, why, rtnvalp, statvalp)
- struct procinfo *pi;
- int syscall_num;
- int why;
- int *rtnvalp;
- int *statvalp;
-{
- struct procinfo *pitemp;
-
-/* At this point, we've detected the completion of a fork (or vfork) call in
- our child. The grandchild is also stopped because we set inherit-on-fork
- earlier. (Note that nobody has the grandchilds' /proc file open at this
- point.) We will release the grandchild from the debugger by opening it's
- /proc file and then closing it. Since run-on-last-close is set, the
- grandchild continues on its' merry way. */
-
-
- pitemp = create_procinfo (pi->prstatus.pr_rval1);
- if (pitemp)
- close_proc_file (pitemp);
-
- if (ioctl (pi->ctl_fd, PIOCRUN, &pi->prrun) != 0)
- perror_with_name (pi->pathname);
-
- return 0;
-}
-#endif /* SYS_sproc && !UNIXWARE */
-
-/*
-
- LOCAL FUNCTION
-
- procfs_set_inferior_syscall_traps - setup the syscall traps
-
- SYNOPSIS
-
- void procfs_set_inferior_syscall_traps (struct procinfo *pip)
-
- DESCRIPTION
-
- Called for each "procinfo" (process, thread, or LWP) in the
- inferior, to register for notification of and handlers for
- syscall traps in the inferior.
-
- */
-
-static void
-procfs_set_inferior_syscall_traps (pip)
- struct procinfo *pip;
-{
- procfs_set_syscall_trap (pip, SYS_exit, PROCFS_SYSCALL_ENTRY,
- procfs_exit_handler);
-
-#ifndef PRFS_STOPEXEC
-#ifdef SYS_exec
- procfs_set_syscall_trap (pip, SYS_exec, PROCFS_SYSCALL_EXIT,
- procfs_exec_handler);
-#endif
-#ifdef SYS_execv
- procfs_set_syscall_trap (pip, SYS_execv, PROCFS_SYSCALL_EXIT,
- procfs_exec_handler);
-#endif
-#ifdef SYS_execve
- procfs_set_syscall_trap (pip, SYS_execve, PROCFS_SYSCALL_EXIT,
- procfs_exec_handler);
-#endif
-#endif /* PRFS_STOPEXEC */
-
- /* Setup traps on exit from sproc() */
-
-#ifdef SYS_sproc
- procfs_set_syscall_trap (pip, SYS_sproc, PROCFS_SYSCALL_EXIT,
- procfs_sproc_handler);
- procfs_set_syscall_trap (pip, SYS_fork, PROCFS_SYSCALL_EXIT,
- procfs_fork_handler);
-#ifdef SYS_vfork
- procfs_set_syscall_trap (pip, SYS_vfork, PROCFS_SYSCALL_EXIT,
- procfs_fork_handler);
-#endif
-/* Turn on inherit-on-fork flag so that all children of the target process
- start with tracing flags set. This allows us to trap lwp creation. Note
- that we also have to trap on fork and vfork in order to disable all tracing
- in the targets child processes. */