[PATCH RFA] procfs.c related changes for AIX 5

Kevin Buettner
2001-03-05T18:58:00Z

The patch below represent the changes needed to procfs.c and related files
for making GDB work natively on AIX5/IA-64.

Here is a high-level description of the more significant changes which
were required:

1) The operation code for writing to /proc/PID/ctl is an int (32-bits)
on AIX5/IA-64 and not a long (64-bits). At Michael Snyder's
suggestion, a new type called procfs_ctl_t was added to
proc-utils.h. By default, this type will be defined to be a long
(which is what Solaris and Unixware want), but a native port can
override this by defining PROC_CTL_WORD_TYPE in a suitable fashion
in the appropriate nm-*.h files.

There were many places in the code which assumed that the
operation code for writing to /proc/PID/ctl was a long. These
were all changed to be procfs_ctl_t instead.

2) AIX5 does not have a static set of syscalls. Consequently, there
is no sys/syscall.h file which provides a nice mapping of
symbolic names to syscall numbers. Instead, AIX5 provides
/proc/PID/sysent which contains the information necessary to map
strings to syscall numbers.

These syscall numbers are guaranteed (at least according to the
developer that I spoke with) to be fixed for the lifetime of a
process, but they can certainly vary between processes.

The changes needed to the code due to this change were fairly
significant:

a) sysset_t data structures (or data structures which contain
sysset_t) must be dynamically allocated. They must be
copied with memcpy() and explicitly freed when no longer
needed.

b) Comparisons against SYS_* constants no longer work. I've
introduced a number of predicate functions (such as
syscall_is_exit()) which will indicate whether a
given system call number is a particular system call. All code
which formerly relied on comparisons against a system call
number was rewritten to call one of these new predicate
functions instead.

3) AIX5 uses differently named types for representing sigset_t,
struct sigaction, and struct siginfo. In addition, due to the
fact that system call numbers are represented differently, the
premptyset, praddset, prdelset, and prismember macros (which are
also used to query/modify signal sets) no longer work for sets of
system calls. AIX5 has added macros for this. They are
premptysysset, praddsysset, prdelsysset, and prissyssetmember.

Fortunately, the changes needed for accomodating these differences
were fairly mechanical. But they still bulk up the final patch.

I have tested this patch on sparc-sun-solaris2.7 and
ia64-unknown-aix5.0 and see no ill effects. I would also like to test
it on Unixware, but do not have access to a Unixware machine at the
moment. As soon as my access to a Unixware machine is restored, I
will test this patch there too.

It's not clear to me who it is that needs to approve these changes;
Initially, I assumed it was Michael Snyder and/or David Taylor since
they are listed as the Solaris/SPARC maintainers. But, now that I
look at the list again, I also see that Nick Duffek and Peter Schauer
are listed as the Solaris/x86 maintainers. Also, Nick and Robert Lipe
are listed as the Unixware maintainers, and as noted earlier, these
changes will likely affect Unixware native support.

Anyway, I would appreciate it if one or more of these gentlemen would
look over the patches below and give approval (or not) as you see fit.

Thanks,

Kevin

