/* Machine independent support for SVR4 /proc (process file system) for GDB.
- Copyright 1999 Free Software Foundation, Inc.
+ Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
Written by Michael Snyder at Cygnus Solutions.
Based on work by Fred Fish, Stu Grossman, Geoff Noer, and others.
#endif
#include <sys/procfs.h>
+#ifdef HAVE_SYS_FAULT_H
#include <sys/fault.h>
+#endif
+#ifdef HAVE_SYS_SYSCALL_H
#include <sys/syscall.h>
+#endif
#include <sys/errno.h>
#include <sys/wait.h>
#include <signal.h>
* Solaris
* OSF
* Unixware
+ * AIX5
*
* /proc works by immitating a file system: you open a simulated file
* that represents the process you wish to interact with, and
#ifdef NEW_PROC_API
#include <sys/types.h>
-#include <dirent.h> /* opendir/readdir, for listing the LWP's */
+#include "gdb_dirent.h" /* opendir/readdir, for listing the LWP's */
#endif
#include <fcntl.h> /* for O_RDONLY */
files, because it redefines various system calls using macros.
This may be incompatible with the prototype declarations. */
-#define PROCFS_TRACE
#include "proc-utils.h"
+/* Prototypes for supply_gregset etc. */
+#include "gregset.h"
+
/* =================== TARGET_OPS "MODULE" =================== */
/*
* This module defines the GDB target vector and its methods.
*/
-static void procfs_open PARAMS((char *, int));
-static void procfs_attach PARAMS ((char *, int));
-static void procfs_detach PARAMS ((char *, int));
-static void procfs_resume PARAMS ((int, int, enum target_signal));
-static int procfs_can_run PARAMS ((void));
-static void procfs_stop PARAMS ((void));
-static void procfs_files_info PARAMS ((struct target_ops *));
-static void procfs_fetch_registers PARAMS ((int));
-static void procfs_store_registers PARAMS ((int));
-static void procfs_notice_signals PARAMS ((int));
-static void procfs_prepare_to_store PARAMS ((void));
-static void procfs_kill_inferior PARAMS ((void));
-static void procfs_mourn_inferior PARAMS ((void));
-static void procfs_create_inferior PARAMS ((char *, char *, char **));
-static int procfs_wait PARAMS ((int,
- struct target_waitstatus *));
-static int procfs_xfer_memory PARAMS ((CORE_ADDR,
- char *, int, int,
- struct target_ops *));
-
-static int procfs_thread_alive PARAMS ((int));
-
-void procfs_find_new_threads PARAMS ((void));
-char *procfs_pid_to_str PARAMS ((int));
+static void procfs_open (char *, int);
+static void procfs_attach (char *, int);
+static void procfs_detach (char *, int);
+static void procfs_resume (ptid_t, int, enum target_signal);
+static int procfs_can_run (void);
+static void procfs_stop (void);
+static void procfs_files_info (struct target_ops *);
+static void procfs_fetch_registers (int);
+static void procfs_store_registers (int);
+static void procfs_notice_signals (ptid_t);
+static void procfs_prepare_to_store (void);
+static void procfs_kill_inferior (void);
+static void procfs_mourn_inferior (void);
+static void procfs_create_inferior (char *, char *, char **);
+static ptid_t procfs_wait (ptid_t, struct target_waitstatus *);
+static int procfs_xfer_memory (CORE_ADDR, char *, int, int,
+ struct mem_attrib *attrib,
+ struct target_ops *);
+
+static int procfs_thread_alive (ptid_t);
+
+void procfs_find_new_threads (void);
+char *procfs_pid_to_str (ptid_t);
struct target_ops procfs_ops; /* the target vector */
static void
-init_procfs_ops ()
+init_procfs_ops (void)
{
procfs_ops.to_shortname = "procfs";
procfs_ops.to_longname = "Unix /proc child process";
*/
#ifdef NEW_PROC_API /* Solaris 7 && 8 method for watchpoints */
-#ifndef UNIXWARE
+#ifdef WA_READ
enum { READ_WATCHFLAG = WA_READ,
WRITE_WATCHFLAG = WA_WRITE,
EXEC_WATCHFLAG = WA_EXEC,
};
#endif
+/* gdb_sigset_t */
+#ifdef HAVE_PR_SIGSET_T
+typedef pr_sigset_t gdb_sigset_t;
+#else
+typedef sigset_t gdb_sigset_t;
+#endif
+
+/* sigaction */
+#ifdef HAVE_PR_SIGACTION64_T
+typedef pr_sigaction64_t gdb_sigaction_t;
+#else
+typedef struct sigaction gdb_sigaction_t;
+#endif
+
+/* siginfo */
+#ifdef HAVE_PR_SIGINFO64_T
+typedef pr_siginfo64_t gdb_siginfo_t;
+#else
+typedef struct siginfo gdb_siginfo_t;
+#endif
+
+/* gdb_premptysysset */
+#ifdef premptysysset
+#define gdb_premptysysset premptysysset
+#else
+#define gdb_premptysysset premptyset
+#endif
+
+/* praddsysset */
+#ifdef praddsysset
+#define gdb_praddsysset praddsysset
+#else
+#define gdb_praddsysset praddset
+#endif
+
+/* prdelsysset */
+#ifdef prdelsysset
+#define gdb_prdelsysset prdelsysset
+#else
+#define gdb_prdelsysset prdelset
+#endif
+
+/* prissyssetmember */
+#ifdef prissyssetmember
+#define gdb_pr_issyssetmember prissyssetmember
+#else
+#define gdb_pr_issyssetmember prismember
+#endif
+
+/* As a feature test, saying ``#if HAVE_PRSYSENT_T'' everywhere isn't
+ as intuitively descriptive as it could be, so we'll define
+ DYNAMIC_SYSCALLS to mean the same thing. Anyway, at the time of
+ this writing, this feature is only found on AIX5 systems and
+ basically means that the set of syscalls is not fixed. I.e,
+ there's no nice table that one can #include to get all of the
+ syscall numbers. Instead, they're stored in /proc/PID/sysent
+ for each process. We are at least guaranteed that they won't
+ change over the lifetime of the process. But each process could
+ (in theory) have different syscall numbers.
+*/
+#ifdef HAVE_PRSYSENT_T
+#define DYNAMIC_SYSCALLS
+#endif
typedef prstatus_t gdb_lwpstatus_t;
#endif /* NEW_PROC_API */
-
-/* These #ifdefs are for sol2.x in particular. sol2.x has
- both a "gregset_t" and a "prgregset_t", which have
- similar uses but different layouts. sol2.x gdb tries to
- use prgregset_t (and prfpregset_t) everywhere. */
-
-#ifdef GDB_GREGSET_TYPE
- typedef GDB_GREGSET_TYPE gdb_gregset_t;
-#else
- typedef gregset_t gdb_gregset_t;
-#endif
-
-#ifdef GDB_FPREGSET_TYPE
- typedef GDB_FPREGSET_TYPE gdb_fpregset_t;
-#else
- typedef fpregset_t gdb_fpregset_t;
-#endif
-
-/* Provide default composite pid manipulation macros for systems that
- don't have threads. */
-
-#ifndef PIDGET
-#define PIDGET(PID) (PID)
-#define TIDGET(PID) (PID)
-#endif
-#ifndef MERGEPID
-#define MERGEPID(PID, TID) (PID)
-#endif
-
typedef struct procinfo {
struct procinfo *next;
int pid; /* Process ID */
char pathname[MAX_PROC_NAME_SIZE]; /* Pathname to /proc entry */
fltset_t saved_fltset; /* Saved traced hardware fault set */
- sigset_t saved_sigset; /* 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 */
+ gdb_sigset_t saved_sigset; /* Saved traced signal set */
+ gdb_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 */
gdb_prstatus_t prstatus; /* Current process status info */
#ifndef NEW_PROC_API
gdb_fpregset_t fpregset; /* Current floating point registers */
#endif
+
+#ifdef DYNAMIC_SYSCALLS
+ int num_syscalls; /* Total number of syscalls */
+ char **syscall_names; /* Syscall number to name map */
+#endif
struct procinfo *thread_list;
/* Function prototypes for procinfo module: */
-static procinfo *find_procinfo_or_die PARAMS ((int pid, int tid));
-static procinfo *find_procinfo PARAMS ((int pid, int tid));
-static procinfo *create_procinfo PARAMS ((int pid, int tid));
-static void destroy_procinfo PARAMS ((procinfo *p));
-static void dead_procinfo PARAMS ((procinfo *p,
- char *msg, int killp));
-static int open_procinfo_files PARAMS ((procinfo *p, int which));
-static void close_procinfo_files PARAMS ((procinfo *p));
+static procinfo *find_procinfo_or_die (int pid, int tid);
+static procinfo *find_procinfo (int pid, int tid);
+static procinfo *create_procinfo (int pid, int tid);
+static void destroy_procinfo (procinfo * p);
+static void do_destroy_procinfo_cleanup (void *);
+static void dead_procinfo (procinfo * p, char *msg, int killp);
+static int open_procinfo_files (procinfo * p, int which);
+static void close_procinfo_files (procinfo * p);
+static int sysset_t_size (procinfo *p);
+static sysset_t *sysset_t_alloc (procinfo * pi);
+#ifdef DYNAMIC_SYSCALLS
+static void load_syscalls (procinfo *pi);
+static void free_syscalls (procinfo *pi);
+static int find_syscall (procinfo *pi, char *name);
+#endif /* DYNAMIC_SYSCALLS */
/* The head of the procinfo list: */
static procinfo * procinfo_list;
*/
static procinfo *
-find_procinfo (pid, tid)
- int pid;
- int tid;
+find_procinfo (int pid, int tid)
{
procinfo *pi;
*/
static procinfo *
-find_procinfo_or_die (pid, tid)
- int pid;
- int tid;
+find_procinfo_or_die (int pid, int tid)
{
procinfo *pi = find_procinfo (pid, tid);
return pi;
}
+/* open_with_retry() is a wrapper for open(). The appropriate
+ open() call is attempted; if unsuccessful, it will be retried as
+ many times as needed for the EAGAIN and EINTR conditions.
+
+ For other conditions, open_with_retry() will retry the open() a
+ limited number of times. In addition, a short sleep is imposed
+ prior to retrying the open(). The reason for this sleep is to give
+ the kernel a chance to catch up and create the file in question in
+ the event that GDB "wins" the race to open a file before the kernel
+ has created it. */
+
+static int
+open_with_retry (const char *pathname, int flags)
+{
+ int retries_remaining, status;
+
+ retries_remaining = 2;
+
+ while (1)
+ {
+ status = open (pathname, flags);
+
+ if (status >= 0 || retries_remaining == 0)
+ break;
+ else if (errno != EINTR && errno != EAGAIN)
+ {
+ retries_remaining--;
+ sleep (1);
+ }
+ }
+
+ return status;
+}
+
/*
* Function: open_procinfo_files
*
enum { FD_CTL, FD_STATUS, FD_AS };
static int
-open_procinfo_files (pi, which)
- procinfo *pi;
- int which;
+open_procinfo_files (procinfo *pi, int which)
{
#ifdef NEW_PROC_API
char tmp[MAX_PROC_NAME_SIZE];
strcat (tmp, "/lwpctl");
else
strcat (tmp, "/ctl");
- fd = open (tmp, O_WRONLY);
+ fd = open_with_retry (tmp, O_WRONLY);
if (fd <= 0)
return 0; /* fail */
pi->ctl_fd = fd;
if (pi->tid)
return 0; /* there is no 'as' file descriptor for an lwp */
strcat (tmp, "/as");
- fd = open (tmp, O_RDWR);
+ fd = open_with_retry (tmp, O_RDWR);
if (fd <= 0)
return 0; /* fail */
pi->as_fd = fd;
strcat (tmp, "/lwpstatus");
else
strcat (tmp, "/status");
- fd = open (tmp, O_RDONLY);
+ fd = open_with_retry (tmp, O_RDONLY);
if (fd <= 0)
return 0; /* fail */
pi->status_fd = fd;
#ifdef PIOCTSTATUS /* OSF */
- if ((fd = open (pi->pathname, O_RDWR)) == 0) /* Only one FD; just open it. */
+ /* Only one FD; just open it. */
+ if ((fd = open_with_retry (pi->pathname, O_RDWR)) == 0)
return 0;
#else /* Sol 2.5, Irix, other? */
if (pi->tid == 0) /* Master procinfo for the process */
{
- fd = open (pi->pathname, O_RDWR);
+ fd = open_with_retry (pi->pathname, O_RDWR);
if (fd <= 0)
return 0; /* fail */
}
*/
static procinfo *
-create_procinfo (pid, tid)
- int pid;
- int tid;
+create_procinfo (int pid, int tid)
{
procinfo *pi, *parent;
pi->pid = pid;
pi->tid = tid;
+#ifdef DYNAMIC_SYSCALLS
+ load_syscalls (pi);
+#endif
+
/* Chain into list. */
if (tid == 0)
{
*/
static void
-close_procinfo_files (pi)
- procinfo *pi;
+close_procinfo_files (procinfo *pi)
{
if (pi->ctl_fd > 0)
close (pi->ctl_fd);
*/
static void
-destroy_one_procinfo (list, pi)
- procinfo **list;
- procinfo *pi;
+destroy_one_procinfo (procinfo **list, procinfo *pi)
{
procinfo *ptr;
close_procinfo_files (pi);
/* Step three: free the memory. */
- free (pi);
+#ifdef DYNAMIC_SYSCALLS
+ free_syscalls (pi);
+#endif
+ xfree (pi);
}
static void
-destroy_procinfo (pi)
- procinfo *pi;
+destroy_procinfo (procinfo *pi)
{
procinfo *tmp;
}
}
+static void
+do_destroy_procinfo_cleanup (void *pi)
+{
+ destroy_procinfo (pi);
+}
+
enum { NOKILL, KILL };
/*
*/
static void
-dead_procinfo (pi, msg, kill_p)
- procinfo *pi;
- char *msg;
- int kill_p;
+dead_procinfo (procinfo *pi, char *msg, int kill_p)
{
char procfile[80];
error (msg);
}
+/*
+ * Function: sysset_t_size
+ *
+ * Returns the (complete) size of a sysset_t struct. Normally, this
+ * is just sizeof (syset_t), but in the case of Monterey/64, the actual
+ * size of sysset_t isn't known until runtime.
+ */
+
+static int
+sysset_t_size (procinfo * pi)
+{
+#ifndef DYNAMIC_SYSCALLS
+ return sizeof (sysset_t);
+#else
+ return sizeof (sysset_t) - sizeof (uint64_t)
+ + sizeof (uint64_t) * ((pi->num_syscalls + (8 * sizeof (uint64_t) - 1))
+ / (8 * sizeof (uint64_t)));
+#endif
+}
+
+/* Function: sysset_t_alloc
+
+ Allocate and (partially) initialize a sysset_t struct. */
+
+static sysset_t *
+sysset_t_alloc (procinfo * pi)
+{
+ sysset_t *ret;
+ int size = sysset_t_size (pi);
+ ret = xmalloc (size);
+#ifdef DYNAMIC_SYSCALLS
+ ret->pr_size = (pi->num_syscalls + (8 * sizeof (uint64_t) - 1))
+ / (8 * sizeof (uint64_t));
+#endif
+ return ret;
+}
+
+#ifdef DYNAMIC_SYSCALLS
+
+/* Function: load_syscalls
+
+ Extract syscall numbers and names from /proc/<pid>/sysent. Initialize
+ pi->num_syscalls with the number of syscalls and pi->syscall_names
+ with the names. (Certain numbers may be skipped in which case the
+ names for these numbers will be left as NULL.) */
+
+#define MAX_SYSCALL_NAME_LENGTH 256
+#define MAX_SYSCALLS 65536
+
+static void
+load_syscalls (procinfo *pi)
+{
+ char pathname[MAX_PROC_NAME_SIZE];
+ int sysent_fd;
+ prsysent_t header;
+ prsyscall_t *syscalls;
+ int i, size, maxcall;
+
+ pi->num_syscalls = 0;
+ pi->syscall_names = 0;
+
+ /* Open the file descriptor for the sysent file */
+ sprintf (pathname, "/proc/%d/sysent", pi->pid);
+ sysent_fd = open_with_retry (pathname, O_RDONLY);
+ if (sysent_fd < 0)
+ {
+ error ("load_syscalls: Can't open /proc/%d/sysent", pi->pid);
+ }
+
+ size = sizeof header - sizeof (prsyscall_t);
+ if (read (sysent_fd, &header, size) != size)
+ {
+ error ("load_syscalls: Error reading /proc/%d/sysent", pi->pid);
+ }
+
+ if (header.pr_nsyscalls == 0)
+ {
+ error ("load_syscalls: /proc/%d/sysent contains no syscalls!", pi->pid);
+ }
+
+ size = header.pr_nsyscalls * sizeof (prsyscall_t);
+ syscalls = xmalloc (size);
+
+ if (read (sysent_fd, syscalls, size) != size)
+ {
+ xfree (syscalls);
+ error ("load_syscalls: Error reading /proc/%d/sysent", pi->pid);
+ }
+
+ /* Find maximum syscall number. This may not be the same as
+ pr_nsyscalls since that value refers to the number of entries
+ in the table. (Also, the docs indicate that some system
+ call numbers may be skipped.) */
+
+ maxcall = syscalls[0].pr_number;
+
+ for (i = 1; i < header.pr_nsyscalls; i++)
+ if (syscalls[i].pr_number > maxcall
+ && syscalls[i].pr_nameoff > 0
+ && syscalls[i].pr_number < MAX_SYSCALLS)
+ maxcall = syscalls[i].pr_number;
+
+ pi->num_syscalls = maxcall+1;
+ pi->syscall_names = xmalloc (pi->num_syscalls * sizeof (char *));
+
+ for (i = 0; i < pi->num_syscalls; i++)
+ pi->syscall_names[i] = NULL;
+
+ /* Read the syscall names in */
+ for (i = 0; i < header.pr_nsyscalls; i++)
+ {
+ char namebuf[MAX_SYSCALL_NAME_LENGTH];
+ int nread;
+ int callnum;
+
+ if (syscalls[i].pr_number >= MAX_SYSCALLS
+ || syscalls[i].pr_number < 0
+ || syscalls[i].pr_nameoff <= 0
+ || (lseek (sysent_fd, (off_t) syscalls[i].pr_nameoff, SEEK_SET)
+ != (off_t) syscalls[i].pr_nameoff))
+ continue;
+
+ nread = read (sysent_fd, namebuf, sizeof namebuf);
+ if (nread <= 0)
+ continue;
+
+ callnum = syscalls[i].pr_number;
+
+ if (pi->syscall_names[callnum] != NULL)
+ {
+ /* FIXME: Generate warning */
+ continue;
+ }
+
+ namebuf[nread-1] = '\0';
+ size = strlen (namebuf) + 1;
+ pi->syscall_names[callnum] = xmalloc (size);
+ strncpy (pi->syscall_names[callnum], namebuf, size-1);
+ pi->syscall_names[callnum][size-1] = '\0';
+ }
+
+ close (sysent_fd);
+ xfree (syscalls);
+}
+
+/* Function: free_syscalls
+
+ Free the space allocated for the syscall names from the procinfo
+ structure. */
+
+static void
+free_syscalls (procinfo *pi)
+{
+ if (pi->syscall_names)
+ {
+ int i;
+
+ for (i = 0; i < pi->num_syscalls; i++)
+ if (pi->syscall_names[i] != NULL)
+ xfree (pi->syscall_names[i]);
+
+ xfree (pi->syscall_names);
+ pi->syscall_names = 0;
+ }
+}
+
+/* Function: find_syscall
+
+ Given a name, look up (and return) the corresponding syscall number.
+ If no match is found, return -1. */
+
+static int
+find_syscall (procinfo *pi, char *name)
+{
+ int i;
+ for (i = 0; i < pi->num_syscalls; i++)
+ {
+ if (pi->syscall_names[i] && strcmp (name, pi->syscall_names[i]) == 0)
+ return i;
+ }
+ return -1;
+}
+#endif
+
/* =================== END, STRUCT PROCINFO "MODULE" =================== */
/* =================== /proc "MODULE" =================== */
* functions, we do our best to hide them all in here.
*/
-int proc_get_status PARAMS ((procinfo *pi));
-long proc_flags PARAMS ((procinfo *pi));
-int proc_why PARAMS ((procinfo *pi));
-int proc_what PARAMS ((procinfo *pi));
-int proc_set_run_on_last_close PARAMS ((procinfo *pi));
-int proc_unset_run_on_last_close PARAMS ((procinfo *pi));
-int proc_set_inherit_on_fork PARAMS ((procinfo *pi));
-int proc_unset_inherit_on_fork PARAMS ((procinfo *pi));
-int proc_set_async PARAMS ((procinfo *pi));
-int proc_unset_async PARAMS ((procinfo *pi));
-int proc_stop_process PARAMS ((procinfo *pi));
-int proc_trace_signal PARAMS ((procinfo *pi, int signo));
-int proc_ignore_signal PARAMS ((procinfo *pi, int signo));
-int proc_clear_current_fault PARAMS ((procinfo *pi));
-int proc_set_current_signal PARAMS ((procinfo *pi, int signo));
-int proc_clear_current_signal PARAMS ((procinfo *pi));
-int proc_set_gregs PARAMS ((procinfo *pi));
-int proc_set_fpregs PARAMS ((procinfo *pi));
-int proc_wait_for_stop PARAMS ((procinfo *pi));
-int proc_run_process PARAMS ((procinfo *pi, int step, int signo));
-int proc_kill PARAMS ((procinfo *pi, int signo));
-int proc_parent_pid PARAMS ((procinfo *pi));
-int proc_get_nthreads PARAMS ((procinfo *pi));
-int proc_get_current_thread PARAMS ((procinfo *pi));
-int proc_set_held_signals PARAMS ((procinfo *pi, sigset_t *sighold));
-int proc_set_traced_sysexit PARAMS ((procinfo *pi, sysset_t *sysset));
-int proc_set_traced_sysentry PARAMS ((procinfo *pi, sysset_t *sysset));
-int proc_set_traced_faults PARAMS ((procinfo *pi, fltset_t *fltset));
-int proc_set_traced_signals PARAMS ((procinfo *pi, sigset_t *sigset));
-
-int proc_update_threads PARAMS ((procinfo *pi));
-int proc_iterate_over_threads PARAMS ((procinfo *pi,
- int (*func) PARAMS ((procinfo *,
- procinfo *,
- void *)),
- void *ptr));
-
-gdb_gregset_t *proc_get_gregs PARAMS ((procinfo *pi));
-gdb_fpregset_t *proc_get_fpregs PARAMS ((procinfo *pi));
-sysset_t *proc_get_traced_sysexit PARAMS ((procinfo *pi, sysset_t *save));
-sysset_t *proc_get_traced_sysentry PARAMS ((procinfo *pi, sysset_t *save));
-fltset_t *proc_get_traced_faults PARAMS ((procinfo *pi, fltset_t *save));
-sigset_t *proc_get_traced_signals PARAMS ((procinfo *pi, sigset_t *save));
-sigset_t *proc_get_held_signals PARAMS ((procinfo *pi, sigset_t *save));
-sigset_t *proc_get_pending_signals PARAMS ((procinfo *pi, sigset_t *save));
-struct sigaction *proc_get_signal_actions PARAMS ((procinfo *pi,
- struct sigaction *save));
-
-void proc_warn PARAMS ((procinfo *pi, char *func, int line));
-void proc_error PARAMS ((procinfo *pi, char *func, int line));
+int proc_get_status (procinfo * pi);
+long proc_flags (procinfo * pi);
+int proc_why (procinfo * pi);
+int proc_what (procinfo * pi);
+int proc_set_run_on_last_close (procinfo * pi);
+int proc_unset_run_on_last_close (procinfo * pi);
+int proc_set_inherit_on_fork (procinfo * pi);
+int proc_unset_inherit_on_fork (procinfo * pi);
+int proc_set_async (procinfo * pi);
+int proc_unset_async (procinfo * pi);
+int proc_stop_process (procinfo * pi);
+int proc_trace_signal (procinfo * pi, int signo);
+int proc_ignore_signal (procinfo * pi, int signo);
+int proc_clear_current_fault (procinfo * pi);
+int proc_set_current_signal (procinfo * pi, int signo);
+int proc_clear_current_signal (procinfo * pi);
+int proc_set_gregs (procinfo * pi);
+int proc_set_fpregs (procinfo * pi);
+int proc_wait_for_stop (procinfo * pi);
+int proc_run_process (procinfo * pi, int step, int signo);
+int proc_kill (procinfo * pi, int signo);
+int proc_parent_pid (procinfo * pi);
+int proc_get_nthreads (procinfo * pi);
+int proc_get_current_thread (procinfo * pi);
+int proc_set_held_signals (procinfo * pi, gdb_sigset_t * sighold);
+int proc_set_traced_sysexit (procinfo * pi, sysset_t * sysset);
+int proc_set_traced_sysentry (procinfo * pi, sysset_t * sysset);
+int proc_set_traced_faults (procinfo * pi, fltset_t * fltset);
+int proc_set_traced_signals (procinfo * pi, gdb_sigset_t * sigset);
+
+int proc_update_threads (procinfo * pi);
+int proc_iterate_over_threads (procinfo * pi,
+ int (*func) (procinfo *, procinfo *, void *),
+ void *ptr);
+
+gdb_gregset_t *proc_get_gregs (procinfo * pi);
+gdb_fpregset_t *proc_get_fpregs (procinfo * pi);
+sysset_t *proc_get_traced_sysexit (procinfo * pi, sysset_t * save);
+sysset_t *proc_get_traced_sysentry (procinfo * pi, sysset_t * save);
+fltset_t *proc_get_traced_faults (procinfo * pi, fltset_t * save);
+gdb_sigset_t *proc_get_traced_signals (procinfo * pi, gdb_sigset_t * save);
+gdb_sigset_t *proc_get_held_signals (procinfo * pi, gdb_sigset_t * save);
+gdb_sigset_t *proc_get_pending_signals (procinfo * pi, gdb_sigset_t * save);
+gdb_sigaction_t *proc_get_signal_actions (procinfo * pi, gdb_sigaction_t *save);
+
+void proc_warn (procinfo * pi, char *func, int line);
+void proc_error (procinfo * pi, char *func, int line);
void
-proc_warn (pi, func, line)
- procinfo *pi;
- char *func;
- int line;
+proc_warn (procinfo *pi, char *func, int line)
{
sprintf (errmsg, "procfs: %s line %d, %s", func, line, pi->pathname);
print_sys_errmsg (errmsg, errno);
}
void
-proc_error (pi, func, line)
- procinfo *pi;
- char *func;
- int line;
+proc_error (procinfo *pi, char *func, int line)
{
sprintf (errmsg, "procfs: %s line %d, %s", func, line, pi->pathname);
perror_with_name (errmsg);
*/
int
-proc_get_status (pi)
- procinfo *pi;
+proc_get_status (procinfo *pi)
{
/* Status file descriptor is opened "lazily" */
if (pi->status_fd == 0 &&
*/
long
-proc_flags (pi)
- procinfo *pi;
+proc_flags (procinfo *pi)
{
if (!pi->status_valid)
if (!proc_get_status (pi))
*/
int
-proc_why (pi)
- procinfo *pi;
+proc_why (procinfo *pi)
{
if (!pi->status_valid)
if (!proc_get_status (pi))
*/
int
-proc_what (pi)
- procinfo *pi;
+proc_what (procinfo *pi)
{
if (!pi->status_valid)
if (!proc_get_status (pi))
*/
int
-proc_nsysarg (pi)
- procinfo *pi;
+proc_nsysarg (procinfo *pi)
{
if (!pi->status_valid)
if (!proc_get_status (pi))
*/
long *
-proc_sysargs (pi)
- procinfo *pi;
+proc_sysargs (procinfo *pi)
{
if (!pi->status_valid)
if (!proc_get_status (pi))
*/
int
-proc_syscall (pi)
- procinfo *pi;
+proc_syscall (procinfo *pi)
{
if (!pi->status_valid)
if (!proc_get_status (pi))
enum { FLAG_RESET, FLAG_SET };
static int
-proc_modify_flag (pi, flag, mode)
- procinfo *pi;
- long flag;
- long mode;
+proc_modify_flag (procinfo *pi, long flag, long mode)
{
long win = 0; /* default to fail */
from one operating system to the next...) */
#ifdef PCUNSET
#define GDBRESET PCUNSET
-#endif
+#else
#ifdef PCRESET
#define GDBRESET PCRESET
+#endif
#endif
{
- long arg[2];
+ procfs_ctl_t arg[2];
if (mode == FLAG_SET) /* Set the flag (RLC, FORK, or ASYNC) */
arg[0] = PCSET;
*/
int
-proc_set_run_on_last_close (pi)
- procinfo *pi;
+proc_set_run_on_last_close (procinfo *pi)
{
return proc_modify_flag (pi, PR_RLC, FLAG_SET);
}
*/
int
-proc_unset_run_on_last_close (pi)
- procinfo *pi;
+proc_unset_run_on_last_close (procinfo *pi)
{
return proc_modify_flag (pi, PR_RLC, FLAG_RESET);
}
*/
int
-proc_set_kill_on_last_close (pi)
- procinfo *pi;
+proc_set_kill_on_last_close (procinfo *pi)
{
return proc_modify_flag (pi, PR_KLC, FLAG_SET);
}
*/
int
-proc_unset_kill_on_last_close (pi)
- procinfo *pi;
+proc_unset_kill_on_last_close (procinfo *pi)
{
return proc_modify_flag (pi, PR_KLC, FLAG_RESET);
}
*/
int
-proc_set_inherit_on_fork (pi)
- procinfo *pi;
+proc_set_inherit_on_fork (procinfo *pi)
{
return proc_modify_flag (pi, PR_FORK, FLAG_SET);
}
*/
int
-proc_unset_inherit_on_fork (pi)
- procinfo *pi;
+proc_unset_inherit_on_fork (procinfo *pi)
{
return proc_modify_flag (pi, PR_FORK, FLAG_RESET);
}
*/
int
-proc_set_async (pi)
- procinfo *pi;
+proc_set_async (procinfo *pi)
{
return proc_modify_flag (pi, PR_ASYNC, FLAG_SET);
}
*/
int
-proc_unset_async (pi)
- procinfo *pi;
+proc_unset_async (procinfo *pi)
{
return proc_modify_flag (pi, PR_ASYNC, FLAG_RESET);
}
*/
int
-proc_stop_process (pi)
- procinfo *pi;
+proc_stop_process (procinfo *pi)
{
int win;
else
{
#ifdef NEW_PROC_API
- long cmd = PCSTOP;
+ procfs_ctl_t cmd = PCSTOP;
win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd));
#else /* ioctl method */
win = (ioctl (pi->ctl_fd, PIOCSTOP, &pi->prstatus) >= 0);
*/
int
-proc_wait_for_stop (pi)
- procinfo *pi;
+proc_wait_for_stop (procinfo *pi)
{
int win;
#ifdef NEW_PROC_API
{
- long cmd = PCWSTOP;
+ procfs_ctl_t cmd = PCWSTOP;
win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd));
/* We been runnin' and we stopped -- need to update status. */
pi->status_valid = 0;
*/
int
-proc_run_process (pi, step, signo)
- procinfo *pi;
- int step;
- int signo;
+proc_run_process (procinfo *pi, int step, int signo)
{
int win;
int runflags;
#ifdef NEW_PROC_API
{
- long cmd[2];
+ procfs_ctl_t cmd[2];
cmd[0] = PCRUN;
cmd[1] = runflags;
*/
int
-proc_set_traced_signals (pi, sigset)
- procinfo *pi;
- sigset_t *sigset;
+proc_set_traced_signals (procinfo *pi, gdb_sigset_t *sigset)
{
int win;
#ifdef NEW_PROC_API
{
struct {
- long cmd;
+ procfs_ctl_t cmd;
/* Use char array to avoid alignment issues. */
- char sigset[sizeof (sigset_t)];
+ char sigset[sizeof (gdb_sigset_t)];
} arg;
arg.cmd = PCSTRACE;
- memcpy (&arg.sigset, sigset, sizeof (sigset_t));
+ memcpy (&arg.sigset, sigset, sizeof (gdb_sigset_t));
win = (write (pi->ctl_fd, (char *) &arg, sizeof (arg)) == sizeof (arg));
}
*/
int
-proc_set_traced_faults (pi, fltset)
- procinfo *pi;
- fltset_t *fltset;
+proc_set_traced_faults (procinfo *pi, fltset_t *fltset)
{
int win;
#ifdef NEW_PROC_API
{
struct {
- long cmd;
+ procfs_ctl_t cmd;
/* Use char array to avoid alignment issues. */
char fltset[sizeof (fltset_t)];
} arg;
*/
int
-proc_set_traced_sysentry (pi, sysset)
- procinfo *pi;
- sysset_t *sysset;
+proc_set_traced_sysentry (procinfo *pi, sysset_t *sysset)
{
int win;
#ifdef NEW_PROC_API
{
- struct {
- long cmd;
+ struct gdb_proc_ctl_pcsentry {
+ procfs_ctl_t cmd;
/* Use char array to avoid alignment issues. */
char sysset[sizeof (sysset_t)];
- } arg;
+ } *argp;
+ int argp_size = sizeof (struct gdb_proc_ctl_pcsentry)
+ - sizeof (sysset_t)
+ + sysset_t_size (pi);
- arg.cmd = PCSENTRY;
- memcpy (&arg.sysset, sysset, sizeof (sysset_t));
+ argp = xmalloc (argp_size);
- win = (write (pi->ctl_fd, (char *) &arg, sizeof (arg)) == sizeof (arg));
+ argp->cmd = PCSENTRY;
+ memcpy (&argp->sysset, sysset, sysset_t_size (pi));
+
+ win = (write (pi->ctl_fd, (char *) argp, argp_size) == argp_size);
+ xfree (argp);
}
#else /* ioctl method */
win = (ioctl (pi->ctl_fd, PIOCSENTRY, sysset) >= 0);
*/
int
-proc_set_traced_sysexit (pi, sysset)
- procinfo *pi;
- sysset_t *sysset;
+proc_set_traced_sysexit (procinfo *pi, sysset_t *sysset)
{
int win;
#ifdef NEW_PROC_API
{
- struct {
- long cmd;
+ struct gdb_proc_ctl_pcsexit {
+ procfs_ctl_t cmd;
/* Use char array to avoid alignment issues. */
char sysset[sizeof (sysset_t)];
- } arg;
+ } *argp;
+ int argp_size = sizeof (struct gdb_proc_ctl_pcsexit)
+ - sizeof (sysset_t)
+ + sysset_t_size (pi);
- arg.cmd = PCSEXIT;
- memcpy (&arg.sysset, sysset, sizeof (sysset_t));
+ argp = xmalloc (argp_size);
- win = (write (pi->ctl_fd, (char *) &arg, sizeof (arg)) == sizeof (arg));
+ argp->cmd = PCSEXIT;
+ memcpy (&argp->sysset, sysset, sysset_t_size (pi));
+
+ win = (write (pi->ctl_fd, (char *) argp, argp_size) == argp_size);
+ xfree (argp);
}
#else /* ioctl method */
win = (ioctl (pi->ctl_fd, PIOCSEXIT, sysset) >= 0);
*/
int
-proc_set_held_signals (pi, sighold)
- procinfo *pi;
- sigset_t *sighold;
+proc_set_held_signals (procinfo *pi, gdb_sigset_t *sighold)
{
int win;
#ifdef NEW_PROC_API
{
struct {
- long cmd;
+ procfs_ctl_t cmd;
/* Use char array to avoid alignment issues. */
- char hold[sizeof (sigset_t)];
+ char hold[sizeof (gdb_sigset_t)];
} arg;
arg.cmd = PCSHOLD;
- memcpy (&arg.hold, sighold, sizeof (sigset_t));
+ memcpy (&arg.hold, sighold, sizeof (gdb_sigset_t));
win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg));
}
#else
* Will also copy the sigset if 'save' is non-zero.
*/
-sigset_t *
-proc_get_pending_signals (pi, save)
- procinfo *pi;
- sigset_t *save;
+gdb_sigset_t *
+proc_get_pending_signals (procinfo *pi, gdb_sigset_t *save)
{
- sigset_t *ret = NULL;
+ gdb_sigset_t *ret = NULL;
/*
* We should never have to apply this operation to any procinfo
ret = &pi->prstatus.pr_sigpend;
#endif
if (save && ret)
- memcpy (save, ret, sizeof (sigset_t));
+ memcpy (save, ret, sizeof (gdb_sigset_t));
return ret;
}
* Will also copy the sigactionset if 'save' is non-zero.
*/
-struct sigaction *
-proc_get_signal_actions (pi, save)
- procinfo *pi;
- struct sigaction *save;
+gdb_sigaction_t *
+proc_get_signal_actions (procinfo *pi, gdb_sigaction_t *save)
{
- struct sigaction *ret = NULL;
+ gdb_sigaction_t *ret = NULL;
/*
* We should never have to apply this operation to any procinfo
ret = &pi->prstatus.pr_action;
#endif
if (save && ret)
- memcpy (save, ret, sizeof (struct sigaction));
+ memcpy (save, ret, sizeof (gdb_sigaction_t));
return ret;
}
* Will also copy the sigset if 'save' is non-zero.
*/
-sigset_t *
-proc_get_held_signals (pi, save)
- procinfo *pi;
- sigset_t *save;
+gdb_sigset_t *
+proc_get_held_signals (procinfo *pi, gdb_sigset_t *save)
{
- sigset_t *ret = NULL;
+ gdb_sigset_t *ret = NULL;
/*
* We should never have to apply this operation to any procinfo
#endif /* UNIXWARE */
#else /* not NEW_PROC_API */
{
- static sigset_t sigheld;
+ static gdb_sigset_t sigheld;
if (ioctl (pi->ctl_fd, PIOCGHOLD, &sigheld) >= 0)
ret = &sigheld;
}
#endif /* NEW_PROC_API */
if (save && ret)
- memcpy (save, ret, sizeof (sigset_t));
+ memcpy (save, ret, sizeof (gdb_sigset_t));
return ret;
}
* Will also copy the sigset if 'save' is non-zero.
*/
-sigset_t *
-proc_get_traced_signals (pi, save)
- procinfo *pi;
- sigset_t *save;
+gdb_sigset_t *
+proc_get_traced_signals (procinfo *pi, gdb_sigset_t *save)
{
- sigset_t *ret = NULL;
+ gdb_sigset_t *ret = NULL;
/*
* We should never have to apply this operation to any procinfo
ret = &pi->prstatus.pr_sigtrace;
#else
{
- static sigset_t sigtrace;
+ static gdb_sigset_t sigtrace;
if (ioctl (pi->ctl_fd, PIOCGTRACE, &sigtrace) >= 0)
ret = &sigtrace;
}
#endif
if (save && ret)
- memcpy (save, ret, sizeof (sigset_t));
+ memcpy (save, ret, sizeof (gdb_sigset_t));
return ret;
}
*/
int
-proc_trace_signal (pi, signo)
- procinfo *pi;
- int signo;
+proc_trace_signal (procinfo *pi, int signo)
{
- sigset_t temp;
+ gdb_sigset_t temp;
/*
* We should never have to apply this operation to any procinfo
*/
int
-proc_ignore_signal (pi, signo)
- procinfo *pi;
- int signo;
+proc_ignore_signal (procinfo *pi, int signo)
{
- sigset_t temp;
+ gdb_sigset_t temp;
/*
* We should never have to apply this operation to any procinfo
*/
fltset_t *
-proc_get_traced_faults (pi, save)
- procinfo *pi;
- fltset_t *save;
+proc_get_traced_faults (procinfo *pi, fltset_t *save)
{
fltset_t *ret = NULL;
*/
sysset_t *
-proc_get_traced_sysentry (pi, save)
- procinfo *pi;
- sysset_t *save;
+proc_get_traced_sysentry (procinfo *pi, sysset_t *save)
{
sysset_t *ret = NULL;
if (!proc_get_status (pi))
return NULL;
+#ifndef DYNAMIC_SYSCALLS
ret = &pi->prstatus.pr_sysentry;
-#else
+#else /* DYNAMIC_SYSCALLS */
+ {
+ static sysset_t *sysentry;
+ size_t size;
+
+ if (!sysentry)
+ sysentry = sysset_t_alloc (pi);
+ ret = sysentry;
+ if (pi->status_fd == 0 && open_procinfo_files (pi, FD_STATUS) == 0)
+ return NULL;
+ if (pi->prstatus.pr_sysentry_offset == 0)
+ {
+ gdb_premptysysset (sysentry);
+ }
+ else
+ {
+ int rsize;
+
+ if (lseek (pi->status_fd, (off_t) pi->prstatus.pr_sysentry_offset,
+ SEEK_SET)
+ != (off_t) pi->prstatus.pr_sysentry_offset)
+ return NULL;
+ size = sysset_t_size (pi);
+ gdb_premptysysset (sysentry);
+ rsize = read (pi->status_fd, sysentry, size);
+ if (rsize < 0)
+ return NULL;
+ }
+ }
+#endif /* DYNAMIC_SYSCALLS */
+#else /* !NEW_PROC_API */
{
static sysset_t sysentry;
if (ioctl (pi->ctl_fd, PIOCGENTRY, &sysentry) >= 0)
ret = &sysentry;
}
-#endif
+#endif /* NEW_PROC_API */
if (save && ret)
- memcpy (save, ret, sizeof (sysset_t));
+ memcpy (save, ret, sysset_t_size (pi));
return ret;
}
*/
sysset_t *
-proc_get_traced_sysexit (pi, save)
- procinfo *pi;
- sysset_t *save;
+proc_get_traced_sysexit (procinfo *pi, sysset_t *save)
{
sysset_t * ret = NULL;
if (!proc_get_status (pi))
return NULL;
+#ifndef DYNAMIC_SYSCALLS
ret = &pi->prstatus.pr_sysexit;
+#else /* DYNAMIC_SYSCALLS */
+ {
+ static sysset_t *sysexit;
+ size_t size;
+
+ if (!sysexit)
+ sysexit = sysset_t_alloc (pi);
+ ret = sysexit;
+ if (pi->status_fd == 0 && open_procinfo_files (pi, FD_STATUS) == 0)
+ return NULL;
+ if (pi->prstatus.pr_sysexit_offset == 0)
+ {
+ gdb_premptysysset (sysexit);
+ }
+ else
+ {
+ int rsize;
+
+ if (lseek (pi->status_fd, (off_t) pi->prstatus.pr_sysexit_offset, SEEK_SET)
+ != (off_t) pi->prstatus.pr_sysexit_offset)
+ return NULL;
+ size = sysset_t_size (pi);
+ gdb_premptysysset (sysexit);
+ rsize = read (pi->status_fd, sysexit, size);
+ if (rsize < 0)
+ return NULL;
+ }
+ }
+#endif /* DYNAMIC_SYSCALLS */
#else
{
static sysset_t sysexit;
}
#endif
if (save && ret)
- memcpy (save, ret, sizeof (sysset_t));
+ memcpy (save, ret, sysset_t_size (pi));
return ret;
}
*/
int
-proc_clear_current_fault (pi)
- procinfo *pi;
+proc_clear_current_fault (procinfo *pi)
{
int win;
#ifdef NEW_PROC_API
{
- long cmd = PCCFAULT;
+ procfs_ctl_t cmd = PCCFAULT;
win = (write (pi->ctl_fd, (void *) &cmd, sizeof (cmd)) == sizeof (cmd));
}
#else
*/
int
-proc_set_current_signal (pi, signo)
- procinfo *pi;
- int signo;
+proc_set_current_signal (procinfo *pi, int signo)
{
int win;
struct {
- long cmd;
+ procfs_ctl_t cmd;
/* Use char array to avoid alignment issues. */
- char sinfo[sizeof (struct siginfo)];
+ char sinfo[sizeof (gdb_siginfo_t)];
} arg;
- struct siginfo *mysinfo;
+ gdb_siginfo_t *mysinfo;
/*
* We should never have to apply this operation to any procinfo
#endif
/* The pointer is just a type alias. */
- mysinfo = (struct siginfo *) &arg.sinfo;
+ mysinfo = (gdb_siginfo_t *) &arg.sinfo;
mysinfo->si_signo = signo;
mysinfo->si_code = 0;
mysinfo->si_pid = getpid (); /* ?why? */
*/
int
-proc_clear_current_signal (pi)
- procinfo *pi;
+proc_clear_current_signal (procinfo *pi)
{
int win;
#ifdef NEW_PROC_API
{
struct {
- long cmd;
+ procfs_ctl_t cmd;
/* Use char array to avoid alignment issues. */
- char sinfo[sizeof (struct siginfo)];
+ char sinfo[sizeof (gdb_siginfo_t)];
} arg;
- struct siginfo *mysinfo;
+ gdb_siginfo_t *mysinfo;
arg.cmd = PCSSIG;
/* The pointer is just a type alias. */
- mysinfo = (struct siginfo *) &arg.sinfo;
+ mysinfo = (gdb_siginfo_t *) &arg.sinfo;
mysinfo->si_signo = 0;
mysinfo->si_code = 0;
mysinfo->si_errno = 0;
*/
gdb_gregset_t *
-proc_get_gregs (pi)
- procinfo *pi;
+proc_get_gregs (procinfo *pi)
{
if (!pi->status_valid || !pi->gregs_valid)
if (!proc_get_status (pi))
*/
gdb_fpregset_t *
-proc_get_fpregs (pi)
- procinfo *pi;
+proc_get_fpregs (procinfo *pi)
{
#ifdef NEW_PROC_API
if (!pi->status_valid || !pi->fpregs_valid)
*/
int
-proc_set_gregs (pi)
- procinfo *pi;
+proc_set_gregs (procinfo *pi)
{
gdb_gregset_t *gregs;
int win;
{
#ifdef NEW_PROC_API
struct {
- long cmd;
+ procfs_ctl_t cmd;
/* Use char array to avoid alignment issues. */
char gregs[sizeof (gdb_gregset_t)];
} arg;
*/
int
-proc_set_fpregs (pi)
- procinfo *pi;
+proc_set_fpregs (procinfo *pi)
{
gdb_fpregset_t *fpregs;
int win;
{
#ifdef NEW_PROC_API
struct {
- long cmd;
+ procfs_ctl_t cmd;
/* Use char array to avoid alignment issues. */
char fpregs[sizeof (gdb_fpregset_t)];
} arg;
*/
int
-proc_kill (pi, signo)
- procinfo *pi;
- int signo;
+proc_kill (procinfo *pi, int signo)
{
int win;
else
{
#ifdef NEW_PROC_API
- long cmd[2];
+ procfs_ctl_t cmd[2];
cmd[0] = PCKILL;
cmd[1] = signo;
*/
int
-proc_parent_pid (pi)
- procinfo *pi;
+proc_parent_pid (procinfo *pi)
{
/*
* We should never have to apply this operation to any procinfo
*/
int
-proc_set_watchpoint (pi, addr, len, wflags)
- procinfo *pi;
- CORE_ADDR addr;
- int len;
- int wflags;
+proc_set_watchpoint (procinfo *pi, CORE_ADDR addr, int len, int wflags)
{
#if !defined (TARGET_HAS_HARDWARE_WATCHPOINTS)
return 0;
return 0;
#else
struct {
- long cmd;
+ procfs_ctl_t cmd;
char watch[sizeof (prwatch_t)];
} arg;
prwatch_t *pwatch;
pwatch = (prwatch_t *) &arg.watch;
- pwatch->pr_vaddr = addr;
+ pwatch->pr_vaddr = address_to_host_pointer (addr);
pwatch->pr_size = len;
pwatch->pr_wflags = wflags;
#if defined(NEW_PROC_API) && defined (PCWATCH)
It doesn't get called that often... and if I open it
every time, I don't need to lseek it. */
int
-proc_iterate_over_mappings (func)
- int (*func) PARAMS ((int, CORE_ADDR));
+proc_iterate_over_mappings (int (*func) (int, CORE_ADDR))
{
struct prmap *map;
procinfo *pi;
int funcstat = 0;
int fd;
- pi = find_procinfo_or_die (PIDGET (inferior_pid), 0);
+ pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
#ifdef NEW_PROC_API
/* Open map fd. */
sprintf (pathname, "/proc/%d/map", pi->pid);
- if ((map_fd = open (pathname, O_RDONLY)) < 0)
+ if ((map_fd = open_with_retry (pathname, O_RDONLY)) < 0)
proc_error (pi, "proc_iterate_over_mappings (open)", __LINE__);
/* Make sure it gets closed again. */
- make_cleanup ((make_cleanup_func) close, (void *) map_fd);
+ make_cleanup_close (map_fd);
/* Allocate space for mapping (lifetime only for this function). */
map = alloca (sizeof (struct prmap));
{
sprintf (name, "/proc/%d/object/%s", pi->pid, map->pr_mapname);
/* Note: caller's responsibility to close this fd! */
- fd = open (name, O_RDONLY);
+ fd = open_with_retry (name, O_RDONLY);
/* Note: we don't test the above call for failure;
we just pass the FD on as given. Sometimes there is
no file, so the ioctl may return failure, but that's
not a problem. */
/* Stop looping if the callback returns non-zero. */
- if ((funcstat = (*func) (fd, (CORE_ADDR) map[i].pr_vaddr)) != 0)
+ funcstat = (*func) (fd, host_pointer_to_address (map[i].pr_vaddr));
+ if (funcstat != 0)
break;
}
#endif
*/
struct ssd *
-proc_get_LDT_entry (pi, key)
- procinfo *pi;
- int key;
+proc_get_LDT_entry (procinfo *pi, int key)
{
static struct ssd *ldt_entry = NULL;
#ifdef NEW_PROC_API
/* Open the file descriptor for the LDT table. */
sprintf (pathname, "/proc/%d/ldt", pi->pid);
- if ((fd = open (pathname, O_RDONLY)) < 0)
+ if ((fd = open_with_retry (pathname, O_RDONLY)) < 0)
{
proc_warn (pi, "proc_get_LDT_entry (open)", __LINE__);
return NULL;
}
/* Make sure it gets closed again! */
- old_chain = make_cleanup ((make_cleanup_func) close, (void *) fd);
+ old_chain = make_cleanup_close (fd);
/* Now 'read' thru the table, find a match and return it. */
while (read (fd, ldt_entry, sizeof (struct ssd)) == sizeof (struct ssd))
* OSF version
*/
int
-proc_get_nthreads (pi)
- procinfo *pi;
+proc_get_nthreads (procinfo *pi)
{
int nthreads = 0;
* Solaris and Unixware version
*/
int
-proc_get_nthreads (pi)
- procinfo *pi;
+proc_get_nthreads (procinfo *pi)
{
if (!pi->status_valid)
if (!proc_get_status (pi))
* Default version
*/
int
-proc_get_nthreads (pi)
- procinfo *pi;
+proc_get_nthreads (procinfo *pi)
{
return 0;
}
* Solaris and Unixware version
*/
int
-proc_get_current_thread (pi)
- procinfo *pi;
+proc_get_current_thread (procinfo *pi)
{
/*
* Note: this should be applied to the root procinfo for the process,
* OSF version
*/
int
-proc_get_current_thread (pi)
- procinfo *pi;
+proc_get_current_thread (procinfo *pi)
{
#if 0 /* FIXME: not ready for prime time? */
return pi->prstatus.pr_tid;
* Default version
*/
int
-proc_get_current_thread (pi)
- procinfo *pi;
+proc_get_current_thread (procinfo *pi)
{
return 0;
}
*/
int
-proc_delete_dead_threads (parent, thread, ignore)
- procinfo *parent;
- procinfo *thread;
- void *ignore;
+proc_delete_dead_threads (procinfo *parent, procinfo *thread, void *ignore)
{
if (thread && parent) /* sanity */
{
* Solaris 2.5 (ioctl) version
*/
int
-proc_update_threads (pi)
- procinfo *pi;
+proc_update_threads (procinfo *pi)
{
gdb_prstatus_t *prstatus;
struct cleanup *old_chain = NULL;
if ((nlwp = proc_get_nthreads (pi)) <= 1)
return 1; /* Process is not multi-threaded; nothing to do. */
- if ((prstatus = (gdb_prstatus_t *)
- malloc (sizeof (gdb_prstatus_t) * (nlwp + 1))) == 0)
- perror_with_name ("procfs: malloc failed in update_threads");
+ prstatus = xmalloc (sizeof (gdb_prstatus_t) * (nlwp + 1));
- old_chain = make_cleanup (free, prstatus);
+ old_chain = make_cleanup (xfree, prstatus);
if (ioctl (pi->ctl_fd, PIOCLSTATUS, prstatus) < 0)
proc_error (pi, "update_threads (PIOCLSTATUS)", __LINE__);
/*
* Unixware and Solaris 6 (and later) version
*/
+static void
+do_closedir_cleanup (void *dir)
+{
+ closedir (dir);
+}
+
int
-proc_update_threads (pi)
- procinfo *pi;
+proc_update_threads (procinfo *pi)
{
char pathname[MAX_PROC_NAME_SIZE + 16];
struct dirent *direntry;
if ((dirp = opendir (pathname)) == NULL)
proc_error (pi, "update_threads, opendir", __LINE__);
- old_chain = make_cleanup ((make_cleanup_func) closedir, dirp);
+ old_chain = make_cleanup (do_closedir_cleanup, dirp);
while ((direntry = readdir (dirp)) != NULL)
if (direntry->d_name[0] != '.') /* skip '.' and '..' */
{
* OSF version
*/
int
-proc_update_threads (pi)
- procinfo *pi;
+proc_update_threads (procinfo *pi)
{
int nthreads, i;
tid_t *threads;
if (nthreads < 2)
return 0; /* nothing to do for 1 or fewer threads */
- if ((threads = malloc (nthreads * sizeof (tid_t))) == NULL)
- proc_error (pi, "update_threads, malloc", __LINE__);
+ threads = xmalloc (nthreads * sizeof (tid_t));
if (ioctl (pi->ctl_fd, PIOCTLIST, threads) < 0)
proc_error (pi, "procfs: update_threads (PIOCTLIST)", __LINE__);
* Default version
*/
int
-proc_update_threads (pi)
- procinfo *pi;
+proc_update_threads (procinfo *pi)
{
return 0;
}
*/
int
-proc_iterate_over_threads (pi, func, ptr)
- procinfo *pi;
- int (*func) PARAMS ((procinfo *, procinfo *, void *));
- void *ptr;
+proc_iterate_over_threads (procinfo *pi,
+ int (*func) (procinfo *, procinfo *, void *),
+ void *ptr)
{
procinfo *thread, *next;
int retval = 0;
* Here are all of the gdb target vector functions and their friends.
*/
-static int do_attach PARAMS ((int pid));
-static void do_detach PARAMS ((int signo));
-static int register_gdb_signals PARAMS ((procinfo *, sigset_t *));
+static ptid_t do_attach (ptid_t ptid);
+static void do_detach (int signo);
+static int register_gdb_signals (procinfo *, gdb_sigset_t *);
/*
* Function: procfs_debug_inferior
*/
static int
-procfs_debug_inferior (pi)
- procinfo *pi;
+procfs_debug_inferior (procinfo *pi)
{
fltset_t traced_faults;
- sigset_t traced_signals;
- sysset_t traced_syscall_entries;
- sysset_t traced_syscall_exits;
+ gdb_sigset_t traced_signals;
+ sysset_t *traced_syscall_entries;
+ sysset_t *traced_syscall_exits;
+ int status;
#ifdef PROCFS_DONT_TRACE_FAULTS
/* On some systems (OSF), we don't trace hardware faults.
if (!register_gdb_signals (pi, &traced_signals))
return __LINE__;
+
/* Register to trace the 'exit' system call (on entry). */
- premptyset (&traced_syscall_entries);
- praddset (&traced_syscall_entries, SYS_exit);
+ traced_syscall_entries = sysset_t_alloc (pi);
+ gdb_premptysysset (traced_syscall_entries);
+#ifdef SYS_exit
+ gdb_praddsysset (traced_syscall_entries, SYS_exit);
+#endif
#ifdef SYS_lwpexit
- praddset (&traced_syscall_entries, SYS_lwpexit); /* And _lwp_exit... */
+ gdb_praddsysset (traced_syscall_entries, SYS_lwpexit); /* And _lwp_exit... */
#endif
#ifdef SYS_lwp_exit
- praddset (&traced_syscall_entries, SYS_lwp_exit);
+ gdb_praddsysset (traced_syscall_entries, SYS_lwp_exit);
+#endif
+#ifdef DYNAMIC_SYSCALLS
+ {
+ int callnum = find_syscall (pi, "_exit");
+ if (callnum >= 0)
+ gdb_praddsysset (traced_syscall_entries, callnum);
+ }
#endif
- if (!proc_set_traced_sysentry (pi, &traced_syscall_entries))
+ status = proc_set_traced_sysentry (pi, traced_syscall_entries);
+ xfree (traced_syscall_entries);
+ if (!status)
return __LINE__;
#ifdef PRFS_STOPEXEC /* defined on OSF */
names. On the SGI, for example, there is no SYS_exec, but there
*is* a SYS_execv. So, we try to account for that. */
- premptyset (&traced_syscall_exits);
+ traced_syscall_exits = sysset_t_alloc (pi);
+ gdb_premptysysset (traced_syscall_exits);
#ifdef SYS_exec
- praddset (&traced_syscall_exits, SYS_exec);
+ gdb_praddsysset (traced_syscall_exits, SYS_exec);
#endif
#ifdef SYS_execve
- praddset (&traced_syscall_exits, SYS_execve);
+ gdb_praddsysset (traced_syscall_exits, SYS_execve);
#endif
#ifdef SYS_execv
- praddset (&traced_syscall_exits, SYS_execv);
+ gdb_praddsysset (traced_syscall_exits, SYS_execv);
#endif
#ifdef SYS_lwpcreate
- praddset (&traced_syscall_exits, SYS_lwpcreate);
- praddset (&traced_syscall_exits, SYS_lwpexit);
+ gdb_praddsysset (traced_syscall_exits, SYS_lwpcreate);
+ gdb_praddsysset (traced_syscall_exits, SYS_lwpexit);
#endif
#ifdef SYS_lwp_create /* FIXME: once only, please */
- praddset (&traced_syscall_exits, SYS_lwp_create);
- praddset (&traced_syscall_exits, SYS_lwp_exit);
+ gdb_praddsysset (traced_syscall_exits, SYS_lwp_create);
+ gdb_praddsysset (traced_syscall_exits, SYS_lwp_exit);
#endif
+#ifdef DYNAMIC_SYSCALLS
+ {
+ int callnum = find_syscall (pi, "execve");
+ if (callnum >= 0)
+ gdb_praddsysset (traced_syscall_exits, callnum);
+ callnum = find_syscall (pi, "ra_execve");
+ if (callnum >= 0)
+ gdb_praddsysset (traced_syscall_exits, callnum);
+ }
+#endif
- if (!proc_set_traced_sysexit (pi, &traced_syscall_exits))
+ status = proc_set_traced_sysexit (pi, traced_syscall_exits);
+ xfree (traced_syscall_exits);
+ if (!status)
return __LINE__;
#endif /* PRFS_STOPEXEC */
}
static void
-procfs_attach (args, from_tty)
- char *args;
- int from_tty;
+procfs_attach (char *args, int from_tty)
{
char *exec_file;
int pid;
if (exec_file)
printf_filtered ("Attaching to program `%s', %s\n",
- exec_file, target_pid_to_str (pid));
+ exec_file, target_pid_to_str (pid_to_ptid (pid)));
else
- printf_filtered ("Attaching to %s\n", target_pid_to_str (pid));
+ printf_filtered ("Attaching to %s\n",
+ target_pid_to_str (pid_to_ptid (pid)));
fflush (stdout);
}
- inferior_pid = do_attach (pid);
+ inferior_ptid = do_attach (pid_to_ptid (pid));
push_target (&procfs_ops);
}
static void
-procfs_detach (args, from_tty)
- char *args;
- int from_tty;
+procfs_detach (char *args, int from_tty)
{
char *exec_file;
int signo = 0;
if (exec_file == 0)
exec_file = "";
printf_filtered ("Detaching from program: %s %s\n",
- exec_file, target_pid_to_str (inferior_pid));
+ exec_file, target_pid_to_str (inferior_ptid));
fflush (stdout);
}
if (args)
signo = atoi (args);
do_detach (signo);
- inferior_pid = 0;
+ inferior_ptid = null_ptid;
unpush_target (&procfs_ops); /* Pop out of handling an inferior */
}
-static int
-do_attach (pid)
- int pid;
+static ptid_t
+do_attach (ptid_t ptid)
{
procinfo *pi;
int fail;
- if ((pi = create_procinfo (pid, 0)) == NULL)
+ if ((pi = create_procinfo (PIDGET (ptid), 0)) == NULL)
perror ("procfs: out of memory in 'attach'");
if (!open_procinfo_files (pi, FD_CTL))
{
fprintf_filtered (gdb_stderr, "procfs:%d -- ", __LINE__);
sprintf (errmsg, "do_attach: couldn't open /proc file for process %d",
- pid);
+ PIDGET (ptid));
dead_procinfo (pi, errmsg, NOKILL);
}
dead_procinfo (pi, "do_attach: couldn't save traced faults.", NOKILL);
if (!proc_get_traced_signals (pi, &pi->saved_sigset))
dead_procinfo (pi, "do_attach: couldn't save traced signals.", NOKILL);
- if (!proc_get_traced_sysentry (pi, &pi->saved_entryset))
+ if (!proc_get_traced_sysentry (pi, pi->saved_entryset))
dead_procinfo (pi, "do_attach: couldn't save traced syscall entries.",
NOKILL);
- if (!proc_get_traced_sysexit (pi, &pi->saved_exitset))
+ if (!proc_get_traced_sysexit (pi, pi->saved_exitset))
dead_procinfo (pi, "do_attach: couldn't save traced syscall exits.",
NOKILL);
if (!proc_get_held_signals (pi, &pi->saved_sighold))
}
static void
-do_detach (signo)
- int signo;
+do_detach (int signo)
{
procinfo *pi;
/* Find procinfo for the main process */
- pi = find_procinfo_or_die (PIDGET (inferior_pid), 0); /* FIXME: threads */
+ pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0); /* FIXME: threads */
if (signo)
if (!proc_set_current_signal (pi, signo))
proc_warn (pi, "do_detach, set_current_signal", __LINE__);
if (!proc_set_traced_faults (pi, &pi->saved_fltset))
proc_warn (pi, "do_detach, set_traced_faults", __LINE__);
- if (!proc_set_traced_sysentry (pi, &pi->saved_entryset))
+ if (!proc_set_traced_sysentry (pi, pi->saved_entryset))
proc_warn (pi, "do_detach, set_traced_sysentry", __LINE__);
- if (!proc_set_traced_sysexit (pi, &pi->saved_exitset))
+ if (!proc_set_traced_sysexit (pi, pi->saved_exitset))
proc_warn (pi, "do_detach, set_traced_sysexit", __LINE__);
if (!proc_set_held_signals (pi, &pi->saved_sighold))
* is resumed.
*/
-/* These could go in a header file, but the many and various
- definitions of gregset_t would make it tricky and ugly. Several
- different native operating systems (notably Solaris and Linux) have
- various different definitions for gregset_t and fpregset_t. We
- have been kludging around this problem for a while, it would be
- nice if someday we came up with a prettier way of handling it
- (FIXME). */
-
-extern void fill_gregset (gdb_gregset_t *, int);
-extern void fill_fpregset (gdb_fpregset_t *, int);
-extern void supply_gregset (gdb_gregset_t *);
-extern void supply_fpregset (gdb_fpregset_t *);
-
static void
-procfs_fetch_registers (regno)
- int regno;
+procfs_fetch_registers (int regno)
{
gdb_fpregset_t *fpregs;
gdb_gregset_t *gregs;
int pid;
int tid;
- pid = PIDGET (inferior_pid);
- tid = TIDGET (inferior_pid);
+ pid = PIDGET (inferior_ptid);
+ tid = TIDGET (inferior_ptid);
/* First look up procinfo for the main process. */
pi = find_procinfo_or_die (pid, 0);
/* If the event thread is not the same as GDB's requested thread
- (ie. inferior_pid), then look up procinfo for the requested
+ (ie. inferior_ptid), then look up procinfo for the requested
thread. */
if ((tid != 0) &&
(tid != proc_get_current_thread (pi)))
if (pi == NULL)
error ("procfs: fetch_registers failed to find procinfo for %s",
- target_pid_to_str (inferior_pid));
+ target_pid_to_str (inferior_ptid));
if ((gregs = proc_get_gregs (pi)) == NULL)
proc_error (pi, "fetch_registers, get_gregs", __LINE__);
supply_gregset (gregs);
-#if defined (FP0_REGNUM) /* need floating point? */
- if ((regno >= 0 && regno < FP0_REGNUM) ||
- regno == PC_REGNUM ||
- (NPC_REGNUM >= 0 && regno == NPC_REGNUM) ||
- regno == FP_REGNUM ||
- regno == SP_REGNUM)
- return; /* not a floating point register */
+ if (FP0_REGNUM >= 0) /* need floating point? */
+ {
+ if ((regno >= 0 && regno < FP0_REGNUM) ||
+ regno == PC_REGNUM ||
+ (NPC_REGNUM >= 0 && regno == NPC_REGNUM) ||
+ regno == FP_REGNUM ||
+ regno == SP_REGNUM)
+ return; /* not a floating point register */
- if ((fpregs = proc_get_fpregs (pi)) == NULL)
- proc_error (pi, "fetch_registers, get_fpregs", __LINE__);
+ if ((fpregs = proc_get_fpregs (pi)) == NULL)
+ proc_error (pi, "fetch_registers, get_fpregs", __LINE__);
- supply_fpregset (fpregs);
-#endif
+ supply_fpregset (fpregs);
+ }
}
/* Get ready to modify the registers array. On machines which store
from the program being debugged. */
static void
-procfs_prepare_to_store ()
+procfs_prepare_to_store (void)
{
#ifdef CHILD_PREPARE_TO_STORE
CHILD_PREPARE_TO_STORE ();
*/
static void
-procfs_store_registers (regno)
- int regno;
+procfs_store_registers (int regno)
{
gdb_fpregset_t *fpregs;
gdb_gregset_t *gregs;
int pid;
int tid;
- pid = PIDGET (inferior_pid);
- tid = TIDGET (inferior_pid);
+ pid = PIDGET (inferior_ptid);
+ tid = TIDGET (inferior_ptid);
/* First find procinfo for main process */
pi = find_procinfo_or_die (pid, 0);
/* If current lwp for process is not the same as requested thread
- (ie. inferior_pid), then find procinfo for the requested thread. */
+ (ie. inferior_ptid), then find procinfo for the requested thread. */
if ((tid != 0) &&
(tid != proc_get_current_thread (pi)))
if (pi == NULL)
error ("procfs: store_registers: failed to find procinfo for %s",
- target_pid_to_str (inferior_pid));
+ target_pid_to_str (inferior_ptid));
if ((gregs = proc_get_gregs (pi)) == NULL)
proc_error (pi, "store_registers, get_gregs", __LINE__);
if (!proc_set_gregs (pi))
proc_error (pi, "store_registers, set_gregs", __LINE__);
-#if defined (FP0_REGNUM) /* need floating point? */
- if ((regno >= 0 && regno < FP0_REGNUM) ||
- regno == PC_REGNUM ||
- (NPC_REGNUM >= 0 && regno == NPC_REGNUM) ||
- regno == FP_REGNUM ||
- regno == SP_REGNUM)
- return; /* not a floating point register */
+ if (FP0_REGNUM >= 0) /* need floating point? */
+ {
+ if ((regno >= 0 && regno < FP0_REGNUM) ||
+ regno == PC_REGNUM ||
+ (NPC_REGNUM >= 0 && regno == NPC_REGNUM) ||
+ regno == FP_REGNUM ||
+ regno == SP_REGNUM)
+ return; /* not a floating point register */
+
+ if ((fpregs = proc_get_fpregs (pi)) == NULL)
+ proc_error (pi, "store_registers, get_fpregs", __LINE__);
+
+ fill_fpregset (fpregs, regno);
+ if (!proc_set_fpregs (pi))
+ proc_error (pi, "store_registers, set_fpregs", __LINE__);
+ }
+}
- if ((fpregs = proc_get_fpregs (pi)) == NULL)
- proc_error (pi, "store_registers, get_fpregs", __LINE__);
+static int
+syscall_is_lwp_exit (procinfo *pi, int scall)
+{
- fill_fpregset (fpregs, regno);
- if (!proc_set_fpregs (pi))
- proc_error (pi, "store_registers, set_fpregs", __LINE__);
+#ifdef SYS_lwp_exit
+ if (scall == SYS_lwp_exit)
+ return 1;
#endif
+#ifdef SYS_lwpexit
+ if (scall == SYS_lwpexit)
+ return 1;
+#endif
+ return 0;
+}
+
+static int
+syscall_is_exit (procinfo *pi, int scall)
+{
+#ifdef SYS_exit
+ if (scall == SYS_exit)
+ return 1;
+#endif
+#ifdef DYNAMIC_SYSCALLS
+ if (find_syscall (pi, "_exit") == scall)
+ return 1;
+#endif
+ return 0;
+}
+
+static int
+syscall_is_exec (procinfo *pi, int scall)
+{
+#ifdef SYS_exec
+ if (scall == SYS_exec)
+ return 1;
+#endif
+#ifdef SYS_execv
+ if (scall == SYS_execv)
+ return 1;
+#endif
+#ifdef SYS_execve
+ if (scall == SYS_execve)
+ return 1;
+#endif
+#ifdef DYNAMIC_SYSCALLS
+ if (find_syscall (pi, "_execve"))
+ return 1;
+ if (find_syscall (pi, "ra_execve"))
+ return 1;
+#endif
+ return 0;
+}
+
+static int
+syscall_is_lwp_create (procinfo *pi, int scall)
+{
+#ifdef SYS_lwp_create
+ if (scall == SYS_lwp_create)
+ return 1;
+#endif
+#ifdef SYS_lwpcreate
+ if (scall == SYS_lwpcreate)
+ return 1;
+#endif
+ return 0;
}
/*
* event codes are returned thru a pointer parameter.
*/
-static int
-procfs_wait (pid, status)
- int pid;
- struct target_waitstatus *status;
+static ptid_t
+procfs_wait (ptid_t ptid, struct target_waitstatus *status)
{
/* First cut: loosely based on original version 2.1 */
procinfo *pi;
- int temp, wstat;
- int retval;
+ int wstat;
+ int temp_tid;
+ ptid_t retval, temp_ptid;
int why, what, flags;
int retry = 0;
retry++;
wstat = 0;
- retval = -1;
+ retval = pid_to_ptid (-1);
/* Find procinfo for main process */
- pi = find_procinfo_or_die (PIDGET (inferior_pid), 0);
+ pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
if (pi)
{
/* We must assume that the status is stale now... */
/* wait_for_stop failed: has the child terminated? */
if (errno == ENOENT)
{
+ int wait_retval;
+
/* /proc file not found; presumably child has terminated. */
- retval = wait (&wstat); /* "wait" for the child's exit */
+ wait_retval = wait (&wstat); /* "wait" for the child's exit */
- if (retval != PIDGET (inferior_pid)) /* wrong child? */
+ if (wait_retval != PIDGET (inferior_ptid)) /* wrong child? */
error ("procfs: couldn't stop process %d: wait returned %d\n",
- inferior_pid, retval);
+ PIDGET (inferior_ptid), wait_retval);
/* FIXME: might I not just use waitpid?
Or try find_procinfo to see if I know about this child? */
+ retval = pid_to_ptid (wait_retval);
}
+ else if (errno == EINTR)
+ goto wait_again;
else
{
/* Unknown error from wait_for_stop. */
wstat = (what << 8) | 0177;
break;
case PR_SYSENTRY:
- switch (what) {
-#ifdef SYS_lwp_exit
- case SYS_lwp_exit:
-#endif
-#ifdef SYS_lwpexit
- case SYS_lwpexit:
-#endif
-#if defined (SYS_lwp_exit) || defined (SYS_lwpexit)
- printf_filtered ("[%s exited]\n",
- target_pid_to_str (retval));
- delete_thread (retval);
- status->kind = TARGET_WAITKIND_SPURIOUS;
- return retval;
-#endif /* _lwp_exit */
-
- case SYS_exit:
- /* Handle SYS_exit call only */
- /* Stopped at entry to SYS_exit.
- Make it runnable, resume it, then use
- the wait system call to get its exit code.
- Proc_run_process always clears the current
- fault and signal.
- Then return its exit status. */
- pi->status_valid = 0;
- wstat = 0;
- /* FIXME: what we should do is return
- TARGET_WAITKIND_SPURIOUS. */
- if (!proc_run_process (pi, 0, 0))
- proc_error (pi, "target_wait, run_process", __LINE__);
- if (attach_flag)
- {
- /* Don't call wait: simulate waiting for exit,
- return a "success" exit code. Bogus: what if
- it returns something else? */
- wstat = 0;
- retval = inferior_pid; /* ? ? ? */
- }
- else
- {
- int temp = wait (&wstat);
-
- /* FIXME: shouldn't I make sure I get the right
- event from the right process? If (for
- instance) I have killed an earlier inferior
- process but failed to clean up after it
- somehow, I could get its termination event
- here. */
-
- /* If wait returns -1, that's what we return to GDB. */
- if (temp < 0)
- retval = temp;
- }
- break;
- default:
- printf_filtered ("procfs: trapped on entry to ");
- proc_prettyprint_syscall (proc_what (pi), 0);
- printf_filtered ("\n");
-#ifndef PIOCSSPCACT
+ if (syscall_is_lwp_exit (pi, what))
{
- long i, nsysargs, *sysargs;
-
- if ((nsysargs = proc_nsysarg (pi)) > 0 &&
- (sysargs = proc_sysargs (pi)) != NULL)
+ printf_filtered ("[%s exited]\n",
+ target_pid_to_str (retval));
+ delete_thread (retval);
+ status->kind = TARGET_WAITKIND_SPURIOUS;
+ return retval;
+ }
+ else if (syscall_is_exit (pi, what))
+ {
+ /* Handle SYS_exit call only */
+ /* Stopped at entry to SYS_exit.
+ Make it runnable, resume it, then use
+ the wait system call to get its exit code.
+ Proc_run_process always clears the current
+ fault and signal.
+ Then return its exit status. */
+ pi->status_valid = 0;
+ wstat = 0;
+ /* FIXME: what we should do is return
+ TARGET_WAITKIND_SPURIOUS. */
+ if (!proc_run_process (pi, 0, 0))
+ proc_error (pi, "target_wait, run_process", __LINE__);
+ if (attach_flag)
{
- printf_filtered ("%ld syscall arguments:\n", nsysargs);
- for (i = 0; i < nsysargs; i++)
- printf_filtered ("#%ld: 0x%08lx\n",
- i, sysargs[i]);
+ /* Don't call wait: simulate waiting for exit,
+ return a "success" exit code. Bogus: what if
+ it returns something else? */
+ wstat = 0;
+ retval = inferior_ptid; /* ? ? ? */
+ }
+ else
+ {
+ int temp = wait (&wstat);
+
+ /* FIXME: shouldn't I make sure I get the right
+ event from the right process? If (for
+ instance) I have killed an earlier inferior
+ process but failed to clean up after it
+ somehow, I could get its termination event
+ here. */
+
+ /* If wait returns -1, that's what we return to GDB. */
+ if (temp < 0)
+ retval = pid_to_ptid (temp);
}
-
}
-#endif
- if (status)
- {
- /* How to exit gracefully, returning "unknown event" */
- status->kind = TARGET_WAITKIND_SPURIOUS;
- return inferior_pid;
- }
- else
+ else
+ {
+ printf_filtered ("procfs: trapped on entry to ");
+ proc_prettyprint_syscall (proc_what (pi), 0);
+ printf_filtered ("\n");
+#ifndef PIOCSSPCACT
{
- /* How to keep going without returning to wfi: */
- target_resume (pid, 0, TARGET_SIGNAL_0);
- goto wait_again;
- }
- break;
- }
- break;
- case PR_SYSEXIT:
- switch (what) {
-#ifdef SYS_exec
- case SYS_exec:
-#endif
-#ifdef SYS_execv
- case SYS_execv:
-#endif
-#ifdef SYS_execve
- case SYS_execve:
-#endif
- /* Hopefully this is our own "fork-child" execing
- the real child. Hoax this event into a trap, and
- GDB will see the child about to execute its start
- address. */
- wstat = (SIGTRAP << 8) | 0177;
- break;
-#ifdef SYS_lwp_create
- case SYS_lwp_create:
-#endif
-#ifdef SYS_lwpcreate
- case SYS_lwpcreate:
-#endif
-#if defined(SYS_lwp_create) || defined(SYS_lwpcreate)
- /*
- * This syscall is somewhat like fork/exec.
- * We will get the event twice: once for the parent LWP,
- * and once for the child. We should already know about
- * the parent LWP, but the child will be new to us. So,
- * whenever we get this event, if it represents a new
- * thread, simply add the thread to the list.
- */
+ long i, nsysargs, *sysargs;
- /* If not in procinfo list, add it. */
- temp = proc_get_current_thread (pi);
- if (!find_procinfo (pi->pid, temp))
- create_procinfo (pi->pid, temp);
+ if ((nsysargs = proc_nsysarg (pi)) > 0 &&
+ (sysargs = proc_sysargs (pi)) != NULL)
+ {
+ printf_filtered ("%ld syscall arguments:\n", nsysargs);
+ for (i = 0; i < nsysargs; i++)
+ printf_filtered ("#%ld: 0x%08lx\n",
+ i, sysargs[i]);
+ }
- temp = MERGEPID (pi->pid, temp);
- /* If not in GDB's thread list, add it. */
- if (!in_thread_list (temp))
- {
- printf_filtered ("[New %s]\n", target_pid_to_str (temp));
- add_thread (temp);
}
- /* Return to WFI, but tell it to immediately resume. */
- status->kind = TARGET_WAITKIND_SPURIOUS;
- return inferior_pid;
-#endif /* _lwp_create */
-
-#ifdef SYS_lwp_exit
- case SYS_lwp_exit:
-#endif
-#ifdef SYS_lwpexit
- case SYS_lwpexit:
#endif
-#if defined (SYS_lwp_exit) || defined (SYS_lwpexit)
- printf_filtered ("[%s exited]\n",
- target_pid_to_str (retval));
- delete_thread (retval);
- status->kind = TARGET_WAITKIND_SPURIOUS;
- return retval;
-#endif /* _lwp_exit */
-
-#ifdef SYS_sproc
- case SYS_sproc:
- /* Nothing to do here for now. The old procfs
- seemed to use this event to handle threads on
- older (non-LWP) systems, where I'm assuming that
- threads were actually separate processes. Irix,
- maybe? Anyway, low priority for now. */
-#endif
-#ifdef SYS_fork
- case SYS_fork:
- /* FIXME: do we need to handle this? Investigate. */
-#endif
-#ifdef SYS_vfork
- case SYS_vfork:
- /* FIXME: see above. */
-#endif
- default:
- printf_filtered ("procfs: trapped on exit from ");
- proc_prettyprint_syscall (proc_what (pi), 0);
- printf_filtered ("\n");
-#ifndef PIOCSSPCACT
+ if (status)
+ {
+ /* How to exit gracefully, returning "unknown event" */
+ status->kind = TARGET_WAITKIND_SPURIOUS;
+ return inferior_ptid;
+ }
+ else
+ {
+ /* How to keep going without returning to wfi: */
+ target_resume (ptid, 0, TARGET_SIGNAL_0);
+ goto wait_again;
+ }
+ }
+ break;
+ case PR_SYSEXIT:
+ if (syscall_is_exec (pi, what))
+ {
+ /* Hopefully this is our own "fork-child" execing
+ the real child. Hoax this event into a trap, and
+ GDB will see the child about to execute its start
+ address. */
+ wstat = (SIGTRAP << 8) | 0177;
+ }
+ else if (syscall_is_lwp_create (pi, what))
{
- long i, nsysargs, *sysargs;
+ /*
+ * This syscall is somewhat like fork/exec.
+ * We will get the event twice: once for the parent LWP,
+ * and once for the child. We should already know about
+ * the parent LWP, but the child will be new to us. So,
+ * whenever we get this event, if it represents a new
+ * thread, simply add the thread to the list.
+ */
+
+ /* If not in procinfo list, add it. */
+ temp_tid = proc_get_current_thread (pi);
+ if (!find_procinfo (pi->pid, temp_tid))
+ create_procinfo (pi->pid, temp_tid);
- if ((nsysargs = proc_nsysarg (pi)) > 0 &&
- (sysargs = proc_sysargs (pi)) != NULL)
+ temp_ptid = MERGEPID (pi->pid, temp_tid);
+ /* If not in GDB's thread list, add it. */
+ if (!in_thread_list (temp_ptid))
{
- printf_filtered ("%ld syscall arguments:\n", nsysargs);
- for (i = 0; i < nsysargs; i++)
- printf_filtered ("#%ld: 0x%08lx\n",
- i, sysargs[i]);
+ printf_filtered ("[New %s]\n",
+ target_pid_to_str (temp_ptid));
+ add_thread (temp_ptid);
}
+ /* Return to WFI, but tell it to immediately resume. */
+ status->kind = TARGET_WAITKIND_SPURIOUS;
+ return inferior_ptid;
+ }
+ else if (syscall_is_lwp_exit (pi, what))
+ {
+ printf_filtered ("[%s exited]\n",
+ target_pid_to_str (retval));
+ delete_thread (retval);
+ status->kind = TARGET_WAITKIND_SPURIOUS;
+ return retval;
+ }
+ else if (0)
+ {
+ /* FIXME: Do we need to handle SYS_sproc,
+ SYS_fork, or SYS_vfork here? The old procfs
+ seemed to use this event to handle threads on
+ older (non-LWP) systems, where I'm assuming
+ that threads were actually separate processes.
+ Irix, maybe? Anyway, low priority for now. */
}
+ else
+ {
+ printf_filtered ("procfs: trapped on exit from ");
+ proc_prettyprint_syscall (proc_what (pi), 0);
+ printf_filtered ("\n");
+#ifndef PIOCSSPCACT
+ {
+ long i, nsysargs, *sysargs;
+
+ if ((nsysargs = proc_nsysarg (pi)) > 0 &&
+ (sysargs = proc_sysargs (pi)) != NULL)
+ {
+ printf_filtered ("%ld syscall arguments:\n", nsysargs);
+ for (i = 0; i < nsysargs; i++)
+ printf_filtered ("#%ld: 0x%08lx\n",
+ i, sysargs[i]);
+ }
+ }
#endif
- status->kind = TARGET_WAITKIND_SPURIOUS;
- return inferior_pid;
- }
+ status->kind = TARGET_WAITKIND_SPURIOUS;
+ return inferior_ptid;
+ }
break;
case PR_REQUESTED:
#if 0 /* FIXME */
else
{
/* If not in procinfo list, add it. */
- temp = proc_get_current_thread (pi);
- if (!find_procinfo (pi->pid, temp))
- create_procinfo (pi->pid, temp);
+ temp_tid = proc_get_current_thread (pi);
+ if (!find_procinfo (pi->pid, temp_tid))
+ create_procinfo (pi->pid, temp_tid);
/* If not in GDB's thread list, add it. */
- temp = MERGEPID (pi->pid, temp);
- if (!in_thread_list (temp))
+ temp_ptid = MERGEPID (pi->pid, temp_tid);
+ if (!in_thread_list (temp_ptid))
{
printf_filtered ("[New %s]\n",
- target_pid_to_str (temp));
- add_thread (temp);
+ target_pid_to_str (temp_ptid));
+ add_thread (temp_ptid);
}
status->kind = TARGET_WAITKIND_STOPPED;
break;
case FLTPAGE: /* Recoverable page fault */
default: /* FIXME: use si_signo if possible for fault */
- retval = -1;
+ retval = pid_to_ptid (-1);
printf_filtered ("procfs:%d -- ", __LINE__);
printf_filtered ("child stopped for unknown reason:\n");
proc_prettyprint_why (why, what, 1);
* Got this far without error:
* If retval isn't in the threads database, add it.
*/
- if (retval > 0 &&
- retval != inferior_pid &&
+ if (PIDGET (retval) > 0 &&
+ !ptid_equal (retval, inferior_ptid) &&
!in_thread_list (retval))
{
/*
/* In addition, it's possible that this is the first
* new thread we've seen, in which case we may not
- * have created entries for inferior_pid yet.
+ * have created entries for inferior_ptid yet.
*/
- if (TIDGET (inferior_pid) != 0)
+ if (TIDGET (inferior_ptid) != 0)
{
- if (!in_thread_list (inferior_pid))
- add_thread (inferior_pid);
- if (find_procinfo (PIDGET (inferior_pid),
- TIDGET (inferior_pid)) == NULL)
- create_procinfo (PIDGET (inferior_pid),
- TIDGET (inferior_pid));
+ if (!in_thread_list (inferior_ptid))
+ add_thread (inferior_ptid);
+ if (find_procinfo (PIDGET (inferior_ptid),
+ TIDGET (inferior_ptid)) == NULL)
+ create_procinfo (PIDGET (inferior_ptid),
+ TIDGET (inferior_ptid));
}
}
}
return retval;
}
+/* Transfer LEN bytes between GDB address MYADDR and target address
+ MEMADDR. If DOWRITE is non-zero, transfer them to the target,
+ otherwise transfer them from the target. TARGET is unused.
+
+ The return value is 0 if an error occurred or no bytes were
+ transferred. Otherwise, it will be a positive value which
+ indicates the number of bytes transferred between gdb and the
+ target. (Note that the interface also makes provisions for
+ negative values, but this capability isn't implemented here.) */
+
static int
-procfs_xfer_memory (memaddr, myaddr, len, dowrite, target)
- CORE_ADDR memaddr;
- char *myaddr;
- int len;
- int dowrite;
- struct target_ops *target; /* ignored */
+procfs_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int dowrite,
+ struct mem_attrib *attrib, struct target_ops *target)
{
procinfo *pi;
int nbytes = 0;
/* Find procinfo for main process */
- pi = find_procinfo_or_die (PIDGET (inferior_pid), 0);
+ pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
if (pi->as_fd == 0 &&
open_procinfo_files (pi, FD_AS) == 0)
{
static int
-invalidate_cache (parent, pi, ptr)
- procinfo *parent;
- procinfo *pi;
- void *ptr;
+invalidate_cache (procinfo *parent, procinfo *pi, void *ptr)
{
/*
* About to run the child; invalidate caches and do any other cleanup.
if (!proc_set_gregs (pi)) /* flush gregs cache */
proc_warn (pi, "target_resume, set_gregs",
__LINE__);
-#ifdef FP0_REGNUM
- if (pi->fpregs_dirty)
- if (parent == NULL ||
- proc_get_current_thread (parent) != pi->tid)
- if (!proc_set_fpregs (pi)) /* flush fpregs cache */
- proc_warn (pi, "target_resume, set_fpregs",
- __LINE__);
-#endif
+ if (FP0_REGNUM >= 0)
+ if (pi->fpregs_dirty)
+ if (parent == NULL ||
+ proc_get_current_thread (parent) != pi->tid)
+ if (!proc_set_fpregs (pi)) /* flush fpregs cache */
+ proc_warn (pi, "target_resume, set_fpregs",
+ __LINE__);
#endif
if (parent != NULL)
*/
static int
-make_signal_thread_runnable (process, pi, ptr)
- procinfo *process;
- procinfo *pi;
- void *ptr;
+make_signal_thread_runnable (procinfo *process, procinfo *pi, void *ptr)
{
#ifdef PR_ASLWP
if (proc_flags (pi) & PR_ASLWP)
*/
static void
-procfs_resume (pid, step, signo)
- int pid;
- int step;
- enum target_signal signo;
+procfs_resume (ptid_t ptid, int step, enum target_signal signo)
{
procinfo *pi, *thread;
int native_signo;
to proc_run_process (for use in the prrun struct by ioctl). */
/* Find procinfo for main process */
- pi = find_procinfo_or_die (PIDGET (inferior_pid), 0);
+ pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
/* First cut: ignore pid argument */
errno = 0;
/* Void the process procinfo's caches. */
invalidate_cache (NULL, pi, NULL);
- if (pid != -1)
+ if (PIDGET (ptid) != -1)
{
/* Resume a specific thread, presumably suppressing the others. */
- thread = find_procinfo (PIDGET (pid), TIDGET (pid));
+ thread = find_procinfo (PIDGET (ptid), TIDGET (ptid));
if (thread == NULL)
- warning ("procfs: resume can't find thread %d -- resuming all.",
- TIDGET (pid));
+ warning ("procfs: resume can't find thread %ld -- resuming all.",
+ TIDGET (ptid));
else
{
if (thread->tid != 0)
*/
static int
-register_gdb_signals (pi, signals)
- procinfo *pi;
- sigset_t *signals;
+register_gdb_signals (procinfo *pi, gdb_sigset_t *signals)
{
int signo;
*/
static void
-procfs_notice_signals (pid)
- int pid;
+procfs_notice_signals (ptid_t ptid)
{
- sigset_t signals;
- procinfo *pi = find_procinfo_or_die (PIDGET (pid), 0);
+ gdb_sigset_t signals;
+ procinfo *pi = find_procinfo_or_die (PIDGET (ptid), 0);
if (proc_get_traced_signals (pi, &signals) &&
register_gdb_signals (pi, &signals))
*/
static void
-procfs_files_info (ignore)
- struct target_ops *ignore;
+procfs_files_info (struct target_ops *ignore)
{
printf_filtered ("\tUsing the running image of %s %s via /proc.\n",
attach_flag? "attached": "child",
- target_pid_to_str (inferior_pid));
+ target_pid_to_str (inferior_ptid));
}
/*
*/
static void
-procfs_open (args, from_tty)
- char *args;
- int from_tty;
+procfs_open (char *args, int from_tty)
{
error ("Use the \"run\" command to start a Unix child process.");
}
static int
-procfs_can_run ()
+procfs_can_run (void)
{
/* This variable is controlled by modules that sit atop procfs that
may layer their own process structure atop that provided here.
*/
static void
-procfs_stop ()
+procfs_stop (void)
{
extern pid_t inferior_process_group;
*/
static void
-unconditionally_kill_inferior (pi)
- procinfo *pi;
+unconditionally_kill_inferior (procinfo *pi)
{
int parent_pid;
We do not check the result of the PIOCSSIG, the inferior might have
died already. */
{
- struct siginfo newsiginfo;
+ gdb_siginfo_t newsiginfo;
memset ((char *) &newsiginfo, 0, sizeof (newsiginfo));
newsiginfo.si_signo = SIGKILL;
*/
static void
-procfs_kill_inferior ()
+procfs_kill_inferior (void)
{
- if (inferior_pid != 0) /* ? */
+ if (!ptid_equal (inferior_ptid, null_ptid)) /* ? */
{
/* Find procinfo for main process */
- procinfo *pi = find_procinfo (PIDGET (inferior_pid), 0);
+ procinfo *pi = find_procinfo (PIDGET (inferior_ptid), 0);
if (pi)
unconditionally_kill_inferior (pi);
*/
static void
-procfs_mourn_inferior ()
+procfs_mourn_inferior (void)
{
procinfo *pi;
- if (inferior_pid != 0)
+ if (!ptid_equal (inferior_ptid, null_ptid))
{
/* Find procinfo for main process */
- pi = find_procinfo (PIDGET (inferior_pid), 0);
+ pi = find_procinfo (PIDGET (inferior_ptid), 0);
if (pi)
destroy_procinfo (pi);
}
*/
static void
-procfs_init_inferior (pid)
- int pid;
+procfs_init_inferior (int pid)
{
procinfo *pi;
- sigset_t signals;
+ gdb_sigset_t signals;
int fail;
/* This routine called on the parent side (GDB side)
proc_error (pi, "init_inferior, get_held_signals", __LINE__);
if (!proc_get_traced_faults (pi, &pi->saved_fltset))
proc_error (pi, "init_inferior, get_traced_faults", __LINE__);
- if (!proc_get_traced_sysentry (pi, &pi->saved_entryset))
+ if (!proc_get_traced_sysentry (pi, pi->saved_entryset))
proc_error (pi, "init_inferior, get_traced_sysentry", __LINE__);
- if (!proc_get_traced_sysexit (pi, &pi->saved_exitset))
+ if (!proc_get_traced_sysexit (pi, pi->saved_exitset))
proc_error (pi, "init_inferior, get_traced_sysexit", __LINE__);
/* Register to trace selected signals in the child. */
/* The 'process ID' we return to GDB is composed of
the actual process ID plus the lwp ID. */
- inferior_pid = MERGEPID (pi->pid, proc_get_current_thread (pi));
+ inferior_ptid = MERGEPID (pi->pid, proc_get_current_thread (pi));
#ifdef START_INFERIOR_TRAPS_EXPECTED
startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
*/
static void
-procfs_set_exec_trap ()
+procfs_set_exec_trap (void)
{
/* This routine called on the child side (inferior side)
after GDB forks the inferior. It must use only local variables,
because it may be sharing data space with its parent. */
procinfo *pi;
- sysset_t exitset;
+ sysset_t *exitset;
if ((pi = create_procinfo (getpid (), 0)) == NULL)
perror_with_name ("procfs: create_procinfo failed in child.");
names. On the SGI, for example, there is no SYS_exec, but there
*is* a SYS_execv. So, we try to account for that. */
- premptyset (&exitset);
+ exitset = sysset_t_alloc (pi);
+ gdb_premptysysset (exitset);
#ifdef SYS_exec
- praddset (&exitset, SYS_exec);
+ gdb_praddsysset (exitset, SYS_exec);
#endif
#ifdef SYS_execve
- praddset (&exitset, SYS_execve);
+ gdb_praddsysset (exitset, SYS_execve);
#endif
#ifdef SYS_execv
- praddset (&exitset, SYS_execv);
+ gdb_praddsysset (exitset, SYS_execv);
#endif
+#ifdef DYNAMIC_SYSCALLS
+ {
+ int callnum = find_syscall (pi, "execve");
- if (!proc_set_traced_sysexit (pi, &exitset))
+ if (callnum >= 0)
+ gdb_praddsysset (exitset, callnum);
+
+ callnum = find_syscall (pi, "ra_execve");
+ if (callnum >= 0)
+ gdb_praddsysset (exitset, callnum);
+ }
+#endif /* DYNAMIC_SYSCALLS */
+
+ if (!proc_set_traced_sysexit (pi, exitset))
{
proc_warn (pi, "set_exec_trap, set_traced_sysexit", __LINE__);
gdb_flush (gdb_stderr);
*/
static void
-procfs_create_inferior (exec_file, allargs, env)
- char *exec_file;
- char *allargs;
- char **env;
+procfs_create_inferior (char *exec_file, char *allargs, char **env)
{
char *shell_file = getenv ("SHELL");
char *tryname;
*/
static int
-procfs_notice_thread (pi, thread, ptr)
- procinfo *pi;
- procinfo *thread;
- void *ptr;
+procfs_notice_thread (procinfo *pi, procinfo *thread, void *ptr)
{
- int gdb_threadid = MERGEPID (pi->pid, thread->tid);
+ ptid_t gdb_threadid = MERGEPID (pi->pid, thread->tid);
if (!in_thread_list (gdb_threadid))
add_thread (gdb_threadid);
*/
void
-procfs_find_new_threads ()
+procfs_find_new_threads (void)
{
procinfo *pi;
/* Find procinfo for main process */
- pi = find_procinfo_or_die (PIDGET (inferior_pid), 0);
+ pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
proc_update_threads (pi);
proc_iterate_over_threads (pi, procfs_notice_thread, NULL);
}
*/
static int
-procfs_thread_alive (pid)
- int pid;
+procfs_thread_alive (ptid_t ptid)
{
int proc, thread;
procinfo *pi;
- proc = PIDGET (pid);
- thread = TIDGET (pid);
+ proc = PIDGET (ptid);
+ thread = TIDGET (ptid);
/* If I don't know it, it ain't alive! */
if ((pi = find_procinfo (proc, thread)) == NULL)
return 0;
*/
char *
-procfs_pid_to_str (pid)
- int pid;
+procfs_pid_to_str (ptid_t ptid)
{
static char buf[80];
int proc, thread;
procinfo *pi;
- proc = PIDGET (pid);
- thread = TIDGET (pid);
+ proc = PIDGET (ptid);
+ thread = TIDGET (ptid);
pi = find_procinfo (proc, thread);
if (thread == 0)
*/
int
-procfs_set_watchpoint (pid, addr, len, rwflag, after)
- int pid;
- CORE_ADDR addr;
- int len;
- int rwflag;
- int after;
+procfs_set_watchpoint (ptid_t ptid, CORE_ADDR addr, int len, int rwflag,
+ int after)
{
#ifndef UNIXWARE
+#ifndef AIX5
int pflags = 0;
procinfo *pi;
- pi = find_procinfo_or_die (pid == -1 ?
- PIDGET (inferior_pid) : PIDGET (pid), 0);
+ pi = find_procinfo_or_die (PIDGET (ptid) == -1 ?
+ PIDGET (inferior_ptid) : PIDGET (ptid), 0);
/* Translate from GDB's flags to /proc's */
if (len > 0) /* len == 0 means delete watchpoint */
return 0; /* ignore */
proc_error (pi, "set_watchpoint", __LINE__);
}
-#endif
+#endif /* AIX5 */
+#endif /* UNIXWARE */
return 0;
}
*/
int
-procfs_stopped_by_watchpoint (pid)
- int pid;
+procfs_stopped_by_watchpoint (ptid_t ptid)
{
procinfo *pi;
- pi = find_procinfo_or_die (pid == -1 ?
- PIDGET (inferior_pid) : PIDGET (pid), 0);
+ pi = find_procinfo_or_die (PIDGET (ptid) == -1 ?
+ PIDGET (inferior_ptid) : PIDGET (ptid), 0);
+
+ if (!pi) /* If no process, then not stopped by watchpoint! */
+ return 0;
+
if (proc_flags (pi) & (PR_STOPPED | PR_ISTOP))
{
if (proc_why (pi) == PR_FAULTED)
* Function: procfs_find_LDT_entry
*
* Input:
- * int pid; // The GDB-style pid-plus-LWP.
+ * ptid_t ptid; // The GDB-style pid-plus-LWP.
*
* Return:
* pointer to the corresponding LDT entry.
*/
struct ssd *
-procfs_find_LDT_entry (pid)
- int pid;
+procfs_find_LDT_entry (ptid_t ptid)
{
gdb_gregset_t *gregs;
int key;
procinfo *pi;
/* Find procinfo for the lwp. */
- if ((pi = find_procinfo (PIDGET (pid), TIDGET (pid))) == NULL)
+ if ((pi = find_procinfo (PIDGET (ptid), TIDGET (ptid))) == NULL)
{
- warning ("procfs_find_LDT_entry: could not find procinfi for %d.",
- pid);
+ warning ("procfs_find_LDT_entry: could not find procinfo for %d:%d.",
+ PIDGET (ptid), TIDGET (ptid));
return NULL;
}
/* get its general registers. */
if ((gregs = proc_get_gregs (pi)) == NULL)
{
- warning ("procfs_find_LDT_entry: could not read gregs for %d.",
- pid);
+ warning ("procfs_find_LDT_entry: could not read gregs for %d:%d.",
+ PIDGET (ptid), TIDGET (ptid));
return NULL;
}
/* Now extract the GS register's lower 16 bits. */
static void
-info_proc_cmd (args, from_tty)
- char *args;
- int from_tty;
+info_proc_cmd (char *args, int from_tty)
{
struct cleanup *old_chain;
procinfo *process = NULL;
if ((argv = buildargv (args)) == NULL)
nomem (0);
else
- make_cleanup ((make_cleanup_func) freeargv, argv);
+ make_cleanup_freeargv (argv);
}
while (argv != NULL && *argv != NULL)
{
argv++;
}
if (pid == 0)
- pid = PIDGET (inferior_pid);
+ pid = PIDGET (inferior_ptid);
if (pid == 0)
error ("No current process: you must name one.");
else
/* No. So open a procinfo for it, but
remember to close it again when finished. */
process = create_procinfo (pid, 0);
- make_cleanup ((make_cleanup_func) destroy_procinfo, process);
+ make_cleanup (do_destroy_procinfo_cleanup, process);
if (!open_procinfo_files (process, FD_CTL))
proc_error (process, "info proc, open_procinfo_files", __LINE__);
}
}
static void
-proc_trace_syscalls (args, from_tty, entry_or_exit, mode)
- char *args;
- int from_tty;
- int entry_or_exit;
- int mode;
+proc_trace_syscalls (char *args, int from_tty, int entry_or_exit, int mode)
{
procinfo *pi;
sysset_t *sysset;
int syscallnum = 0;
- if (inferior_pid <= 0)
+ if (PIDGET (inferior_ptid) <= 0)
error ("you must be debugging a process to use this command.");
if (args == NULL || args[0] == 0)
error_no_arg ("system call to trace");
- pi = find_procinfo_or_die (PIDGET (inferior_pid), 0);
+ pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
if (isdigit (args[0]))
{
syscallnum = atoi (args);
proc_error (pi, "proc-trace, get_traced_sysset", __LINE__);
if (mode == FLAG_SET)
- praddset (sysset, syscallnum);
+ gdb_praddsysset (sysset, syscallnum);
else
- prdelset (sysset, syscallnum);
+ gdb_prdelsysset (sysset, syscallnum);
if (entry_or_exit == PR_SYSENTRY)
{
}
static void
-proc_trace_sysentry_cmd (args, from_tty)
- char *args;
- int from_tty;
+proc_trace_sysentry_cmd (char *args, int from_tty)
{
proc_trace_syscalls (args, from_tty, PR_SYSENTRY, FLAG_SET);
}
static void
-proc_trace_sysexit_cmd (args, from_tty)
- char *args;
- int from_tty;
+proc_trace_sysexit_cmd (char *args, int from_tty)
{
proc_trace_syscalls (args, from_tty, PR_SYSEXIT, FLAG_SET);
}
static void
-proc_untrace_sysentry_cmd (args, from_tty)
- char *args;
- int from_tty;
+proc_untrace_sysentry_cmd (char *args, int from_tty)
{
proc_trace_syscalls (args, from_tty, PR_SYSENTRY, FLAG_RESET);
}
static void
-proc_untrace_sysexit_cmd (args, from_tty)
- char *args;
- int from_tty;
+proc_untrace_sysexit_cmd (char *args, int from_tty)
{
proc_trace_syscalls (args, from_tty, PR_SYSEXIT, FLAG_RESET);
}
void
-_initialize_procfs ()
+_initialize_procfs (void)
{
init_procfs_ops ();
add_target (&procfs_ops);
* we will be able to find a 'live' procinfo.
*/
-int
-procfs_first_available ()
+ptid_t
+procfs_first_available (void)
{
- if (procinfo_list)
- return procinfo_list->pid;
- else
- return -1;
+ return pid_to_ptid (procinfo_list ? procinfo_list->pid : -1);
}