* proc-utils.h (procfs_ctl_t): New typedef.
* proc-api.c (write_with_trace): Change type of ``opcode'' from
long to procfs_ctl_t. Don't assume that the target has defined
BREAKPOINT. Handle case in which PCRESET is the same as PCUNSET.
* proc-events.c (sys/syscall.h, sys/fault.h): Include these
files.
* procfs.c (sys/fault.h, sys/syscall.h): Include.
(SYSENT_PROC_NAME_FMT): Define.
(gdb_sigset_t, gdb_premptysysset, gdb_praddsysset, gdb_prdelsysset,
gdb_pr_issyssetmember, sigaction, siginfo): Conditionally
define as appropriate for AIX/non-AIX systems. Use these defines
as appropriate elsewhere in file.
(struct procinfo): Change type of saved_sigset and saved_sighold
from sigset_t to gdb_sigset_t. Make saved_exitset and
saved_entryset pointer variables. Add two new fields, num_syscalls
and syscall_names.
(DYNAMIC_SYSCALLS): Define when HAVE_PRSYSENT_T is defined.
(sysset_t_size, sysset_t_alloc): New functions.
(load_syscalls, free_syscalls, find_syscall): New functions for
platforms which define DYNAMIC_SYSCALLS.
(create_procinfo): Call load_syscalls.
(destroy_one_procinfo): Call free_syscalls.
(GDBRESET): Don't define twice.
(proc_modify_flag): Change type of operation code array `arg'
from long to procfs_ctl_t.
(proc_stop_process, proc_wait_for_stop, proc_run_process)
(proc_set_traced_signals, proc_set_traced_faults)
(proc_set_traced_sysentry, proc_set_traced_sysexit)
(proc_set_held_signals, proc_clear_current_fault)
(proc_set_current_signal, proc_clear_current_signal, proc_set_gregs)
(proc_set_fpregs, proc_kill, proc_set_watchpoint): Likewise for `cmd'.
(proc_set_traced_sysentry): Dynamically allocate variable sized
struct gdb_proc_ctl_pcsentry. Also, free it at function exit.
(proc_set_traced_sysexit): Dynamically allocate variable
sized struct gdb_proc_ctl_pcsexit. Also, free it at
function exit.
(proc_get_traced_sysentry, proc_get_traced_sysexit): Add new code
for reading the sysset_t struct on AIX5.
(procfs_debug_inferior): Don't assume that SYS_exit will be
defined. Add new code for finding certain syscalls on AIX5.
(syscall_is_lwp_exit, syscall_is_exit, syscall_is_exec)
(syscall_is_lwp_create): New functions.
(procfs_wait): Restructured code which checks for certain
system calls to use the new syscall_is_... functions.
(procfs_notice_signals): Account for the fact that saved_entryset
and saved_exitset in struct procinfo are now pointers.
(procfs_xfer_memory): Update declaration to include the
struct mem_attrib * parameter.

Index: proc-api.c
===================================================================
RCS file: /cvs/src/src/gdb/proc-api.c,v
retrieving revision 1.7
diff -u -p -r1.7 proc-api.c
--- proc-api.c 2001/02/19 11:47:16 1.7
+++ proc-api.c 2001/03/06 01:32:36
@@ -446,12 +446,12 @@ write_with_trace (int fd, void *varg, si
{
int i;
int ret;
- long *arg = (long *) varg;
+ procfs_ctl_t *arg = (procfs_ctl_t *) varg;

prepare_to_trace ();
if (procfs_trace)
{
- long opcode = arg[0];
+ procfs_ctl_t opcode = arg[0];
for (i = 0; rw_table[i].name != NULL; i++)
if (rw_table[i].value == opcode)
break;
@@ -475,8 +475,10 @@ write_with_trace (int fd, void *varg, si
case PCUNSET:
#endif
#ifdef PCRESET
+#if PCRESET != PCUNSET
case PCRESET:
#endif
+#endif
fprintf (procfs_file ? procfs_file : stdout,
"write (PCRESET, %s) %s\n",
arg[1] == PR_FORK ? "PR_FORK" :
@@ -551,6 +553,7 @@ write_with_trace (int fd, void *varg, si
break;
default:
{
+#ifdef BREAKPOINT
static unsigned char break_insn[] = BREAKPOINT;

if (len == sizeof (break_insn) &&
@@ -558,7 +561,9 @@ write_with_trace (int fd, void *varg, si
fprintf (procfs_file ? procfs_file : stdout,
"write (<breakpoint at 0x%08lx>) \n",
(unsigned long) lseek_offset);
- else if (rw_table[i].name)
+ else
+#endif
+ if (rw_table[i].name)
fprintf (procfs_file ? procfs_file : stdout,
"write (%s) %s\n",
rw_table[i].name,
Index: proc-events.c
===================================================================
RCS file: /cvs/src/src/gdb/proc-events.c,v
retrieving revision 1.3
diff -u -p -r1.3 proc-events.c
--- proc-events.c 2000/07/30 01:48:26 1.3
+++ proc-events.c 2001/03/06 01:32:38
@@ -40,8 +40,12 @@ Inc., 59 Temple Place - Suite 330, Bosto
#include <stdio.h>
#include <sys/types.h>
#include <sys/procfs.h>
+#ifdef HAVE_SYS_SYSCALL_H
#include <sys/syscall.h>
+#endif
+#ifdef HAVE_SYS_FAULT_H
#include <sys/fault.h>
+#endif

/* Much of the information used in the /proc interface, particularly for
printing status information, is kept as tables of structures of the
Index: proc-utils.h
===================================================================
RCS file: /cvs/src/src/gdb/proc-utils.h,v
retrieving revision 1.3
diff -u -p -r1.3 proc-utils.h
--- proc-utils.h 2000/05/07 23:09:45 1.3
+++ proc-utils.h 2001/03/06 01:32:38
@@ -92,3 +92,11 @@ extern void procfs_note (char *,
#define PROCFS_NOTE(X) procfs_note (X, __FILE__, __LINE__)
#define PROC_PRETTYFPRINT_STATUS(X,Y,Z,T) \
proc_prettyfprint_status (X, Y, Z, T)
+
+/* Define the type (and more importantly the width) of the control
+ word used to write to the /proc/PID/ctl file. */
+#if defined (PROC_CTL_WORD_TYPE)
+typedef PROC_CTL_WORD_TYPE procfs_ctl_t;
+#else
+typedef long procfs_ctl_t;
+#endif
Index: procfs.c
===================================================================
RCS file: /cvs/src/src/gdb/procfs.c,v
retrieving revision 1.22
diff -u -p -r1.22 procfs.c
--- procfs.c 2001/01/16 17:41:51 1.22
+++ procfs.c 2001/03/06 01:32:44
@@ -31,8 +31,12 @@ Inc., 59 Temple Place - Suite 330, Bosto
#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>
@@ -49,6 +53,7 @@ Inc., 59 Temple Place - Suite 330, Bosto
* 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
@@ -114,7 +119,8 @@ static void procfs_mourn_inferior (void)
static void procfs_create_inferior (char *, char *, char **);
static int procfs_wait (int, struct target_waitstatus *);
static int procfs_xfer_memory (CORE_ADDR,
- char *, int, int, struct target_ops *);
+ char *, int, int, struct mem_attrib *,
+ struct target_ops *);

static int procfs_thread_alive (int);

@@ -179,7 +185,7 @@ init_procfs_ops (void)
*/

#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,
@@ -194,9 +200,68 @@ init_procfs_ops (void)
};
#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
+#define sigaction pr_sigaction64
+#endif
+
+/* siginfo */
+#ifdef HAVE_PR_SIGINFO64_T
+#define siginfo pr_siginfo64
+#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
+
+
+
/* =================== STRUCT PROCINFO "MODULE" =================== */

/* FIXME: this comment will soon be out of date W.R.T. threads. */
@@ -246,6 +311,7 @@ typedef prstatus_t gdb_prstatus_t;
typedef prstatus_t gdb_lwpstatus_t;
#endif /* NEW_PROC_API */

+
/* Provide default composite pid manipulation macros for systems that
don't have threads. */

@@ -284,16 +350,21 @@ typedef struct procinfo {
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;

@@ -315,6 +386,13 @@ static void do_destroy_procinfo_cleanup
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;
@@ -565,6 +643,10 @@ create_procinfo (int pid, int tid)
pi->pid = pid;
pi->tid = tid;

+#ifdef DYNAMIC_SYSCALLS
+ load_syscalls (pi);
+#endif
+
/* Chain into list. */
if (tid == 0)
{
@@ -631,6 +713,9 @@ destroy_one_procinfo (procinfo **list, p
close_procinfo_files (pi);

/* Step three: free the memory. */
+#ifdef DYNAMIC_SYSCALLS
+ free_syscalls (pi);
+#endif
xfree (pi);
}

@@ -691,6 +776,190 @@ dead_procinfo (procinfo *pi, char *msg,
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 (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" =================== */
@@ -731,11 +1000,11 @@ 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, sigset_t * sighold);
+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, sigset_t * sigset);
+int proc_set_traced_signals (procinfo * pi, gdb_sigset_t * sigset);

int proc_update_threads (procinfo * pi);
int proc_iterate_over_threads (procinfo * pi,
@@ -747,9 +1016,9 @@ gdb_fpregset_t *proc_get_fpregs (procinf
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);
-sigset_t *proc_get_traced_signals (procinfo * pi, sigset_t * save);
-sigset_t *proc_get_held_signals (procinfo * pi, sigset_t * save);
-sigset_t *proc_get_pending_signals (procinfo * pi, sigset_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);
struct sigaction *proc_get_signal_actions (procinfo * pi,
struct sigaction *save);

@@ -1081,12 +1350,13 @@ proc_modify_flag (procinfo *pi, long fla
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;
@@ -1312,7 +1582,7 @@ proc_stop_process (procinfo *pi)
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);
@@ -1355,7 +1625,7 @@ proc_wait_for_stop (procinfo *pi)

#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;
@@ -1429,7 +1699,7 @@ proc_run_process (procinfo *pi, int step

#ifdef NEW_PROC_API
{
- long cmd[2];
+ procfs_ctl_t cmd[2];

cmd[0] = PCRUN;
cmd[1] = runflags;
@@ -1456,7 +1726,7 @@ proc_run_process (procinfo *pi, int step
*/

int
-proc_set_traced_signals (procinfo *pi, sigset_t *sigset)
+proc_set_traced_signals (procinfo *pi, gdb_sigset_t *sigset)
{
int win;

@@ -1473,13 +1743,13 @@ proc_set_traced_signals (procinfo *pi, s
#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));
}
@@ -1519,7 +1789,7 @@ proc_set_traced_faults (procinfo *pi, fl
#ifdef NEW_PROC_API
{
struct {
- long cmd;
+ procfs_ctl_t cmd;
/* Use char array to avoid alignment issues. */
char fltset[sizeof (fltset_t)];
} arg;
@@ -1562,16 +1832,22 @@ proc_set_traced_sysentry (procinfo *pi,

#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);
@@ -1606,16 +1882,22 @@ proc_set_traced_sysexit (procinfo *pi, s

#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);
@@ -1634,7 +1916,7 @@ proc_set_traced_sysexit (procinfo *pi, s
*/

int
-proc_set_held_signals (procinfo *pi, sigset_t *sighold)
+proc_set_held_signals (procinfo *pi, gdb_sigset_t *sighold)
{
int win;

@@ -1651,13 +1933,13 @@ proc_set_held_signals (procinfo *pi, sig
#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
@@ -1676,10 +1958,10 @@ proc_set_held_signals (procinfo *pi, sig
* Will also copy the sigset if 'save' is non-zero.
*/

-sigset_t *
-proc_get_pending_signals (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
@@ -1701,7 +1983,7 @@ proc_get_pending_signals (procinfo *pi,
ret = &pi->prstatus.pr_sigpend;
#endif
if (save && ret)
- memcpy (save, ret, sizeof (sigset_t));
+ memcpy (save, ret, sizeof (gdb_sigset_t));

return ret;
}
@@ -1750,10 +2032,10 @@ proc_get_signal_actions (procinfo *pi, s
* Will also copy the sigset if 'save' is non-zero.
*/

-sigset_t *
-proc_get_held_signals (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
@@ -1777,14 +2059,14 @@ proc_get_held_signals (procinfo *pi, sig
#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;
}
@@ -1796,10 +2078,10 @@ proc_get_held_signals (procinfo *pi, sig
* Will also copy the sigset if 'save' is non-zero.
*/

-sigset_t *
-proc_get_traced_signals (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
@@ -1819,14 +2101,14 @@ proc_get_traced_signals (procinfo *pi, s
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;
}
@@ -1841,7 +2123,7 @@ proc_get_traced_signals (procinfo *pi, s
int
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
@@ -1875,7 +2157,7 @@ proc_trace_signal (procinfo *pi, int sig
int
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
@@ -1968,17 +2250,48 @@ proc_get_traced_sysentry (procinfo *pi,
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;
}
@@ -2010,7 +2323,37 @@ proc_get_traced_sysexit (procinfo *pi, s
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;
@@ -2020,7 +2363,7 @@ proc_get_traced_sysexit (procinfo *pi, s
}
#endif
if (save && ret)
- memcpy (save, ret, sizeof (sysset_t));
+ memcpy (save, ret, sysset_t_size (pi));

return ret;
}
@@ -2050,7 +2393,7 @@ proc_clear_current_fault (procinfo *pi)

#ifdef NEW_PROC_API
{
- long cmd = PCCFAULT;
+ procfs_ctl_t cmd = PCCFAULT;
win = (write (pi->ctl_fd, (void *) &cmd, sizeof (cmd)) == sizeof (cmd));
}
#else
@@ -2078,7 +2421,7 @@ proc_set_current_signal (procinfo *pi, i
{
int win;
struct {
- long cmd;
+ procfs_ctl_t cmd;
/* Use char array to avoid alignment issues. */
char sinfo[sizeof (struct siginfo)];
} arg;
@@ -2147,7 +2490,7 @@ proc_clear_current_signal (procinfo *pi)
#ifdef NEW_PROC_API
{
struct {
- long cmd;
+ procfs_ctl_t cmd;
/* Use char array to avoid alignment issues. */
char sinfo[sizeof (struct siginfo)];
} arg;
@@ -2304,7 +2647,7 @@ proc_set_gregs (procinfo *pi)
{
#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;
@@ -2347,7 +2690,7 @@ proc_set_fpregs (procinfo *pi)
{
#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;
@@ -2409,7 +2752,7 @@ proc_kill (procinfo *pi, int signo)
else
{
#ifdef NEW_PROC_API
- long cmd[2];
+ procfs_ctl_t cmd[2];

cmd[0] = PCKILL;
cmd[1] = signo;
@@ -2468,7 +2811,7 @@ proc_set_watchpoint (procinfo *pi, CORE_
return 0;
#else
struct {
- long cmd;
+ procfs_ctl_t cmd;
char watch[sizeof (prwatch_t)];
} arg;
prwatch_t *pwatch;
@@ -3074,7 +3417,7 @@ proc_iterate_over_threads (procinfo *pi,

static int do_attach (int pid);
static void do_detach (int signo);
-static int register_gdb_signals (procinfo *, sigset_t *);
+static int register_gdb_signals (procinfo *, gdb_sigset_t *);

/*
* Function: procfs_debug_inferior
@@ -3091,9 +3434,10 @@ static int
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.
@@ -3113,17 +3457,30 @@ procfs_debug_inferior (procinfo *pi)
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 */
@@ -3149,29 +3506,42 @@ procfs_debug_inferior (procinfo *pi)
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 */
@@ -3270,10 +3640,10 @@ do_attach (int pid)
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))
@@ -3304,10 +3674,10 @@ do_detach (int signo)
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))
@@ -3463,6 +3833,73 @@ procfs_store_registers (int regno)
}
}

+static int
+syscall_is_lwp_exit (procinfo *pi, int scall)
+{
+
+#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;
+}
+
/*
* Function: target_wait
*
@@ -3566,194 +4003,162 @@ wait_again:
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_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;
+ }
}
-#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);
-
- 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 */
+ 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]);
+ }

-#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_pid;
+ }
+ else
+ {
+ /* How to keep going without returning to wfi: */
+ target_resume (pid, 0, TARGET_SIGNAL_0);
+ goto wait_again;
+ }
+ }
+ break;
+ case PR_SYSEXIT:
+ if (syscall_is_exec (pi, what))
{
- long i, nsysargs, *sysargs;
+ /* 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))
+ {
+ /*
+ * 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 ((nsysargs = proc_nsysarg (pi)) > 0 &&
- (sysargs = proc_sysargs (pi)) != NULL)
+ /* 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 = MERGEPID (pi->pid, temp);
+ /* If not in GDB's thread list, add it. */
+ if (!in_thread_list (temp))
{
- 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));
+ add_thread (temp);
}
+ /* Return to WFI, but tell it to immediately resume. */
+ status->kind = TARGET_WAITKIND_SPURIOUS;
+ return inferior_pid;
+ }
+ 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_pid;
+ }
break;
case PR_REQUESTED:
#if 0 /* FIXME */
@@ -3909,7 +4314,7 @@ wait_again:

static int
procfs_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int dowrite,
- struct target_ops *target)
+ struct mem_attrib *attrib, struct target_ops *target)
{
procinfo *pi;
int nbytes = 0;
@@ -4143,7 +4548,7 @@ procfs_resume (int pid, int step, enum t
*/

static int
-register_gdb_signals (procinfo *pi, sigset_t *signals)
+register_gdb_signals (procinfo *pi, gdb_sigset_t *signals)
{
int signo;

@@ -4167,7 +4572,7 @@ register_gdb_signals (procinfo *pi, sigs
static void
procfs_notice_signals (int pid)
{
- sigset_t signals;
+ gdb_sigset_t signals;
procinfo *pi = find_procinfo_or_die (PIDGET (pid), 0);

if (proc_get_traced_signals (pi, &signals) &&
@@ -4366,7 +4771,7 @@ static void
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)
@@ -4406,9 +4811,9 @@ procfs_init_inferior (int pid)
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. */
@@ -4460,7 +4865,7 @@ procfs_set_exec_trap (void)
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.");
@@ -4503,18 +4908,31 @@ procfs_set_exec_trap (void)
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 (callnum >= 0)
+ gdb_praddsysset (exitset, callnum);

- if (!proc_set_traced_sysexit (pi, &exitset))
+ 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);
@@ -4738,6 +5156,7 @@ int
procfs_set_watchpoint (int pid, CORE_ADDR addr, int len, int rwflag, int after)
{
#ifndef UNIXWARE
+#ifndef AIX5
int pflags = 0;
procinfo *pi;

@@ -4777,7 +5196,8 @@ procfs_set_watchpoint (int pid, CORE_ADD
return 0; /* ignore */
proc_error (pi, "set_watchpoint", __LINE__);
}
-#endif
+#endif /* AIX5 */
+#endif /* UNIXWARE */
return 0;
}

@@ -4964,9 +5384,9 @@ proc_trace_syscalls (char *args, int fro
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)
{