1130812Smarcel/* Machine independent support for SVR4 /proc (process file system) for GDB.
2130812Smarcel
3130812Smarcel   Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation,
4130812Smarcel   Inc.
5130812Smarcel
6130812Smarcel   Written by Michael Snyder at Cygnus Solutions.
7130812Smarcel   Based on work by Fred Fish, Stu Grossman, Geoff Noer, and others.
8130812Smarcel
9130812SmarcelThis file is part of GDB.
10130812Smarcel
11130812SmarcelThis program is free software; you can redistribute it and/or modify
12130812Smarcelit under the terms of the GNU General Public License as published by
13130812Smarcelthe Free Software Foundation; either version 2 of the License, or
14130812Smarcel(at your option) any later version.
15130812Smarcel
16130812SmarcelThis program is distributed in the hope that it will be useful,
17130812Smarcelbut WITHOUT ANY WARRANTY; without even the implied warranty of
18130812SmarcelMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19130812SmarcelGNU General Public License for more details.
20130812Smarcel
21130812SmarcelYou should have received a copy of the GNU General Public License
22130812Smarcelalong with this program; if not, write to the Free Software Foundation,
23130812SmarcelInc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
24130812Smarcel
25130812Smarcel#include "defs.h"
26130812Smarcel#include "inferior.h"
27130812Smarcel#include "target.h"
28130812Smarcel#include "gdbcore.h"
29130812Smarcel#include "elf-bfd.h"		/* for elfcore_write_* */
30130812Smarcel#include "gdbcmd.h"
31130812Smarcel#include "gdbthread.h"
32130812Smarcel
33130812Smarcel#if defined (NEW_PROC_API)
34130812Smarcel#define _STRUCTURED_PROC 1	/* Should be done by configure script. */
35130812Smarcel#endif
36130812Smarcel
37130812Smarcel#include <sys/procfs.h>
38130812Smarcel#ifdef HAVE_SYS_FAULT_H
39130812Smarcel#include <sys/fault.h>
40130812Smarcel#endif
41130812Smarcel#ifdef HAVE_SYS_SYSCALL_H
42130812Smarcel#include <sys/syscall.h>
43130812Smarcel#endif
44130812Smarcel#include <sys/errno.h>
45130812Smarcel#include "gdb_wait.h"
46130812Smarcel#include <signal.h>
47130812Smarcel#include <ctype.h>
48130812Smarcel#include "gdb_string.h"
49130812Smarcel#include "gdb_assert.h"
50130812Smarcel#include "inflow.h"
51130812Smarcel#include "auxv.h"
52130812Smarcel
53130812Smarcel/*
54130812Smarcel * PROCFS.C
55130812Smarcel *
56130812Smarcel * This module provides the interface between GDB and the
57130812Smarcel * /proc file system, which is used on many versions of Unix
58130812Smarcel * as a means for debuggers to control other processes.
59130812Smarcel * Examples of the systems that use this interface are:
60130812Smarcel *   Irix
61130812Smarcel *   Solaris
62130812Smarcel *   OSF
63130812Smarcel *   Unixware
64130812Smarcel *   AIX5
65130812Smarcel *
66130812Smarcel * /proc works by imitating a file system: you open a simulated file
67130812Smarcel * that represents the process you wish to interact with, and
68130812Smarcel * perform operations on that "file" in order to examine or change
69130812Smarcel * the state of the other process.
70130812Smarcel *
71130812Smarcel * The most important thing to know about /proc and this module
72130812Smarcel * is that there are two very different interfaces to /proc:
73130812Smarcel *   One that uses the ioctl system call, and
74130812Smarcel *   another that uses read and write system calls.
75130812Smarcel * This module has to support both /proc interfaces.  This means
76130812Smarcel * that there are two different ways of doing every basic operation.
77130812Smarcel *
78130812Smarcel * In order to keep most of the code simple and clean, I have
79130812Smarcel * defined an interface "layer" which hides all these system calls.
80130812Smarcel * An ifdef (NEW_PROC_API) determines which interface we are using,
81130812Smarcel * and most or all occurrances of this ifdef should be confined to
82130812Smarcel * this interface layer.
83130812Smarcel */
84130812Smarcel
85130812Smarcel
86130812Smarcel/* Determine which /proc API we are using:
87130812Smarcel   The ioctl API defines PIOCSTATUS, while
88130812Smarcel   the read/write (multiple fd) API never does.  */
89130812Smarcel
90130812Smarcel#ifdef NEW_PROC_API
91130812Smarcel#include <sys/types.h>
92130812Smarcel#include "gdb_dirent.h"	/* opendir/readdir, for listing the LWP's */
93130812Smarcel#endif
94130812Smarcel
95130812Smarcel#include <fcntl.h>	/* for O_RDONLY */
96130812Smarcel#include <unistd.h>	/* for "X_OK" */
97130812Smarcel#include "gdb_stat.h"	/* for struct stat */
98130812Smarcel
99130812Smarcel/* Note: procfs-utils.h must be included after the above system header
100130812Smarcel   files, because it redefines various system calls using macros.
101130812Smarcel   This may be incompatible with the prototype declarations.  */
102130812Smarcel
103130812Smarcel#include "proc-utils.h"
104130812Smarcel
105130812Smarcel/* Prototypes for supply_gregset etc. */
106130812Smarcel#include "gregset.h"
107130812Smarcel
108130812Smarcel/* =================== TARGET_OPS "MODULE" =================== */
109130812Smarcel
110130812Smarcel/*
111130812Smarcel * This module defines the GDB target vector and its methods.
112130812Smarcel */
113130812Smarcel
114130812Smarcelstatic void procfs_open (char *, int);
115130812Smarcelstatic void procfs_attach (char *, int);
116130812Smarcelstatic void procfs_detach (char *, int);
117130812Smarcelstatic void procfs_resume (ptid_t, int, enum target_signal);
118130812Smarcelstatic int procfs_can_run (void);
119130812Smarcelstatic void procfs_stop (void);
120130812Smarcelstatic void procfs_files_info (struct target_ops *);
121130812Smarcelstatic void procfs_fetch_registers (int);
122130812Smarcelstatic void procfs_store_registers (int);
123130812Smarcelstatic void procfs_notice_signals (ptid_t);
124130812Smarcelstatic void procfs_prepare_to_store (void);
125130812Smarcelstatic void procfs_kill_inferior (void);
126130812Smarcelstatic void procfs_mourn_inferior (void);
127130812Smarcelstatic void procfs_create_inferior (char *, char *, char **);
128130812Smarcelstatic ptid_t procfs_wait (ptid_t, struct target_waitstatus *);
129130812Smarcelstatic int procfs_xfer_memory (CORE_ADDR, char *, int, int,
130130812Smarcel			       struct mem_attrib *attrib,
131130812Smarcel			       struct target_ops *);
132130812Smarcelstatic LONGEST procfs_xfer_partial (struct target_ops *ops,
133130812Smarcel				    enum target_object object,
134130812Smarcel				    const char *annex,
135130812Smarcel				    void *readbuf, const void *writebuf,
136130812Smarcel				    ULONGEST offset, LONGEST len);
137130812Smarcel
138130812Smarcelstatic int procfs_thread_alive (ptid_t);
139130812Smarcel
140130812Smarcelvoid procfs_find_new_threads (void);
141130812Smarcelchar *procfs_pid_to_str (ptid_t);
142130812Smarcel
143130812Smarcelstatic int proc_find_memory_regions (int (*) (CORE_ADDR,
144130812Smarcel					      unsigned long,
145130812Smarcel					      int, int, int,
146130812Smarcel					      void *),
147130812Smarcel				     void *);
148130812Smarcel
149130812Smarcelstatic char * procfs_make_note_section (bfd *, int *);
150130812Smarcel
151130812Smarcelstatic int procfs_can_use_hw_breakpoint (int, int, int);
152130812Smarcel
153130812Smarcelstruct target_ops procfs_ops;		/* the target vector */
154130812Smarcel
155130812Smarcelstatic void
156130812Smarcelinit_procfs_ops (void)
157130812Smarcel{
158130812Smarcel  procfs_ops.to_shortname           = "procfs";
159130812Smarcel  procfs_ops.to_longname            = "Unix /proc child process";
160130812Smarcel  procfs_ops.to_doc                 =
161130812Smarcel    "Unix /proc child process (started by the \"run\" command).";
162130812Smarcel  procfs_ops.to_open                = procfs_open;
163130812Smarcel  procfs_ops.to_can_run             = procfs_can_run;
164130812Smarcel  procfs_ops.to_create_inferior     = procfs_create_inferior;
165130812Smarcel  procfs_ops.to_kill                = procfs_kill_inferior;
166130812Smarcel  procfs_ops.to_mourn_inferior      = procfs_mourn_inferior;
167130812Smarcel  procfs_ops.to_attach              = procfs_attach;
168130812Smarcel  procfs_ops.to_detach              = procfs_detach;
169130812Smarcel  procfs_ops.to_wait                = procfs_wait;
170130812Smarcel  procfs_ops.to_resume              = procfs_resume;
171130812Smarcel  procfs_ops.to_prepare_to_store    = procfs_prepare_to_store;
172130812Smarcel  procfs_ops.to_fetch_registers     = procfs_fetch_registers;
173130812Smarcel  procfs_ops.to_store_registers     = procfs_store_registers;
174130812Smarcel  procfs_ops.to_xfer_partial        = procfs_xfer_partial;
175130812Smarcel  procfs_ops.to_xfer_memory         = procfs_xfer_memory;
176130812Smarcel  procfs_ops.to_insert_breakpoint   =  memory_insert_breakpoint;
177130812Smarcel  procfs_ops.to_remove_breakpoint   =  memory_remove_breakpoint;
178130812Smarcel  procfs_ops.to_notice_signals      = procfs_notice_signals;
179130812Smarcel  procfs_ops.to_files_info          = procfs_files_info;
180130812Smarcel  procfs_ops.to_stop                = procfs_stop;
181130812Smarcel
182130812Smarcel  procfs_ops.to_terminal_init       = terminal_init_inferior;
183130812Smarcel  procfs_ops.to_terminal_inferior   = terminal_inferior;
184130812Smarcel  procfs_ops.to_terminal_ours_for_output = terminal_ours_for_output;
185130812Smarcel  procfs_ops.to_terminal_ours       = terminal_ours;
186130812Smarcel  procfs_ops.to_terminal_save_ours  = terminal_save_ours;
187130812Smarcel  procfs_ops.to_terminal_info       = child_terminal_info;
188130812Smarcel
189130812Smarcel  procfs_ops.to_find_new_threads    = procfs_find_new_threads;
190130812Smarcel  procfs_ops.to_thread_alive        = procfs_thread_alive;
191130812Smarcel  procfs_ops.to_pid_to_str          = procfs_pid_to_str;
192130812Smarcel
193130812Smarcel  procfs_ops.to_has_all_memory      = 1;
194130812Smarcel  procfs_ops.to_has_memory          = 1;
195130812Smarcel  procfs_ops.to_has_execution       = 1;
196130812Smarcel  procfs_ops.to_has_stack           = 1;
197130812Smarcel  procfs_ops.to_has_registers       = 1;
198130812Smarcel  procfs_ops.to_stratum             = process_stratum;
199130812Smarcel  procfs_ops.to_has_thread_control  = tc_schedlock;
200130812Smarcel  procfs_ops.to_find_memory_regions = proc_find_memory_regions;
201130812Smarcel  procfs_ops.to_make_corefile_notes = procfs_make_note_section;
202130812Smarcel  procfs_ops.to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint;
203130812Smarcel  procfs_ops.to_magic               = OPS_MAGIC;
204130812Smarcel}
205130812Smarcel
206130812Smarcel/* =================== END, TARGET_OPS "MODULE" =================== */
207130812Smarcel
208130812Smarcel/*
209130812Smarcel * World Unification:
210130812Smarcel *
211130812Smarcel * Put any typedefs, defines etc. here that are required for
212130812Smarcel * the unification of code that handles different versions of /proc.
213130812Smarcel */
214130812Smarcel
215130812Smarcel#ifdef NEW_PROC_API		/* Solaris 7 && 8 method for watchpoints */
216130812Smarcel#ifdef WA_READ
217130812Smarcel     enum { READ_WATCHFLAG  = WA_READ,
218130812Smarcel	    WRITE_WATCHFLAG = WA_WRITE,
219130812Smarcel	    EXEC_WATCHFLAG  = WA_EXEC,
220130812Smarcel	    AFTER_WATCHFLAG = WA_TRAPAFTER
221130812Smarcel     };
222130812Smarcel#endif
223130812Smarcel#else				/* Irix method for watchpoints */
224130812Smarcel     enum { READ_WATCHFLAG  = MA_READ,
225130812Smarcel	    WRITE_WATCHFLAG = MA_WRITE,
226130812Smarcel	    EXEC_WATCHFLAG  = MA_EXEC,
227130812Smarcel	    AFTER_WATCHFLAG = 0		/* trapafter not implemented */
228130812Smarcel     };
229130812Smarcel#endif
230130812Smarcel
231130812Smarcel/* gdb_sigset_t */
232130812Smarcel#ifdef HAVE_PR_SIGSET_T
233130812Smarceltypedef pr_sigset_t gdb_sigset_t;
234130812Smarcel#else
235130812Smarceltypedef sigset_t gdb_sigset_t;
236130812Smarcel#endif
237130812Smarcel
238130812Smarcel/* sigaction */
239130812Smarcel#ifdef HAVE_PR_SIGACTION64_T
240130812Smarceltypedef pr_sigaction64_t gdb_sigaction_t;
241130812Smarcel#else
242130812Smarceltypedef struct sigaction gdb_sigaction_t;
243130812Smarcel#endif
244130812Smarcel
245130812Smarcel/* siginfo */
246130812Smarcel#ifdef HAVE_PR_SIGINFO64_T
247130812Smarceltypedef pr_siginfo64_t gdb_siginfo_t;
248130812Smarcel#else
249130812Smarceltypedef struct siginfo gdb_siginfo_t;
250130812Smarcel#endif
251130812Smarcel
252130812Smarcel/* gdb_premptysysset */
253130812Smarcel#ifdef premptysysset
254130812Smarcel#define gdb_premptysysset premptysysset
255130812Smarcel#else
256130812Smarcel#define gdb_premptysysset premptyset
257130812Smarcel#endif
258130812Smarcel
259130812Smarcel/* praddsysset */
260130812Smarcel#ifdef praddsysset
261130812Smarcel#define gdb_praddsysset praddsysset
262130812Smarcel#else
263130812Smarcel#define gdb_praddsysset praddset
264130812Smarcel#endif
265130812Smarcel
266130812Smarcel/* prdelsysset */
267130812Smarcel#ifdef prdelsysset
268130812Smarcel#define gdb_prdelsysset prdelsysset
269130812Smarcel#else
270130812Smarcel#define gdb_prdelsysset prdelset
271130812Smarcel#endif
272130812Smarcel
273130812Smarcel/* prissyssetmember */
274130812Smarcel#ifdef prissyssetmember
275130812Smarcel#define gdb_pr_issyssetmember prissyssetmember
276130812Smarcel#else
277130812Smarcel#define gdb_pr_issyssetmember prismember
278130812Smarcel#endif
279130812Smarcel
280130812Smarcel/* As a feature test, saying ``#if HAVE_PRSYSENT_T'' everywhere isn't
281130812Smarcel   as intuitively descriptive as it could be, so we'll define
282130812Smarcel   DYNAMIC_SYSCALLS to mean the same thing.  Anyway, at the time of
283130812Smarcel   this writing, this feature is only found on AIX5 systems and
284130812Smarcel   basically means that the set of syscalls is not fixed.  I.e,
285130812Smarcel   there's no nice table that one can #include to get all of the
286130812Smarcel   syscall numbers.  Instead, they're stored in /proc/PID/sysent
287130812Smarcel   for each process.  We are at least guaranteed that they won't
288130812Smarcel   change over the lifetime of the process.  But each process could
289130812Smarcel   (in theory) have different syscall numbers.
290130812Smarcel*/
291130812Smarcel#ifdef HAVE_PRSYSENT_T
292130812Smarcel#define DYNAMIC_SYSCALLS
293130812Smarcel#endif
294130812Smarcel
295130812Smarcel
296130812Smarcel
297130812Smarcel/* =================== STRUCT PROCINFO "MODULE" =================== */
298130812Smarcel
299130812Smarcel     /* FIXME: this comment will soon be out of date W.R.T. threads.  */
300130812Smarcel
301130812Smarcel/* The procinfo struct is a wrapper to hold all the state information
302130812Smarcel   concerning a /proc process.  There should be exactly one procinfo
303130812Smarcel   for each process, and since GDB currently can debug only one
304130812Smarcel   process at a time, that means there should be only one procinfo.
305130812Smarcel   All of the LWP's of a process can be accessed indirectly thru the
306130812Smarcel   single process procinfo.
307130812Smarcel
308130812Smarcel   However, against the day when GDB may debug more than one process,
309130812Smarcel   this data structure is kept in a list (which for now will hold no
310130812Smarcel   more than one member), and many functions will have a pointer to a
311130812Smarcel   procinfo as an argument.
312130812Smarcel
313130812Smarcel   There will be a separate procinfo structure for use by the (not yet
314130812Smarcel   implemented) "info proc" command, so that we can print useful
315130812Smarcel   information about any random process without interfering with the
316130812Smarcel   inferior's procinfo information. */
317130812Smarcel
318130812Smarcel#ifdef NEW_PROC_API
319130812Smarcel/* format strings for /proc paths */
320130812Smarcel# ifndef CTL_PROC_NAME_FMT
321130812Smarcel#  define MAIN_PROC_NAME_FMT   "/proc/%d"
322130812Smarcel#  define CTL_PROC_NAME_FMT    "/proc/%d/ctl"
323130812Smarcel#  define AS_PROC_NAME_FMT     "/proc/%d/as"
324130812Smarcel#  define MAP_PROC_NAME_FMT    "/proc/%d/map"
325130812Smarcel#  define STATUS_PROC_NAME_FMT "/proc/%d/status"
326130812Smarcel#  define MAX_PROC_NAME_SIZE sizeof("/proc/99999/lwp/8096/lstatus")
327130812Smarcel# endif
328130812Smarcel/* the name of the proc status struct depends on the implementation */
329130812Smarceltypedef pstatus_t   gdb_prstatus_t;
330130812Smarceltypedef lwpstatus_t gdb_lwpstatus_t;
331130812Smarcel#else /* ! NEW_PROC_API */
332130812Smarcel/* format strings for /proc paths */
333130812Smarcel# ifndef CTL_PROC_NAME_FMT
334130812Smarcel#  define MAIN_PROC_NAME_FMT   "/proc/%05d"
335130812Smarcel#  define CTL_PROC_NAME_FMT    "/proc/%05d"
336130812Smarcel#  define AS_PROC_NAME_FMT     "/proc/%05d"
337130812Smarcel#  define MAP_PROC_NAME_FMT    "/proc/%05d"
338130812Smarcel#  define STATUS_PROC_NAME_FMT "/proc/%05d"
339130812Smarcel#  define MAX_PROC_NAME_SIZE sizeof("/proc/ttttppppp")
340130812Smarcel# endif
341130812Smarcel/* the name of the proc status struct depends on the implementation */
342130812Smarceltypedef prstatus_t gdb_prstatus_t;
343130812Smarceltypedef prstatus_t gdb_lwpstatus_t;
344130812Smarcel#endif /* NEW_PROC_API */
345130812Smarcel
346130812Smarceltypedef struct procinfo {
347130812Smarcel  struct procinfo *next;
348130812Smarcel  int pid;			/* Process ID    */
349130812Smarcel  int tid;			/* Thread/LWP id */
350130812Smarcel
351130812Smarcel  /* process state */
352130812Smarcel  int was_stopped;
353130812Smarcel  int ignore_next_sigstop;
354130812Smarcel
355130812Smarcel  /* The following four fd fields may be identical, or may contain
356130812Smarcel     several different fd's, depending on the version of /proc
357130812Smarcel     (old ioctl or new read/write).  */
358130812Smarcel
359130812Smarcel  int ctl_fd;			/* File descriptor for /proc control file */
360130812Smarcel  /*
361130812Smarcel   * The next three file descriptors are actually only needed in the
362130812Smarcel   * read/write, multiple-file-descriptor implemenation (NEW_PROC_API).
363130812Smarcel   * However, to avoid a bunch of #ifdefs in the code, we will use
364130812Smarcel   * them uniformly by (in the case of the ioctl single-file-descriptor
365130812Smarcel   * implementation) filling them with copies of the control fd.
366130812Smarcel   */
367130812Smarcel  int status_fd;		/* File descriptor for /proc status file */
368130812Smarcel  int as_fd;			/* File descriptor for /proc as file */
369130812Smarcel
370130812Smarcel  char pathname[MAX_PROC_NAME_SIZE];	/* Pathname to /proc entry */
371130812Smarcel
372130812Smarcel  fltset_t saved_fltset;	/* Saved traced hardware fault set */
373130812Smarcel  gdb_sigset_t saved_sigset;	/* Saved traced signal set */
374130812Smarcel  gdb_sigset_t saved_sighold;	/* Saved held signal set */
375130812Smarcel  sysset_t *saved_exitset;	/* Saved traced system call exit set */
376130812Smarcel  sysset_t *saved_entryset;	/* Saved traced system call entry set */
377130812Smarcel
378130812Smarcel  gdb_prstatus_t prstatus;	/* Current process status info */
379130812Smarcel
380130812Smarcel#ifndef NEW_PROC_API
381130812Smarcel  gdb_fpregset_t fpregset;	/* Current floating point registers */
382130812Smarcel#endif
383130812Smarcel
384130812Smarcel#ifdef DYNAMIC_SYSCALLS
385130812Smarcel  int num_syscalls;		/* Total number of syscalls */
386130812Smarcel  char **syscall_names;		/* Syscall number to name map */
387130812Smarcel#endif
388130812Smarcel
389130812Smarcel  struct procinfo *thread_list;
390130812Smarcel
391130812Smarcel  int status_valid : 1;
392130812Smarcel  int gregs_valid  : 1;
393130812Smarcel  int fpregs_valid : 1;
394130812Smarcel  int threads_valid: 1;
395130812Smarcel} procinfo;
396130812Smarcel
397130812Smarcelstatic char errmsg[128];	/* shared error msg buffer */
398130812Smarcel
399130812Smarcel/* Function prototypes for procinfo module: */
400130812Smarcel
401130812Smarcelstatic procinfo *find_procinfo_or_die (int pid, int tid);
402130812Smarcelstatic procinfo *find_procinfo (int pid, int tid);
403130812Smarcelstatic procinfo *create_procinfo (int pid, int tid);
404130812Smarcelstatic void destroy_procinfo (procinfo * p);
405130812Smarcelstatic void do_destroy_procinfo_cleanup (void *);
406130812Smarcelstatic void dead_procinfo (procinfo * p, char *msg, int killp);
407130812Smarcelstatic int open_procinfo_files (procinfo * p, int which);
408130812Smarcelstatic void close_procinfo_files (procinfo * p);
409130812Smarcelstatic int sysset_t_size (procinfo *p);
410130812Smarcelstatic sysset_t *sysset_t_alloc (procinfo * pi);
411130812Smarcel#ifdef DYNAMIC_SYSCALLS
412130812Smarcelstatic void load_syscalls (procinfo *pi);
413130812Smarcelstatic void free_syscalls (procinfo *pi);
414130812Smarcelstatic int find_syscall (procinfo *pi, char *name);
415130812Smarcel#endif /* DYNAMIC_SYSCALLS */
416130812Smarcel
417130812Smarcel/* The head of the procinfo list: */
418130812Smarcelstatic procinfo * procinfo_list;
419130812Smarcel
420130812Smarcel/*
421130812Smarcel * Function: find_procinfo
422130812Smarcel *
423130812Smarcel * Search the procinfo list.
424130812Smarcel *
425130812Smarcel * Returns: pointer to procinfo, or NULL if not found.
426130812Smarcel */
427130812Smarcel
428130812Smarcelstatic procinfo *
429130812Smarcelfind_procinfo (int pid, int tid)
430130812Smarcel{
431130812Smarcel  procinfo *pi;
432130812Smarcel
433130812Smarcel  for (pi = procinfo_list; pi; pi = pi->next)
434130812Smarcel    if (pi->pid == pid)
435130812Smarcel      break;
436130812Smarcel
437130812Smarcel  if (pi)
438130812Smarcel    if (tid)
439130812Smarcel      {
440130812Smarcel	/* Don't check threads_valid.  If we're updating the
441130812Smarcel	   thread_list, we want to find whatever threads are already
442130812Smarcel	   here.  This means that in general it is the caller's
443130812Smarcel	   responsibility to check threads_valid and update before
444130812Smarcel	   calling find_procinfo, if the caller wants to find a new
445130812Smarcel	   thread. */
446130812Smarcel
447130812Smarcel	for (pi = pi->thread_list; pi; pi = pi->next)
448130812Smarcel	  if (pi->tid == tid)
449130812Smarcel	    break;
450130812Smarcel      }
451130812Smarcel
452130812Smarcel  return pi;
453130812Smarcel}
454130812Smarcel
455130812Smarcel/*
456130812Smarcel * Function: find_procinfo_or_die
457130812Smarcel *
458130812Smarcel * Calls find_procinfo, but errors on failure.
459130812Smarcel */
460130812Smarcel
461130812Smarcelstatic procinfo *
462130812Smarcelfind_procinfo_or_die (int pid, int tid)
463130812Smarcel{
464130812Smarcel  procinfo *pi = find_procinfo (pid, tid);
465130812Smarcel
466130812Smarcel  if (pi == NULL)
467130812Smarcel    {
468130812Smarcel      if (tid)
469130812Smarcel	error ("procfs: couldn't find pid %d (kernel thread %d) in procinfo list.",
470130812Smarcel	       pid, tid);
471130812Smarcel      else
472130812Smarcel	error ("procfs: couldn't find pid %d in procinfo list.", pid);
473130812Smarcel    }
474130812Smarcel  return pi;
475130812Smarcel}
476130812Smarcel
477130812Smarcel/* open_with_retry() is a wrapper for open().  The appropriate
478130812Smarcel   open() call is attempted; if unsuccessful, it will be retried as
479130812Smarcel   many times as needed for the EAGAIN and EINTR conditions.
480130812Smarcel
481130812Smarcel   For other conditions, open_with_retry() will retry the open() a
482130812Smarcel   limited number of times.  In addition, a short sleep is imposed
483130812Smarcel   prior to retrying the open().  The reason for this sleep is to give
484130812Smarcel   the kernel a chance to catch up and create the file in question in
485130812Smarcel   the event that GDB "wins" the race to open a file before the kernel
486130812Smarcel   has created it.  */
487130812Smarcel
488130812Smarcelstatic int
489130812Smarcelopen_with_retry (const char *pathname, int flags)
490130812Smarcel{
491130812Smarcel  int retries_remaining, status;
492130812Smarcel
493130812Smarcel  retries_remaining = 2;
494130812Smarcel
495130812Smarcel  while (1)
496130812Smarcel    {
497130812Smarcel      status = open (pathname, flags);
498130812Smarcel
499130812Smarcel      if (status >= 0 || retries_remaining == 0)
500130812Smarcel	break;
501130812Smarcel      else if (errno != EINTR && errno != EAGAIN)
502130812Smarcel	{
503130812Smarcel	  retries_remaining--;
504130812Smarcel	  sleep (1);
505130812Smarcel	}
506130812Smarcel    }
507130812Smarcel
508130812Smarcel  return status;
509130812Smarcel}
510130812Smarcel
511130812Smarcel/*
512130812Smarcel * Function: open_procinfo_files
513130812Smarcel *
514130812Smarcel * Open the file descriptor for the process or LWP.
515130812Smarcel * ifdef NEW_PROC_API, we only open the control file descriptor;
516130812Smarcel * the others are opened lazily as needed.
517130812Smarcel * else (if not NEW_PROC_API), there is only one real
518130812Smarcel * file descriptor, but we keep multiple copies of it so that
519130812Smarcel * the code that uses them does not have to be #ifdef'd.
520130812Smarcel *
521130812Smarcel * Return: file descriptor, or zero for failure.
522130812Smarcel */
523130812Smarcel
524130812Smarcelenum { FD_CTL, FD_STATUS, FD_AS };
525130812Smarcel
526130812Smarcelstatic int
527130812Smarcelopen_procinfo_files (procinfo *pi, int which)
528130812Smarcel{
529130812Smarcel#ifdef NEW_PROC_API
530130812Smarcel  char tmp[MAX_PROC_NAME_SIZE];
531130812Smarcel#endif
532130812Smarcel  int  fd;
533130812Smarcel
534130812Smarcel  /*
535130812Smarcel   * This function is getting ALMOST long enough to break up into several.
536130812Smarcel   * Here is some rationale:
537130812Smarcel   *
538130812Smarcel   * NEW_PROC_API (Solaris 2.6, Solaris 2.7, Unixware):
539130812Smarcel   *   There are several file descriptors that may need to be open
540130812Smarcel   *   for any given process or LWP.  The ones we're intereted in are:
541130812Smarcel   *     - control	 (ctl)	  write-only	change the state
542130812Smarcel   *     - status	 (status) read-only	query the state
543130812Smarcel   *     - address space (as)     read/write	access memory
544130812Smarcel   *     - map           (map)    read-only     virtual addr map
545130812Smarcel   *   Most of these are opened lazily as they are needed.
546130812Smarcel   *   The pathnames for the 'files' for an LWP look slightly
547130812Smarcel   *   different from those of a first-class process:
548130812Smarcel   *     Pathnames for a process (<proc-id>):
549130812Smarcel   *       /proc/<proc-id>/ctl
550130812Smarcel   *       /proc/<proc-id>/status
551130812Smarcel   *       /proc/<proc-id>/as
552130812Smarcel   *       /proc/<proc-id>/map
553130812Smarcel   *     Pathnames for an LWP (lwp-id):
554130812Smarcel   *       /proc/<proc-id>/lwp/<lwp-id>/lwpctl
555130812Smarcel   *       /proc/<proc-id>/lwp/<lwp-id>/lwpstatus
556130812Smarcel   *   An LWP has no map or address space file descriptor, since
557130812Smarcel   *   the memory map and address space are shared by all LWPs.
558130812Smarcel   *
559130812Smarcel   * Everyone else (Solaris 2.5, Irix, OSF)
560130812Smarcel   *   There is only one file descriptor for each process or LWP.
561130812Smarcel   *   For convenience, we copy the same file descriptor into all
562130812Smarcel   *   three fields of the procinfo struct (ctl_fd, status_fd, and
563130812Smarcel   *   as_fd, see NEW_PROC_API above) so that code that uses them
564130812Smarcel   *   doesn't need any #ifdef's.
565130812Smarcel   *     Pathname for all:
566130812Smarcel   *       /proc/<proc-id>
567130812Smarcel   *
568130812Smarcel   *   Solaris 2.5 LWP's:
569130812Smarcel   *     Each LWP has an independent file descriptor, but these
570130812Smarcel   *     are not obtained via the 'open' system call like the rest:
571130812Smarcel   *     instead, they're obtained thru an ioctl call (PIOCOPENLWP)
572130812Smarcel   *     to the file descriptor of the parent process.
573130812Smarcel   *
574130812Smarcel   *   OSF threads:
575130812Smarcel   *     These do not even have their own independent file descriptor.
576130812Smarcel   *     All operations are carried out on the file descriptor of the
577130812Smarcel   *     parent process.  Therefore we just call open again for each
578130812Smarcel   *     thread, getting a new handle for the same 'file'.
579130812Smarcel   */
580130812Smarcel
581130812Smarcel#ifdef NEW_PROC_API
582130812Smarcel  /*
583130812Smarcel   * In this case, there are several different file descriptors that
584130812Smarcel   * we might be asked to open.  The control file descriptor will be
585130812Smarcel   * opened early, but the others will be opened lazily as they are
586130812Smarcel   * needed.
587130812Smarcel   */
588130812Smarcel
589130812Smarcel  strcpy (tmp, pi->pathname);
590130812Smarcel  switch (which) {	/* which file descriptor to open? */
591130812Smarcel  case FD_CTL:
592130812Smarcel    if (pi->tid)
593130812Smarcel      strcat (tmp, "/lwpctl");
594130812Smarcel    else
595130812Smarcel      strcat (tmp, "/ctl");
596130812Smarcel    fd = open_with_retry (tmp, O_WRONLY);
597130812Smarcel    if (fd <= 0)
598130812Smarcel      return 0;		/* fail */
599130812Smarcel    pi->ctl_fd = fd;
600130812Smarcel    break;
601130812Smarcel  case FD_AS:
602130812Smarcel    if (pi->tid)
603130812Smarcel      return 0;		/* there is no 'as' file descriptor for an lwp */
604130812Smarcel    strcat (tmp, "/as");
605130812Smarcel    fd = open_with_retry (tmp, O_RDWR);
606130812Smarcel    if (fd <= 0)
607130812Smarcel      return 0;		/* fail */
608130812Smarcel    pi->as_fd = fd;
609130812Smarcel    break;
610130812Smarcel  case FD_STATUS:
611130812Smarcel    if (pi->tid)
612130812Smarcel      strcat (tmp, "/lwpstatus");
613130812Smarcel    else
614130812Smarcel      strcat (tmp, "/status");
615130812Smarcel    fd = open_with_retry (tmp, O_RDONLY);
616130812Smarcel    if (fd <= 0)
617130812Smarcel      return 0;		/* fail */
618130812Smarcel    pi->status_fd = fd;
619130812Smarcel    break;
620130812Smarcel  default:
621130812Smarcel    return 0;		/* unknown file descriptor */
622130812Smarcel  }
623130812Smarcel#else  /* not NEW_PROC_API */
624130812Smarcel  /*
625130812Smarcel   * In this case, there is only one file descriptor for each procinfo
626130812Smarcel   * (ie. each process or LWP).  In fact, only the file descriptor for
627130812Smarcel   * the process can actually be opened by an 'open' system call.
628130812Smarcel   * The ones for the LWPs have to be obtained thru an IOCTL call
629130812Smarcel   * on the process's file descriptor.
630130812Smarcel   *
631130812Smarcel   * For convenience, we copy each procinfo's single file descriptor
632130812Smarcel   * into all of the fields occupied by the several file descriptors
633130812Smarcel   * of the NEW_PROC_API implementation.  That way, the code that uses
634130812Smarcel   * them can be written without ifdefs.
635130812Smarcel   */
636130812Smarcel
637130812Smarcel
638130812Smarcel#ifdef PIOCTSTATUS	/* OSF */
639130812Smarcel  /* Only one FD; just open it. */
640130812Smarcel  if ((fd = open_with_retry (pi->pathname, O_RDWR)) == 0)
641130812Smarcel    return 0;
642130812Smarcel#else			/* Sol 2.5, Irix, other? */
643130812Smarcel  if (pi->tid == 0)	/* Master procinfo for the process */
644130812Smarcel    {
645130812Smarcel      fd = open_with_retry (pi->pathname, O_RDWR);
646130812Smarcel      if (fd <= 0)
647130812Smarcel	return 0;	/* fail */
648130812Smarcel    }
649130812Smarcel  else			/* LWP thread procinfo */
650130812Smarcel    {
651130812Smarcel#ifdef PIOCOPENLWP	/* Sol 2.5, thread/LWP */
652130812Smarcel      procinfo *process;
653130812Smarcel      int lwpid = pi->tid;
654130812Smarcel
655130812Smarcel      /* Find the procinfo for the entire process. */
656130812Smarcel      if ((process = find_procinfo (pi->pid, 0)) == NULL)
657130812Smarcel	return 0;	/* fail */
658130812Smarcel
659130812Smarcel      /* Now obtain the file descriptor for the LWP. */
660130812Smarcel      if ((fd = ioctl (process->ctl_fd, PIOCOPENLWP, &lwpid)) <= 0)
661130812Smarcel	return 0;	/* fail */
662130812Smarcel#else			/* Irix, other? */
663130812Smarcel      return 0;		/* Don't know how to open threads */
664130812Smarcel#endif	/* Sol 2.5 PIOCOPENLWP */
665130812Smarcel    }
666130812Smarcel#endif	/* OSF     PIOCTSTATUS */
667130812Smarcel  pi->ctl_fd = pi->as_fd = pi->status_fd = fd;
668130812Smarcel#endif	/* NEW_PROC_API */
669130812Smarcel
670130812Smarcel  return 1;		/* success */
671130812Smarcel}
672130812Smarcel
673130812Smarcel/*
674130812Smarcel * Function: create_procinfo
675130812Smarcel *
676130812Smarcel * Allocate a data structure and link it into the procinfo list.
677130812Smarcel * (First tries to find a pre-existing one (FIXME: why?)
678130812Smarcel *
679130812Smarcel * Return: pointer to new procinfo struct.
680130812Smarcel */
681130812Smarcel
682130812Smarcelstatic procinfo *
683130812Smarcelcreate_procinfo (int pid, int tid)
684130812Smarcel{
685130812Smarcel  procinfo *pi, *parent;
686130812Smarcel
687130812Smarcel  if ((pi = find_procinfo (pid, tid)))
688130812Smarcel    return pi;			/* Already exists, nothing to do. */
689130812Smarcel
690130812Smarcel  /* find parent before doing malloc, to save having to cleanup */
691130812Smarcel  if (tid != 0)
692130812Smarcel    parent = find_procinfo_or_die (pid, 0);	/* FIXME: should I
693130812Smarcel						   create it if it
694130812Smarcel						   doesn't exist yet? */
695130812Smarcel
696130812Smarcel  pi = (procinfo *) xmalloc (sizeof (procinfo));
697130812Smarcel  memset (pi, 0, sizeof (procinfo));
698130812Smarcel  pi->pid = pid;
699130812Smarcel  pi->tid = tid;
700130812Smarcel
701130812Smarcel#ifdef DYNAMIC_SYSCALLS
702130812Smarcel  load_syscalls (pi);
703130812Smarcel#endif
704130812Smarcel
705130812Smarcel  pi->saved_entryset = sysset_t_alloc (pi);
706130812Smarcel  pi->saved_exitset = sysset_t_alloc (pi);
707130812Smarcel
708130812Smarcel  /* Chain into list.  */
709130812Smarcel  if (tid == 0)
710130812Smarcel    {
711130812Smarcel      sprintf (pi->pathname, MAIN_PROC_NAME_FMT, pid);
712130812Smarcel      pi->next = procinfo_list;
713130812Smarcel      procinfo_list = pi;
714130812Smarcel    }
715130812Smarcel  else
716130812Smarcel    {
717130812Smarcel#ifdef NEW_PROC_API
718130812Smarcel      sprintf (pi->pathname, "/proc/%05d/lwp/%d", pid, tid);
719130812Smarcel#else
720130812Smarcel      sprintf (pi->pathname, MAIN_PROC_NAME_FMT, pid);
721130812Smarcel#endif
722130812Smarcel      pi->next = parent->thread_list;
723130812Smarcel      parent->thread_list = pi;
724130812Smarcel    }
725130812Smarcel  return pi;
726130812Smarcel}
727130812Smarcel
728130812Smarcel/*
729130812Smarcel * Function: close_procinfo_files
730130812Smarcel *
731130812Smarcel * Close all file descriptors associated with the procinfo
732130812Smarcel */
733130812Smarcel
734130812Smarcelstatic void
735130812Smarcelclose_procinfo_files (procinfo *pi)
736130812Smarcel{
737130812Smarcel  if (pi->ctl_fd > 0)
738130812Smarcel    close (pi->ctl_fd);
739130812Smarcel#ifdef NEW_PROC_API
740130812Smarcel  if (pi->as_fd > 0)
741130812Smarcel    close (pi->as_fd);
742130812Smarcel  if (pi->status_fd > 0)
743130812Smarcel    close (pi->status_fd);
744130812Smarcel#endif
745130812Smarcel  pi->ctl_fd = pi->as_fd = pi->status_fd = 0;
746130812Smarcel}
747130812Smarcel
748130812Smarcel/*
749130812Smarcel * Function: destroy_procinfo
750130812Smarcel *
751130812Smarcel * Destructor function.  Close, unlink and deallocate the object.
752130812Smarcel */
753130812Smarcel
754130812Smarcelstatic void
755130812Smarceldestroy_one_procinfo (procinfo **list, procinfo *pi)
756130812Smarcel{
757130812Smarcel  procinfo *ptr;
758130812Smarcel
759130812Smarcel  /* Step one: unlink the procinfo from its list */
760130812Smarcel  if (pi == *list)
761130812Smarcel    *list = pi->next;
762130812Smarcel  else
763130812Smarcel    for (ptr = *list; ptr; ptr = ptr->next)
764130812Smarcel      if (ptr->next == pi)
765130812Smarcel	{
766130812Smarcel	  ptr->next =  pi->next;
767130812Smarcel	  break;
768130812Smarcel	}
769130812Smarcel
770130812Smarcel  /* Step two: close any open file descriptors */
771130812Smarcel  close_procinfo_files (pi);
772130812Smarcel
773130812Smarcel  /* Step three: free the memory. */
774130812Smarcel#ifdef DYNAMIC_SYSCALLS
775130812Smarcel  free_syscalls (pi);
776130812Smarcel#endif
777130812Smarcel  xfree (pi->saved_entryset);
778130812Smarcel  xfree (pi->saved_exitset);
779130812Smarcel  xfree (pi);
780130812Smarcel}
781130812Smarcel
782130812Smarcelstatic void
783130812Smarceldestroy_procinfo (procinfo *pi)
784130812Smarcel{
785130812Smarcel  procinfo *tmp;
786130812Smarcel
787130812Smarcel  if (pi->tid != 0)	/* destroy a thread procinfo */
788130812Smarcel    {
789130812Smarcel      tmp = find_procinfo (pi->pid, 0);	/* find the parent process */
790130812Smarcel      destroy_one_procinfo (&tmp->thread_list, pi);
791130812Smarcel    }
792130812Smarcel  else			/* destroy a process procinfo and all its threads */
793130812Smarcel    {
794130812Smarcel      /* First destroy the children, if any; */
795130812Smarcel      while (pi->thread_list != NULL)
796130812Smarcel	destroy_one_procinfo (&pi->thread_list, pi->thread_list);
797130812Smarcel      /* Then destroy the parent.  Genocide!!!  */
798130812Smarcel      destroy_one_procinfo (&procinfo_list, pi);
799130812Smarcel    }
800130812Smarcel}
801130812Smarcel
802130812Smarcelstatic void
803130812Smarceldo_destroy_procinfo_cleanup (void *pi)
804130812Smarcel{
805130812Smarcel  destroy_procinfo (pi);
806130812Smarcel}
807130812Smarcel
808130812Smarcelenum { NOKILL, KILL };
809130812Smarcel
810130812Smarcel/*
811130812Smarcel * Function: dead_procinfo
812130812Smarcel *
813130812Smarcel * To be called on a non_recoverable error for a procinfo.
814130812Smarcel * Prints error messages, optionally sends a SIGKILL to the process,
815130812Smarcel * then destroys the data structure.
816130812Smarcel */
817130812Smarcel
818130812Smarcelstatic void
819130812Smarceldead_procinfo (procinfo *pi, char *msg, int kill_p)
820130812Smarcel{
821130812Smarcel  char procfile[80];
822130812Smarcel
823130812Smarcel  if (pi->pathname)
824130812Smarcel    {
825130812Smarcel      print_sys_errmsg (pi->pathname, errno);
826130812Smarcel    }
827130812Smarcel  else
828130812Smarcel    {
829130812Smarcel      sprintf (procfile, "process %d", pi->pid);
830130812Smarcel      print_sys_errmsg (procfile, errno);
831130812Smarcel    }
832130812Smarcel  if (kill_p == KILL)
833130812Smarcel    kill (pi->pid, SIGKILL);
834130812Smarcel
835130812Smarcel  destroy_procinfo (pi);
836130812Smarcel  error (msg);
837130812Smarcel}
838130812Smarcel
839130812Smarcel/*
840130812Smarcel * Function: sysset_t_size
841130812Smarcel *
842130812Smarcel * Returns the (complete) size of a sysset_t struct.  Normally, this
843130812Smarcel * is just sizeof (syset_t), but in the case of Monterey/64, the actual
844130812Smarcel * size of sysset_t isn't known until runtime.
845130812Smarcel */
846130812Smarcel
847130812Smarcelstatic int
848130812Smarcelsysset_t_size (procinfo * pi)
849130812Smarcel{
850130812Smarcel#ifndef DYNAMIC_SYSCALLS
851130812Smarcel  return sizeof (sysset_t);
852130812Smarcel#else
853130812Smarcel  return sizeof (sysset_t) - sizeof (uint64_t)
854130812Smarcel    + sizeof (uint64_t) * ((pi->num_syscalls + (8 * sizeof (uint64_t) - 1))
855130812Smarcel			   / (8 * sizeof (uint64_t)));
856130812Smarcel#endif
857130812Smarcel}
858130812Smarcel
859130812Smarcel/* Function: sysset_t_alloc
860130812Smarcel
861130812Smarcel   Allocate and (partially) initialize a sysset_t struct.  */
862130812Smarcel
863130812Smarcelstatic sysset_t *
864130812Smarcelsysset_t_alloc (procinfo * pi)
865130812Smarcel{
866130812Smarcel  sysset_t *ret;
867130812Smarcel  int size = sysset_t_size (pi);
868130812Smarcel  ret = xmalloc (size);
869130812Smarcel#ifdef DYNAMIC_SYSCALLS
870130812Smarcel  ret->pr_size = (pi->num_syscalls + (8 * sizeof (uint64_t) - 1))
871130812Smarcel                 / (8 * sizeof (uint64_t));
872130812Smarcel#endif
873130812Smarcel  return ret;
874130812Smarcel}
875130812Smarcel
876130812Smarcel#ifdef DYNAMIC_SYSCALLS
877130812Smarcel
878130812Smarcel/* Function: load_syscalls
879130812Smarcel
880130812Smarcel   Extract syscall numbers and names from /proc/<pid>/sysent.  Initialize
881130812Smarcel   pi->num_syscalls with the number of syscalls and pi->syscall_names
882130812Smarcel   with the names.  (Certain numbers may be skipped in which case the
883130812Smarcel   names for these numbers will be left as NULL.) */
884130812Smarcel
885130812Smarcel#define MAX_SYSCALL_NAME_LENGTH 256
886130812Smarcel#define MAX_SYSCALLS 65536
887130812Smarcel
888130812Smarcelstatic void
889130812Smarcelload_syscalls (procinfo *pi)
890130812Smarcel{
891130812Smarcel  char pathname[MAX_PROC_NAME_SIZE];
892130812Smarcel  int sysent_fd;
893130812Smarcel  prsysent_t header;
894130812Smarcel  prsyscall_t *syscalls;
895130812Smarcel  int i, size, maxcall;
896130812Smarcel
897130812Smarcel  pi->num_syscalls = 0;
898130812Smarcel  pi->syscall_names = 0;
899130812Smarcel
900130812Smarcel  /* Open the file descriptor for the sysent file */
901130812Smarcel  sprintf (pathname, "/proc/%d/sysent", pi->pid);
902130812Smarcel  sysent_fd = open_with_retry (pathname, O_RDONLY);
903130812Smarcel  if (sysent_fd < 0)
904130812Smarcel    {
905130812Smarcel      error ("load_syscalls: Can't open /proc/%d/sysent", pi->pid);
906130812Smarcel    }
907130812Smarcel
908130812Smarcel  size = sizeof header - sizeof (prsyscall_t);
909130812Smarcel  if (read (sysent_fd, &header, size) != size)
910130812Smarcel    {
911130812Smarcel      error ("load_syscalls: Error reading /proc/%d/sysent", pi->pid);
912130812Smarcel    }
913130812Smarcel
914130812Smarcel  if (header.pr_nsyscalls == 0)
915130812Smarcel    {
916130812Smarcel      error ("load_syscalls: /proc/%d/sysent contains no syscalls!", pi->pid);
917130812Smarcel    }
918130812Smarcel
919130812Smarcel  size = header.pr_nsyscalls * sizeof (prsyscall_t);
920130812Smarcel  syscalls = xmalloc (size);
921130812Smarcel
922130812Smarcel  if (read (sysent_fd, syscalls, size) != size)
923130812Smarcel    {
924130812Smarcel      xfree (syscalls);
925130812Smarcel      error ("load_syscalls: Error reading /proc/%d/sysent", pi->pid);
926130812Smarcel    }
927130812Smarcel
928130812Smarcel  /* Find maximum syscall number.  This may not be the same as
929130812Smarcel     pr_nsyscalls since that value refers to the number of entries
930130812Smarcel     in the table.  (Also, the docs indicate that some system
931130812Smarcel     call numbers may be skipped.) */
932130812Smarcel
933130812Smarcel  maxcall = syscalls[0].pr_number;
934130812Smarcel
935130812Smarcel  for (i = 1; i <  header.pr_nsyscalls; i++)
936130812Smarcel    if (syscalls[i].pr_number > maxcall
937130812Smarcel        && syscalls[i].pr_nameoff > 0
938130812Smarcel	&& syscalls[i].pr_number < MAX_SYSCALLS)
939130812Smarcel      maxcall = syscalls[i].pr_number;
940130812Smarcel
941130812Smarcel  pi->num_syscalls = maxcall+1;
942130812Smarcel  pi->syscall_names = xmalloc (pi->num_syscalls * sizeof (char *));
943130812Smarcel
944130812Smarcel  for (i = 0; i < pi->num_syscalls; i++)
945130812Smarcel    pi->syscall_names[i] = NULL;
946130812Smarcel
947130812Smarcel  /* Read the syscall names in */
948130812Smarcel  for (i = 0; i < header.pr_nsyscalls; i++)
949130812Smarcel    {
950130812Smarcel      char namebuf[MAX_SYSCALL_NAME_LENGTH];
951130812Smarcel      int nread;
952130812Smarcel      int callnum;
953130812Smarcel
954130812Smarcel      if (syscalls[i].pr_number >= MAX_SYSCALLS
955130812Smarcel          || syscalls[i].pr_number < 0
956130812Smarcel	  || syscalls[i].pr_nameoff <= 0
957130812Smarcel	  || (lseek (sysent_fd, (off_t) syscalls[i].pr_nameoff, SEEK_SET)
958130812Smarcel                                       != (off_t) syscalls[i].pr_nameoff))
959130812Smarcel	continue;
960130812Smarcel
961130812Smarcel      nread = read (sysent_fd, namebuf, sizeof namebuf);
962130812Smarcel      if (nread <= 0)
963130812Smarcel	continue;
964130812Smarcel
965130812Smarcel      callnum = syscalls[i].pr_number;
966130812Smarcel
967130812Smarcel      if (pi->syscall_names[callnum] != NULL)
968130812Smarcel	{
969130812Smarcel	  /* FIXME: Generate warning */
970130812Smarcel	  continue;
971130812Smarcel	}
972130812Smarcel
973130812Smarcel      namebuf[nread-1] = '\0';
974130812Smarcel      size = strlen (namebuf) + 1;
975130812Smarcel      pi->syscall_names[callnum] = xmalloc (size);
976130812Smarcel      strncpy (pi->syscall_names[callnum], namebuf, size-1);
977130812Smarcel      pi->syscall_names[callnum][size-1] = '\0';
978130812Smarcel    }
979130812Smarcel
980130812Smarcel  close (sysent_fd);
981130812Smarcel  xfree (syscalls);
982130812Smarcel}
983130812Smarcel
984130812Smarcel/* Function: free_syscalls
985130812Smarcel
986130812Smarcel   Free the space allocated for the syscall names from the procinfo
987130812Smarcel   structure.  */
988130812Smarcel
989130812Smarcelstatic void
990130812Smarcelfree_syscalls (procinfo *pi)
991130812Smarcel{
992130812Smarcel  if (pi->syscall_names)
993130812Smarcel    {
994130812Smarcel      int i;
995130812Smarcel
996130812Smarcel      for (i = 0; i < pi->num_syscalls; i++)
997130812Smarcel	if (pi->syscall_names[i] != NULL)
998130812Smarcel	  xfree (pi->syscall_names[i]);
999130812Smarcel
1000130812Smarcel      xfree (pi->syscall_names);
1001130812Smarcel      pi->syscall_names = 0;
1002130812Smarcel    }
1003130812Smarcel}
1004130812Smarcel
1005130812Smarcel/* Function: find_syscall
1006130812Smarcel
1007130812Smarcel   Given a name, look up (and return) the corresponding syscall number.
1008130812Smarcel   If no match is found, return -1.  */
1009130812Smarcel
1010130812Smarcelstatic int
1011130812Smarcelfind_syscall (procinfo *pi, char *name)
1012130812Smarcel{
1013130812Smarcel  int i;
1014130812Smarcel  for (i = 0; i < pi->num_syscalls; i++)
1015130812Smarcel    {
1016130812Smarcel      if (pi->syscall_names[i] && strcmp (name, pi->syscall_names[i]) == 0)
1017130812Smarcel	return i;
1018130812Smarcel    }
1019130812Smarcel  return -1;
1020130812Smarcel}
1021130812Smarcel#endif
1022130812Smarcel
1023130812Smarcel/* =================== END, STRUCT PROCINFO "MODULE" =================== */
1024130812Smarcel
1025130812Smarcel/* ===================  /proc  "MODULE" =================== */
1026130812Smarcel
1027130812Smarcel/*
1028130812Smarcel * This "module" is the interface layer between the /proc system API
1029130812Smarcel * and the gdb target vector functions.  This layer consists of
1030130812Smarcel * access functions that encapsulate each of the basic operations
1031130812Smarcel * that we need to use from the /proc API.
1032130812Smarcel *
1033130812Smarcel * The main motivation for this layer is to hide the fact that
1034130812Smarcel * there are two very different implementations of the /proc API.
1035130812Smarcel * Rather than have a bunch of #ifdefs all thru the gdb target vector
1036130812Smarcel * functions, we do our best to hide them all in here.
1037130812Smarcel */
1038130812Smarcel
1039130812Smarcelint proc_get_status (procinfo * pi);
1040130812Smarcellong proc_flags (procinfo * pi);
1041130812Smarcelint proc_why (procinfo * pi);
1042130812Smarcelint proc_what (procinfo * pi);
1043130812Smarcelint proc_set_run_on_last_close (procinfo * pi);
1044130812Smarcelint proc_unset_run_on_last_close (procinfo * pi);
1045130812Smarcelint proc_set_inherit_on_fork (procinfo * pi);
1046130812Smarcelint proc_unset_inherit_on_fork (procinfo * pi);
1047130812Smarcelint proc_set_async (procinfo * pi);
1048130812Smarcelint proc_unset_async (procinfo * pi);
1049130812Smarcelint proc_stop_process (procinfo * pi);
1050130812Smarcelint proc_trace_signal (procinfo * pi, int signo);
1051130812Smarcelint proc_ignore_signal (procinfo * pi, int signo);
1052130812Smarcelint proc_clear_current_fault (procinfo * pi);
1053130812Smarcelint proc_set_current_signal (procinfo * pi, int signo);
1054130812Smarcelint proc_clear_current_signal (procinfo * pi);
1055130812Smarcelint proc_set_gregs (procinfo * pi);
1056130812Smarcelint proc_set_fpregs (procinfo * pi);
1057130812Smarcelint proc_wait_for_stop (procinfo * pi);
1058130812Smarcelint proc_run_process (procinfo * pi, int step, int signo);
1059130812Smarcelint proc_kill (procinfo * pi, int signo);
1060130812Smarcelint proc_parent_pid (procinfo * pi);
1061130812Smarcelint proc_get_nthreads (procinfo * pi);
1062130812Smarcelint proc_get_current_thread (procinfo * pi);
1063130812Smarcelint proc_set_held_signals (procinfo * pi, gdb_sigset_t * sighold);
1064130812Smarcelint proc_set_traced_sysexit (procinfo * pi, sysset_t * sysset);
1065130812Smarcelint proc_set_traced_sysentry (procinfo * pi, sysset_t * sysset);
1066130812Smarcelint proc_set_traced_faults (procinfo * pi, fltset_t * fltset);
1067130812Smarcelint proc_set_traced_signals (procinfo * pi, gdb_sigset_t * sigset);
1068130812Smarcel
1069130812Smarcelint proc_update_threads (procinfo * pi);
1070130812Smarcelint proc_iterate_over_threads (procinfo * pi,
1071130812Smarcel			       int (*func) (procinfo *, procinfo *, void *),
1072130812Smarcel			       void *ptr);
1073130812Smarcel
1074130812Smarcelgdb_gregset_t *proc_get_gregs (procinfo * pi);
1075130812Smarcelgdb_fpregset_t *proc_get_fpregs (procinfo * pi);
1076130812Smarcelsysset_t *proc_get_traced_sysexit (procinfo * pi, sysset_t * save);
1077130812Smarcelsysset_t *proc_get_traced_sysentry (procinfo * pi, sysset_t * save);
1078130812Smarcelfltset_t *proc_get_traced_faults (procinfo * pi, fltset_t * save);
1079130812Smarcelgdb_sigset_t *proc_get_traced_signals (procinfo * pi, gdb_sigset_t * save);
1080130812Smarcelgdb_sigset_t *proc_get_held_signals (procinfo * pi, gdb_sigset_t * save);
1081130812Smarcelgdb_sigset_t *proc_get_pending_signals (procinfo * pi, gdb_sigset_t * save);
1082130812Smarcelgdb_sigaction_t *proc_get_signal_actions (procinfo * pi, gdb_sigaction_t *save);
1083130812Smarcel
1084130812Smarcelvoid proc_warn (procinfo * pi, char *func, int line);
1085130812Smarcelvoid proc_error (procinfo * pi, char *func, int line);
1086130812Smarcel
1087130812Smarcelvoid
1088130812Smarcelproc_warn (procinfo *pi, char *func, int line)
1089130812Smarcel{
1090130812Smarcel  sprintf (errmsg, "procfs: %s line %d, %s", func, line, pi->pathname);
1091130812Smarcel  print_sys_errmsg (errmsg, errno);
1092130812Smarcel}
1093130812Smarcel
1094130812Smarcelvoid
1095130812Smarcelproc_error (procinfo *pi, char *func, int line)
1096130812Smarcel{
1097130812Smarcel  sprintf (errmsg, "procfs: %s line %d, %s", func, line, pi->pathname);
1098130812Smarcel  perror_with_name (errmsg);
1099130812Smarcel}
1100130812Smarcel
1101130812Smarcel/*
1102130812Smarcel * Function: proc_get_status
1103130812Smarcel *
1104130812Smarcel * Updates the status struct in the procinfo.
1105130812Smarcel * There is a 'valid' flag, to let other functions know when
1106130812Smarcel * this function needs to be called (so the status is only
1107130812Smarcel * read when it is needed).  The status file descriptor is
1108130812Smarcel * also only opened when it is needed.
1109130812Smarcel *
1110130812Smarcel * Return: non-zero for success, zero for failure.
1111130812Smarcel */
1112130812Smarcel
1113130812Smarcelint
1114130812Smarcelproc_get_status (procinfo *pi)
1115130812Smarcel{
1116130812Smarcel  /* Status file descriptor is opened "lazily" */
1117130812Smarcel  if (pi->status_fd == 0 &&
1118130812Smarcel      open_procinfo_files (pi, FD_STATUS) == 0)
1119130812Smarcel    {
1120130812Smarcel      pi->status_valid = 0;
1121130812Smarcel      return 0;
1122130812Smarcel    }
1123130812Smarcel
1124130812Smarcel#ifdef NEW_PROC_API
1125130812Smarcel  if (lseek (pi->status_fd, 0, SEEK_SET) < 0)
1126130812Smarcel    pi->status_valid = 0;			/* fail */
1127130812Smarcel  else
1128130812Smarcel    {
1129130812Smarcel      /* Sigh... I have to read a different data structure,
1130130812Smarcel	 depending on whether this is a main process or an LWP. */
1131130812Smarcel      if (pi->tid)
1132130812Smarcel	pi->status_valid = (read (pi->status_fd,
1133130812Smarcel				  (char *) &pi->prstatus.pr_lwp,
1134130812Smarcel				  sizeof (lwpstatus_t))
1135130812Smarcel			    == sizeof (lwpstatus_t));
1136130812Smarcel      else
1137130812Smarcel	{
1138130812Smarcel	  pi->status_valid = (read (pi->status_fd,
1139130812Smarcel				    (char *) &pi->prstatus,
1140130812Smarcel				    sizeof (gdb_prstatus_t))
1141130812Smarcel			      == sizeof (gdb_prstatus_t));
1142130812Smarcel#if 0 /*def UNIXWARE*/
1143130812Smarcel	  if (pi->status_valid &&
1144130812Smarcel	      (pi->prstatus.pr_lwp.pr_flags & PR_ISTOP) &&
1145130812Smarcel	      pi->prstatus.pr_lwp.pr_why == PR_REQUESTED)
1146130812Smarcel	    /* Unixware peculiarity -- read the damn thing again! */
1147130812Smarcel	    pi->status_valid = (read (pi->status_fd,
1148130812Smarcel				      (char *) &pi->prstatus,
1149130812Smarcel				      sizeof (gdb_prstatus_t))
1150130812Smarcel				== sizeof (gdb_prstatus_t));
1151130812Smarcel#endif /* UNIXWARE */
1152130812Smarcel	}
1153130812Smarcel    }
1154130812Smarcel#else	/* ioctl method */
1155130812Smarcel#ifdef PIOCTSTATUS	/* osf */
1156130812Smarcel  if (pi->tid == 0)	/* main process */
1157130812Smarcel    {
1158130812Smarcel      /* Just read the danged status.  Now isn't that simple? */
1159130812Smarcel      pi->status_valid =
1160130812Smarcel	(ioctl (pi->status_fd, PIOCSTATUS, &pi->prstatus) >= 0);
1161130812Smarcel    }
1162130812Smarcel  else
1163130812Smarcel    {
1164130812Smarcel      int win;
1165130812Smarcel      struct {
1166130812Smarcel	long pr_count;
1167130812Smarcel	tid_t pr_error_thread;
1168130812Smarcel	struct prstatus status;
1169130812Smarcel      } thread_status;
1170130812Smarcel
1171130812Smarcel      thread_status.pr_count = 1;
1172130812Smarcel      thread_status.status.pr_tid = pi->tid;
1173130812Smarcel      win = (ioctl (pi->status_fd, PIOCTSTATUS, &thread_status) >= 0);
1174130812Smarcel      if (win)
1175130812Smarcel	{
1176130812Smarcel	  memcpy (&pi->prstatus, &thread_status.status,
1177130812Smarcel		  sizeof (pi->prstatus));
1178130812Smarcel	  pi->status_valid = 1;
1179130812Smarcel	}
1180130812Smarcel    }
1181130812Smarcel#else
1182130812Smarcel  /* Just read the danged status.  Now isn't that simple? */
1183130812Smarcel  pi->status_valid = (ioctl (pi->status_fd, PIOCSTATUS, &pi->prstatus) >= 0);
1184130812Smarcel#endif
1185130812Smarcel#endif
1186130812Smarcel
1187130812Smarcel  if (pi->status_valid)
1188130812Smarcel    {
1189130812Smarcel      PROC_PRETTYFPRINT_STATUS (proc_flags (pi),
1190130812Smarcel				proc_why (pi),
1191130812Smarcel				proc_what (pi),
1192130812Smarcel				proc_get_current_thread (pi));
1193130812Smarcel    }
1194130812Smarcel
1195130812Smarcel  /* The status struct includes general regs, so mark them valid too */
1196130812Smarcel  pi->gregs_valid  = pi->status_valid;
1197130812Smarcel#ifdef NEW_PROC_API
1198130812Smarcel  /* In the read/write multiple-fd model,
1199130812Smarcel     the status struct includes the fp regs too, so mark them valid too */
1200130812Smarcel  pi->fpregs_valid = pi->status_valid;
1201130812Smarcel#endif
1202130812Smarcel  return pi->status_valid;	/* True if success, false if failure. */
1203130812Smarcel}
1204130812Smarcel
1205130812Smarcel/*
1206130812Smarcel * Function: proc_flags
1207130812Smarcel *
1208130812Smarcel * returns the process flags (pr_flags field).
1209130812Smarcel */
1210130812Smarcel
1211130812Smarcellong
1212130812Smarcelproc_flags (procinfo *pi)
1213130812Smarcel{
1214130812Smarcel  if (!pi->status_valid)
1215130812Smarcel    if (!proc_get_status (pi))
1216130812Smarcel      return 0;	/* FIXME: not a good failure value (but what is?) */
1217130812Smarcel
1218130812Smarcel#ifdef NEW_PROC_API
1219130812Smarcel# ifdef UNIXWARE
1220130812Smarcel  /* UnixWare 7.1 puts process status flags, e.g. PR_ASYNC, in
1221130812Smarcel     pstatus_t and LWP status flags, e.g. PR_STOPPED, in lwpstatus_t.
1222130812Smarcel     The two sets of flags don't overlap. */
1223130812Smarcel  return pi->prstatus.pr_flags | pi->prstatus.pr_lwp.pr_flags;
1224130812Smarcel# else
1225130812Smarcel  return pi->prstatus.pr_lwp.pr_flags;
1226130812Smarcel# endif
1227130812Smarcel#else
1228130812Smarcel  return pi->prstatus.pr_flags;
1229130812Smarcel#endif
1230130812Smarcel}
1231130812Smarcel
1232130812Smarcel/*
1233130812Smarcel * Function: proc_why
1234130812Smarcel *
1235130812Smarcel * returns the pr_why field (why the process stopped).
1236130812Smarcel */
1237130812Smarcel
1238130812Smarcelint
1239130812Smarcelproc_why (procinfo *pi)
1240130812Smarcel{
1241130812Smarcel  if (!pi->status_valid)
1242130812Smarcel    if (!proc_get_status (pi))
1243130812Smarcel      return 0;	/* FIXME: not a good failure value (but what is?) */
1244130812Smarcel
1245130812Smarcel#ifdef NEW_PROC_API
1246130812Smarcel  return pi->prstatus.pr_lwp.pr_why;
1247130812Smarcel#else
1248130812Smarcel  return pi->prstatus.pr_why;
1249130812Smarcel#endif
1250130812Smarcel}
1251130812Smarcel
1252130812Smarcel/*
1253130812Smarcel * Function: proc_what
1254130812Smarcel *
1255130812Smarcel * returns the pr_what field (details of why the process stopped).
1256130812Smarcel */
1257130812Smarcel
1258130812Smarcelint
1259130812Smarcelproc_what (procinfo *pi)
1260130812Smarcel{
1261130812Smarcel  if (!pi->status_valid)
1262130812Smarcel    if (!proc_get_status (pi))
1263130812Smarcel      return 0;	/* FIXME: not a good failure value (but what is?) */
1264130812Smarcel
1265130812Smarcel#ifdef NEW_PROC_API
1266130812Smarcel  return pi->prstatus.pr_lwp.pr_what;
1267130812Smarcel#else
1268130812Smarcel  return pi->prstatus.pr_what;
1269130812Smarcel#endif
1270130812Smarcel}
1271130812Smarcel
1272130812Smarcel#ifndef PIOCSSPCACT	/* The following is not supported on OSF.  */
1273130812Smarcel/*
1274130812Smarcel * Function: proc_nsysarg
1275130812Smarcel *
1276130812Smarcel * returns the pr_nsysarg field (number of args to the current syscall).
1277130812Smarcel */
1278130812Smarcel
1279130812Smarcelint
1280130812Smarcelproc_nsysarg (procinfo *pi)
1281130812Smarcel{
1282130812Smarcel  if (!pi->status_valid)
1283130812Smarcel    if (!proc_get_status (pi))
1284130812Smarcel      return 0;
1285130812Smarcel
1286130812Smarcel#ifdef NEW_PROC_API
1287130812Smarcel  return pi->prstatus.pr_lwp.pr_nsysarg;
1288130812Smarcel#else
1289130812Smarcel  return pi->prstatus.pr_nsysarg;
1290130812Smarcel#endif
1291130812Smarcel}
1292130812Smarcel
1293130812Smarcel/*
1294130812Smarcel * Function: proc_sysargs
1295130812Smarcel *
1296130812Smarcel * returns the pr_sysarg field (pointer to the arguments of current syscall).
1297130812Smarcel */
1298130812Smarcel
1299130812Smarcellong *
1300130812Smarcelproc_sysargs (procinfo *pi)
1301130812Smarcel{
1302130812Smarcel  if (!pi->status_valid)
1303130812Smarcel    if (!proc_get_status (pi))
1304130812Smarcel      return NULL;
1305130812Smarcel
1306130812Smarcel#ifdef NEW_PROC_API
1307130812Smarcel  return (long *) &pi->prstatus.pr_lwp.pr_sysarg;
1308130812Smarcel#else
1309130812Smarcel  return (long *) &pi->prstatus.pr_sysarg;
1310130812Smarcel#endif
1311130812Smarcel}
1312130812Smarcel
1313130812Smarcel/*
1314130812Smarcel * Function: proc_syscall
1315130812Smarcel *
1316130812Smarcel * returns the pr_syscall field (id of current syscall if we are in one).
1317130812Smarcel */
1318130812Smarcel
1319130812Smarcelint
1320130812Smarcelproc_syscall (procinfo *pi)
1321130812Smarcel{
1322130812Smarcel  if (!pi->status_valid)
1323130812Smarcel    if (!proc_get_status (pi))
1324130812Smarcel      return 0;
1325130812Smarcel
1326130812Smarcel#ifdef NEW_PROC_API
1327130812Smarcel  return pi->prstatus.pr_lwp.pr_syscall;
1328130812Smarcel#else
1329130812Smarcel  return pi->prstatus.pr_syscall;
1330130812Smarcel#endif
1331130812Smarcel}
1332130812Smarcel#endif /* PIOCSSPCACT */
1333130812Smarcel
1334130812Smarcel/*
1335130812Smarcel * Function: proc_cursig:
1336130812Smarcel *
1337130812Smarcel * returns the pr_cursig field (current signal).
1338130812Smarcel */
1339130812Smarcel
1340130812Smarcellong
1341130812Smarcelproc_cursig (struct procinfo *pi)
1342130812Smarcel{
1343130812Smarcel  if (!pi->status_valid)
1344130812Smarcel    if (!proc_get_status (pi))
1345130812Smarcel      return 0;	/* FIXME: not a good failure value (but what is?) */
1346130812Smarcel
1347130812Smarcel#ifdef NEW_PROC_API
1348130812Smarcel  return pi->prstatus.pr_lwp.pr_cursig;
1349130812Smarcel#else
1350130812Smarcel  return pi->prstatus.pr_cursig;
1351130812Smarcel#endif
1352130812Smarcel}
1353130812Smarcel
1354130812Smarcel/*
1355130812Smarcel * Function: proc_modify_flag
1356130812Smarcel *
1357130812Smarcel *  === I appologize for the messiness of this function.
1358130812Smarcel *  === This is an area where the different versions of
1359130812Smarcel *  === /proc are more inconsistent than usual.     MVS
1360130812Smarcel *
1361130812Smarcel * Set or reset any of the following process flags:
1362130812Smarcel *    PR_FORK	-- forked child will inherit trace flags
1363130812Smarcel *    PR_RLC	-- traced process runs when last /proc file closed.
1364130812Smarcel *    PR_KLC    -- traced process is killed when last /proc file closed.
1365130812Smarcel *    PR_ASYNC	-- LWP's get to run/stop independently.
1366130812Smarcel *
1367130812Smarcel * There are three methods for doing this function:
1368130812Smarcel * 1) Newest: read/write [PCSET/PCRESET/PCUNSET]
1369130812Smarcel *    [Sol6, Sol7, UW]
1370130812Smarcel * 2) Middle: PIOCSET/PIOCRESET
1371130812Smarcel *    [Irix, Sol5]
1372130812Smarcel * 3) Oldest: PIOCSFORK/PIOCRFORK/PIOCSRLC/PIOCRRLC
1373130812Smarcel *    [OSF, Sol5]
1374130812Smarcel *
1375130812Smarcel * Note: Irix does not define PR_ASYNC.
1376130812Smarcel * Note: OSF  does not define PR_KLC.
1377130812Smarcel * Note: OSF  is the only one that can ONLY use the oldest method.
1378130812Smarcel *
1379130812Smarcel * Arguments:
1380130812Smarcel *    pi   -- the procinfo
1381130812Smarcel *    flag -- one of PR_FORK, PR_RLC, or PR_ASYNC
1382130812Smarcel *    mode -- 1 for set, 0 for reset.
1383130812Smarcel *
1384130812Smarcel * Returns non-zero for success, zero for failure.
1385130812Smarcel */
1386130812Smarcel
1387130812Smarcelenum { FLAG_RESET, FLAG_SET };
1388130812Smarcel
1389130812Smarcelstatic int
1390130812Smarcelproc_modify_flag (procinfo *pi, long flag, long mode)
1391130812Smarcel{
1392130812Smarcel  long win = 0;		/* default to fail */
1393130812Smarcel
1394130812Smarcel  /*
1395130812Smarcel   * These operations affect the process as a whole, and applying
1396130812Smarcel   * them to an individual LWP has the same meaning as applying them
1397130812Smarcel   * to the main process.  Therefore, if we're ever called with a
1398130812Smarcel   * pointer to an LWP's procinfo, let's substitute the process's
1399130812Smarcel   * procinfo and avoid opening the LWP's file descriptor
1400130812Smarcel   * unnecessarily.
1401130812Smarcel   */
1402130812Smarcel
1403130812Smarcel  if (pi->pid != 0)
1404130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
1405130812Smarcel
1406130812Smarcel#ifdef NEW_PROC_API	/* Newest method: UnixWare and newer Solarii */
1407130812Smarcel  /* First normalize the PCUNSET/PCRESET command opcode
1408130812Smarcel     (which for no obvious reason has a different definition
1409130812Smarcel     from one operating system to the next...)  */
1410130812Smarcel#ifdef  PCUNSET
1411130812Smarcel#define GDBRESET PCUNSET
1412130812Smarcel#else
1413130812Smarcel#ifdef  PCRESET
1414130812Smarcel#define GDBRESET PCRESET
1415130812Smarcel#endif
1416130812Smarcel#endif
1417130812Smarcel  {
1418130812Smarcel    procfs_ctl_t arg[2];
1419130812Smarcel
1420130812Smarcel    if (mode == FLAG_SET)	/* Set the flag (RLC, FORK, or ASYNC) */
1421130812Smarcel      arg[0] = PCSET;
1422130812Smarcel    else			/* Reset the flag */
1423130812Smarcel      arg[0] = GDBRESET;
1424130812Smarcel
1425130812Smarcel    arg[1] = flag;
1426130812Smarcel    win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg));
1427130812Smarcel  }
1428130812Smarcel#else
1429130812Smarcel#ifdef PIOCSET		/* Irix/Sol5 method */
1430130812Smarcel  if (mode == FLAG_SET)	/* Set the flag (hopefully RLC, FORK, or ASYNC) */
1431130812Smarcel    {
1432130812Smarcel      win = (ioctl (pi->ctl_fd, PIOCSET, &flag)   >= 0);
1433130812Smarcel    }
1434130812Smarcel  else			/* Reset the flag */
1435130812Smarcel    {
1436130812Smarcel      win = (ioctl (pi->ctl_fd, PIOCRESET, &flag) >= 0);
1437130812Smarcel    }
1438130812Smarcel
1439130812Smarcel#else
1440130812Smarcel#ifdef PIOCSRLC		/* Oldest method: OSF */
1441130812Smarcel  switch (flag) {
1442130812Smarcel  case PR_RLC:
1443130812Smarcel    if (mode == FLAG_SET)	/* Set run-on-last-close */
1444130812Smarcel      {
1445130812Smarcel	win = (ioctl (pi->ctl_fd, PIOCSRLC, NULL) >= 0);
1446130812Smarcel      }
1447130812Smarcel    else			/* Clear run-on-last-close */
1448130812Smarcel      {
1449130812Smarcel	win = (ioctl (pi->ctl_fd, PIOCRRLC, NULL) >= 0);
1450130812Smarcel      }
1451130812Smarcel    break;
1452130812Smarcel  case PR_FORK:
1453130812Smarcel    if (mode == FLAG_SET)	/* Set inherit-on-fork */
1454130812Smarcel      {
1455130812Smarcel	win = (ioctl (pi->ctl_fd, PIOCSFORK, NULL) >= 0);
1456130812Smarcel      }
1457130812Smarcel    else			/* Clear inherit-on-fork */
1458130812Smarcel      {
1459130812Smarcel	win = (ioctl (pi->ctl_fd, PIOCRFORK, NULL) >= 0);
1460130812Smarcel      }
1461130812Smarcel    break;
1462130812Smarcel  default:
1463130812Smarcel    win = 0;		/* fail -- unknown flag (can't do PR_ASYNC) */
1464130812Smarcel    break;
1465130812Smarcel  }
1466130812Smarcel#endif
1467130812Smarcel#endif
1468130812Smarcel#endif
1469130812Smarcel#undef GDBRESET
1470130812Smarcel  /* The above operation renders the procinfo's cached pstatus obsolete. */
1471130812Smarcel  pi->status_valid = 0;
1472130812Smarcel
1473130812Smarcel  if (!win)
1474130812Smarcel    warning ("procfs: modify_flag failed to turn %s %s",
1475130812Smarcel	     flag == PR_FORK  ? "PR_FORK"  :
1476130812Smarcel	     flag == PR_RLC   ? "PR_RLC"   :
1477130812Smarcel#ifdef PR_ASYNC
1478130812Smarcel	     flag == PR_ASYNC ? "PR_ASYNC" :
1479130812Smarcel#endif
1480130812Smarcel#ifdef PR_KLC
1481130812Smarcel	     flag == PR_KLC   ? "PR_KLC"   :
1482130812Smarcel#endif
1483130812Smarcel	     "<unknown flag>",
1484130812Smarcel	     mode == FLAG_RESET ? "off" : "on");
1485130812Smarcel
1486130812Smarcel  return win;
1487130812Smarcel}
1488130812Smarcel
1489130812Smarcel/*
1490130812Smarcel * Function: proc_set_run_on_last_close
1491130812Smarcel *
1492130812Smarcel * Set the run_on_last_close flag.
1493130812Smarcel * Process with all threads will become runnable
1494130812Smarcel * when debugger closes all /proc fds.
1495130812Smarcel *
1496130812Smarcel * Returns non-zero for success, zero for failure.
1497130812Smarcel */
1498130812Smarcel
1499130812Smarcelint
1500130812Smarcelproc_set_run_on_last_close (procinfo *pi)
1501130812Smarcel{
1502130812Smarcel  return proc_modify_flag (pi, PR_RLC, FLAG_SET);
1503130812Smarcel}
1504130812Smarcel
1505130812Smarcel/*
1506130812Smarcel * Function: proc_unset_run_on_last_close
1507130812Smarcel *
1508130812Smarcel * Reset the run_on_last_close flag.
1509130812Smarcel * Process will NOT become runnable
1510130812Smarcel * when debugger closes its file handles.
1511130812Smarcel *
1512130812Smarcel * Returns non-zero for success, zero for failure.
1513130812Smarcel */
1514130812Smarcel
1515130812Smarcelint
1516130812Smarcelproc_unset_run_on_last_close (procinfo *pi)
1517130812Smarcel{
1518130812Smarcel  return proc_modify_flag (pi, PR_RLC, FLAG_RESET);
1519130812Smarcel}
1520130812Smarcel
1521130812Smarcel#ifdef PR_KLC
1522130812Smarcel/*
1523130812Smarcel * Function: proc_set_kill_on_last_close
1524130812Smarcel *
1525130812Smarcel * Set the kill_on_last_close flag.
1526130812Smarcel * Process with all threads will be killed when debugger
1527130812Smarcel * closes all /proc fds (or debugger exits or dies).
1528130812Smarcel *
1529130812Smarcel * Returns non-zero for success, zero for failure.
1530130812Smarcel */
1531130812Smarcel
1532130812Smarcelint
1533130812Smarcelproc_set_kill_on_last_close (procinfo *pi)
1534130812Smarcel{
1535130812Smarcel  return proc_modify_flag (pi, PR_KLC, FLAG_SET);
1536130812Smarcel}
1537130812Smarcel
1538130812Smarcel/*
1539130812Smarcel * Function: proc_unset_kill_on_last_close
1540130812Smarcel *
1541130812Smarcel * Reset the kill_on_last_close flag.
1542130812Smarcel * Process will NOT be killed when debugger
1543130812Smarcel * closes its file handles (or exits or dies).
1544130812Smarcel *
1545130812Smarcel * Returns non-zero for success, zero for failure.
1546130812Smarcel */
1547130812Smarcel
1548130812Smarcelint
1549130812Smarcelproc_unset_kill_on_last_close (procinfo *pi)
1550130812Smarcel{
1551130812Smarcel  return proc_modify_flag (pi, PR_KLC, FLAG_RESET);
1552130812Smarcel}
1553130812Smarcel#endif /* PR_KLC */
1554130812Smarcel
1555130812Smarcel/*
1556130812Smarcel * Function: proc_set_inherit_on_fork
1557130812Smarcel *
1558130812Smarcel * Set inherit_on_fork flag.
1559130812Smarcel * If the process forks a child while we are registered for events
1560130812Smarcel * in the parent, then we will also recieve events from the child.
1561130812Smarcel *
1562130812Smarcel * Returns non-zero for success, zero for failure.
1563130812Smarcel */
1564130812Smarcel
1565130812Smarcelint
1566130812Smarcelproc_set_inherit_on_fork (procinfo *pi)
1567130812Smarcel{
1568130812Smarcel  return proc_modify_flag (pi, PR_FORK, FLAG_SET);
1569130812Smarcel}
1570130812Smarcel
1571130812Smarcel/*
1572130812Smarcel * Function: proc_unset_inherit_on_fork
1573130812Smarcel *
1574130812Smarcel * Reset inherit_on_fork flag.
1575130812Smarcel * If the process forks a child while we are registered for events
1576130812Smarcel * in the parent, then we will NOT recieve events from the child.
1577130812Smarcel *
1578130812Smarcel * Returns non-zero for success, zero for failure.
1579130812Smarcel */
1580130812Smarcel
1581130812Smarcelint
1582130812Smarcelproc_unset_inherit_on_fork (procinfo *pi)
1583130812Smarcel{
1584130812Smarcel  return proc_modify_flag (pi, PR_FORK, FLAG_RESET);
1585130812Smarcel}
1586130812Smarcel
1587130812Smarcel#ifdef PR_ASYNC
1588130812Smarcel/*
1589130812Smarcel * Function: proc_set_async
1590130812Smarcel *
1591130812Smarcel * Set PR_ASYNC flag.
1592130812Smarcel * If one LWP stops because of a debug event (signal etc.),
1593130812Smarcel * the remaining LWPs will continue to run.
1594130812Smarcel *
1595130812Smarcel * Returns non-zero for success, zero for failure.
1596130812Smarcel */
1597130812Smarcel
1598130812Smarcelint
1599130812Smarcelproc_set_async (procinfo *pi)
1600130812Smarcel{
1601130812Smarcel  return proc_modify_flag (pi, PR_ASYNC, FLAG_SET);
1602130812Smarcel}
1603130812Smarcel
1604130812Smarcel/*
1605130812Smarcel * Function: proc_unset_async
1606130812Smarcel *
1607130812Smarcel * Reset PR_ASYNC flag.
1608130812Smarcel * If one LWP stops because of a debug event (signal etc.),
1609130812Smarcel * then all other LWPs will stop as well.
1610130812Smarcel *
1611130812Smarcel * Returns non-zero for success, zero for failure.
1612130812Smarcel */
1613130812Smarcel
1614130812Smarcelint
1615130812Smarcelproc_unset_async (procinfo *pi)
1616130812Smarcel{
1617130812Smarcel  return proc_modify_flag (pi, PR_ASYNC, FLAG_RESET);
1618130812Smarcel}
1619130812Smarcel#endif /* PR_ASYNC */
1620130812Smarcel
1621130812Smarcel/*
1622130812Smarcel * Function: proc_stop_process
1623130812Smarcel *
1624130812Smarcel * Request the process/LWP to stop.  Does not wait.
1625130812Smarcel * Returns non-zero for success, zero for failure.
1626130812Smarcel */
1627130812Smarcel
1628130812Smarcelint
1629130812Smarcelproc_stop_process (procinfo *pi)
1630130812Smarcel{
1631130812Smarcel  int win;
1632130812Smarcel
1633130812Smarcel  /*
1634130812Smarcel   * We might conceivably apply this operation to an LWP, and
1635130812Smarcel   * the LWP's ctl file descriptor might not be open.
1636130812Smarcel   */
1637130812Smarcel
1638130812Smarcel  if (pi->ctl_fd == 0 &&
1639130812Smarcel      open_procinfo_files (pi, FD_CTL) == 0)
1640130812Smarcel    return 0;
1641130812Smarcel  else
1642130812Smarcel    {
1643130812Smarcel#ifdef NEW_PROC_API
1644130812Smarcel      procfs_ctl_t cmd = PCSTOP;
1645130812Smarcel      win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd));
1646130812Smarcel#else	/* ioctl method */
1647130812Smarcel      win = (ioctl (pi->ctl_fd, PIOCSTOP, &pi->prstatus) >= 0);
1648130812Smarcel      /* Note: the call also reads the prstatus.  */
1649130812Smarcel      if (win)
1650130812Smarcel	{
1651130812Smarcel	  pi->status_valid = 1;
1652130812Smarcel	  PROC_PRETTYFPRINT_STATUS (proc_flags (pi),
1653130812Smarcel				    proc_why (pi),
1654130812Smarcel				    proc_what (pi),
1655130812Smarcel				    proc_get_current_thread (pi));
1656130812Smarcel	}
1657130812Smarcel#endif
1658130812Smarcel    }
1659130812Smarcel
1660130812Smarcel  return win;
1661130812Smarcel}
1662130812Smarcel
1663130812Smarcel/*
1664130812Smarcel * Function: proc_wait_for_stop
1665130812Smarcel *
1666130812Smarcel * Wait for the process or LWP to stop (block until it does).
1667130812Smarcel * Returns non-zero for success, zero for failure.
1668130812Smarcel */
1669130812Smarcel
1670130812Smarcelint
1671130812Smarcelproc_wait_for_stop (procinfo *pi)
1672130812Smarcel{
1673130812Smarcel  int win;
1674130812Smarcel
1675130812Smarcel  /*
1676130812Smarcel   * We should never have to apply this operation to any procinfo
1677130812Smarcel   * except the one for the main process.  If that ever changes
1678130812Smarcel   * for any reason, then take out the following clause and
1679130812Smarcel   * replace it with one that makes sure the ctl_fd is open.
1680130812Smarcel   */
1681130812Smarcel
1682130812Smarcel  if (pi->tid != 0)
1683130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
1684130812Smarcel
1685130812Smarcel#ifdef NEW_PROC_API
1686130812Smarcel  {
1687130812Smarcel    procfs_ctl_t cmd = PCWSTOP;
1688130812Smarcel    win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd));
1689130812Smarcel    /* We been runnin' and we stopped -- need to update status.  */
1690130812Smarcel    pi->status_valid = 0;
1691130812Smarcel  }
1692130812Smarcel#else	/* ioctl method */
1693130812Smarcel  win = (ioctl (pi->ctl_fd, PIOCWSTOP, &pi->prstatus) >= 0);
1694130812Smarcel  /* Above call also refreshes the prstatus.  */
1695130812Smarcel  if (win)
1696130812Smarcel    {
1697130812Smarcel      pi->status_valid = 1;
1698130812Smarcel      PROC_PRETTYFPRINT_STATUS (proc_flags (pi),
1699130812Smarcel				proc_why (pi),
1700130812Smarcel				proc_what (pi),
1701130812Smarcel				proc_get_current_thread (pi));
1702130812Smarcel    }
1703130812Smarcel#endif
1704130812Smarcel
1705130812Smarcel  return win;
1706130812Smarcel}
1707130812Smarcel
1708130812Smarcel/*
1709130812Smarcel * Function: proc_run_process
1710130812Smarcel *
1711130812Smarcel * Make the process or LWP runnable.
1712130812Smarcel * Options (not all are implemented):
1713130812Smarcel *   - single-step
1714130812Smarcel *   - clear current fault
1715130812Smarcel *   - clear current signal
1716130812Smarcel *   - abort the current system call
1717130812Smarcel *   - stop as soon as finished with system call
1718130812Smarcel *   - (ioctl): set traced signal set
1719130812Smarcel *   - (ioctl): set held   signal set
1720130812Smarcel *   - (ioctl): set traced fault  set
1721130812Smarcel *   - (ioctl): set start pc (vaddr)
1722130812Smarcel * Always clear the current fault.
1723130812Smarcel * Clear the current signal if 'signo' is zero.
1724130812Smarcel *
1725130812Smarcel * Arguments:
1726130812Smarcel *   pi		the process or LWP to operate on.
1727130812Smarcel *   step	if true, set the process or LWP to trap after one instr.
1728130812Smarcel *   signo	if zero, clear the current signal if any.
1729130812Smarcel *		if non-zero, set the current signal to this one.
1730130812Smarcel *
1731130812Smarcel * Returns non-zero for success, zero for failure.
1732130812Smarcel */
1733130812Smarcel
1734130812Smarcelint
1735130812Smarcelproc_run_process (procinfo *pi, int step, int signo)
1736130812Smarcel{
1737130812Smarcel  int win;
1738130812Smarcel  int runflags;
1739130812Smarcel
1740130812Smarcel  /*
1741130812Smarcel   * We will probably have to apply this operation to individual threads,
1742130812Smarcel   * so make sure the control file descriptor is open.
1743130812Smarcel   */
1744130812Smarcel
1745130812Smarcel  if (pi->ctl_fd == 0 &&
1746130812Smarcel      open_procinfo_files (pi, FD_CTL) == 0)
1747130812Smarcel    {
1748130812Smarcel      return 0;
1749130812Smarcel    }
1750130812Smarcel
1751130812Smarcel  runflags    = PRCFAULT;	/* always clear current fault  */
1752130812Smarcel  if (step)
1753130812Smarcel    runflags |= PRSTEP;
1754130812Smarcel  if (signo == 0)
1755130812Smarcel    runflags |= PRCSIG;
1756130812Smarcel  else if (signo != -1)		/* -1 means do nothing W.R.T. signals */
1757130812Smarcel    proc_set_current_signal (pi, signo);
1758130812Smarcel
1759130812Smarcel#ifdef NEW_PROC_API
1760130812Smarcel  {
1761130812Smarcel    procfs_ctl_t cmd[2];
1762130812Smarcel
1763130812Smarcel    cmd[0]  = PCRUN;
1764130812Smarcel    cmd[1]  = runflags;
1765130812Smarcel    win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd));
1766130812Smarcel  }
1767130812Smarcel#else	/* ioctl method */
1768130812Smarcel  {
1769130812Smarcel    prrun_t prrun;
1770130812Smarcel
1771130812Smarcel    memset (&prrun, 0, sizeof (prrun));
1772130812Smarcel    prrun.pr_flags  = runflags;
1773130812Smarcel    win = (ioctl (pi->ctl_fd, PIOCRUN, &prrun) >= 0);
1774130812Smarcel  }
1775130812Smarcel#endif
1776130812Smarcel
1777130812Smarcel  return win;
1778130812Smarcel}
1779130812Smarcel
1780130812Smarcel/*
1781130812Smarcel * Function: proc_set_traced_signals
1782130812Smarcel *
1783130812Smarcel * Register to trace signals in the process or LWP.
1784130812Smarcel * Returns non-zero for success, zero for failure.
1785130812Smarcel */
1786130812Smarcel
1787130812Smarcelint
1788130812Smarcelproc_set_traced_signals (procinfo *pi, gdb_sigset_t *sigset)
1789130812Smarcel{
1790130812Smarcel  int win;
1791130812Smarcel
1792130812Smarcel  /*
1793130812Smarcel   * We should never have to apply this operation to any procinfo
1794130812Smarcel   * except the one for the main process.  If that ever changes
1795130812Smarcel   * for any reason, then take out the following clause and
1796130812Smarcel   * replace it with one that makes sure the ctl_fd is open.
1797130812Smarcel   */
1798130812Smarcel
1799130812Smarcel  if (pi->tid != 0)
1800130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
1801130812Smarcel
1802130812Smarcel#ifdef NEW_PROC_API
1803130812Smarcel  {
1804130812Smarcel    struct {
1805130812Smarcel      procfs_ctl_t cmd;
1806130812Smarcel      /* Use char array to avoid alignment issues.  */
1807130812Smarcel      char sigset[sizeof (gdb_sigset_t)];
1808130812Smarcel    } arg;
1809130812Smarcel
1810130812Smarcel    arg.cmd = PCSTRACE;
1811130812Smarcel    memcpy (&arg.sigset, sigset, sizeof (gdb_sigset_t));
1812130812Smarcel
1813130812Smarcel    win = (write (pi->ctl_fd, (char *) &arg, sizeof (arg)) == sizeof (arg));
1814130812Smarcel  }
1815130812Smarcel#else	/* ioctl method */
1816130812Smarcel  win = (ioctl (pi->ctl_fd, PIOCSTRACE, sigset) >= 0);
1817130812Smarcel#endif
1818130812Smarcel  /* The above operation renders the procinfo's cached pstatus obsolete. */
1819130812Smarcel  pi->status_valid = 0;
1820130812Smarcel
1821130812Smarcel  if (!win)
1822130812Smarcel    warning ("procfs: set_traced_signals failed");
1823130812Smarcel  return win;
1824130812Smarcel}
1825130812Smarcel
1826130812Smarcel/*
1827130812Smarcel * Function: proc_set_traced_faults
1828130812Smarcel *
1829130812Smarcel * Register to trace hardware faults in the process or LWP.
1830130812Smarcel * Returns non-zero for success, zero for failure.
1831130812Smarcel */
1832130812Smarcel
1833130812Smarcelint
1834130812Smarcelproc_set_traced_faults (procinfo *pi, fltset_t *fltset)
1835130812Smarcel{
1836130812Smarcel  int win;
1837130812Smarcel
1838130812Smarcel  /*
1839130812Smarcel   * We should never have to apply this operation to any procinfo
1840130812Smarcel   * except the one for the main process.  If that ever changes
1841130812Smarcel   * for any reason, then take out the following clause and
1842130812Smarcel   * replace it with one that makes sure the ctl_fd is open.
1843130812Smarcel   */
1844130812Smarcel
1845130812Smarcel  if (pi->tid != 0)
1846130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
1847130812Smarcel
1848130812Smarcel#ifdef NEW_PROC_API
1849130812Smarcel  {
1850130812Smarcel    struct {
1851130812Smarcel      procfs_ctl_t cmd;
1852130812Smarcel      /* Use char array to avoid alignment issues.  */
1853130812Smarcel      char fltset[sizeof (fltset_t)];
1854130812Smarcel    } arg;
1855130812Smarcel
1856130812Smarcel    arg.cmd = PCSFAULT;
1857130812Smarcel    memcpy (&arg.fltset, fltset, sizeof (fltset_t));
1858130812Smarcel
1859130812Smarcel    win = (write (pi->ctl_fd, (char *) &arg, sizeof (arg)) == sizeof (arg));
1860130812Smarcel  }
1861130812Smarcel#else	/* ioctl method */
1862130812Smarcel  win = (ioctl (pi->ctl_fd, PIOCSFAULT, fltset) >= 0);
1863130812Smarcel#endif
1864130812Smarcel  /* The above operation renders the procinfo's cached pstatus obsolete. */
1865130812Smarcel  pi->status_valid = 0;
1866130812Smarcel
1867130812Smarcel  return win;
1868130812Smarcel}
1869130812Smarcel
1870130812Smarcel/*
1871130812Smarcel * Function: proc_set_traced_sysentry
1872130812Smarcel *
1873130812Smarcel * Register to trace entry to system calls in the process or LWP.
1874130812Smarcel * Returns non-zero for success, zero for failure.
1875130812Smarcel */
1876130812Smarcel
1877130812Smarcelint
1878130812Smarcelproc_set_traced_sysentry (procinfo *pi, sysset_t *sysset)
1879130812Smarcel{
1880130812Smarcel  int win;
1881130812Smarcel
1882130812Smarcel  /*
1883130812Smarcel   * We should never have to apply this operation to any procinfo
1884130812Smarcel   * except the one for the main process.  If that ever changes
1885130812Smarcel   * for any reason, then take out the following clause and
1886130812Smarcel   * replace it with one that makes sure the ctl_fd is open.
1887130812Smarcel   */
1888130812Smarcel
1889130812Smarcel  if (pi->tid != 0)
1890130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
1891130812Smarcel
1892130812Smarcel#ifdef NEW_PROC_API
1893130812Smarcel  {
1894130812Smarcel    struct gdb_proc_ctl_pcsentry {
1895130812Smarcel      procfs_ctl_t cmd;
1896130812Smarcel      /* Use char array to avoid alignment issues.  */
1897130812Smarcel      char sysset[sizeof (sysset_t)];
1898130812Smarcel    } *argp;
1899130812Smarcel    int argp_size = sizeof (struct gdb_proc_ctl_pcsentry)
1900130812Smarcel                  - sizeof (sysset_t)
1901130812Smarcel		  + sysset_t_size (pi);
1902130812Smarcel
1903130812Smarcel    argp = xmalloc (argp_size);
1904130812Smarcel
1905130812Smarcel    argp->cmd = PCSENTRY;
1906130812Smarcel    memcpy (&argp->sysset, sysset, sysset_t_size (pi));
1907130812Smarcel
1908130812Smarcel    win = (write (pi->ctl_fd, (char *) argp, argp_size) == argp_size);
1909130812Smarcel    xfree (argp);
1910130812Smarcel  }
1911130812Smarcel#else	/* ioctl method */
1912130812Smarcel  win = (ioctl (pi->ctl_fd, PIOCSENTRY, sysset) >= 0);
1913130812Smarcel#endif
1914130812Smarcel  /* The above operation renders the procinfo's cached pstatus obsolete. */
1915130812Smarcel  pi->status_valid = 0;
1916130812Smarcel
1917130812Smarcel  return win;
1918130812Smarcel}
1919130812Smarcel
1920130812Smarcel/*
1921130812Smarcel * Function: proc_set_traced_sysexit
1922130812Smarcel *
1923130812Smarcel * Register to trace exit from system calls in the process or LWP.
1924130812Smarcel * Returns non-zero for success, zero for failure.
1925130812Smarcel */
1926130812Smarcel
1927130812Smarcelint
1928130812Smarcelproc_set_traced_sysexit (procinfo *pi, sysset_t *sysset)
1929130812Smarcel{
1930130812Smarcel  int win;
1931130812Smarcel
1932130812Smarcel  /*
1933130812Smarcel   * We should never have to apply this operation to any procinfo
1934130812Smarcel   * except the one for the main process.  If that ever changes
1935130812Smarcel   * for any reason, then take out the following clause and
1936130812Smarcel   * replace it with one that makes sure the ctl_fd is open.
1937130812Smarcel   */
1938130812Smarcel
1939130812Smarcel  if (pi->tid != 0)
1940130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
1941130812Smarcel
1942130812Smarcel#ifdef NEW_PROC_API
1943130812Smarcel  {
1944130812Smarcel    struct gdb_proc_ctl_pcsexit {
1945130812Smarcel      procfs_ctl_t cmd;
1946130812Smarcel      /* Use char array to avoid alignment issues.  */
1947130812Smarcel      char sysset[sizeof (sysset_t)];
1948130812Smarcel    } *argp;
1949130812Smarcel    int argp_size = sizeof (struct gdb_proc_ctl_pcsexit)
1950130812Smarcel                  - sizeof (sysset_t)
1951130812Smarcel		  + sysset_t_size (pi);
1952130812Smarcel
1953130812Smarcel    argp = xmalloc (argp_size);
1954130812Smarcel
1955130812Smarcel    argp->cmd = PCSEXIT;
1956130812Smarcel    memcpy (&argp->sysset, sysset, sysset_t_size (pi));
1957130812Smarcel
1958130812Smarcel    win = (write (pi->ctl_fd, (char *) argp, argp_size) == argp_size);
1959130812Smarcel    xfree (argp);
1960130812Smarcel  }
1961130812Smarcel#else	/* ioctl method */
1962130812Smarcel  win = (ioctl (pi->ctl_fd, PIOCSEXIT, sysset) >= 0);
1963130812Smarcel#endif
1964130812Smarcel  /* The above operation renders the procinfo's cached pstatus obsolete. */
1965130812Smarcel  pi->status_valid = 0;
1966130812Smarcel
1967130812Smarcel  return win;
1968130812Smarcel}
1969130812Smarcel
1970130812Smarcel/*
1971130812Smarcel * Function: proc_set_held_signals
1972130812Smarcel *
1973130812Smarcel * Specify the set of blocked / held signals in the process or LWP.
1974130812Smarcel * Returns non-zero for success, zero for failure.
1975130812Smarcel */
1976130812Smarcel
1977130812Smarcelint
1978130812Smarcelproc_set_held_signals (procinfo *pi, gdb_sigset_t *sighold)
1979130812Smarcel{
1980130812Smarcel  int win;
1981130812Smarcel
1982130812Smarcel  /*
1983130812Smarcel   * We should never have to apply this operation to any procinfo
1984130812Smarcel   * except the one for the main process.  If that ever changes
1985130812Smarcel   * for any reason, then take out the following clause and
1986130812Smarcel   * replace it with one that makes sure the ctl_fd is open.
1987130812Smarcel   */
1988130812Smarcel
1989130812Smarcel  if (pi->tid != 0)
1990130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
1991130812Smarcel
1992130812Smarcel#ifdef NEW_PROC_API
1993130812Smarcel  {
1994130812Smarcel    struct {
1995130812Smarcel      procfs_ctl_t cmd;
1996130812Smarcel      /* Use char array to avoid alignment issues.  */
1997130812Smarcel      char hold[sizeof (gdb_sigset_t)];
1998130812Smarcel    } arg;
1999130812Smarcel
2000130812Smarcel    arg.cmd  = PCSHOLD;
2001130812Smarcel    memcpy (&arg.hold, sighold, sizeof (gdb_sigset_t));
2002130812Smarcel    win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg));
2003130812Smarcel  }
2004130812Smarcel#else
2005130812Smarcel  win = (ioctl (pi->ctl_fd, PIOCSHOLD, sighold) >= 0);
2006130812Smarcel#endif
2007130812Smarcel  /* The above operation renders the procinfo's cached pstatus obsolete. */
2008130812Smarcel  pi->status_valid = 0;
2009130812Smarcel
2010130812Smarcel  return win;
2011130812Smarcel}
2012130812Smarcel
2013130812Smarcel/*
2014130812Smarcel * Function: proc_get_pending_signals
2015130812Smarcel *
2016130812Smarcel * returns the set of signals that are pending in the process or LWP.
2017130812Smarcel * Will also copy the sigset if 'save' is non-zero.
2018130812Smarcel */
2019130812Smarcel
2020130812Smarcelgdb_sigset_t *
2021130812Smarcelproc_get_pending_signals (procinfo *pi, gdb_sigset_t *save)
2022130812Smarcel{
2023130812Smarcel  gdb_sigset_t *ret = NULL;
2024130812Smarcel
2025130812Smarcel  /*
2026130812Smarcel   * We should never have to apply this operation to any procinfo
2027130812Smarcel   * except the one for the main process.  If that ever changes
2028130812Smarcel   * for any reason, then take out the following clause and
2029130812Smarcel   * replace it with one that makes sure the ctl_fd is open.
2030130812Smarcel   */
2031130812Smarcel
2032130812Smarcel  if (pi->tid != 0)
2033130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
2034130812Smarcel
2035130812Smarcel  if (!pi->status_valid)
2036130812Smarcel    if (!proc_get_status (pi))
2037130812Smarcel      return NULL;
2038130812Smarcel
2039130812Smarcel#ifdef NEW_PROC_API
2040130812Smarcel  ret = &pi->prstatus.pr_lwp.pr_lwppend;
2041130812Smarcel#else
2042130812Smarcel  ret = &pi->prstatus.pr_sigpend;
2043130812Smarcel#endif
2044130812Smarcel  if (save && ret)
2045130812Smarcel    memcpy (save, ret, sizeof (gdb_sigset_t));
2046130812Smarcel
2047130812Smarcel  return ret;
2048130812Smarcel}
2049130812Smarcel
2050130812Smarcel/*
2051130812Smarcel * Function: proc_get_signal_actions
2052130812Smarcel *
2053130812Smarcel * returns the set of signal actions.
2054130812Smarcel * Will also copy the sigactionset if 'save' is non-zero.
2055130812Smarcel */
2056130812Smarcel
2057130812Smarcelgdb_sigaction_t *
2058130812Smarcelproc_get_signal_actions (procinfo *pi, gdb_sigaction_t *save)
2059130812Smarcel{
2060130812Smarcel  gdb_sigaction_t *ret = NULL;
2061130812Smarcel
2062130812Smarcel  /*
2063130812Smarcel   * We should never have to apply this operation to any procinfo
2064130812Smarcel   * except the one for the main process.  If that ever changes
2065130812Smarcel   * for any reason, then take out the following clause and
2066130812Smarcel   * replace it with one that makes sure the ctl_fd is open.
2067130812Smarcel   */
2068130812Smarcel
2069130812Smarcel  if (pi->tid != 0)
2070130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
2071130812Smarcel
2072130812Smarcel  if (!pi->status_valid)
2073130812Smarcel    if (!proc_get_status (pi))
2074130812Smarcel      return NULL;
2075130812Smarcel
2076130812Smarcel#ifdef NEW_PROC_API
2077130812Smarcel  ret = &pi->prstatus.pr_lwp.pr_action;
2078130812Smarcel#else
2079130812Smarcel  ret = &pi->prstatus.pr_action;
2080130812Smarcel#endif
2081130812Smarcel  if (save && ret)
2082130812Smarcel    memcpy (save, ret, sizeof (gdb_sigaction_t));
2083130812Smarcel
2084130812Smarcel  return ret;
2085130812Smarcel}
2086130812Smarcel
2087130812Smarcel/*
2088130812Smarcel * Function: proc_get_held_signals
2089130812Smarcel *
2090130812Smarcel * returns the set of signals that are held / blocked.
2091130812Smarcel * Will also copy the sigset if 'save' is non-zero.
2092130812Smarcel */
2093130812Smarcel
2094130812Smarcelgdb_sigset_t *
2095130812Smarcelproc_get_held_signals (procinfo *pi, gdb_sigset_t *save)
2096130812Smarcel{
2097130812Smarcel  gdb_sigset_t *ret = NULL;
2098130812Smarcel
2099130812Smarcel  /*
2100130812Smarcel   * We should never have to apply this operation to any procinfo
2101130812Smarcel   * except the one for the main process.  If that ever changes
2102130812Smarcel   * for any reason, then take out the following clause and
2103130812Smarcel   * replace it with one that makes sure the ctl_fd is open.
2104130812Smarcel   */
2105130812Smarcel
2106130812Smarcel  if (pi->tid != 0)
2107130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
2108130812Smarcel
2109130812Smarcel#ifdef NEW_PROC_API
2110130812Smarcel  if (!pi->status_valid)
2111130812Smarcel    if (!proc_get_status (pi))
2112130812Smarcel      return NULL;
2113130812Smarcel
2114130812Smarcel#ifdef UNIXWARE
2115130812Smarcel  ret = &pi->prstatus.pr_lwp.pr_context.uc_sigmask;
2116130812Smarcel#else
2117130812Smarcel  ret = &pi->prstatus.pr_lwp.pr_lwphold;
2118130812Smarcel#endif /* UNIXWARE */
2119130812Smarcel#else  /* not NEW_PROC_API */
2120130812Smarcel  {
2121130812Smarcel    static gdb_sigset_t sigheld;
2122130812Smarcel
2123130812Smarcel    if (ioctl (pi->ctl_fd, PIOCGHOLD, &sigheld) >= 0)
2124130812Smarcel      ret = &sigheld;
2125130812Smarcel  }
2126130812Smarcel#endif /* NEW_PROC_API */
2127130812Smarcel  if (save && ret)
2128130812Smarcel    memcpy (save, ret, sizeof (gdb_sigset_t));
2129130812Smarcel
2130130812Smarcel  return ret;
2131130812Smarcel}
2132130812Smarcel
2133130812Smarcel/*
2134130812Smarcel * Function: proc_get_traced_signals
2135130812Smarcel *
2136130812Smarcel * returns the set of signals that are traced / debugged.
2137130812Smarcel * Will also copy the sigset if 'save' is non-zero.
2138130812Smarcel */
2139130812Smarcel
2140130812Smarcelgdb_sigset_t *
2141130812Smarcelproc_get_traced_signals (procinfo *pi, gdb_sigset_t *save)
2142130812Smarcel{
2143130812Smarcel  gdb_sigset_t *ret = NULL;
2144130812Smarcel
2145130812Smarcel  /*
2146130812Smarcel   * We should never have to apply this operation to any procinfo
2147130812Smarcel   * except the one for the main process.  If that ever changes
2148130812Smarcel   * for any reason, then take out the following clause and
2149130812Smarcel   * replace it with one that makes sure the ctl_fd is open.
2150130812Smarcel   */
2151130812Smarcel
2152130812Smarcel  if (pi->tid != 0)
2153130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
2154130812Smarcel
2155130812Smarcel#ifdef NEW_PROC_API
2156130812Smarcel  if (!pi->status_valid)
2157130812Smarcel    if (!proc_get_status (pi))
2158130812Smarcel      return NULL;
2159130812Smarcel
2160130812Smarcel  ret = &pi->prstatus.pr_sigtrace;
2161130812Smarcel#else
2162130812Smarcel  {
2163130812Smarcel    static gdb_sigset_t sigtrace;
2164130812Smarcel
2165130812Smarcel    if (ioctl (pi->ctl_fd, PIOCGTRACE, &sigtrace) >= 0)
2166130812Smarcel      ret = &sigtrace;
2167130812Smarcel  }
2168130812Smarcel#endif
2169130812Smarcel  if (save && ret)
2170130812Smarcel    memcpy (save, ret, sizeof (gdb_sigset_t));
2171130812Smarcel
2172130812Smarcel  return ret;
2173130812Smarcel}
2174130812Smarcel
2175130812Smarcel/*
2176130812Smarcel * Function: proc_trace_signal
2177130812Smarcel *
2178130812Smarcel * Add 'signo' to the set of signals that are traced.
2179130812Smarcel * Returns non-zero for success, zero for failure.
2180130812Smarcel */
2181130812Smarcel
2182130812Smarcelint
2183130812Smarcelproc_trace_signal (procinfo *pi, int signo)
2184130812Smarcel{
2185130812Smarcel  gdb_sigset_t temp;
2186130812Smarcel
2187130812Smarcel  /*
2188130812Smarcel   * We should never have to apply this operation to any procinfo
2189130812Smarcel   * except the one for the main process.  If that ever changes
2190130812Smarcel   * for any reason, then take out the following clause and
2191130812Smarcel   * replace it with one that makes sure the ctl_fd is open.
2192130812Smarcel   */
2193130812Smarcel
2194130812Smarcel  if (pi->tid != 0)
2195130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
2196130812Smarcel
2197130812Smarcel  if (pi)
2198130812Smarcel    {
2199130812Smarcel      if (proc_get_traced_signals (pi, &temp))
2200130812Smarcel	{
2201130812Smarcel	  praddset (&temp, signo);
2202130812Smarcel	  return proc_set_traced_signals (pi, &temp);
2203130812Smarcel	}
2204130812Smarcel    }
2205130812Smarcel
2206130812Smarcel  return 0;	/* failure */
2207130812Smarcel}
2208130812Smarcel
2209130812Smarcel/*
2210130812Smarcel * Function: proc_ignore_signal
2211130812Smarcel *
2212130812Smarcel * Remove 'signo' from the set of signals that are traced.
2213130812Smarcel * Returns non-zero for success, zero for failure.
2214130812Smarcel */
2215130812Smarcel
2216130812Smarcelint
2217130812Smarcelproc_ignore_signal (procinfo *pi, int signo)
2218130812Smarcel{
2219130812Smarcel  gdb_sigset_t temp;
2220130812Smarcel
2221130812Smarcel  /*
2222130812Smarcel   * We should never have to apply this operation to any procinfo
2223130812Smarcel   * except the one for the main process.  If that ever changes
2224130812Smarcel   * for any reason, then take out the following clause and
2225130812Smarcel   * replace it with one that makes sure the ctl_fd is open.
2226130812Smarcel   */
2227130812Smarcel
2228130812Smarcel  if (pi->tid != 0)
2229130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
2230130812Smarcel
2231130812Smarcel  if (pi)
2232130812Smarcel    {
2233130812Smarcel      if (proc_get_traced_signals (pi, &temp))
2234130812Smarcel	{
2235130812Smarcel	  prdelset (&temp, signo);
2236130812Smarcel	  return proc_set_traced_signals (pi, &temp);
2237130812Smarcel	}
2238130812Smarcel    }
2239130812Smarcel
2240130812Smarcel  return 0;	/* failure */
2241130812Smarcel}
2242130812Smarcel
2243130812Smarcel/*
2244130812Smarcel * Function: proc_get_traced_faults
2245130812Smarcel *
2246130812Smarcel * returns the set of hardware faults that are traced /debugged.
2247130812Smarcel * Will also copy the faultset if 'save' is non-zero.
2248130812Smarcel */
2249130812Smarcel
2250130812Smarcelfltset_t *
2251130812Smarcelproc_get_traced_faults (procinfo *pi, fltset_t *save)
2252130812Smarcel{
2253130812Smarcel  fltset_t *ret = NULL;
2254130812Smarcel
2255130812Smarcel  /*
2256130812Smarcel   * We should never have to apply this operation to any procinfo
2257130812Smarcel   * except the one for the main process.  If that ever changes
2258130812Smarcel   * for any reason, then take out the following clause and
2259130812Smarcel   * replace it with one that makes sure the ctl_fd is open.
2260130812Smarcel   */
2261130812Smarcel
2262130812Smarcel  if (pi->tid != 0)
2263130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
2264130812Smarcel
2265130812Smarcel#ifdef NEW_PROC_API
2266130812Smarcel  if (!pi->status_valid)
2267130812Smarcel    if (!proc_get_status (pi))
2268130812Smarcel      return NULL;
2269130812Smarcel
2270130812Smarcel  ret = &pi->prstatus.pr_flttrace;
2271130812Smarcel#else
2272130812Smarcel  {
2273130812Smarcel    static fltset_t flttrace;
2274130812Smarcel
2275130812Smarcel    if (ioctl (pi->ctl_fd, PIOCGFAULT, &flttrace) >= 0)
2276130812Smarcel      ret = &flttrace;
2277130812Smarcel  }
2278130812Smarcel#endif
2279130812Smarcel  if (save && ret)
2280130812Smarcel    memcpy (save, ret, sizeof (fltset_t));
2281130812Smarcel
2282130812Smarcel  return ret;
2283130812Smarcel}
2284130812Smarcel
2285130812Smarcel/*
2286130812Smarcel * Function: proc_get_traced_sysentry
2287130812Smarcel *
2288130812Smarcel * returns the set of syscalls that are traced /debugged on entry.
2289130812Smarcel * Will also copy the syscall set if 'save' is non-zero.
2290130812Smarcel */
2291130812Smarcel
2292130812Smarcelsysset_t *
2293130812Smarcelproc_get_traced_sysentry (procinfo *pi, sysset_t *save)
2294130812Smarcel{
2295130812Smarcel  sysset_t *ret = NULL;
2296130812Smarcel
2297130812Smarcel  /*
2298130812Smarcel   * We should never have to apply this operation to any procinfo
2299130812Smarcel   * except the one for the main process.  If that ever changes
2300130812Smarcel   * for any reason, then take out the following clause and
2301130812Smarcel   * replace it with one that makes sure the ctl_fd is open.
2302130812Smarcel   */
2303130812Smarcel
2304130812Smarcel  if (pi->tid != 0)
2305130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
2306130812Smarcel
2307130812Smarcel#ifdef NEW_PROC_API
2308130812Smarcel  if (!pi->status_valid)
2309130812Smarcel    if (!proc_get_status (pi))
2310130812Smarcel      return NULL;
2311130812Smarcel
2312130812Smarcel#ifndef DYNAMIC_SYSCALLS
2313130812Smarcel  ret = &pi->prstatus.pr_sysentry;
2314130812Smarcel#else /* DYNAMIC_SYSCALLS */
2315130812Smarcel  {
2316130812Smarcel    static sysset_t *sysentry;
2317130812Smarcel    size_t size;
2318130812Smarcel
2319130812Smarcel    if (!sysentry)
2320130812Smarcel      sysentry = sysset_t_alloc (pi);
2321130812Smarcel    ret = sysentry;
2322130812Smarcel    if (pi->status_fd == 0 && open_procinfo_files (pi, FD_STATUS) == 0)
2323130812Smarcel      return NULL;
2324130812Smarcel    if (pi->prstatus.pr_sysentry_offset == 0)
2325130812Smarcel      {
2326130812Smarcel	gdb_premptysysset (sysentry);
2327130812Smarcel      }
2328130812Smarcel    else
2329130812Smarcel      {
2330130812Smarcel	int rsize;
2331130812Smarcel
2332130812Smarcel	if (lseek (pi->status_fd, (off_t) pi->prstatus.pr_sysentry_offset,
2333130812Smarcel	           SEEK_SET)
2334130812Smarcel	    != (off_t) pi->prstatus.pr_sysentry_offset)
2335130812Smarcel	  return NULL;
2336130812Smarcel	size = sysset_t_size (pi);
2337130812Smarcel	gdb_premptysysset (sysentry);
2338130812Smarcel	rsize = read (pi->status_fd, sysentry, size);
2339130812Smarcel	if (rsize < 0)
2340130812Smarcel	  return NULL;
2341130812Smarcel      }
2342130812Smarcel  }
2343130812Smarcel#endif /* DYNAMIC_SYSCALLS */
2344130812Smarcel#else /* !NEW_PROC_API */
2345130812Smarcel  {
2346130812Smarcel    static sysset_t sysentry;
2347130812Smarcel
2348130812Smarcel    if (ioctl (pi->ctl_fd, PIOCGENTRY, &sysentry) >= 0)
2349130812Smarcel      ret = &sysentry;
2350130812Smarcel  }
2351130812Smarcel#endif /* NEW_PROC_API */
2352130812Smarcel  if (save && ret)
2353130812Smarcel    memcpy (save, ret, sysset_t_size (pi));
2354130812Smarcel
2355130812Smarcel  return ret;
2356130812Smarcel}
2357130812Smarcel
2358130812Smarcel/*
2359130812Smarcel * Function: proc_get_traced_sysexit
2360130812Smarcel *
2361130812Smarcel * returns the set of syscalls that are traced /debugged on exit.
2362130812Smarcel * Will also copy the syscall set if 'save' is non-zero.
2363130812Smarcel */
2364130812Smarcel
2365130812Smarcelsysset_t *
2366130812Smarcelproc_get_traced_sysexit (procinfo *pi, sysset_t *save)
2367130812Smarcel{
2368130812Smarcel  sysset_t * ret = NULL;
2369130812Smarcel
2370130812Smarcel  /*
2371130812Smarcel   * We should never have to apply this operation to any procinfo
2372130812Smarcel   * except the one for the main process.  If that ever changes
2373130812Smarcel   * for any reason, then take out the following clause and
2374130812Smarcel   * replace it with one that makes sure the ctl_fd is open.
2375130812Smarcel   */
2376130812Smarcel
2377130812Smarcel  if (pi->tid != 0)
2378130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
2379130812Smarcel
2380130812Smarcel#ifdef NEW_PROC_API
2381130812Smarcel  if (!pi->status_valid)
2382130812Smarcel    if (!proc_get_status (pi))
2383130812Smarcel      return NULL;
2384130812Smarcel
2385130812Smarcel#ifndef DYNAMIC_SYSCALLS
2386130812Smarcel  ret = &pi->prstatus.pr_sysexit;
2387130812Smarcel#else /* DYNAMIC_SYSCALLS */
2388130812Smarcel  {
2389130812Smarcel    static sysset_t *sysexit;
2390130812Smarcel    size_t size;
2391130812Smarcel
2392130812Smarcel    if (!sysexit)
2393130812Smarcel      sysexit = sysset_t_alloc (pi);
2394130812Smarcel    ret = sysexit;
2395130812Smarcel    if (pi->status_fd == 0 && open_procinfo_files (pi, FD_STATUS) == 0)
2396130812Smarcel      return NULL;
2397130812Smarcel    if (pi->prstatus.pr_sysexit_offset == 0)
2398130812Smarcel      {
2399130812Smarcel	gdb_premptysysset (sysexit);
2400130812Smarcel      }
2401130812Smarcel    else
2402130812Smarcel      {
2403130812Smarcel	int rsize;
2404130812Smarcel
2405130812Smarcel	if (lseek (pi->status_fd, (off_t) pi->prstatus.pr_sysexit_offset, SEEK_SET)
2406130812Smarcel	    != (off_t) pi->prstatus.pr_sysexit_offset)
2407130812Smarcel	  return NULL;
2408130812Smarcel	size = sysset_t_size (pi);
2409130812Smarcel	gdb_premptysysset (sysexit);
2410130812Smarcel	rsize = read (pi->status_fd, sysexit, size);
2411130812Smarcel	if (rsize < 0)
2412130812Smarcel	  return NULL;
2413130812Smarcel      }
2414130812Smarcel  }
2415130812Smarcel#endif /* DYNAMIC_SYSCALLS */
2416130812Smarcel#else
2417130812Smarcel  {
2418130812Smarcel    static sysset_t sysexit;
2419130812Smarcel
2420130812Smarcel    if (ioctl (pi->ctl_fd, PIOCGEXIT, &sysexit) >= 0)
2421130812Smarcel      ret = &sysexit;
2422130812Smarcel  }
2423130812Smarcel#endif
2424130812Smarcel  if (save && ret)
2425130812Smarcel    memcpy (save, ret, sysset_t_size (pi));
2426130812Smarcel
2427130812Smarcel  return ret;
2428130812Smarcel}
2429130812Smarcel
2430130812Smarcel/*
2431130812Smarcel * Function: proc_clear_current_fault
2432130812Smarcel *
2433130812Smarcel * The current fault (if any) is cleared; the associated signal
2434130812Smarcel * will not be sent to the process or LWP when it resumes.
2435130812Smarcel * Returns non-zero for success,  zero for failure.
2436130812Smarcel */
2437130812Smarcel
2438130812Smarcelint
2439130812Smarcelproc_clear_current_fault (procinfo *pi)
2440130812Smarcel{
2441130812Smarcel  int win;
2442130812Smarcel
2443130812Smarcel  /*
2444130812Smarcel   * We should never have to apply this operation to any procinfo
2445130812Smarcel   * except the one for the main process.  If that ever changes
2446130812Smarcel   * for any reason, then take out the following clause and
2447130812Smarcel   * replace it with one that makes sure the ctl_fd is open.
2448130812Smarcel   */
2449130812Smarcel
2450130812Smarcel  if (pi->tid != 0)
2451130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
2452130812Smarcel
2453130812Smarcel#ifdef NEW_PROC_API
2454130812Smarcel  {
2455130812Smarcel    procfs_ctl_t cmd = PCCFAULT;
2456130812Smarcel    win = (write (pi->ctl_fd, (void *) &cmd, sizeof (cmd)) == sizeof (cmd));
2457130812Smarcel  }
2458130812Smarcel#else
2459130812Smarcel  win = (ioctl (pi->ctl_fd, PIOCCFAULT, 0) >= 0);
2460130812Smarcel#endif
2461130812Smarcel
2462130812Smarcel  return win;
2463130812Smarcel}
2464130812Smarcel
2465130812Smarcel/*
2466130812Smarcel * Function: proc_set_current_signal
2467130812Smarcel *
2468130812Smarcel * Set the "current signal" that will be delivered next to the process.
2469130812Smarcel * NOTE: semantics are different from those of KILL.
2470130812Smarcel * This signal will be delivered to the process or LWP
2471130812Smarcel * immediately when it is resumed (even if the signal is held/blocked);
2472130812Smarcel * it will NOT immediately cause another event of interest, and will NOT
2473130812Smarcel * first trap back to the debugger.
2474130812Smarcel *
2475130812Smarcel * Returns non-zero for success,  zero for failure.
2476130812Smarcel */
2477130812Smarcel
2478130812Smarcelint
2479130812Smarcelproc_set_current_signal (procinfo *pi, int signo)
2480130812Smarcel{
2481130812Smarcel  int win;
2482130812Smarcel  struct {
2483130812Smarcel    procfs_ctl_t cmd;
2484130812Smarcel    /* Use char array to avoid alignment issues.  */
2485130812Smarcel    char sinfo[sizeof (gdb_siginfo_t)];
2486130812Smarcel  } arg;
2487130812Smarcel  gdb_siginfo_t *mysinfo;
2488130812Smarcel
2489130812Smarcel  /*
2490130812Smarcel   * We should never have to apply this operation to any procinfo
2491130812Smarcel   * except the one for the main process.  If that ever changes
2492130812Smarcel   * for any reason, then take out the following clause and
2493130812Smarcel   * replace it with one that makes sure the ctl_fd is open.
2494130812Smarcel   */
2495130812Smarcel
2496130812Smarcel  if (pi->tid != 0)
2497130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
2498130812Smarcel
2499130812Smarcel#ifdef PROCFS_DONT_PIOCSSIG_CURSIG
2500130812Smarcel  /* With Alpha OSF/1 procfs, the kernel gets really confused if it
2501130812Smarcel   * receives a PIOCSSIG with a signal identical to the current signal,
2502130812Smarcel   * it messes up the current signal. Work around the kernel bug.
2503130812Smarcel   */
2504130812Smarcel  if (signo > 0 &&
2505130812Smarcel      signo == proc_cursig (pi))
2506130812Smarcel    return 1;           /* I assume this is a success? */
2507130812Smarcel#endif
2508130812Smarcel
2509130812Smarcel  /* The pointer is just a type alias.  */
2510130812Smarcel  mysinfo = (gdb_siginfo_t *) &arg.sinfo;
2511130812Smarcel  mysinfo->si_signo = signo;
2512130812Smarcel  mysinfo->si_code  = 0;
2513130812Smarcel  mysinfo->si_pid   = getpid ();       /* ?why? */
2514130812Smarcel  mysinfo->si_uid   = getuid ();       /* ?why? */
2515130812Smarcel
2516130812Smarcel#ifdef NEW_PROC_API
2517130812Smarcel  arg.cmd = PCSSIG;
2518130812Smarcel  win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg))  == sizeof (arg));
2519130812Smarcel#else
2520130812Smarcel  win = (ioctl (pi->ctl_fd, PIOCSSIG, (void *) &arg.sinfo) >= 0);
2521130812Smarcel#endif
2522130812Smarcel
2523130812Smarcel  return win;
2524130812Smarcel}
2525130812Smarcel
2526130812Smarcel/*
2527130812Smarcel * Function: proc_clear_current_signal
2528130812Smarcel *
2529130812Smarcel * The current signal (if any) is cleared, and
2530130812Smarcel * is not sent to the process or LWP when it resumes.
2531130812Smarcel * Returns non-zero for success,  zero for failure.
2532130812Smarcel */
2533130812Smarcel
2534130812Smarcelint
2535130812Smarcelproc_clear_current_signal (procinfo *pi)
2536130812Smarcel{
2537130812Smarcel  int win;
2538130812Smarcel
2539130812Smarcel  /*
2540130812Smarcel   * We should never have to apply this operation to any procinfo
2541130812Smarcel   * except the one for the main process.  If that ever changes
2542130812Smarcel   * for any reason, then take out the following clause and
2543130812Smarcel   * replace it with one that makes sure the ctl_fd is open.
2544130812Smarcel   */
2545130812Smarcel
2546130812Smarcel  if (pi->tid != 0)
2547130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
2548130812Smarcel
2549130812Smarcel#ifdef NEW_PROC_API
2550130812Smarcel  {
2551130812Smarcel    struct {
2552130812Smarcel      procfs_ctl_t cmd;
2553130812Smarcel      /* Use char array to avoid alignment issues.  */
2554130812Smarcel      char sinfo[sizeof (gdb_siginfo_t)];
2555130812Smarcel    } arg;
2556130812Smarcel    gdb_siginfo_t *mysinfo;
2557130812Smarcel
2558130812Smarcel    arg.cmd = PCSSIG;
2559130812Smarcel    /* The pointer is just a type alias.  */
2560130812Smarcel    mysinfo = (gdb_siginfo_t *) &arg.sinfo;
2561130812Smarcel    mysinfo->si_signo = 0;
2562130812Smarcel    mysinfo->si_code  = 0;
2563130812Smarcel    mysinfo->si_errno = 0;
2564130812Smarcel    mysinfo->si_pid   = getpid ();       /* ?why? */
2565130812Smarcel    mysinfo->si_uid   = getuid ();       /* ?why? */
2566130812Smarcel
2567130812Smarcel    win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg));
2568130812Smarcel  }
2569130812Smarcel#else
2570130812Smarcel  win = (ioctl (pi->ctl_fd, PIOCSSIG, 0) >= 0);
2571130812Smarcel#endif
2572130812Smarcel
2573130812Smarcel  return win;
2574130812Smarcel}
2575130812Smarcel
2576130812Smarcel/*
2577130812Smarcel * Function: proc_get_gregs
2578130812Smarcel *
2579130812Smarcel * Get the general registers for the process or LWP.
2580130812Smarcel * Returns non-zero for success, zero for failure.
2581130812Smarcel */
2582130812Smarcel
2583130812Smarcelgdb_gregset_t *
2584130812Smarcelproc_get_gregs (procinfo *pi)
2585130812Smarcel{
2586130812Smarcel  if (!pi->status_valid || !pi->gregs_valid)
2587130812Smarcel    if (!proc_get_status (pi))
2588130812Smarcel      return NULL;
2589130812Smarcel
2590130812Smarcel  /*
2591130812Smarcel   * OK, sorry about the ifdef's.
2592130812Smarcel   * There's three cases instead of two, because
2593130812Smarcel   * in this instance Unixware and Solaris/RW differ.
2594130812Smarcel   */
2595130812Smarcel
2596130812Smarcel#ifdef NEW_PROC_API
2597130812Smarcel#ifdef UNIXWARE		/* ugh, a true architecture dependency */
2598130812Smarcel  return &pi->prstatus.pr_lwp.pr_context.uc_mcontext.gregs;
2599130812Smarcel#else	/* not Unixware */
2600130812Smarcel  return &pi->prstatus.pr_lwp.pr_reg;
2601130812Smarcel#endif	/* Unixware */
2602130812Smarcel#else	/* not NEW_PROC_API */
2603130812Smarcel  return &pi->prstatus.pr_reg;
2604130812Smarcel#endif	/* NEW_PROC_API */
2605130812Smarcel}
2606130812Smarcel
2607130812Smarcel/*
2608130812Smarcel * Function: proc_get_fpregs
2609130812Smarcel *
2610130812Smarcel * Get the floating point registers for the process or LWP.
2611130812Smarcel * Returns non-zero for success, zero for failure.
2612130812Smarcel */
2613130812Smarcel
2614130812Smarcelgdb_fpregset_t *
2615130812Smarcelproc_get_fpregs (procinfo *pi)
2616130812Smarcel{
2617130812Smarcel#ifdef NEW_PROC_API
2618130812Smarcel  if (!pi->status_valid || !pi->fpregs_valid)
2619130812Smarcel    if (!proc_get_status (pi))
2620130812Smarcel      return NULL;
2621130812Smarcel
2622130812Smarcel#ifdef UNIXWARE		/* a true architecture dependency */
2623130812Smarcel  return &pi->prstatus.pr_lwp.pr_context.uc_mcontext.fpregs;
2624130812Smarcel#else
2625130812Smarcel  return &pi->prstatus.pr_lwp.pr_fpreg;
2626130812Smarcel#endif	/* Unixware */
2627130812Smarcel
2628130812Smarcel#else	/* not NEW_PROC_API */
2629130812Smarcel  if (pi->fpregs_valid)
2630130812Smarcel    return &pi->fpregset;	/* already got 'em */
2631130812Smarcel  else
2632130812Smarcel    {
2633130812Smarcel      if (pi->ctl_fd == 0 &&
2634130812Smarcel	  open_procinfo_files (pi, FD_CTL) == 0)
2635130812Smarcel	{
2636130812Smarcel	  return NULL;
2637130812Smarcel	}
2638130812Smarcel      else
2639130812Smarcel	{
2640130812Smarcel#ifdef PIOCTGFPREG
2641130812Smarcel	  struct {
2642130812Smarcel	    long pr_count;
2643130812Smarcel	    tid_t pr_error_thread;
2644130812Smarcel	    tfpregset_t thread_1;
2645130812Smarcel	  } thread_fpregs;
2646130812Smarcel
2647130812Smarcel	  thread_fpregs.pr_count = 1;
2648130812Smarcel	  thread_fpregs.thread_1.tid = pi->tid;
2649130812Smarcel
2650130812Smarcel	  if (pi->tid == 0 &&
2651130812Smarcel	      ioctl (pi->ctl_fd, PIOCGFPREG, &pi->fpregset) >= 0)
2652130812Smarcel	    {
2653130812Smarcel	      pi->fpregs_valid = 1;
2654130812Smarcel	      return &pi->fpregset;	/* got 'em now! */
2655130812Smarcel	    }
2656130812Smarcel	  else if (pi->tid != 0 &&
2657130812Smarcel		   ioctl (pi->ctl_fd, PIOCTGFPREG, &thread_fpregs) >= 0)
2658130812Smarcel	    {
2659130812Smarcel	      memcpy (&pi->fpregset, &thread_fpregs.thread_1.pr_fpregs,
2660130812Smarcel		      sizeof (pi->fpregset));
2661130812Smarcel	      pi->fpregs_valid = 1;
2662130812Smarcel	      return &pi->fpregset;	/* got 'em now! */
2663130812Smarcel	    }
2664130812Smarcel	  else
2665130812Smarcel	    {
2666130812Smarcel	      return NULL;
2667130812Smarcel	    }
2668130812Smarcel#else
2669130812Smarcel	  if (ioctl (pi->ctl_fd, PIOCGFPREG, &pi->fpregset) >= 0)
2670130812Smarcel	    {
2671130812Smarcel	      pi->fpregs_valid = 1;
2672130812Smarcel	      return &pi->fpregset;	/* got 'em now! */
2673130812Smarcel	    }
2674130812Smarcel	  else
2675130812Smarcel	    {
2676130812Smarcel	      return NULL;
2677130812Smarcel	    }
2678130812Smarcel#endif
2679130812Smarcel	}
2680130812Smarcel    }
2681130812Smarcel#endif
2682130812Smarcel}
2683130812Smarcel
2684130812Smarcel/*
2685130812Smarcel * Function: proc_set_gregs
2686130812Smarcel *
2687130812Smarcel * Write the general registers back to the process or LWP.
2688130812Smarcel * Returns non-zero for success, zero for failure.
2689130812Smarcel */
2690130812Smarcel
2691130812Smarcelint
2692130812Smarcelproc_set_gregs (procinfo *pi)
2693130812Smarcel{
2694130812Smarcel  gdb_gregset_t *gregs;
2695130812Smarcel  int win;
2696130812Smarcel
2697130812Smarcel  if ((gregs = proc_get_gregs (pi)) == NULL)
2698130812Smarcel    return 0;	/* get_regs has already warned */
2699130812Smarcel
2700130812Smarcel  if (pi->ctl_fd == 0 &&
2701130812Smarcel      open_procinfo_files (pi, FD_CTL) == 0)
2702130812Smarcel    {
2703130812Smarcel      return 0;
2704130812Smarcel    }
2705130812Smarcel  else
2706130812Smarcel    {
2707130812Smarcel#ifdef NEW_PROC_API
2708130812Smarcel      struct {
2709130812Smarcel	procfs_ctl_t cmd;
2710130812Smarcel	/* Use char array to avoid alignment issues.  */
2711130812Smarcel	char gregs[sizeof (gdb_gregset_t)];
2712130812Smarcel      } arg;
2713130812Smarcel
2714130812Smarcel      arg.cmd   = PCSREG;
2715130812Smarcel      memcpy (&arg.gregs, gregs, sizeof (arg.gregs));
2716130812Smarcel      win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg));
2717130812Smarcel#else
2718130812Smarcel      win = (ioctl (pi->ctl_fd, PIOCSREG, gregs) >= 0);
2719130812Smarcel#endif
2720130812Smarcel    }
2721130812Smarcel
2722130812Smarcel  /* Policy: writing the regs invalidates our cache. */
2723130812Smarcel  pi->gregs_valid = 0;
2724130812Smarcel  return win;
2725130812Smarcel}
2726130812Smarcel
2727130812Smarcel/*
2728130812Smarcel * Function: proc_set_fpregs
2729130812Smarcel *
2730130812Smarcel * Modify the floating point register set of the process or LWP.
2731130812Smarcel * Returns non-zero for success, zero for failure.
2732130812Smarcel */
2733130812Smarcel
2734130812Smarcelint
2735130812Smarcelproc_set_fpregs (procinfo *pi)
2736130812Smarcel{
2737130812Smarcel  gdb_fpregset_t *fpregs;
2738130812Smarcel  int win;
2739130812Smarcel
2740130812Smarcel  if ((fpregs = proc_get_fpregs (pi)) == NULL)
2741130812Smarcel    return 0;		/* get_fpregs has already warned */
2742130812Smarcel
2743130812Smarcel  if (pi->ctl_fd == 0 &&
2744130812Smarcel      open_procinfo_files (pi, FD_CTL) == 0)
2745130812Smarcel    {
2746130812Smarcel      return 0;
2747130812Smarcel    }
2748130812Smarcel  else
2749130812Smarcel    {
2750130812Smarcel#ifdef NEW_PROC_API
2751130812Smarcel      struct {
2752130812Smarcel	procfs_ctl_t cmd;
2753130812Smarcel	/* Use char array to avoid alignment issues.  */
2754130812Smarcel	char fpregs[sizeof (gdb_fpregset_t)];
2755130812Smarcel      } arg;
2756130812Smarcel
2757130812Smarcel      arg.cmd   = PCSFPREG;
2758130812Smarcel      memcpy (&arg.fpregs, fpregs, sizeof (arg.fpregs));
2759130812Smarcel      win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg));
2760130812Smarcel#else
2761130812Smarcel#ifdef PIOCTSFPREG
2762130812Smarcel      if (pi->tid == 0)
2763130812Smarcel	win = (ioctl (pi->ctl_fd, PIOCSFPREG, fpregs) >= 0);
2764130812Smarcel      else
2765130812Smarcel	{
2766130812Smarcel	  struct {
2767130812Smarcel	    long pr_count;
2768130812Smarcel	    tid_t pr_error_thread;
2769130812Smarcel	    tfpregset_t thread_1;
2770130812Smarcel	  } thread_fpregs;
2771130812Smarcel
2772130812Smarcel	  thread_fpregs.pr_count = 1;
2773130812Smarcel	  thread_fpregs.thread_1.tid = pi->tid;
2774130812Smarcel	  memcpy (&thread_fpregs.thread_1.pr_fpregs, fpregs,
2775130812Smarcel		  sizeof (*fpregs));
2776130812Smarcel	  win = (ioctl (pi->ctl_fd, PIOCTSFPREG, &thread_fpregs) >= 0);
2777130812Smarcel	}
2778130812Smarcel#else
2779130812Smarcel      win = (ioctl (pi->ctl_fd, PIOCSFPREG, fpregs) >= 0);
2780130812Smarcel#endif	/* osf PIOCTSFPREG */
2781130812Smarcel#endif	/* NEW_PROC_API */
2782130812Smarcel    }
2783130812Smarcel
2784130812Smarcel  /* Policy: writing the regs invalidates our cache. */
2785130812Smarcel  pi->fpregs_valid = 0;
2786130812Smarcel  return win;
2787130812Smarcel}
2788130812Smarcel
2789130812Smarcel/*
2790130812Smarcel * Function: proc_kill
2791130812Smarcel *
2792130812Smarcel * Send a signal to the proc or lwp with the semantics of "kill()".
2793130812Smarcel * Returns non-zero for success,  zero for failure.
2794130812Smarcel */
2795130812Smarcel
2796130812Smarcelint
2797130812Smarcelproc_kill (procinfo *pi, int signo)
2798130812Smarcel{
2799130812Smarcel  int win;
2800130812Smarcel
2801130812Smarcel  /*
2802130812Smarcel   * We might conceivably apply this operation to an LWP, and
2803130812Smarcel   * the LWP's ctl file descriptor might not be open.
2804130812Smarcel   */
2805130812Smarcel
2806130812Smarcel  if (pi->ctl_fd == 0 &&
2807130812Smarcel      open_procinfo_files (pi, FD_CTL) == 0)
2808130812Smarcel    {
2809130812Smarcel      return 0;
2810130812Smarcel    }
2811130812Smarcel  else
2812130812Smarcel    {
2813130812Smarcel#ifdef NEW_PROC_API
2814130812Smarcel      procfs_ctl_t cmd[2];
2815130812Smarcel
2816130812Smarcel      cmd[0] = PCKILL;
2817130812Smarcel      cmd[1] = signo;
2818130812Smarcel      win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd));
2819130812Smarcel#else   /* ioctl method */
2820130812Smarcel      /* FIXME: do I need the Alpha OSF fixups present in
2821130812Smarcel	 procfs.c/unconditionally_kill_inferior?  Perhaps only for SIGKILL? */
2822130812Smarcel      win = (ioctl (pi->ctl_fd, PIOCKILL, &signo) >= 0);
2823130812Smarcel#endif
2824130812Smarcel  }
2825130812Smarcel
2826130812Smarcel  return win;
2827130812Smarcel}
2828130812Smarcel
2829130812Smarcel/*
2830130812Smarcel * Function: proc_parent_pid
2831130812Smarcel *
2832130812Smarcel * Find the pid of the process that started this one.
2833130812Smarcel * Returns the parent process pid, or zero.
2834130812Smarcel */
2835130812Smarcel
2836130812Smarcelint
2837130812Smarcelproc_parent_pid (procinfo *pi)
2838130812Smarcel{
2839130812Smarcel  /*
2840130812Smarcel   * We should never have to apply this operation to any procinfo
2841130812Smarcel   * except the one for the main process.  If that ever changes
2842130812Smarcel   * for any reason, then take out the following clause and
2843130812Smarcel   * replace it with one that makes sure the ctl_fd is open.
2844130812Smarcel   */
2845130812Smarcel
2846130812Smarcel  if (pi->tid != 0)
2847130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
2848130812Smarcel
2849130812Smarcel  if (!pi->status_valid)
2850130812Smarcel    if (!proc_get_status (pi))
2851130812Smarcel      return 0;
2852130812Smarcel
2853130812Smarcel  return pi->prstatus.pr_ppid;
2854130812Smarcel}
2855130812Smarcel
2856130812Smarcel
2857130812Smarcel/* Convert a target address (a.k.a. CORE_ADDR) into a host address
2858130812Smarcel   (a.k.a void pointer)!  */
2859130812Smarcel
2860130812Smarcelstatic void *
2861130812Smarcelprocfs_address_to_host_pointer (CORE_ADDR addr)
2862130812Smarcel{
2863130812Smarcel  void *ptr;
2864130812Smarcel
2865130812Smarcel  gdb_assert (sizeof (ptr) == TYPE_LENGTH (builtin_type_void_data_ptr));
2866130812Smarcel  ADDRESS_TO_POINTER (builtin_type_void_data_ptr, &ptr, addr);
2867130812Smarcel  return ptr;
2868130812Smarcel}
2869130812Smarcel
2870130812Smarcel/*
2871130812Smarcel * Function: proc_set_watchpoint
2872130812Smarcel *
2873130812Smarcel */
2874130812Smarcel
2875130812Smarcelint
2876130812Smarcelproc_set_watchpoint (procinfo *pi, CORE_ADDR addr, int len, int wflags)
2877130812Smarcel{
2878130812Smarcel#if !defined (TARGET_HAS_HARDWARE_WATCHPOINTS)
2879130812Smarcel  return 0;
2880130812Smarcel#else
2881130812Smarcel/* Horrible hack!  Detect Solaris 2.5, because this doesn't work on 2.5 */
2882130812Smarcel#if defined (PIOCOPENLWP) || defined (UNIXWARE)	/* Solaris 2.5: bail out */
2883130812Smarcel  return 0;
2884130812Smarcel#else
2885130812Smarcel  struct {
2886130812Smarcel    procfs_ctl_t cmd;
2887130812Smarcel    char watch[sizeof (prwatch_t)];
2888130812Smarcel  } arg;
2889130812Smarcel  prwatch_t *pwatch;
2890130812Smarcel
2891130812Smarcel  pwatch            = (prwatch_t *) &arg.watch;
2892130812Smarcel  /* NOTE: cagney/2003-02-01: Even more horrible hack.  Need to
2893130812Smarcel     convert a target address into something that can be stored in a
2894130812Smarcel     native data structure.  */
2895130812Smarcel#ifdef PCAGENT	/* Horrible hack: only defined on Solaris 2.6+ */
2896130812Smarcel  pwatch->pr_vaddr  = (uintptr_t) procfs_address_to_host_pointer (addr);
2897130812Smarcel#else
2898130812Smarcel  pwatch->pr_vaddr  = (caddr_t) procfs_address_to_host_pointer (addr);
2899130812Smarcel#endif
2900130812Smarcel  pwatch->pr_size   = len;
2901130812Smarcel  pwatch->pr_wflags = wflags;
2902130812Smarcel#if defined(NEW_PROC_API) && defined (PCWATCH)
2903130812Smarcel  arg.cmd = PCWATCH;
2904130812Smarcel  return (write (pi->ctl_fd, &arg, sizeof (arg)) == sizeof (arg));
2905130812Smarcel#else
2906130812Smarcel#if defined (PIOCSWATCH)
2907130812Smarcel  return (ioctl (pi->ctl_fd, PIOCSWATCH, pwatch) >= 0);
2908130812Smarcel#else
2909130812Smarcel  return 0;	/* Fail */
2910130812Smarcel#endif
2911130812Smarcel#endif
2912130812Smarcel#endif
2913130812Smarcel#endif
2914130812Smarcel}
2915130812Smarcel
2916130812Smarcel#ifdef TM_I386SOL2_H		/* Is it hokey to use this? */
2917130812Smarcel
2918130812Smarcel#include <sys/sysi86.h>
2919130812Smarcel
2920130812Smarcel/*
2921130812Smarcel * Function: proc_get_LDT_entry
2922130812Smarcel *
2923130812Smarcel * Inputs:
2924130812Smarcel *   procinfo *pi;
2925130812Smarcel *   int key;
2926130812Smarcel *
2927130812Smarcel * The 'key' is actually the value of the lower 16 bits of
2928130812Smarcel * the GS register for the LWP that we're interested in.
2929130812Smarcel *
2930130812Smarcel * Return: matching ssh struct (LDT entry).
2931130812Smarcel */
2932130812Smarcel
2933130812Smarcelstruct ssd *
2934130812Smarcelproc_get_LDT_entry (procinfo *pi, int key)
2935130812Smarcel{
2936130812Smarcel  static struct ssd *ldt_entry = NULL;
2937130812Smarcel#ifdef NEW_PROC_API
2938130812Smarcel  char pathname[MAX_PROC_NAME_SIZE];
2939130812Smarcel  struct cleanup *old_chain = NULL;
2940130812Smarcel  int  fd;
2941130812Smarcel
2942130812Smarcel  /* Allocate space for one LDT entry.
2943130812Smarcel     This alloc must persist, because we return a pointer to it.  */
2944130812Smarcel  if (ldt_entry == NULL)
2945130812Smarcel    ldt_entry = (struct ssd *) xmalloc (sizeof (struct ssd));
2946130812Smarcel
2947130812Smarcel  /* Open the file descriptor for the LDT table.  */
2948130812Smarcel  sprintf (pathname, "/proc/%d/ldt", pi->pid);
2949130812Smarcel  if ((fd = open_with_retry (pathname, O_RDONLY)) < 0)
2950130812Smarcel    {
2951130812Smarcel      proc_warn (pi, "proc_get_LDT_entry (open)", __LINE__);
2952130812Smarcel      return NULL;
2953130812Smarcel    }
2954130812Smarcel  /* Make sure it gets closed again! */
2955130812Smarcel  old_chain = make_cleanup_close (fd);
2956130812Smarcel
2957130812Smarcel  /* Now 'read' thru the table, find a match and return it.  */
2958130812Smarcel  while (read (fd, ldt_entry, sizeof (struct ssd)) == sizeof (struct ssd))
2959130812Smarcel    {
2960130812Smarcel      if (ldt_entry->sel == 0 &&
2961130812Smarcel	  ldt_entry->bo  == 0 &&
2962130812Smarcel	  ldt_entry->acc1 == 0 &&
2963130812Smarcel	  ldt_entry->acc2 == 0)
2964130812Smarcel	break;	/* end of table */
2965130812Smarcel      /* If key matches, return this entry. */
2966130812Smarcel      if (ldt_entry->sel == key)
2967130812Smarcel	return ldt_entry;
2968130812Smarcel    }
2969130812Smarcel  /* Loop ended, match not found. */
2970130812Smarcel  return NULL;
2971130812Smarcel#else
2972130812Smarcel  int nldt, i;
2973130812Smarcel  static int nalloc = 0;
2974130812Smarcel
2975130812Smarcel  /* Get the number of LDT entries.  */
2976130812Smarcel  if (ioctl (pi->ctl_fd, PIOCNLDT, &nldt) < 0)
2977130812Smarcel    {
2978130812Smarcel      proc_warn (pi, "proc_get_LDT_entry (PIOCNLDT)", __LINE__);
2979130812Smarcel      return NULL;
2980130812Smarcel    }
2981130812Smarcel
2982130812Smarcel  /* Allocate space for the number of LDT entries. */
2983130812Smarcel  /* This alloc has to persist, 'cause we return a pointer to it. */
2984130812Smarcel  if (nldt > nalloc)
2985130812Smarcel    {
2986130812Smarcel      ldt_entry = (struct ssd *)
2987130812Smarcel	xrealloc (ldt_entry, (nldt + 1) * sizeof (struct ssd));
2988130812Smarcel      nalloc = nldt;
2989130812Smarcel    }
2990130812Smarcel
2991130812Smarcel  /* Read the whole table in one gulp.  */
2992130812Smarcel  if (ioctl (pi->ctl_fd, PIOCLDT, ldt_entry) < 0)
2993130812Smarcel    {
2994130812Smarcel      proc_warn (pi, "proc_get_LDT_entry (PIOCLDT)", __LINE__);
2995130812Smarcel      return NULL;
2996130812Smarcel    }
2997130812Smarcel
2998130812Smarcel  /* Search the table and return the (first) entry matching 'key'. */
2999130812Smarcel  for (i = 0; i < nldt; i++)
3000130812Smarcel    if (ldt_entry[i].sel == key)
3001130812Smarcel      return &ldt_entry[i];
3002130812Smarcel
3003130812Smarcel  /* Loop ended, match not found. */
3004130812Smarcel  return NULL;
3005130812Smarcel#endif
3006130812Smarcel}
3007130812Smarcel
3008130812Smarcel#endif /* TM_I386SOL2_H */
3009130812Smarcel
3010130812Smarcel/* =============== END, non-thread part of /proc  "MODULE" =============== */
3011130812Smarcel
3012130812Smarcel/* =================== Thread "MODULE" =================== */
3013130812Smarcel
3014130812Smarcel/* NOTE: you'll see more ifdefs and duplication of functions here,
3015130812Smarcel   since there is a different way to do threads on every OS.  */
3016130812Smarcel
3017130812Smarcel/*
3018130812Smarcel * Function: proc_get_nthreads
3019130812Smarcel *
3020130812Smarcel * Return the number of threads for the process
3021130812Smarcel */
3022130812Smarcel
3023130812Smarcel#if defined (PIOCNTHR) && defined (PIOCTLIST)
3024130812Smarcel/*
3025130812Smarcel * OSF version
3026130812Smarcel */
3027130812Smarcelint
3028130812Smarcelproc_get_nthreads (procinfo *pi)
3029130812Smarcel{
3030130812Smarcel  int nthreads = 0;
3031130812Smarcel
3032130812Smarcel  if (ioctl (pi->ctl_fd, PIOCNTHR, &nthreads) < 0)
3033130812Smarcel    proc_warn (pi, "procfs: PIOCNTHR failed", __LINE__);
3034130812Smarcel
3035130812Smarcel  return nthreads;
3036130812Smarcel}
3037130812Smarcel
3038130812Smarcel#else
3039130812Smarcel#if defined (SYS_lwpcreate) || defined (SYS_lwp_create) /* FIXME: multiple */
3040130812Smarcel/*
3041130812Smarcel * Solaris and Unixware version
3042130812Smarcel */
3043130812Smarcelint
3044130812Smarcelproc_get_nthreads (procinfo *pi)
3045130812Smarcel{
3046130812Smarcel  if (!pi->status_valid)
3047130812Smarcel    if (!proc_get_status (pi))
3048130812Smarcel      return 0;
3049130812Smarcel
3050130812Smarcel  /*
3051130812Smarcel   * NEW_PROC_API: only works for the process procinfo,
3052130812Smarcel   * because the LWP procinfos do not get prstatus filled in.
3053130812Smarcel   */
3054130812Smarcel#ifdef NEW_PROC_API
3055130812Smarcel  if (pi->tid != 0)	/* find the parent process procinfo */
3056130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
3057130812Smarcel#endif
3058130812Smarcel  return pi->prstatus.pr_nlwp;
3059130812Smarcel}
3060130812Smarcel
3061130812Smarcel#else
3062130812Smarcel/*
3063130812Smarcel * Default version
3064130812Smarcel */
3065130812Smarcelint
3066130812Smarcelproc_get_nthreads (procinfo *pi)
3067130812Smarcel{
3068130812Smarcel  return 0;
3069130812Smarcel}
3070130812Smarcel#endif
3071130812Smarcel#endif
3072130812Smarcel
3073130812Smarcel/*
3074130812Smarcel * Function: proc_get_current_thread (LWP version)
3075130812Smarcel *
3076130812Smarcel * Return the ID of the thread that had an event of interest.
3077130812Smarcel * (ie. the one that hit a breakpoint or other traced event).
3078130812Smarcel * All other things being equal, this should be the ID of a
3079130812Smarcel * thread that is currently executing.
3080130812Smarcel */
3081130812Smarcel
3082130812Smarcel#if defined (SYS_lwpcreate) || defined (SYS_lwp_create) /* FIXME: multiple */
3083130812Smarcel/*
3084130812Smarcel * Solaris and Unixware version
3085130812Smarcel */
3086130812Smarcelint
3087130812Smarcelproc_get_current_thread (procinfo *pi)
3088130812Smarcel{
3089130812Smarcel  /*
3090130812Smarcel   * Note: this should be applied to the root procinfo for the process,
3091130812Smarcel   * not to the procinfo for an LWP.  If applied to the procinfo for
3092130812Smarcel   * an LWP, it will simply return that LWP's ID.  In that case,
3093130812Smarcel   * find the parent process procinfo.
3094130812Smarcel   */
3095130812Smarcel
3096130812Smarcel  if (pi->tid != 0)
3097130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
3098130812Smarcel
3099130812Smarcel  if (!pi->status_valid)
3100130812Smarcel    if (!proc_get_status (pi))
3101130812Smarcel      return 0;
3102130812Smarcel
3103130812Smarcel#ifdef NEW_PROC_API
3104130812Smarcel  return pi->prstatus.pr_lwp.pr_lwpid;
3105130812Smarcel#else
3106130812Smarcel  return pi->prstatus.pr_who;
3107130812Smarcel#endif
3108130812Smarcel}
3109130812Smarcel
3110130812Smarcel#else
3111130812Smarcel#if defined (PIOCNTHR) && defined (PIOCTLIST)
3112130812Smarcel/*
3113130812Smarcel * OSF version
3114130812Smarcel */
3115130812Smarcelint
3116130812Smarcelproc_get_current_thread (procinfo *pi)
3117130812Smarcel{
3118130812Smarcel#if 0	/* FIXME: not ready for prime time? */
3119130812Smarcel  return pi->prstatus.pr_tid;
3120130812Smarcel#else
3121130812Smarcel  return 0;
3122130812Smarcel#endif
3123130812Smarcel}
3124130812Smarcel
3125130812Smarcel#else
3126130812Smarcel/*
3127130812Smarcel * Default version
3128130812Smarcel */
3129130812Smarcelint
3130130812Smarcelproc_get_current_thread (procinfo *pi)
3131130812Smarcel{
3132130812Smarcel  return 0;
3133130812Smarcel}
3134130812Smarcel
3135130812Smarcel#endif
3136130812Smarcel#endif
3137130812Smarcel
3138130812Smarcel/*
3139130812Smarcel * Function: proc_update_threads
3140130812Smarcel *
3141130812Smarcel * Discover the IDs of all the threads within the process, and
3142130812Smarcel * create a procinfo for each of them (chained to the parent).
3143130812Smarcel *
3144130812Smarcel * This unfortunately requires a different method on every OS.
3145130812Smarcel *
3146130812Smarcel * Return: non-zero for success, zero for failure.
3147130812Smarcel */
3148130812Smarcel
3149130812Smarcelint
3150130812Smarcelproc_delete_dead_threads (procinfo *parent, procinfo *thread, void *ignore)
3151130812Smarcel{
3152130812Smarcel  if (thread && parent)	/* sanity */
3153130812Smarcel    {
3154130812Smarcel      thread->status_valid = 0;
3155130812Smarcel      if (!proc_get_status (thread))
3156130812Smarcel	destroy_one_procinfo (&parent->thread_list, thread);
3157130812Smarcel    }
3158130812Smarcel  return 0;	/* keep iterating */
3159130812Smarcel}
3160130812Smarcel
3161130812Smarcel#if defined (PIOCLSTATUS)
3162130812Smarcel/*
3163130812Smarcel * Solaris 2.5 (ioctl) version
3164130812Smarcel */
3165130812Smarcelint
3166130812Smarcelproc_update_threads (procinfo *pi)
3167130812Smarcel{
3168130812Smarcel  gdb_prstatus_t *prstatus;
3169130812Smarcel  struct cleanup *old_chain = NULL;
3170130812Smarcel  procinfo *thread;
3171130812Smarcel  int nlwp, i;
3172130812Smarcel
3173130812Smarcel  /*
3174130812Smarcel   * We should never have to apply this operation to any procinfo
3175130812Smarcel   * except the one for the main process.  If that ever changes
3176130812Smarcel   * for any reason, then take out the following clause and
3177130812Smarcel   * replace it with one that makes sure the ctl_fd is open.
3178130812Smarcel   */
3179130812Smarcel
3180130812Smarcel  if (pi->tid != 0)
3181130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
3182130812Smarcel
3183130812Smarcel  proc_iterate_over_threads (pi, proc_delete_dead_threads, NULL);
3184130812Smarcel
3185130812Smarcel  if ((nlwp = proc_get_nthreads (pi)) <= 1)
3186130812Smarcel    return 1;	/* Process is not multi-threaded; nothing to do.  */
3187130812Smarcel
3188130812Smarcel  prstatus = xmalloc (sizeof (gdb_prstatus_t) * (nlwp + 1));
3189130812Smarcel
3190130812Smarcel  old_chain = make_cleanup (xfree, prstatus);
3191130812Smarcel  if (ioctl (pi->ctl_fd, PIOCLSTATUS, prstatus) < 0)
3192130812Smarcel    proc_error (pi, "update_threads (PIOCLSTATUS)", __LINE__);
3193130812Smarcel
3194130812Smarcel  /* Skip element zero, which represents the process as a whole. */
3195130812Smarcel  for (i = 1; i < nlwp + 1; i++)
3196130812Smarcel    {
3197130812Smarcel      if ((thread = create_procinfo (pi->pid, prstatus[i].pr_who)) == NULL)
3198130812Smarcel	proc_error (pi, "update_threads, create_procinfo", __LINE__);
3199130812Smarcel
3200130812Smarcel      memcpy (&thread->prstatus, &prstatus[i], sizeof (*prstatus));
3201130812Smarcel      thread->status_valid = 1;
3202130812Smarcel    }
3203130812Smarcel  pi->threads_valid = 1;
3204130812Smarcel  do_cleanups (old_chain);
3205130812Smarcel  return 1;
3206130812Smarcel}
3207130812Smarcel#else
3208130812Smarcel#ifdef NEW_PROC_API
3209130812Smarcel/*
3210130812Smarcel * Unixware and Solaris 6 (and later) version
3211130812Smarcel */
3212130812Smarcelstatic void
3213130812Smarceldo_closedir_cleanup (void *dir)
3214130812Smarcel{
3215130812Smarcel  closedir (dir);
3216130812Smarcel}
3217130812Smarcel
3218130812Smarcelint
3219130812Smarcelproc_update_threads (procinfo *pi)
3220130812Smarcel{
3221130812Smarcel  char pathname[MAX_PROC_NAME_SIZE + 16];
3222130812Smarcel  struct dirent *direntry;
3223130812Smarcel  struct cleanup *old_chain = NULL;
3224130812Smarcel  procinfo *thread;
3225130812Smarcel  DIR *dirp;
3226130812Smarcel  int lwpid;
3227130812Smarcel
3228130812Smarcel  /*
3229130812Smarcel   * We should never have to apply this operation to any procinfo
3230130812Smarcel   * except the one for the main process.  If that ever changes
3231130812Smarcel   * for any reason, then take out the following clause and
3232130812Smarcel   * replace it with one that makes sure the ctl_fd is open.
3233130812Smarcel   */
3234130812Smarcel
3235130812Smarcel  if (pi->tid != 0)
3236130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
3237130812Smarcel
3238130812Smarcel  proc_iterate_over_threads (pi, proc_delete_dead_threads, NULL);
3239130812Smarcel
3240130812Smarcel  /*
3241130812Smarcel   * Unixware
3242130812Smarcel   *
3243130812Smarcel   * Note: this brute-force method is the only way I know of
3244130812Smarcel   * to accomplish this task on Unixware.  This method will
3245130812Smarcel   * also work on Solaris 2.6 and 2.7.  There is a much simpler
3246130812Smarcel   * and more elegant way to do this on Solaris, but the margins
3247130812Smarcel   * of this manuscript are too small to write it here...  ;-)
3248130812Smarcel   */
3249130812Smarcel
3250130812Smarcel  strcpy (pathname, pi->pathname);
3251130812Smarcel  strcat (pathname, "/lwp");
3252130812Smarcel  if ((dirp = opendir (pathname)) == NULL)
3253130812Smarcel    proc_error (pi, "update_threads, opendir", __LINE__);
3254130812Smarcel
3255130812Smarcel  old_chain = make_cleanup (do_closedir_cleanup, dirp);
3256130812Smarcel  while ((direntry = readdir (dirp)) != NULL)
3257130812Smarcel    if (direntry->d_name[0] != '.')		/* skip '.' and '..' */
3258130812Smarcel      {
3259130812Smarcel	lwpid = atoi (&direntry->d_name[0]);
3260130812Smarcel	if ((thread = create_procinfo (pi->pid, lwpid)) == NULL)
3261130812Smarcel	  proc_error (pi, "update_threads, create_procinfo", __LINE__);
3262130812Smarcel      }
3263130812Smarcel  pi->threads_valid = 1;
3264130812Smarcel  do_cleanups (old_chain);
3265130812Smarcel  return 1;
3266130812Smarcel}
3267130812Smarcel#else
3268130812Smarcel#ifdef PIOCTLIST
3269130812Smarcel/*
3270130812Smarcel * OSF version
3271130812Smarcel */
3272130812Smarcelint
3273130812Smarcelproc_update_threads (procinfo *pi)
3274130812Smarcel{
3275130812Smarcel  int nthreads, i;
3276130812Smarcel  tid_t *threads;
3277130812Smarcel
3278130812Smarcel  /*
3279130812Smarcel   * We should never have to apply this operation to any procinfo
3280130812Smarcel   * except the one for the main process.  If that ever changes
3281130812Smarcel   * for any reason, then take out the following clause and
3282130812Smarcel   * replace it with one that makes sure the ctl_fd is open.
3283130812Smarcel   */
3284130812Smarcel
3285130812Smarcel  if (pi->tid != 0)
3286130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
3287130812Smarcel
3288130812Smarcel  proc_iterate_over_threads (pi, proc_delete_dead_threads, NULL);
3289130812Smarcel
3290130812Smarcel  nthreads = proc_get_nthreads (pi);
3291130812Smarcel  if (nthreads < 2)
3292130812Smarcel    return 0;		/* nothing to do for 1 or fewer threads */
3293130812Smarcel
3294130812Smarcel  threads = xmalloc (nthreads * sizeof (tid_t));
3295130812Smarcel
3296130812Smarcel  if (ioctl (pi->ctl_fd, PIOCTLIST, threads) < 0)
3297130812Smarcel    proc_error (pi, "procfs: update_threads (PIOCTLIST)", __LINE__);
3298130812Smarcel
3299130812Smarcel  for (i = 0; i < nthreads; i++)
3300130812Smarcel    {
3301130812Smarcel      if (!find_procinfo (pi->pid, threads[i]))
3302130812Smarcel	if (!create_procinfo  (pi->pid, threads[i]))
3303130812Smarcel	  proc_error (pi, "update_threads, create_procinfo", __LINE__);
3304130812Smarcel    }
3305130812Smarcel  pi->threads_valid = 1;
3306130812Smarcel  return 1;
3307130812Smarcel}
3308130812Smarcel#else
3309130812Smarcel/*
3310130812Smarcel * Default version
3311130812Smarcel */
3312130812Smarcelint
3313130812Smarcelproc_update_threads (procinfo *pi)
3314130812Smarcel{
3315130812Smarcel  return 0;
3316130812Smarcel}
3317130812Smarcel#endif	/* OSF PIOCTLIST */
3318130812Smarcel#endif  /* NEW_PROC_API   */
3319130812Smarcel#endif  /* SOL 2.5 PIOCLSTATUS */
3320130812Smarcel
3321130812Smarcel/*
3322130812Smarcel * Function: proc_iterate_over_threads
3323130812Smarcel *
3324130812Smarcel * Description:
3325130812Smarcel *   Given a pointer to a function, call that function once
3326130812Smarcel *   for each lwp in the procinfo list, until the function
3327130812Smarcel *   returns non-zero, in which event return the value
3328130812Smarcel *   returned by the function.
3329130812Smarcel *
3330130812Smarcel * Note: this function does NOT call update_threads.
3331130812Smarcel * If you want to discover new threads first, you must
3332130812Smarcel * call that function explicitly.  This function just makes
3333130812Smarcel * a quick pass over the currently-known procinfos.
3334130812Smarcel *
3335130812Smarcel * Arguments:
3336130812Smarcel *   pi		- parent process procinfo
3337130812Smarcel *   func	- per-thread function
3338130812Smarcel *   ptr	- opaque parameter for function.
3339130812Smarcel *
3340130812Smarcel * Return:
3341130812Smarcel *   First non-zero return value from the callee, or zero.
3342130812Smarcel */
3343130812Smarcel
3344130812Smarcelint
3345130812Smarcelproc_iterate_over_threads (procinfo *pi,
3346130812Smarcel			   int (*func) (procinfo *, procinfo *, void *),
3347130812Smarcel			   void *ptr)
3348130812Smarcel{
3349130812Smarcel  procinfo *thread, *next;
3350130812Smarcel  int retval = 0;
3351130812Smarcel
3352130812Smarcel  /*
3353130812Smarcel   * We should never have to apply this operation to any procinfo
3354130812Smarcel   * except the one for the main process.  If that ever changes
3355130812Smarcel   * for any reason, then take out the following clause and
3356130812Smarcel   * replace it with one that makes sure the ctl_fd is open.
3357130812Smarcel   */
3358130812Smarcel
3359130812Smarcel  if (pi->tid != 0)
3360130812Smarcel    pi = find_procinfo_or_die (pi->pid, 0);
3361130812Smarcel
3362130812Smarcel  for (thread = pi->thread_list; thread != NULL; thread = next)
3363130812Smarcel    {
3364130812Smarcel      next = thread->next;	/* in case thread is destroyed */
3365130812Smarcel      if ((retval = (*func) (pi, thread, ptr)) != 0)
3366130812Smarcel	break;
3367130812Smarcel    }
3368130812Smarcel
3369130812Smarcel  return retval;
3370130812Smarcel}
3371130812Smarcel
3372130812Smarcel/* =================== END, Thread "MODULE" =================== */
3373130812Smarcel
3374130812Smarcel/* =================== END, /proc  "MODULE" =================== */
3375130812Smarcel
3376130812Smarcel/* ===================  GDB  "MODULE" =================== */
3377130812Smarcel
3378130812Smarcel/*
3379130812Smarcel * Here are all of the gdb target vector functions and their friends.
3380130812Smarcel */
3381130812Smarcel
3382130812Smarcelstatic ptid_t do_attach (ptid_t ptid);
3383130812Smarcelstatic void do_detach (int signo);
3384130812Smarcelstatic int register_gdb_signals (procinfo *, gdb_sigset_t *);
3385130812Smarcel
3386130812Smarcel/*
3387130812Smarcel * Function: procfs_debug_inferior
3388130812Smarcel *
3389130812Smarcel * Sets up the inferior to be debugged.
3390130812Smarcel * Registers to trace signals, hardware faults, and syscalls.
3391130812Smarcel * Note: does not set RLC flag: caller may want to customize that.
3392130812Smarcel *
3393130812Smarcel * Returns: zero for success (note! unlike most functions in this module)
3394130812Smarcel *   On failure, returns the LINE NUMBER where it failed!
3395130812Smarcel */
3396130812Smarcel
3397130812Smarcelstatic int
3398130812Smarcelprocfs_debug_inferior (procinfo *pi)
3399130812Smarcel{
3400130812Smarcel  fltset_t traced_faults;
3401130812Smarcel  gdb_sigset_t traced_signals;
3402130812Smarcel  sysset_t *traced_syscall_entries;
3403130812Smarcel  sysset_t *traced_syscall_exits;
3404130812Smarcel  int status;
3405130812Smarcel
3406130812Smarcel#ifdef PROCFS_DONT_TRACE_FAULTS
3407130812Smarcel  /* On some systems (OSF), we don't trace hardware faults.
3408130812Smarcel     Apparently it's enough that we catch them as signals.
3409130812Smarcel     Wonder why we don't just do that in general? */
3410130812Smarcel  premptyset (&traced_faults);		/* don't trace faults. */
3411130812Smarcel#else
3412130812Smarcel  /* Register to trace hardware faults in the child. */
3413130812Smarcel  prfillset (&traced_faults);		/* trace all faults... */
3414130812Smarcel  prdelset  (&traced_faults, FLTPAGE);	/* except page fault.  */
3415130812Smarcel#endif
3416130812Smarcel  if (!proc_set_traced_faults  (pi, &traced_faults))
3417130812Smarcel    return __LINE__;
3418130812Smarcel
3419130812Smarcel  /* Register to trace selected signals in the child. */
3420130812Smarcel  premptyset (&traced_signals);
3421130812Smarcel  if (!register_gdb_signals (pi, &traced_signals))
3422130812Smarcel    return __LINE__;
3423130812Smarcel
3424130812Smarcel
3425130812Smarcel  /* Register to trace the 'exit' system call (on entry).  */
3426130812Smarcel  traced_syscall_entries = sysset_t_alloc (pi);
3427130812Smarcel  gdb_premptysysset (traced_syscall_entries);
3428130812Smarcel#ifdef SYS_exit
3429130812Smarcel  gdb_praddsysset (traced_syscall_entries, SYS_exit);
3430130812Smarcel#endif
3431130812Smarcel#ifdef SYS_lwpexit
3432130812Smarcel  gdb_praddsysset (traced_syscall_entries, SYS_lwpexit);	/* And _lwp_exit... */
3433130812Smarcel#endif
3434130812Smarcel#ifdef SYS_lwp_exit
3435130812Smarcel  gdb_praddsysset (traced_syscall_entries, SYS_lwp_exit);
3436130812Smarcel#endif
3437130812Smarcel#ifdef DYNAMIC_SYSCALLS
3438130812Smarcel  {
3439130812Smarcel    int callnum = find_syscall (pi, "_exit");
3440130812Smarcel    if (callnum >= 0)
3441130812Smarcel      gdb_praddsysset (traced_syscall_entries, callnum);
3442130812Smarcel  }
3443130812Smarcel#endif
3444130812Smarcel
3445130812Smarcel  status = proc_set_traced_sysentry (pi, traced_syscall_entries);
3446130812Smarcel  xfree (traced_syscall_entries);
3447130812Smarcel  if (!status)
3448130812Smarcel    return __LINE__;
3449130812Smarcel
3450130812Smarcel#ifdef PRFS_STOPEXEC	/* defined on OSF */
3451130812Smarcel  /* OSF method for tracing exec syscalls.  Quoting:
3452130812Smarcel     Under Alpha OSF/1 we have to use a PIOCSSPCACT ioctl to trace
3453130812Smarcel     exits from exec system calls because of the user level loader.  */
3454130812Smarcel  /* FIXME: make nice and maybe move into an access function. */
3455130812Smarcel  {
3456130812Smarcel    int prfs_flags;
3457130812Smarcel
3458130812Smarcel    if (ioctl (pi->ctl_fd, PIOCGSPCACT, &prfs_flags) < 0)
3459130812Smarcel      return __LINE__;
3460130812Smarcel
3461130812Smarcel    prfs_flags |= PRFS_STOPEXEC;
3462130812Smarcel
3463130812Smarcel    if (ioctl (pi->ctl_fd, PIOCSSPCACT, &prfs_flags) < 0)
3464130812Smarcel      return __LINE__;
3465130812Smarcel  }
3466130812Smarcel#else /* not PRFS_STOPEXEC */
3467130812Smarcel  /* Everyone else's (except OSF) method for tracing exec syscalls */
3468130812Smarcel  /* GW: Rationale...
3469130812Smarcel     Not all systems with /proc have all the exec* syscalls with the same
3470130812Smarcel     names.  On the SGI, for example, there is no SYS_exec, but there
3471130812Smarcel     *is* a SYS_execv.  So, we try to account for that. */
3472130812Smarcel
3473130812Smarcel  traced_syscall_exits = sysset_t_alloc (pi);
3474130812Smarcel  gdb_premptysysset (traced_syscall_exits);
3475130812Smarcel#ifdef SYS_exec
3476130812Smarcel  gdb_praddsysset (traced_syscall_exits, SYS_exec);
3477130812Smarcel#endif
3478130812Smarcel#ifdef SYS_execve
3479130812Smarcel  gdb_praddsysset (traced_syscall_exits, SYS_execve);
3480130812Smarcel#endif
3481130812Smarcel#ifdef SYS_execv
3482130812Smarcel  gdb_praddsysset (traced_syscall_exits, SYS_execv);
3483130812Smarcel#endif
3484130812Smarcel
3485130812Smarcel#ifdef SYS_lwpcreate
3486130812Smarcel  gdb_praddsysset (traced_syscall_exits, SYS_lwpcreate);
3487130812Smarcel  gdb_praddsysset (traced_syscall_exits, SYS_lwpexit);
3488130812Smarcel#endif
3489130812Smarcel
3490130812Smarcel#ifdef SYS_lwp_create	/* FIXME: once only, please */
3491130812Smarcel  gdb_praddsysset (traced_syscall_exits, SYS_lwp_create);
3492130812Smarcel  gdb_praddsysset (traced_syscall_exits, SYS_lwp_exit);
3493130812Smarcel#endif
3494130812Smarcel
3495130812Smarcel#ifdef DYNAMIC_SYSCALLS
3496130812Smarcel  {
3497130812Smarcel    int callnum = find_syscall (pi, "execve");
3498130812Smarcel    if (callnum >= 0)
3499130812Smarcel      gdb_praddsysset (traced_syscall_exits, callnum);
3500130812Smarcel    callnum = find_syscall (pi, "ra_execve");
3501130812Smarcel    if (callnum >= 0)
3502130812Smarcel      gdb_praddsysset (traced_syscall_exits, callnum);
3503130812Smarcel  }
3504130812Smarcel#endif
3505130812Smarcel
3506130812Smarcel  status = proc_set_traced_sysexit (pi, traced_syscall_exits);
3507130812Smarcel  xfree (traced_syscall_exits);
3508130812Smarcel  if (!status)
3509130812Smarcel    return __LINE__;
3510130812Smarcel
3511130812Smarcel#endif /* PRFS_STOPEXEC */
3512130812Smarcel  return 0;
3513130812Smarcel}
3514130812Smarcel
3515130812Smarcelstatic void
3516130812Smarcelprocfs_attach (char *args, int from_tty)
3517130812Smarcel{
3518130812Smarcel  char *exec_file;
3519130812Smarcel  int   pid;
3520130812Smarcel
3521130812Smarcel  if (!args)
3522130812Smarcel    error_no_arg ("process-id to attach");
3523130812Smarcel
3524130812Smarcel  pid = atoi (args);
3525130812Smarcel  if (pid == getpid ())
3526130812Smarcel    error ("Attaching GDB to itself is not a good idea...");
3527130812Smarcel
3528130812Smarcel  if (from_tty)
3529130812Smarcel    {
3530130812Smarcel      exec_file = get_exec_file (0);
3531130812Smarcel
3532130812Smarcel      if (exec_file)
3533130812Smarcel	printf_filtered ("Attaching to program `%s', %s\n",
3534130812Smarcel			 exec_file, target_pid_to_str (pid_to_ptid (pid)));
3535130812Smarcel      else
3536130812Smarcel	printf_filtered ("Attaching to %s\n",
3537130812Smarcel	                 target_pid_to_str (pid_to_ptid (pid)));
3538130812Smarcel
3539130812Smarcel      fflush (stdout);
3540130812Smarcel    }
3541130812Smarcel  inferior_ptid = do_attach (pid_to_ptid (pid));
3542130812Smarcel  push_target (&procfs_ops);
3543130812Smarcel}
3544130812Smarcel
3545130812Smarcelstatic void
3546130812Smarcelprocfs_detach (char *args, int from_tty)
3547130812Smarcel{
3548130812Smarcel  char *exec_file;
3549130812Smarcel  int   signo = 0;
3550130812Smarcel
3551130812Smarcel  if (from_tty)
3552130812Smarcel    {
3553130812Smarcel      exec_file = get_exec_file (0);
3554130812Smarcel      if (exec_file == 0)
3555130812Smarcel	exec_file = "";
3556130812Smarcel      printf_filtered ("Detaching from program: %s %s\n",
3557130812Smarcel	      exec_file, target_pid_to_str (inferior_ptid));
3558130812Smarcel      fflush (stdout);
3559130812Smarcel    }
3560130812Smarcel  if (args)
3561130812Smarcel    signo = atoi (args);
3562130812Smarcel
3563130812Smarcel  do_detach (signo);
3564130812Smarcel  inferior_ptid = null_ptid;
3565130812Smarcel  unpush_target (&procfs_ops);		/* Pop out of handling an inferior */
3566130812Smarcel}
3567130812Smarcel
3568130812Smarcelstatic ptid_t
3569130812Smarceldo_attach (ptid_t ptid)
3570130812Smarcel{
3571130812Smarcel  procinfo *pi;
3572130812Smarcel  int fail;
3573130812Smarcel
3574130812Smarcel  if ((pi = create_procinfo (PIDGET (ptid), 0)) == NULL)
3575130812Smarcel    perror ("procfs: out of memory in 'attach'");
3576130812Smarcel
3577130812Smarcel  if (!open_procinfo_files (pi, FD_CTL))
3578130812Smarcel    {
3579130812Smarcel      fprintf_filtered (gdb_stderr, "procfs:%d -- ", __LINE__);
3580130812Smarcel      sprintf (errmsg, "do_attach: couldn't open /proc file for process %d",
3581130812Smarcel	       PIDGET (ptid));
3582130812Smarcel      dead_procinfo (pi, errmsg, NOKILL);
3583130812Smarcel    }
3584130812Smarcel
3585130812Smarcel  /* Stop the process (if it isn't already stopped).  */
3586130812Smarcel  if (proc_flags (pi) & (PR_STOPPED | PR_ISTOP))
3587130812Smarcel    {
3588130812Smarcel      pi->was_stopped = 1;
3589130812Smarcel      proc_prettyprint_why (proc_why (pi), proc_what (pi), 1);
3590130812Smarcel    }
3591130812Smarcel  else
3592130812Smarcel    {
3593130812Smarcel      pi->was_stopped = 0;
3594130812Smarcel      /* Set the process to run again when we close it.  */
3595130812Smarcel      if (!proc_set_run_on_last_close (pi))
3596130812Smarcel	dead_procinfo (pi, "do_attach: couldn't set RLC.", NOKILL);
3597130812Smarcel
3598130812Smarcel      /* Now stop the process. */
3599130812Smarcel      if (!proc_stop_process (pi))
3600130812Smarcel	dead_procinfo (pi, "do_attach: couldn't stop the process.", NOKILL);
3601130812Smarcel      pi->ignore_next_sigstop = 1;
3602130812Smarcel    }
3603130812Smarcel  /* Save some of the /proc state to be restored if we detach.  */
3604130812Smarcel  if (!proc_get_traced_faults   (pi, &pi->saved_fltset))
3605130812Smarcel    dead_procinfo (pi, "do_attach: couldn't save traced faults.", NOKILL);
3606130812Smarcel  if (!proc_get_traced_signals  (pi, &pi->saved_sigset))
3607130812Smarcel    dead_procinfo (pi, "do_attach: couldn't save traced signals.", NOKILL);
3608130812Smarcel  if (!proc_get_traced_sysentry (pi, pi->saved_entryset))
3609130812Smarcel    dead_procinfo (pi, "do_attach: couldn't save traced syscall entries.",
3610130812Smarcel		   NOKILL);
3611130812Smarcel  if (!proc_get_traced_sysexit  (pi, pi->saved_exitset))
3612130812Smarcel    dead_procinfo (pi, "do_attach: couldn't save traced syscall exits.",
3613130812Smarcel		   NOKILL);
3614130812Smarcel  if (!proc_get_held_signals    (pi, &pi->saved_sighold))
3615130812Smarcel    dead_procinfo (pi, "do_attach: couldn't save held signals.", NOKILL);
3616130812Smarcel
3617130812Smarcel  if ((fail = procfs_debug_inferior (pi)) != 0)
3618130812Smarcel    dead_procinfo (pi, "do_attach: failed in procfs_debug_inferior", NOKILL);
3619130812Smarcel
3620130812Smarcel  /* Let GDB know that the inferior was attached.  */
3621130812Smarcel  attach_flag = 1;
3622130812Smarcel  return MERGEPID (pi->pid, proc_get_current_thread (pi));
3623130812Smarcel}
3624130812Smarcel
3625130812Smarcelstatic void
3626130812Smarceldo_detach (int signo)
3627130812Smarcel{
3628130812Smarcel  procinfo *pi;
3629130812Smarcel
3630130812Smarcel  /* Find procinfo for the main process */
3631130812Smarcel  pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0); /* FIXME: threads */
3632130812Smarcel  if (signo)
3633130812Smarcel    if (!proc_set_current_signal (pi, signo))
3634130812Smarcel      proc_warn (pi, "do_detach, set_current_signal", __LINE__);
3635130812Smarcel
3636130812Smarcel  if (!proc_set_traced_signals (pi, &pi->saved_sigset))
3637130812Smarcel    proc_warn (pi, "do_detach, set_traced_signal", __LINE__);
3638130812Smarcel
3639130812Smarcel  if (!proc_set_traced_faults (pi, &pi->saved_fltset))
3640130812Smarcel    proc_warn (pi, "do_detach, set_traced_faults", __LINE__);
3641130812Smarcel
3642130812Smarcel  if (!proc_set_traced_sysentry (pi, pi->saved_entryset))
3643130812Smarcel    proc_warn (pi, "do_detach, set_traced_sysentry", __LINE__);
3644130812Smarcel
3645130812Smarcel  if (!proc_set_traced_sysexit (pi, pi->saved_exitset))
3646130812Smarcel    proc_warn (pi, "do_detach, set_traced_sysexit", __LINE__);
3647130812Smarcel
3648130812Smarcel  if (!proc_set_held_signals (pi, &pi->saved_sighold))
3649130812Smarcel    proc_warn (pi, "do_detach, set_held_signals", __LINE__);
3650130812Smarcel
3651130812Smarcel  if (signo || (proc_flags (pi) & (PR_STOPPED | PR_ISTOP)))
3652130812Smarcel    if (signo || !(pi->was_stopped) ||
3653130812Smarcel	query ("Was stopped when attached, make it runnable again? "))
3654130812Smarcel      {
3655130812Smarcel	/* Clear any pending signal.  */
3656130812Smarcel	if (!proc_clear_current_fault (pi))
3657130812Smarcel	  proc_warn (pi, "do_detach, clear_current_fault", __LINE__);
3658130812Smarcel
3659130812Smarcel	if (signo == 0 && !proc_clear_current_signal (pi))
3660130812Smarcel	  proc_warn (pi, "do_detach, clear_current_signal", __LINE__);
3661130812Smarcel
3662130812Smarcel	if (!proc_set_run_on_last_close (pi))
3663130812Smarcel	  proc_warn (pi, "do_detach, set_rlc", __LINE__);
3664130812Smarcel      }
3665130812Smarcel
3666130812Smarcel  attach_flag = 0;
3667130812Smarcel  destroy_procinfo (pi);
3668130812Smarcel}
3669130812Smarcel
3670130812Smarcel/*
3671130812Smarcel * fetch_registers
3672130812Smarcel *
3673130812Smarcel * Since the /proc interface cannot give us individual registers,
3674130812Smarcel * we pay no attention to the (regno) argument, and just fetch them all.
3675130812Smarcel * This results in the possibility that we will do unnecessarily many
3676130812Smarcel * fetches, since we may be called repeatedly for individual registers.
3677130812Smarcel * So we cache the results, and mark the cache invalid when the process
3678130812Smarcel * is resumed.
3679130812Smarcel */
3680130812Smarcel
3681130812Smarcelstatic void
3682130812Smarcelprocfs_fetch_registers (int regno)
3683130812Smarcel{
3684130812Smarcel  gdb_fpregset_t *fpregs;
3685130812Smarcel  gdb_gregset_t  *gregs;
3686130812Smarcel  procinfo       *pi;
3687130812Smarcel  int            pid;
3688130812Smarcel  int            tid;
3689130812Smarcel
3690130812Smarcel  pid = PIDGET (inferior_ptid);
3691130812Smarcel  tid = TIDGET (inferior_ptid);
3692130812Smarcel
3693130812Smarcel  /* First look up procinfo for the main process. */
3694130812Smarcel  pi  = find_procinfo_or_die (pid, 0);
3695130812Smarcel
3696130812Smarcel  /* If the event thread is not the same as GDB's requested thread
3697130812Smarcel     (ie. inferior_ptid), then look up procinfo for the requested
3698130812Smarcel     thread.  */
3699130812Smarcel  if ((tid != 0) &&
3700130812Smarcel      (tid != proc_get_current_thread (pi)))
3701130812Smarcel    pi = find_procinfo_or_die (pid, tid);
3702130812Smarcel
3703130812Smarcel  if (pi == NULL)
3704130812Smarcel    error ("procfs: fetch_registers failed to find procinfo for %s",
3705130812Smarcel	   target_pid_to_str (inferior_ptid));
3706130812Smarcel
3707130812Smarcel  if ((gregs = proc_get_gregs (pi)) == NULL)
3708130812Smarcel    proc_error (pi, "fetch_registers, get_gregs", __LINE__);
3709130812Smarcel
3710130812Smarcel  supply_gregset (gregs);
3711130812Smarcel
3712130812Smarcel  if (FP0_REGNUM >= 0)	/* need floating point? */
3713130812Smarcel    {
3714130812Smarcel      if ((regno >= 0 && regno < FP0_REGNUM)
3715130812Smarcel	  || regno == PC_REGNUM
3716130812Smarcel	  || regno == DEPRECATED_FP_REGNUM
3717130812Smarcel	  || regno == SP_REGNUM)
3718130812Smarcel	return;			/* not a floating point register */
3719130812Smarcel
3720130812Smarcel      if ((fpregs = proc_get_fpregs (pi)) == NULL)
3721130812Smarcel	proc_error (pi, "fetch_registers, get_fpregs", __LINE__);
3722130812Smarcel
3723130812Smarcel      supply_fpregset (fpregs);
3724130812Smarcel    }
3725130812Smarcel}
3726130812Smarcel
3727130812Smarcel/* Get ready to modify the registers array.  On machines which store
3728130812Smarcel   individual registers, this doesn't need to do anything.  On
3729130812Smarcel   machines which store all the registers in one fell swoop, such as
3730130812Smarcel   /proc, this makes sure that registers contains all the registers
3731130812Smarcel   from the program being debugged.  */
3732130812Smarcel
3733130812Smarcelstatic void
3734130812Smarcelprocfs_prepare_to_store (void)
3735130812Smarcel{
3736130812Smarcel#ifdef CHILD_PREPARE_TO_STORE
3737130812Smarcel  CHILD_PREPARE_TO_STORE ();
3738130812Smarcel#endif
3739130812Smarcel}
3740130812Smarcel
3741130812Smarcel/*
3742130812Smarcel * store_registers
3743130812Smarcel *
3744130812Smarcel * Since the /proc interface will not read individual registers,
3745130812Smarcel * we will cache these requests until the process is resumed, and
3746130812Smarcel * only then write them back to the inferior process.
3747130812Smarcel *
3748130812Smarcel * FIXME: is that a really bad idea?  Have to think about cases
3749130812Smarcel * where writing one register might affect the value of others, etc.
3750130812Smarcel */
3751130812Smarcel
3752130812Smarcelstatic void
3753130812Smarcelprocfs_store_registers (int regno)
3754130812Smarcel{
3755130812Smarcel  gdb_fpregset_t *fpregs;
3756130812Smarcel  gdb_gregset_t  *gregs;
3757130812Smarcel  procinfo       *pi;
3758130812Smarcel  int            pid;
3759130812Smarcel  int            tid;
3760130812Smarcel
3761130812Smarcel  pid = PIDGET (inferior_ptid);
3762130812Smarcel  tid = TIDGET (inferior_ptid);
3763130812Smarcel
3764130812Smarcel  /* First find procinfo for main process */
3765130812Smarcel  pi  = find_procinfo_or_die (pid, 0);
3766130812Smarcel
3767130812Smarcel  /* If current lwp for process is not the same as requested thread
3768130812Smarcel     (ie. inferior_ptid), then find procinfo for the requested thread.  */
3769130812Smarcel
3770130812Smarcel  if ((tid != 0) &&
3771130812Smarcel      (tid != proc_get_current_thread (pi)))
3772130812Smarcel    pi = find_procinfo_or_die (pid, tid);
3773130812Smarcel
3774130812Smarcel  if (pi == NULL)
3775130812Smarcel    error ("procfs: store_registers: failed to find procinfo for %s",
3776130812Smarcel	   target_pid_to_str (inferior_ptid));
3777130812Smarcel
3778130812Smarcel  if ((gregs = proc_get_gregs (pi)) == NULL)
3779130812Smarcel    proc_error (pi, "store_registers, get_gregs", __LINE__);
3780130812Smarcel
3781130812Smarcel  fill_gregset (gregs, regno);
3782130812Smarcel  if (!proc_set_gregs (pi))
3783130812Smarcel    proc_error (pi, "store_registers, set_gregs", __LINE__);
3784130812Smarcel
3785130812Smarcel  if (FP0_REGNUM >= 0)		/* need floating point? */
3786130812Smarcel    {
3787130812Smarcel      if ((regno >= 0 && regno < FP0_REGNUM)
3788130812Smarcel	  || regno == PC_REGNUM
3789130812Smarcel	  || regno == DEPRECATED_FP_REGNUM
3790130812Smarcel	  || regno == SP_REGNUM)
3791130812Smarcel	return;			/* not a floating point register */
3792130812Smarcel
3793130812Smarcel      if ((fpregs = proc_get_fpregs (pi)) == NULL)
3794130812Smarcel	proc_error (pi, "store_registers, get_fpregs", __LINE__);
3795130812Smarcel
3796130812Smarcel      fill_fpregset (fpregs, regno);
3797130812Smarcel      if (!proc_set_fpregs (pi))
3798130812Smarcel	proc_error (pi, "store_registers, set_fpregs", __LINE__);
3799130812Smarcel    }
3800130812Smarcel}
3801130812Smarcel
3802130812Smarcelstatic int
3803130812Smarcelsyscall_is_lwp_exit (procinfo *pi, int scall)
3804130812Smarcel{
3805130812Smarcel
3806130812Smarcel#ifdef SYS_lwp_exit
3807130812Smarcel  if (scall == SYS_lwp_exit)
3808130812Smarcel    return 1;
3809130812Smarcel#endif
3810130812Smarcel#ifdef SYS_lwpexit
3811130812Smarcel  if (scall == SYS_lwpexit)
3812130812Smarcel    return 1;
3813130812Smarcel#endif
3814130812Smarcel  return 0;
3815130812Smarcel}
3816130812Smarcel
3817130812Smarcelstatic int
3818130812Smarcelsyscall_is_exit (procinfo *pi, int scall)
3819130812Smarcel{
3820130812Smarcel#ifdef SYS_exit
3821130812Smarcel  if (scall == SYS_exit)
3822130812Smarcel    return 1;
3823130812Smarcel#endif
3824130812Smarcel#ifdef DYNAMIC_SYSCALLS
3825130812Smarcel  if (find_syscall (pi, "_exit") == scall)
3826130812Smarcel    return 1;
3827130812Smarcel#endif
3828130812Smarcel  return 0;
3829130812Smarcel}
3830130812Smarcel
3831130812Smarcelstatic int
3832130812Smarcelsyscall_is_exec (procinfo *pi, int scall)
3833130812Smarcel{
3834130812Smarcel#ifdef SYS_exec
3835130812Smarcel  if (scall == SYS_exec)
3836130812Smarcel    return 1;
3837130812Smarcel#endif
3838130812Smarcel#ifdef SYS_execv
3839130812Smarcel  if (scall == SYS_execv)
3840130812Smarcel    return 1;
3841130812Smarcel#endif
3842130812Smarcel#ifdef SYS_execve
3843130812Smarcel  if (scall == SYS_execve)
3844130812Smarcel    return 1;
3845130812Smarcel#endif
3846130812Smarcel#ifdef DYNAMIC_SYSCALLS
3847130812Smarcel  if (find_syscall (pi, "_execve"))
3848130812Smarcel    return 1;
3849130812Smarcel  if (find_syscall (pi, "ra_execve"))
3850130812Smarcel    return 1;
3851130812Smarcel#endif
3852130812Smarcel  return 0;
3853130812Smarcel}
3854130812Smarcel
3855130812Smarcelstatic int
3856130812Smarcelsyscall_is_lwp_create (procinfo *pi, int scall)
3857130812Smarcel{
3858130812Smarcel#ifdef SYS_lwp_create
3859130812Smarcel  if (scall == SYS_lwp_create)
3860130812Smarcel    return 1;
3861130812Smarcel#endif
3862130812Smarcel#ifdef SYS_lwpcreate
3863130812Smarcel  if (scall == SYS_lwpcreate)
3864130812Smarcel    return 1;
3865130812Smarcel#endif
3866130812Smarcel  return 0;
3867130812Smarcel}
3868130812Smarcel
3869130812Smarcel/*
3870130812Smarcel * Function: target_wait
3871130812Smarcel *
3872130812Smarcel * Retrieve the next stop event from the child process.
3873130812Smarcel * If child has not stopped yet, wait for it to stop.
3874130812Smarcel * Translate /proc eventcodes (or possibly wait eventcodes)
3875130812Smarcel * into gdb internal event codes.
3876130812Smarcel *
3877130812Smarcel * Return: id of process (and possibly thread) that incurred the event.
3878130812Smarcel *         event codes are returned thru a pointer parameter.
3879130812Smarcel */
3880130812Smarcel
3881130812Smarcelstatic ptid_t
3882130812Smarcelprocfs_wait (ptid_t ptid, struct target_waitstatus *status)
3883130812Smarcel{
3884130812Smarcel  /* First cut: loosely based on original version 2.1 */
3885130812Smarcel  procinfo *pi;
3886130812Smarcel  int       wstat;
3887130812Smarcel  int       temp_tid;
3888130812Smarcel  ptid_t    retval, temp_ptid;
3889130812Smarcel  int       why, what, flags;
3890130812Smarcel  int       retry = 0;
3891130812Smarcel
3892130812Smarcelwait_again:
3893130812Smarcel
3894130812Smarcel  retry++;
3895130812Smarcel  wstat    = 0;
3896130812Smarcel  retval   = pid_to_ptid (-1);
3897130812Smarcel
3898130812Smarcel  /* Find procinfo for main process */
3899130812Smarcel  pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
3900130812Smarcel  if (pi)
3901130812Smarcel    {
3902130812Smarcel      /* We must assume that the status is stale now... */
3903130812Smarcel      pi->status_valid = 0;
3904130812Smarcel      pi->gregs_valid  = 0;
3905130812Smarcel      pi->fpregs_valid = 0;
3906130812Smarcel
3907130812Smarcel#if 0	/* just try this out... */
3908130812Smarcel      flags = proc_flags (pi);
3909130812Smarcel      why   = proc_why (pi);
3910130812Smarcel      if ((flags & PR_STOPPED) && (why == PR_REQUESTED))
3911130812Smarcel	pi->status_valid = 0;	/* re-read again, IMMEDIATELY... */
3912130812Smarcel#endif
3913130812Smarcel      /* If child is not stopped, wait for it to stop.  */
3914130812Smarcel      if (!(proc_flags (pi) & (PR_STOPPED | PR_ISTOP)) &&
3915130812Smarcel	  !proc_wait_for_stop (pi))
3916130812Smarcel	{
3917130812Smarcel	  /* wait_for_stop failed: has the child terminated? */
3918130812Smarcel	  if (errno == ENOENT)
3919130812Smarcel	    {
3920130812Smarcel	      int wait_retval;
3921130812Smarcel
3922130812Smarcel	      /* /proc file not found; presumably child has terminated. */
3923130812Smarcel	      wait_retval = wait (&wstat); /* "wait" for the child's exit  */
3924130812Smarcel
3925130812Smarcel	      if (wait_retval != PIDGET (inferior_ptid)) /* wrong child? */
3926130812Smarcel		error ("procfs: couldn't stop process %d: wait returned %d\n",
3927130812Smarcel		       PIDGET (inferior_ptid), wait_retval);
3928130812Smarcel	      /* FIXME: might I not just use waitpid?
3929130812Smarcel		 Or try find_procinfo to see if I know about this child? */
3930130812Smarcel	      retval = pid_to_ptid (wait_retval);
3931130812Smarcel	    }
3932130812Smarcel	  else if (errno == EINTR)
3933130812Smarcel	    goto wait_again;
3934130812Smarcel	  else
3935130812Smarcel	    {
3936130812Smarcel	      /* Unknown error from wait_for_stop. */
3937130812Smarcel	      proc_error (pi, "target_wait (wait_for_stop)", __LINE__);
3938130812Smarcel	    }
3939130812Smarcel	}
3940130812Smarcel      else
3941130812Smarcel	{
3942130812Smarcel	  /* This long block is reached if either:
3943130812Smarcel	     a) the child was already stopped, or
3944130812Smarcel	     b) we successfully waited for the child with wait_for_stop.
3945130812Smarcel	     This block will analyze the /proc status, and translate it
3946130812Smarcel	     into a waitstatus for GDB.
3947130812Smarcel
3948130812Smarcel	     If we actually had to call wait because the /proc file
3949130812Smarcel	     is gone (child terminated), then we skip this block,
3950130812Smarcel	     because we already have a waitstatus.  */
3951130812Smarcel
3952130812Smarcel	  flags = proc_flags (pi);
3953130812Smarcel	  why   = proc_why (pi);
3954130812Smarcel	  what  = proc_what (pi);
3955130812Smarcel
3956130812Smarcel	  if (flags & (PR_STOPPED | PR_ISTOP))
3957130812Smarcel	    {
3958130812Smarcel#ifdef PR_ASYNC
3959130812Smarcel	      /* If it's running async (for single_thread control),
3960130812Smarcel		 set it back to normal again.  */
3961130812Smarcel	      if (flags & PR_ASYNC)
3962130812Smarcel		if (!proc_unset_async (pi))
3963130812Smarcel		  proc_error (pi, "target_wait, unset_async", __LINE__);
3964130812Smarcel#endif
3965130812Smarcel
3966130812Smarcel	      if (info_verbose)
3967130812Smarcel		proc_prettyprint_why (why, what, 1);
3968130812Smarcel
3969130812Smarcel	      /* The 'pid' we will return to GDB is composed of
3970130812Smarcel		 the process ID plus the lwp ID.  */
3971130812Smarcel	      retval = MERGEPID (pi->pid, proc_get_current_thread (pi));
3972130812Smarcel
3973130812Smarcel	      switch (why) {
3974130812Smarcel	      case PR_SIGNALLED:
3975130812Smarcel		wstat = (what << 8) | 0177;
3976130812Smarcel		break;
3977130812Smarcel	      case PR_SYSENTRY:
3978130812Smarcel		if (syscall_is_lwp_exit (pi, what))
3979130812Smarcel		  {
3980130812Smarcel		    printf_filtered ("[%s exited]\n",
3981130812Smarcel				     target_pid_to_str (retval));
3982130812Smarcel		    delete_thread (retval);
3983130812Smarcel		    status->kind = TARGET_WAITKIND_SPURIOUS;
3984130812Smarcel		    return retval;
3985130812Smarcel		  }
3986130812Smarcel		else if (syscall_is_exit (pi, what))
3987130812Smarcel		  {
3988130812Smarcel		    /* Handle SYS_exit call only */
3989130812Smarcel		    /* Stopped at entry to SYS_exit.
3990130812Smarcel		       Make it runnable, resume it, then use
3991130812Smarcel		       the wait system call to get its exit code.
3992130812Smarcel		       Proc_run_process always clears the current
3993130812Smarcel		       fault and signal.
3994130812Smarcel		       Then return its exit status.  */
3995130812Smarcel		    pi->status_valid = 0;
3996130812Smarcel		    wstat = 0;
3997130812Smarcel		    /* FIXME: what we should do is return
3998130812Smarcel		       TARGET_WAITKIND_SPURIOUS.  */
3999130812Smarcel		    if (!proc_run_process (pi, 0, 0))
4000130812Smarcel		      proc_error (pi, "target_wait, run_process", __LINE__);
4001130812Smarcel		    if (attach_flag)
4002130812Smarcel		      {
4003130812Smarcel			/* Don't call wait: simulate waiting for exit,
4004130812Smarcel			   return a "success" exit code.  Bogus: what if
4005130812Smarcel			   it returns something else?  */
4006130812Smarcel			wstat = 0;
4007130812Smarcel			retval = inferior_ptid;  /* ? ? ? */
4008130812Smarcel		      }
4009130812Smarcel		    else
4010130812Smarcel		      {
4011130812Smarcel			int temp = wait (&wstat);
4012130812Smarcel
4013130812Smarcel			/* FIXME: shouldn't I make sure I get the right
4014130812Smarcel			   event from the right process?  If (for
4015130812Smarcel			   instance) I have killed an earlier inferior
4016130812Smarcel			   process but failed to clean up after it
4017130812Smarcel			   somehow, I could get its termination event
4018130812Smarcel			   here.  */
4019130812Smarcel
4020130812Smarcel			/* If wait returns -1, that's what we return to GDB. */
4021130812Smarcel			if (temp < 0)
4022130812Smarcel			  retval = pid_to_ptid (temp);
4023130812Smarcel		      }
4024130812Smarcel		  }
4025130812Smarcel		else
4026130812Smarcel		  {
4027130812Smarcel		    printf_filtered ("procfs: trapped on entry to ");
4028130812Smarcel		    proc_prettyprint_syscall (proc_what (pi), 0);
4029130812Smarcel		    printf_filtered ("\n");
4030130812Smarcel#ifndef PIOCSSPCACT
4031130812Smarcel		    {
4032130812Smarcel		      long i, nsysargs, *sysargs;
4033130812Smarcel
4034130812Smarcel		      if ((nsysargs = proc_nsysarg (pi)) > 0 &&
4035130812Smarcel			  (sysargs  = proc_sysargs (pi)) != NULL)
4036130812Smarcel			{
4037130812Smarcel			  printf_filtered ("%ld syscall arguments:\n", nsysargs);
4038130812Smarcel			  for (i = 0; i < nsysargs; i++)
4039130812Smarcel			    printf_filtered ("#%ld: 0x%08lx\n",
4040130812Smarcel					     i, sysargs[i]);
4041130812Smarcel			}
4042130812Smarcel
4043130812Smarcel		    }
4044130812Smarcel#endif
4045130812Smarcel		    if (status)
4046130812Smarcel		      {
4047130812Smarcel			/* How to exit gracefully, returning "unknown event" */
4048130812Smarcel			status->kind = TARGET_WAITKIND_SPURIOUS;
4049130812Smarcel			return inferior_ptid;
4050130812Smarcel		      }
4051130812Smarcel		    else
4052130812Smarcel		      {
4053130812Smarcel			/* How to keep going without returning to wfi: */
4054130812Smarcel			target_resume (ptid, 0, TARGET_SIGNAL_0);
4055130812Smarcel			goto wait_again;
4056130812Smarcel		      }
4057130812Smarcel		  }
4058130812Smarcel		break;
4059130812Smarcel	      case PR_SYSEXIT:
4060130812Smarcel		if (syscall_is_exec (pi, what))
4061130812Smarcel		  {
4062130812Smarcel		    /* Hopefully this is our own "fork-child" execing
4063130812Smarcel		       the real child.  Hoax this event into a trap, and
4064130812Smarcel		       GDB will see the child about to execute its start
4065130812Smarcel		       address. */
4066130812Smarcel		    wstat = (SIGTRAP << 8) | 0177;
4067130812Smarcel		  }
4068130812Smarcel		else if (syscall_is_lwp_create (pi, what))
4069130812Smarcel		  {
4070130812Smarcel		    /*
4071130812Smarcel		     * This syscall is somewhat like fork/exec.
4072130812Smarcel		     * We will get the event twice: once for the parent LWP,
4073130812Smarcel		     * and once for the child.  We should already know about
4074130812Smarcel		     * the parent LWP, but the child will be new to us.  So,
4075130812Smarcel		     * whenever we get this event, if it represents a new
4076130812Smarcel		     * thread, simply add the thread to the list.
4077130812Smarcel		     */
4078130812Smarcel
4079130812Smarcel		    /* If not in procinfo list, add it.  */
4080130812Smarcel		    temp_tid = proc_get_current_thread (pi);
4081130812Smarcel		    if (!find_procinfo (pi->pid, temp_tid))
4082130812Smarcel		      create_procinfo  (pi->pid, temp_tid);
4083130812Smarcel
4084130812Smarcel		    temp_ptid = MERGEPID (pi->pid, temp_tid);
4085130812Smarcel		    /* If not in GDB's thread list, add it.  */
4086130812Smarcel		    if (!in_thread_list (temp_ptid))
4087130812Smarcel		      {
4088130812Smarcel			printf_filtered ("[New %s]\n",
4089130812Smarcel					 target_pid_to_str (temp_ptid));
4090130812Smarcel			add_thread (temp_ptid);
4091130812Smarcel		      }
4092130812Smarcel		    /* Return to WFI, but tell it to immediately resume. */
4093130812Smarcel		    status->kind = TARGET_WAITKIND_SPURIOUS;
4094130812Smarcel		    return inferior_ptid;
4095130812Smarcel		  }
4096130812Smarcel		else if (syscall_is_lwp_exit (pi, what))
4097130812Smarcel		  {
4098130812Smarcel		    printf_filtered ("[%s exited]\n",
4099130812Smarcel				     target_pid_to_str (retval));
4100130812Smarcel		    delete_thread (retval);
4101130812Smarcel		    status->kind = TARGET_WAITKIND_SPURIOUS;
4102130812Smarcel		    return retval;
4103130812Smarcel		  }
4104130812Smarcel		else if (0)
4105130812Smarcel		  {
4106130812Smarcel		    /* FIXME:  Do we need to handle SYS_sproc,
4107130812Smarcel		       SYS_fork, or SYS_vfork here?  The old procfs
4108130812Smarcel		       seemed to use this event to handle threads on
4109130812Smarcel		       older (non-LWP) systems, where I'm assuming
4110130812Smarcel		       that threads were actually separate processes.
4111130812Smarcel		       Irix, maybe?  Anyway, low priority for now.  */
4112130812Smarcel		  }
4113130812Smarcel		else
4114130812Smarcel		  {
4115130812Smarcel		    printf_filtered ("procfs: trapped on exit from ");
4116130812Smarcel		    proc_prettyprint_syscall (proc_what (pi), 0);
4117130812Smarcel		    printf_filtered ("\n");
4118130812Smarcel#ifndef PIOCSSPCACT
4119130812Smarcel		    {
4120130812Smarcel		      long i, nsysargs, *sysargs;
4121130812Smarcel
4122130812Smarcel		      if ((nsysargs = proc_nsysarg (pi)) > 0 &&
4123130812Smarcel			  (sysargs  = proc_sysargs (pi)) != NULL)
4124130812Smarcel			{
4125130812Smarcel			  printf_filtered ("%ld syscall arguments:\n", nsysargs);
4126130812Smarcel			  for (i = 0; i < nsysargs; i++)
4127130812Smarcel			    printf_filtered ("#%ld: 0x%08lx\n",
4128130812Smarcel					     i, sysargs[i]);
4129130812Smarcel			}
4130130812Smarcel		    }
4131130812Smarcel#endif
4132130812Smarcel		    status->kind = TARGET_WAITKIND_SPURIOUS;
4133130812Smarcel		    return inferior_ptid;
4134130812Smarcel		  }
4135130812Smarcel		break;
4136130812Smarcel	      case PR_REQUESTED:
4137130812Smarcel#if 0	/* FIXME */
4138130812Smarcel		wstat = (SIGSTOP << 8) | 0177;
4139130812Smarcel		break;
4140130812Smarcel#else
4141130812Smarcel		if (retry < 5)
4142130812Smarcel		  {
4143130812Smarcel		    printf_filtered ("Retry #%d:\n", retry);
4144130812Smarcel		    pi->status_valid = 0;
4145130812Smarcel		    goto wait_again;
4146130812Smarcel		  }
4147130812Smarcel		else
4148130812Smarcel		  {
4149130812Smarcel		    /* If not in procinfo list, add it.  */
4150130812Smarcel		    temp_tid = proc_get_current_thread (pi);
4151130812Smarcel		    if (!find_procinfo (pi->pid, temp_tid))
4152130812Smarcel		      create_procinfo  (pi->pid, temp_tid);
4153130812Smarcel
4154130812Smarcel		    /* If not in GDB's thread list, add it.  */
4155130812Smarcel		    temp_ptid = MERGEPID (pi->pid, temp_tid);
4156130812Smarcel		    if (!in_thread_list (temp_ptid))
4157130812Smarcel		      {
4158130812Smarcel			printf_filtered ("[New %s]\n",
4159130812Smarcel					 target_pid_to_str (temp_ptid));
4160130812Smarcel			add_thread (temp_ptid);
4161130812Smarcel		      }
4162130812Smarcel
4163130812Smarcel		    status->kind = TARGET_WAITKIND_STOPPED;
4164130812Smarcel		    status->value.sig = 0;
4165130812Smarcel		    return retval;
4166130812Smarcel		  }
4167130812Smarcel#endif
4168130812Smarcel	      case PR_JOBCONTROL:
4169130812Smarcel		wstat = (what << 8) | 0177;
4170130812Smarcel		break;
4171130812Smarcel	      case PR_FAULTED:
4172130812Smarcel		switch (what) {
4173130812Smarcel#ifdef FLTWATCH
4174130812Smarcel		case FLTWATCH:
4175130812Smarcel		  wstat = (SIGTRAP << 8) | 0177;
4176130812Smarcel		  break;
4177130812Smarcel#endif
4178130812Smarcel#ifdef FLTKWATCH
4179130812Smarcel		case FLTKWATCH:
4180130812Smarcel		  wstat = (SIGTRAP << 8) | 0177;
4181130812Smarcel		  break;
4182130812Smarcel#endif
4183130812Smarcel		  /* FIXME: use si_signo where possible. */
4184130812Smarcel		case FLTPRIV:
4185130812Smarcel#if (FLTILL != FLTPRIV)		/* avoid "duplicate case" error */
4186130812Smarcel		case FLTILL:
4187130812Smarcel#endif
4188130812Smarcel		  wstat = (SIGILL << 8) | 0177;
4189130812Smarcel		  break;
4190130812Smarcel		case FLTBPT:
4191130812Smarcel#if (FLTTRACE != FLTBPT)	/* avoid "duplicate case" error */
4192130812Smarcel		case FLTTRACE:
4193130812Smarcel#endif
4194130812Smarcel		  wstat = (SIGTRAP << 8) | 0177;
4195130812Smarcel		  break;
4196130812Smarcel		case FLTSTACK:
4197130812Smarcel		case FLTACCESS:
4198130812Smarcel#if (FLTBOUNDS != FLTSTACK)	/* avoid "duplicate case" error */
4199130812Smarcel		case FLTBOUNDS:
4200130812Smarcel#endif
4201130812Smarcel		  wstat = (SIGSEGV << 8) | 0177;
4202130812Smarcel		  break;
4203130812Smarcel		case FLTIOVF:
4204130812Smarcel		case FLTIZDIV:
4205130812Smarcel#if (FLTFPE != FLTIOVF)		/* avoid "duplicate case" error */
4206130812Smarcel		case FLTFPE:
4207130812Smarcel#endif
4208130812Smarcel		  wstat = (SIGFPE << 8) | 0177;
4209130812Smarcel		  break;
4210130812Smarcel		case FLTPAGE:		/* Recoverable page fault */
4211130812Smarcel		default:	 /* FIXME: use si_signo if possible for fault */
4212130812Smarcel		  retval = pid_to_ptid (-1);
4213130812Smarcel		  printf_filtered ("procfs:%d -- ", __LINE__);
4214130812Smarcel		  printf_filtered ("child stopped for unknown reason:\n");
4215130812Smarcel		  proc_prettyprint_why (why, what, 1);
4216130812Smarcel		  error ("... giving up...");
4217130812Smarcel		  break;
4218130812Smarcel		}
4219130812Smarcel		break;	/* case PR_FAULTED: */
4220130812Smarcel	      default:	/* switch (why) unmatched */
4221130812Smarcel		printf_filtered ("procfs:%d -- ", __LINE__);
4222130812Smarcel		printf_filtered ("child stopped for unknown reason:\n");
4223130812Smarcel		proc_prettyprint_why (why, what, 1);
4224130812Smarcel		error ("... giving up...");
4225130812Smarcel		break;
4226130812Smarcel	      }
4227130812Smarcel	      /*
4228130812Smarcel	       * Got this far without error:
4229130812Smarcel	       * If retval isn't in the threads database, add it.
4230130812Smarcel	       */
4231130812Smarcel	      if (PIDGET (retval) > 0 &&
4232130812Smarcel		  !ptid_equal (retval, inferior_ptid) &&
4233130812Smarcel		  !in_thread_list (retval))
4234130812Smarcel		{
4235130812Smarcel		  /*
4236130812Smarcel		   * We have a new thread.
4237130812Smarcel		   * We need to add it both to GDB's list and to our own.
4238130812Smarcel		   * If we don't create a procinfo, resume may be unhappy
4239130812Smarcel		   * later.
4240130812Smarcel		   */
4241130812Smarcel		  printf_filtered ("[New %s]\n", target_pid_to_str (retval));
4242130812Smarcel		  add_thread (retval);
4243130812Smarcel		  if (find_procinfo (PIDGET (retval), TIDGET (retval)) == NULL)
4244130812Smarcel		    create_procinfo (PIDGET (retval), TIDGET (retval));
4245130812Smarcel
4246130812Smarcel		  /* In addition, it's possible that this is the first
4247130812Smarcel		   * new thread we've seen, in which case we may not
4248130812Smarcel		   * have created entries for inferior_ptid yet.
4249130812Smarcel		   */
4250130812Smarcel		  if (TIDGET (inferior_ptid) != 0)
4251130812Smarcel		    {
4252130812Smarcel		      if (!in_thread_list (inferior_ptid))
4253130812Smarcel			add_thread (inferior_ptid);
4254130812Smarcel		      if (find_procinfo (PIDGET (inferior_ptid),
4255130812Smarcel					 TIDGET (inferior_ptid)) == NULL)
4256130812Smarcel			create_procinfo (PIDGET (inferior_ptid),
4257130812Smarcel					 TIDGET (inferior_ptid));
4258130812Smarcel		    }
4259130812Smarcel		}
4260130812Smarcel	    }
4261130812Smarcel	  else	/* flags do not indicate STOPPED */
4262130812Smarcel	    {
4263130812Smarcel	      /* surely this can't happen... */
4264130812Smarcel	      printf_filtered ("procfs:%d -- process not stopped.\n",
4265130812Smarcel			       __LINE__);
4266130812Smarcel	      proc_prettyprint_flags (flags, 1);
4267130812Smarcel	      error ("procfs: ...giving up...");
4268130812Smarcel	    }
4269130812Smarcel	}
4270130812Smarcel
4271130812Smarcel      if (status)
4272130812Smarcel	store_waitstatus (status, wstat);
4273130812Smarcel    }
4274130812Smarcel
4275130812Smarcel  return retval;
4276130812Smarcel}
4277130812Smarcel
4278130812Smarcel/* Perform a partial transfer to/from the specified object.  For
4279130812Smarcel   memory transfers, fall back to the old memory xfer functions.  */
4280130812Smarcel
4281130812Smarcelstatic LONGEST
4282130812Smarcelprocfs_xfer_partial (struct target_ops *ops, enum target_object object,
4283130812Smarcel		     const char *annex, void *readbuf,
4284130812Smarcel		     const void *writebuf, ULONGEST offset, LONGEST len)
4285130812Smarcel{
4286130812Smarcel  switch (object)
4287130812Smarcel    {
4288130812Smarcel    case TARGET_OBJECT_MEMORY:
4289130812Smarcel      if (readbuf)
4290130812Smarcel	return (*ops->to_xfer_memory) (offset, readbuf, len, 0/*write*/,
4291130812Smarcel				       NULL, ops);
4292130812Smarcel      if (writebuf)
4293130812Smarcel	return (*ops->to_xfer_memory) (offset, readbuf, len, 1/*write*/,
4294130812Smarcel				       NULL, ops);
4295130812Smarcel      return -1;
4296130812Smarcel
4297130812Smarcel#ifdef NEW_PROC_API
4298130812Smarcel    case TARGET_OBJECT_AUXV:
4299130812Smarcel      return procfs_xfer_auxv (ops, object, annex, readbuf, writebuf,
4300130812Smarcel			       offset, len);
4301130812Smarcel#endif
4302130812Smarcel
4303130812Smarcel    default:
4304130812Smarcel      if (ops->beneath != NULL)
4305130812Smarcel	return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
4306130812Smarcel					      readbuf, writebuf, offset, len);
4307130812Smarcel      return -1;
4308130812Smarcel    }
4309130812Smarcel}
4310130812Smarcel
4311130812Smarcel
4312130812Smarcel/* Transfer LEN bytes between GDB address MYADDR and target address
4313130812Smarcel   MEMADDR.  If DOWRITE is non-zero, transfer them to the target,
4314130812Smarcel   otherwise transfer them from the target.  TARGET is unused.
4315130812Smarcel
4316130812Smarcel   The return value is 0 if an error occurred or no bytes were
4317130812Smarcel   transferred.  Otherwise, it will be a positive value which
4318130812Smarcel   indicates the number of bytes transferred between gdb and the
4319130812Smarcel   target.  (Note that the interface also makes provisions for
4320130812Smarcel   negative values, but this capability isn't implemented here.) */
4321130812Smarcel
4322130812Smarcelstatic int
4323130812Smarcelprocfs_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int dowrite,
4324130812Smarcel		    struct mem_attrib *attrib, struct target_ops *target)
4325130812Smarcel{
4326130812Smarcel  procinfo *pi;
4327130812Smarcel  int nbytes = 0;
4328130812Smarcel
4329130812Smarcel  /* Find procinfo for main process */
4330130812Smarcel  pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
4331130812Smarcel  if (pi->as_fd == 0 &&
4332130812Smarcel      open_procinfo_files (pi, FD_AS) == 0)
4333130812Smarcel    {
4334130812Smarcel      proc_warn (pi, "xfer_memory, open_proc_files", __LINE__);
4335130812Smarcel      return 0;
4336130812Smarcel    }
4337130812Smarcel
4338130812Smarcel  if (lseek (pi->as_fd, (off_t) memaddr, SEEK_SET) == (off_t) memaddr)
4339130812Smarcel    {
4340130812Smarcel      if (dowrite)
4341130812Smarcel	{
4342130812Smarcel#ifdef NEW_PROC_API
4343130812Smarcel	  PROCFS_NOTE ("write memory: ");
4344130812Smarcel#else
4345130812Smarcel	  PROCFS_NOTE ("write memory: \n");
4346130812Smarcel#endif
4347130812Smarcel	  nbytes = write (pi->as_fd, myaddr, len);
4348130812Smarcel	}
4349130812Smarcel      else
4350130812Smarcel	{
4351130812Smarcel	  PROCFS_NOTE ("read  memory: \n");
4352130812Smarcel	  nbytes = read (pi->as_fd, myaddr, len);
4353130812Smarcel	}
4354130812Smarcel      if (nbytes < 0)
4355130812Smarcel	{
4356130812Smarcel	  nbytes = 0;
4357130812Smarcel	}
4358130812Smarcel    }
4359130812Smarcel  return nbytes;
4360130812Smarcel}
4361130812Smarcel
4362130812Smarcel/*
4363130812Smarcel * Function: invalidate_cache
4364130812Smarcel *
4365130812Smarcel * Called by target_resume before making child runnable.
4366130812Smarcel * Mark cached registers and status's invalid.
4367130812Smarcel * If there are "dirty" caches that need to be written back
4368130812Smarcel * to the child process, do that.
4369130812Smarcel *
4370130812Smarcel * File descriptors are also cached.
4371130812Smarcel * As they are a limited resource, we cannot hold onto them indefinitely.
4372130812Smarcel * However, as they are expensive to open, we don't want to throw them
4373130812Smarcel * away indescriminately either.  As a compromise, we will keep the
4374130812Smarcel * file descriptors for the parent process, but discard any file
4375130812Smarcel * descriptors we may have accumulated for the threads.
4376130812Smarcel *
4377130812Smarcel * Return value:
4378130812Smarcel * As this function is called by iterate_over_threads, it always
4379130812Smarcel * returns zero (so that iterate_over_threads will keep iterating).
4380130812Smarcel */
4381130812Smarcel
4382130812Smarcel
4383130812Smarcelstatic int
4384130812Smarcelinvalidate_cache (procinfo *parent, procinfo *pi, void *ptr)
4385130812Smarcel{
4386130812Smarcel  /*
4387130812Smarcel   * About to run the child; invalidate caches and do any other cleanup.
4388130812Smarcel   */
4389130812Smarcel
4390130812Smarcel#if 0
4391130812Smarcel  if (pi->gregs_dirty)
4392130812Smarcel    if (parent == NULL ||
4393130812Smarcel	proc_get_current_thread (parent) != pi->tid)
4394130812Smarcel      if (!proc_set_gregs (pi))	/* flush gregs cache */
4395130812Smarcel	proc_warn (pi, "target_resume, set_gregs",
4396130812Smarcel		   __LINE__);
4397130812Smarcel  if (FP0_REGNUM >= 0)
4398130812Smarcel    if (pi->fpregs_dirty)
4399130812Smarcel      if (parent == NULL ||
4400130812Smarcel	  proc_get_current_thread (parent) != pi->tid)
4401130812Smarcel	if (!proc_set_fpregs (pi))	/* flush fpregs cache */
4402130812Smarcel	  proc_warn (pi, "target_resume, set_fpregs",
4403130812Smarcel		     __LINE__);
4404130812Smarcel#endif
4405130812Smarcel
4406130812Smarcel  if (parent != NULL)
4407130812Smarcel    {
4408130812Smarcel      /* The presence of a parent indicates that this is an LWP.
4409130812Smarcel	 Close any file descriptors that it might have open.
4410130812Smarcel	 We don't do this to the master (parent) procinfo.  */
4411130812Smarcel
4412130812Smarcel      close_procinfo_files (pi);
4413130812Smarcel    }
4414130812Smarcel  pi->gregs_valid   = 0;
4415130812Smarcel  pi->fpregs_valid  = 0;
4416130812Smarcel#if 0
4417130812Smarcel  pi->gregs_dirty   = 0;
4418130812Smarcel  pi->fpregs_dirty  = 0;
4419130812Smarcel#endif
4420130812Smarcel  pi->status_valid  = 0;
4421130812Smarcel  pi->threads_valid = 0;
4422130812Smarcel
4423130812Smarcel  return 0;
4424130812Smarcel}
4425130812Smarcel
4426130812Smarcel#if 0
4427130812Smarcel/*
4428130812Smarcel * Function: make_signal_thread_runnable
4429130812Smarcel *
4430130812Smarcel * A callback function for iterate_over_threads.
4431130812Smarcel * Find the asynchronous signal thread, and make it runnable.
4432130812Smarcel * See if that helps matters any.
4433130812Smarcel */
4434130812Smarcel
4435130812Smarcelstatic int
4436130812Smarcelmake_signal_thread_runnable (procinfo *process, procinfo *pi, void *ptr)
4437130812Smarcel{
4438130812Smarcel#ifdef PR_ASLWP
4439130812Smarcel  if (proc_flags (pi) & PR_ASLWP)
4440130812Smarcel    {
4441130812Smarcel      if (!proc_run_process (pi, 0, -1))
4442130812Smarcel	proc_error (pi, "make_signal_thread_runnable", __LINE__);
4443130812Smarcel      return 1;
4444130812Smarcel    }
4445130812Smarcel#endif
4446130812Smarcel  return 0;
4447130812Smarcel}
4448130812Smarcel#endif
4449130812Smarcel
4450130812Smarcel/*
4451130812Smarcel * Function: target_resume
4452130812Smarcel *
4453130812Smarcel * Make the child process runnable.  Normally we will then call
4454130812Smarcel * procfs_wait and wait for it to stop again (unles gdb is async).
4455130812Smarcel *
4456130812Smarcel * Arguments:
4457130812Smarcel *  step:  if true, then arrange for the child to stop again
4458130812Smarcel *         after executing a single instruction.
4459130812Smarcel *  signo: if zero, then cancel any pending signal.
4460130812Smarcel *         If non-zero, then arrange for the indicated signal
4461130812Smarcel *         to be delivered to the child when it runs.
4462130812Smarcel *  pid:   if -1, then allow any child thread to run.
4463130812Smarcel *         if non-zero, then allow only the indicated thread to run.
4464130812Smarcel *******   (not implemented yet)
4465130812Smarcel */
4466130812Smarcel
4467130812Smarcelstatic void
4468130812Smarcelprocfs_resume (ptid_t ptid, int step, enum target_signal signo)
4469130812Smarcel{
4470130812Smarcel  procinfo *pi, *thread;
4471130812Smarcel  int native_signo;
4472130812Smarcel
4473130812Smarcel  /* 2.1:
4474130812Smarcel     prrun.prflags |= PRSVADDR;
4475130812Smarcel     prrun.pr_vaddr = $PC;	   set resume address
4476130812Smarcel     prrun.prflags |= PRSTRACE;    trace signals in pr_trace (all)
4477130812Smarcel     prrun.prflags |= PRSFAULT;    trace faults in pr_fault (all but PAGE)
4478130812Smarcel     prrun.prflags |= PRCFAULT;    clear current fault.
4479130812Smarcel
4480130812Smarcel     PRSTRACE and PRSFAULT can be done by other means
4481130812Smarcel     	(proc_trace_signals, proc_trace_faults)
4482130812Smarcel     PRSVADDR is unnecessary.
4483130812Smarcel     PRCFAULT may be replaced by a PIOCCFAULT call (proc_clear_current_fault)
4484130812Smarcel     This basically leaves PRSTEP and PRCSIG.
4485130812Smarcel     PRCSIG is like PIOCSSIG (proc_clear_current_signal).
4486130812Smarcel     So basically PR_STEP is the sole argument that must be passed
4487130812Smarcel     to proc_run_process (for use in the prrun struct by ioctl). */
4488130812Smarcel
4489130812Smarcel  /* Find procinfo for main process */
4490130812Smarcel  pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
4491130812Smarcel
4492130812Smarcel  /* First cut: ignore pid argument */
4493130812Smarcel  errno = 0;
4494130812Smarcel
4495130812Smarcel  /* Convert signal to host numbering.  */
4496130812Smarcel  if (signo == 0 ||
4497130812Smarcel      (signo == TARGET_SIGNAL_STOP && pi->ignore_next_sigstop))
4498130812Smarcel    native_signo = 0;
4499130812Smarcel  else
4500130812Smarcel    native_signo = target_signal_to_host (signo);
4501130812Smarcel
4502130812Smarcel  pi->ignore_next_sigstop = 0;
4503130812Smarcel
4504130812Smarcel  /* Running the process voids all cached registers and status. */
4505130812Smarcel  /* Void the threads' caches first */
4506130812Smarcel  proc_iterate_over_threads (pi, invalidate_cache, NULL);
4507130812Smarcel  /* Void the process procinfo's caches.  */
4508130812Smarcel  invalidate_cache (NULL, pi, NULL);
4509130812Smarcel
4510130812Smarcel  if (PIDGET (ptid) != -1)
4511130812Smarcel    {
4512130812Smarcel      /* Resume a specific thread, presumably suppressing the others. */
4513130812Smarcel      thread = find_procinfo (PIDGET (ptid), TIDGET (ptid));
4514130812Smarcel      if (thread != NULL)
4515130812Smarcel	{
4516130812Smarcel	  if (thread->tid != 0)
4517130812Smarcel	    {
4518130812Smarcel	      /* We're to resume a specific thread, and not the others.
4519130812Smarcel	       * Set the child process's PR_ASYNC flag.
4520130812Smarcel	       */
4521130812Smarcel#ifdef PR_ASYNC
4522130812Smarcel	      if (!proc_set_async (pi))
4523130812Smarcel		proc_error (pi, "target_resume, set_async", __LINE__);
4524130812Smarcel#endif
4525130812Smarcel#if 0
4526130812Smarcel	      proc_iterate_over_threads (pi,
4527130812Smarcel					 make_signal_thread_runnable,
4528130812Smarcel					 NULL);
4529130812Smarcel#endif
4530130812Smarcel	      pi = thread;	/* substitute the thread's procinfo for run */
4531130812Smarcel	    }
4532130812Smarcel	}
4533130812Smarcel    }
4534130812Smarcel
4535130812Smarcel  if (!proc_run_process (pi, step, native_signo))
4536130812Smarcel    {
4537130812Smarcel      if (errno == EBUSY)
4538130812Smarcel	warning ("resume: target already running.  Pretend to resume, and hope for the best!\n");
4539130812Smarcel      else
4540130812Smarcel	proc_error (pi, "target_resume", __LINE__);
4541130812Smarcel    }
4542130812Smarcel}
4543130812Smarcel
4544130812Smarcel/*
4545130812Smarcel * Function: register_gdb_signals
4546130812Smarcel *
4547130812Smarcel * Traverse the list of signals that GDB knows about
4548130812Smarcel * (see "handle" command), and arrange for the target
4549130812Smarcel * to be stopped or not, according to these settings.
4550130812Smarcel *
4551130812Smarcel * Returns non-zero for success, zero for failure.
4552130812Smarcel */
4553130812Smarcel
4554130812Smarcelstatic int
4555130812Smarcelregister_gdb_signals (procinfo *pi, gdb_sigset_t *signals)
4556130812Smarcel{
4557130812Smarcel  int signo;
4558130812Smarcel
4559130812Smarcel  for (signo = 0; signo < NSIG; signo ++)
4560130812Smarcel    if (signal_stop_state  (target_signal_from_host (signo)) == 0 &&
4561130812Smarcel	signal_print_state (target_signal_from_host (signo)) == 0 &&
4562130812Smarcel	signal_pass_state  (target_signal_from_host (signo)) == 1)
4563130812Smarcel      prdelset (signals, signo);
4564130812Smarcel    else
4565130812Smarcel      praddset (signals, signo);
4566130812Smarcel
4567130812Smarcel  return proc_set_traced_signals (pi, signals);
4568130812Smarcel}
4569130812Smarcel
4570130812Smarcel/*
4571130812Smarcel * Function: target_notice_signals
4572130812Smarcel *
4573130812Smarcel * Set up to trace signals in the child process.
4574130812Smarcel */
4575130812Smarcel
4576130812Smarcelstatic void
4577130812Smarcelprocfs_notice_signals (ptid_t ptid)
4578130812Smarcel{
4579130812Smarcel  gdb_sigset_t signals;
4580130812Smarcel  procinfo *pi = find_procinfo_or_die (PIDGET (ptid), 0);
4581130812Smarcel
4582130812Smarcel  if (proc_get_traced_signals (pi, &signals) &&
4583130812Smarcel      register_gdb_signals    (pi, &signals))
4584130812Smarcel    return;
4585130812Smarcel  else
4586130812Smarcel    proc_error (pi, "notice_signals", __LINE__);
4587130812Smarcel}
4588130812Smarcel
4589130812Smarcel/*
4590130812Smarcel * Function: target_files_info
4591130812Smarcel *
4592130812Smarcel * Print status information about the child process.
4593130812Smarcel */
4594130812Smarcel
4595130812Smarcelstatic void
4596130812Smarcelprocfs_files_info (struct target_ops *ignore)
4597130812Smarcel{
4598130812Smarcel  printf_filtered ("\tUsing the running image of %s %s via /proc.\n",
4599130812Smarcel		   attach_flag? "attached": "child",
4600130812Smarcel		   target_pid_to_str (inferior_ptid));
4601130812Smarcel}
4602130812Smarcel
4603130812Smarcel/*
4604130812Smarcel * Function: target_open
4605130812Smarcel *
4606130812Smarcel * A dummy: you don't open procfs.
4607130812Smarcel */
4608130812Smarcel
4609130812Smarcelstatic void
4610130812Smarcelprocfs_open (char *args, int from_tty)
4611130812Smarcel{
4612130812Smarcel  error ("Use the \"run\" command to start a Unix child process.");
4613130812Smarcel}
4614130812Smarcel
4615130812Smarcel/*
4616130812Smarcel * Function: target_can_run
4617130812Smarcel *
4618130812Smarcel * This tells GDB that this target vector can be invoked
4619130812Smarcel * for "run" or "attach".
4620130812Smarcel */
4621130812Smarcel
4622130812Smarcelint procfs_suppress_run = 0;	/* Non-zero if procfs should pretend not to
4623130812Smarcel				   be a runnable target.  Used by targets
4624130812Smarcel				   that can sit atop procfs, such as solaris
4625130812Smarcel				   thread support.  */
4626130812Smarcel
4627130812Smarcel
4628130812Smarcelstatic int
4629130812Smarcelprocfs_can_run (void)
4630130812Smarcel{
4631130812Smarcel  /* This variable is controlled by modules that sit atop procfs that
4632130812Smarcel     may layer their own process structure atop that provided here.
4633130812Smarcel     sol-thread.c does this because of the Solaris two-level thread
4634130812Smarcel     model.  */
4635130812Smarcel
4636130812Smarcel  /* NOTE: possibly obsolete -- use the thread_stratum approach instead. */
4637130812Smarcel
4638130812Smarcel  return !procfs_suppress_run;
4639130812Smarcel}
4640130812Smarcel
4641130812Smarcel/*
4642130812Smarcel * Function: target_stop
4643130812Smarcel *
4644130812Smarcel * Stop the child process asynchronously, as when the
4645130812Smarcel * gdb user types control-c or presses a "stop" button.
4646130812Smarcel *
4647130812Smarcel * Works by sending kill(SIGINT) to the child's process group.
4648130812Smarcel */
4649130812Smarcel
4650130812Smarcelstatic void
4651130812Smarcelprocfs_stop (void)
4652130812Smarcel{
4653130812Smarcel  kill (-inferior_process_group, SIGINT);
4654130812Smarcel}
4655130812Smarcel
4656130812Smarcel/*
4657130812Smarcel * Function: unconditionally_kill_inferior
4658130812Smarcel *
4659130812Smarcel * Make it die.  Wait for it to die.  Clean up after it.
4660130812Smarcel * Note: this should only be applied to the real process,
4661130812Smarcel * not to an LWP, because of the check for parent-process.
4662130812Smarcel * If we need this to work for an LWP, it needs some more logic.
4663130812Smarcel */
4664130812Smarcel
4665130812Smarcelstatic void
4666130812Smarcelunconditionally_kill_inferior (procinfo *pi)
4667130812Smarcel{
4668130812Smarcel  int parent_pid;
4669130812Smarcel
4670130812Smarcel  parent_pid = proc_parent_pid (pi);
4671130812Smarcel#ifdef PROCFS_NEED_CLEAR_CURSIG_FOR_KILL
4672130812Smarcel  /* FIXME: use access functions */
4673130812Smarcel  /* Alpha OSF/1-3.x procfs needs a clear of the current signal
4674130812Smarcel     before the PIOCKILL, otherwise it might generate a corrupted core
4675130812Smarcel     file for the inferior.  */
4676130812Smarcel  if (ioctl (pi->ctl_fd, PIOCSSIG, NULL) < 0)
4677130812Smarcel    {
4678130812Smarcel      printf_filtered ("unconditionally_kill: SSIG failed!\n");
4679130812Smarcel    }
4680130812Smarcel#endif
4681130812Smarcel#ifdef PROCFS_NEED_PIOCSSIG_FOR_KILL
4682130812Smarcel  /* Alpha OSF/1-2.x procfs needs a PIOCSSIG call with a SIGKILL signal
4683130812Smarcel     to kill the inferior, otherwise it might remain stopped with a
4684130812Smarcel     pending SIGKILL.
4685130812Smarcel     We do not check the result of the PIOCSSIG, the inferior might have
4686130812Smarcel     died already.  */
4687130812Smarcel  {
4688130812Smarcel    gdb_siginfo_t newsiginfo;
4689130812Smarcel
4690130812Smarcel    memset ((char *) &newsiginfo, 0, sizeof (newsiginfo));
4691130812Smarcel    newsiginfo.si_signo = SIGKILL;
4692130812Smarcel    newsiginfo.si_code = 0;
4693130812Smarcel    newsiginfo.si_errno = 0;
4694130812Smarcel    newsiginfo.si_pid = getpid ();
4695130812Smarcel    newsiginfo.si_uid = getuid ();
4696130812Smarcel    /* FIXME: use proc_set_current_signal */
4697130812Smarcel    ioctl (pi->ctl_fd, PIOCSSIG, &newsiginfo);
4698130812Smarcel  }
4699130812Smarcel#else /* PROCFS_NEED_PIOCSSIG_FOR_KILL */
4700130812Smarcel  if (!proc_kill (pi, SIGKILL))
4701130812Smarcel    proc_error (pi, "unconditionally_kill, proc_kill", __LINE__);
4702130812Smarcel#endif /* PROCFS_NEED_PIOCSSIG_FOR_KILL */
4703130812Smarcel  destroy_procinfo (pi);
4704130812Smarcel
4705130812Smarcel  /* If pi is GDB's child, wait for it to die.  */
4706130812Smarcel  if (parent_pid == getpid ())
4707130812Smarcel    /* FIXME: should we use waitpid to make sure we get the right event?
4708130812Smarcel       Should we check the returned event?  */
4709130812Smarcel    {
4710130812Smarcel#if 0
4711130812Smarcel      int status, ret;
4712130812Smarcel
4713130812Smarcel      ret = waitpid (pi->pid, &status, 0);
4714130812Smarcel#else
4715130812Smarcel      wait (NULL);
4716130812Smarcel#endif
4717130812Smarcel    }
4718130812Smarcel}
4719130812Smarcel
4720130812Smarcel/*
4721130812Smarcel * Function: target_kill_inferior
4722130812Smarcel *
4723130812Smarcel * We're done debugging it, and we want it to go away.
4724130812Smarcel * Then we want GDB to forget all about it.
4725130812Smarcel */
4726130812Smarcel
4727130812Smarcelstatic void
4728130812Smarcelprocfs_kill_inferior (void)
4729130812Smarcel{
4730130812Smarcel  if (!ptid_equal (inferior_ptid, null_ptid)) /* ? */
4731130812Smarcel    {
4732130812Smarcel      /* Find procinfo for main process */
4733130812Smarcel      procinfo *pi = find_procinfo (PIDGET (inferior_ptid), 0);
4734130812Smarcel
4735130812Smarcel      if (pi)
4736130812Smarcel	unconditionally_kill_inferior (pi);
4737130812Smarcel      target_mourn_inferior ();
4738130812Smarcel    }
4739130812Smarcel}
4740130812Smarcel
4741130812Smarcel/*
4742130812Smarcel * Function: target_mourn_inferior
4743130812Smarcel *
4744130812Smarcel * Forget we ever debugged this thing!
4745130812Smarcel */
4746130812Smarcel
4747130812Smarcelstatic void
4748130812Smarcelprocfs_mourn_inferior (void)
4749130812Smarcel{
4750130812Smarcel  procinfo *pi;
4751130812Smarcel
4752130812Smarcel  if (!ptid_equal (inferior_ptid, null_ptid))
4753130812Smarcel    {
4754130812Smarcel      /* Find procinfo for main process */
4755130812Smarcel      pi = find_procinfo (PIDGET (inferior_ptid), 0);
4756130812Smarcel      if (pi)
4757130812Smarcel	destroy_procinfo (pi);
4758130812Smarcel    }
4759130812Smarcel  unpush_target (&procfs_ops);
4760130812Smarcel  generic_mourn_inferior ();
4761130812Smarcel}
4762130812Smarcel
4763130812Smarcel/*
4764130812Smarcel * Function: init_inferior
4765130812Smarcel *
4766130812Smarcel * When GDB forks to create a runnable inferior process,
4767130812Smarcel * this function is called on the parent side of the fork.
4768130812Smarcel * It's job is to do whatever is necessary to make the child
4769130812Smarcel * ready to be debugged, and then wait for the child to synchronize.
4770130812Smarcel */
4771130812Smarcel
4772130812Smarcelstatic void
4773130812Smarcelprocfs_init_inferior (int pid)
4774130812Smarcel{
4775130812Smarcel  procinfo *pi;
4776130812Smarcel  gdb_sigset_t signals;
4777130812Smarcel  int fail;
4778130812Smarcel
4779130812Smarcel  /* This routine called on the parent side (GDB side)
4780130812Smarcel     after GDB forks the inferior.  */
4781130812Smarcel
4782130812Smarcel  push_target (&procfs_ops);
4783130812Smarcel
4784130812Smarcel  if ((pi = create_procinfo (pid, 0)) == NULL)
4785130812Smarcel    perror ("procfs: out of memory in 'init_inferior'");
4786130812Smarcel
4787130812Smarcel  if (!open_procinfo_files (pi, FD_CTL))
4788130812Smarcel    proc_error (pi, "init_inferior, open_proc_files", __LINE__);
4789130812Smarcel
4790130812Smarcel  /*
4791130812Smarcel    xmalloc			// done
4792130812Smarcel    open_procinfo_files		// done
4793130812Smarcel    link list			// done
4794130812Smarcel    prfillset (trace)
4795130812Smarcel    procfs_notice_signals
4796130812Smarcel    prfillset (fault)
4797130812Smarcel    prdelset (FLTPAGE)
4798130812Smarcel    PIOCWSTOP
4799130812Smarcel    PIOCSFAULT
4800130812Smarcel    */
4801130812Smarcel
4802130812Smarcel  /* If not stopped yet, wait for it to stop. */
4803130812Smarcel  if (!(proc_flags (pi) & PR_STOPPED) &&
4804130812Smarcel      !(proc_wait_for_stop (pi)))
4805130812Smarcel    dead_procinfo (pi, "init_inferior: wait_for_stop failed", KILL);
4806130812Smarcel
4807130812Smarcel  /* Save some of the /proc state to be restored if we detach.  */
4808130812Smarcel  /* FIXME: Why?  In case another debugger was debugging it?
4809130812Smarcel     We're it's parent, for Ghu's sake! */
4810130812Smarcel  if (!proc_get_traced_signals  (pi, &pi->saved_sigset))
4811130812Smarcel    proc_error (pi, "init_inferior, get_traced_signals", __LINE__);
4812130812Smarcel  if (!proc_get_held_signals    (pi, &pi->saved_sighold))
4813130812Smarcel    proc_error (pi, "init_inferior, get_held_signals", __LINE__);
4814130812Smarcel  if (!proc_get_traced_faults   (pi, &pi->saved_fltset))
4815130812Smarcel    proc_error (pi, "init_inferior, get_traced_faults", __LINE__);
4816130812Smarcel  if (!proc_get_traced_sysentry (pi, pi->saved_entryset))
4817130812Smarcel    proc_error (pi, "init_inferior, get_traced_sysentry", __LINE__);
4818130812Smarcel  if (!proc_get_traced_sysexit  (pi, pi->saved_exitset))
4819130812Smarcel    proc_error (pi, "init_inferior, get_traced_sysexit", __LINE__);
4820130812Smarcel
4821130812Smarcel  /* Register to trace selected signals in the child. */
4822130812Smarcel  prfillset (&signals);
4823130812Smarcel  if (!register_gdb_signals (pi, &signals))
4824130812Smarcel    proc_error (pi, "init_inferior, register_signals", __LINE__);
4825130812Smarcel
4826130812Smarcel  if ((fail = procfs_debug_inferior (pi)) != 0)
4827130812Smarcel    proc_error (pi, "init_inferior (procfs_debug_inferior)", fail);
4828130812Smarcel
4829130812Smarcel  /* FIXME: logically, we should really be turning OFF run-on-last-close,
4830130812Smarcel     and possibly even turning ON kill-on-last-close at this point.  But
4831130812Smarcel     I can't make that change without careful testing which I don't have
4832130812Smarcel     time to do right now...  */
4833130812Smarcel  /* Turn on run-on-last-close flag so that the child
4834130812Smarcel     will die if GDB goes away for some reason.  */
4835130812Smarcel  if (!proc_set_run_on_last_close (pi))
4836130812Smarcel    proc_error (pi, "init_inferior, set_RLC", __LINE__);
4837130812Smarcel
4838130812Smarcel  /* The 'process ID' we return to GDB is composed of
4839130812Smarcel     the actual process ID plus the lwp ID. */
4840130812Smarcel  inferior_ptid = MERGEPID (pi->pid, proc_get_current_thread (pi));
4841130812Smarcel
4842130812Smarcel  /* Typically two, one trap to exec the shell, one to exec the
4843130812Smarcel     program being debugged.  Defined by "inferior.h".  */
4844130812Smarcel  startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
4845130812Smarcel}
4846130812Smarcel
4847130812Smarcel/*
4848130812Smarcel * Function: set_exec_trap
4849130812Smarcel *
4850130812Smarcel * When GDB forks to create a new process, this function is called
4851130812Smarcel * on the child side of the fork before GDB exec's the user program.
4852130812Smarcel * Its job is to make the child minimally debuggable, so that the
4853130812Smarcel * parent GDB process can connect to the child and take over.
4854130812Smarcel * This function should do only the minimum to make that possible,
4855130812Smarcel * and to synchronize with the parent process.  The parent process
4856130812Smarcel * should take care of the details.
4857130812Smarcel */
4858130812Smarcel
4859130812Smarcelstatic void
4860130812Smarcelprocfs_set_exec_trap (void)
4861130812Smarcel{
4862130812Smarcel  /* This routine called on the child side (inferior side)
4863130812Smarcel     after GDB forks the inferior.  It must use only local variables,
4864130812Smarcel     because it may be sharing data space with its parent.  */
4865130812Smarcel
4866130812Smarcel  procinfo *pi;
4867130812Smarcel  sysset_t *exitset;
4868130812Smarcel
4869130812Smarcel  if ((pi = create_procinfo (getpid (), 0)) == NULL)
4870130812Smarcel    perror_with_name ("procfs: create_procinfo failed in child.");
4871130812Smarcel
4872130812Smarcel  if (open_procinfo_files (pi, FD_CTL) == 0)
4873130812Smarcel    {
4874130812Smarcel      proc_warn (pi, "set_exec_trap, open_proc_files", __LINE__);
4875130812Smarcel      gdb_flush (gdb_stderr);
4876130812Smarcel      /* no need to call "dead_procinfo", because we're going to exit. */
4877130812Smarcel      _exit (127);
4878130812Smarcel    }
4879130812Smarcel
4880130812Smarcel#ifdef PRFS_STOPEXEC	/* defined on OSF */
4881130812Smarcel  /* OSF method for tracing exec syscalls.  Quoting:
4882130812Smarcel     Under Alpha OSF/1 we have to use a PIOCSSPCACT ioctl to trace
4883130812Smarcel     exits from exec system calls because of the user level loader.  */
4884130812Smarcel  /* FIXME: make nice and maybe move into an access function. */
4885130812Smarcel  {
4886130812Smarcel    int prfs_flags;
4887130812Smarcel
4888130812Smarcel    if (ioctl (pi->ctl_fd, PIOCGSPCACT, &prfs_flags) < 0)
4889130812Smarcel      {
4890130812Smarcel	proc_warn (pi, "set_exec_trap (PIOCGSPCACT)", __LINE__);
4891130812Smarcel	gdb_flush (gdb_stderr);
4892130812Smarcel	_exit (127);
4893130812Smarcel      }
4894130812Smarcel    prfs_flags |= PRFS_STOPEXEC;
4895130812Smarcel
4896130812Smarcel    if (ioctl (pi->ctl_fd, PIOCSSPCACT, &prfs_flags) < 0)
4897130812Smarcel      {
4898130812Smarcel	proc_warn (pi, "set_exec_trap (PIOCSSPCACT)", __LINE__);
4899130812Smarcel	gdb_flush (gdb_stderr);
4900130812Smarcel	_exit (127);
4901130812Smarcel      }
4902130812Smarcel  }
4903130812Smarcel#else /* not PRFS_STOPEXEC */
4904130812Smarcel  /* Everyone else's (except OSF) method for tracing exec syscalls */
4905130812Smarcel  /* GW: Rationale...
4906130812Smarcel     Not all systems with /proc have all the exec* syscalls with the same
4907130812Smarcel     names.  On the SGI, for example, there is no SYS_exec, but there
4908130812Smarcel     *is* a SYS_execv.  So, we try to account for that. */
4909130812Smarcel
4910130812Smarcel  exitset = sysset_t_alloc (pi);
4911130812Smarcel  gdb_premptysysset (exitset);
4912130812Smarcel#ifdef SYS_exec
4913130812Smarcel  gdb_praddsysset (exitset, SYS_exec);
4914130812Smarcel#endif
4915130812Smarcel#ifdef SYS_execve
4916130812Smarcel  gdb_praddsysset (exitset, SYS_execve);
4917130812Smarcel#endif
4918130812Smarcel#ifdef SYS_execv
4919130812Smarcel  gdb_praddsysset (exitset, SYS_execv);
4920130812Smarcel#endif
4921130812Smarcel#ifdef DYNAMIC_SYSCALLS
4922130812Smarcel  {
4923130812Smarcel    int callnum = find_syscall (pi, "execve");
4924130812Smarcel
4925130812Smarcel    if (callnum >= 0)
4926130812Smarcel      gdb_praddsysset (exitset, callnum);
4927130812Smarcel
4928130812Smarcel    callnum = find_syscall (pi, "ra_execve");
4929130812Smarcel    if (callnum >= 0)
4930130812Smarcel      gdb_praddsysset (exitset, callnum);
4931130812Smarcel  }
4932130812Smarcel#endif /* DYNAMIC_SYSCALLS */
4933130812Smarcel
4934130812Smarcel  if (!proc_set_traced_sysexit (pi, exitset))
4935130812Smarcel    {
4936130812Smarcel      proc_warn (pi, "set_exec_trap, set_traced_sysexit", __LINE__);
4937130812Smarcel      gdb_flush (gdb_stderr);
4938130812Smarcel      _exit (127);
4939130812Smarcel    }
4940130812Smarcel#endif /* PRFS_STOPEXEC */
4941130812Smarcel
4942130812Smarcel  /* FIXME: should this be done in the parent instead? */
4943130812Smarcel  /* Turn off inherit on fork flag so that all grand-children
4944130812Smarcel     of gdb start with tracing flags cleared.  */
4945130812Smarcel  if (!proc_unset_inherit_on_fork (pi))
4946130812Smarcel    proc_warn (pi, "set_exec_trap, unset_inherit", __LINE__);
4947130812Smarcel
4948130812Smarcel  /* Turn off run on last close flag, so that the child process
4949130812Smarcel     cannot run away just because we close our handle on it.
4950130812Smarcel     We want it to wait for the parent to attach.  */
4951130812Smarcel  if (!proc_unset_run_on_last_close (pi))
4952130812Smarcel    proc_warn (pi, "set_exec_trap, unset_RLC", __LINE__);
4953130812Smarcel
4954130812Smarcel  /* FIXME: No need to destroy the procinfo --
4955130812Smarcel     we have our own address space, and we're about to do an exec! */
4956130812Smarcel  /*destroy_procinfo (pi);*/
4957130812Smarcel}
4958130812Smarcel
4959130812Smarcel/*
4960130812Smarcel * Function: create_inferior
4961130812Smarcel *
4962130812Smarcel * This function is called BEFORE gdb forks the inferior process.
4963130812Smarcel * Its only real responsibility is to set things up for the fork,
4964130812Smarcel * and tell GDB which two functions to call after the fork (one
4965130812Smarcel * for the parent, and one for the child).
4966130812Smarcel *
4967130812Smarcel * This function does a complicated search for a unix shell program,
4968130812Smarcel * which it then uses to parse arguments and environment variables
4969130812Smarcel * to be sent to the child.  I wonder whether this code could not
4970130812Smarcel * be abstracted out and shared with other unix targets such as
4971130812Smarcel * infptrace?
4972130812Smarcel */
4973130812Smarcel
4974130812Smarcelstatic void
4975130812Smarcelprocfs_create_inferior (char *exec_file, char *allargs, char **env)
4976130812Smarcel{
4977130812Smarcel  char *shell_file = getenv ("SHELL");
4978130812Smarcel  char *tryname;
4979130812Smarcel  if (shell_file != NULL && strchr (shell_file, '/') == NULL)
4980130812Smarcel    {
4981130812Smarcel
4982130812Smarcel      /* We will be looking down the PATH to find shell_file.  If we
4983130812Smarcel	 just do this the normal way (via execlp, which operates by
4984130812Smarcel	 attempting an exec for each element of the PATH until it
4985130812Smarcel	 finds one which succeeds), then there will be an exec for
4986130812Smarcel	 each failed attempt, each of which will cause a PR_SYSEXIT
4987130812Smarcel	 stop, and we won't know how to distinguish the PR_SYSEXIT's
4988130812Smarcel	 for these failed execs with the ones for successful execs
4989130812Smarcel	 (whether the exec has succeeded is stored at that time in the
4990130812Smarcel	 carry bit or some such architecture-specific and
4991130812Smarcel	 non-ABI-specified place).
4992130812Smarcel
4993130812Smarcel	 So I can't think of anything better than to search the PATH
4994130812Smarcel	 now.  This has several disadvantages: (1) There is a race
4995130812Smarcel	 condition; if we find a file now and it is deleted before we
4996130812Smarcel	 exec it, we lose, even if the deletion leaves a valid file
4997130812Smarcel	 further down in the PATH, (2) there is no way to know exactly
4998130812Smarcel	 what an executable (in the sense of "capable of being
4999130812Smarcel	 exec'd") file is.  Using access() loses because it may lose
5000130812Smarcel	 if the caller is the superuser; failing to use it loses if
5001130812Smarcel	 there are ACLs or some such.  */
5002130812Smarcel
5003130812Smarcel      char *p;
5004130812Smarcel      char *p1;
5005130812Smarcel      /* FIXME-maybe: might want "set path" command so user can change what
5006130812Smarcel	 path is used from within GDB.  */
5007130812Smarcel      char *path = getenv ("PATH");
5008130812Smarcel      int len;
5009130812Smarcel      struct stat statbuf;
5010130812Smarcel
5011130812Smarcel      if (path == NULL)
5012130812Smarcel	path = "/bin:/usr/bin";
5013130812Smarcel
5014130812Smarcel      tryname = alloca (strlen (path) + strlen (shell_file) + 2);
5015130812Smarcel      for (p = path; p != NULL; p = p1 ? p1 + 1: NULL)
5016130812Smarcel	{
5017130812Smarcel	  p1 = strchr (p, ':');
5018130812Smarcel	  if (p1 != NULL)
5019130812Smarcel	    len = p1 - p;
5020130812Smarcel	  else
5021130812Smarcel	    len = strlen (p);
5022130812Smarcel	  strncpy (tryname, p, len);
5023130812Smarcel	  tryname[len] = '\0';
5024130812Smarcel	  strcat (tryname, "/");
5025130812Smarcel	  strcat (tryname, shell_file);
5026130812Smarcel	  if (access (tryname, X_OK) < 0)
5027130812Smarcel	    continue;
5028130812Smarcel	  if (stat (tryname, &statbuf) < 0)
5029130812Smarcel	    continue;
5030130812Smarcel	  if (!S_ISREG (statbuf.st_mode))
5031130812Smarcel	    /* We certainly need to reject directories.  I'm not quite
5032130812Smarcel	       as sure about FIFOs, sockets, etc., but I kind of doubt
5033130812Smarcel	       that people want to exec() these things.  */
5034130812Smarcel	    continue;
5035130812Smarcel	  break;
5036130812Smarcel	}
5037130812Smarcel      if (p == NULL)
5038130812Smarcel	/* Not found.  This must be an error rather than merely passing
5039130812Smarcel	   the file to execlp(), because execlp() would try all the
5040130812Smarcel	   exec()s, causing GDB to get confused.  */
5041130812Smarcel	error ("procfs:%d -- Can't find shell %s in PATH",
5042130812Smarcel	       __LINE__, shell_file);
5043130812Smarcel
5044130812Smarcel      shell_file = tryname;
5045130812Smarcel    }
5046130812Smarcel
5047130812Smarcel  fork_inferior (exec_file, allargs, env, procfs_set_exec_trap,
5048130812Smarcel		 procfs_init_inferior, NULL, shell_file);
5049130812Smarcel
5050130812Smarcel  /* We are at the first instruction we care about.  */
5051130812Smarcel  /* Pedal to the metal... */
5052130812Smarcel
5053130812Smarcel  proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
5054130812Smarcel}
5055130812Smarcel
5056130812Smarcel/*
5057130812Smarcel * Function: notice_thread
5058130812Smarcel *
5059130812Smarcel * Callback for find_new_threads.
5060130812Smarcel * Calls "add_thread".
5061130812Smarcel */
5062130812Smarcel
5063130812Smarcelstatic int
5064130812Smarcelprocfs_notice_thread (procinfo *pi, procinfo *thread, void *ptr)
5065130812Smarcel{
5066130812Smarcel  ptid_t gdb_threadid = MERGEPID (pi->pid, thread->tid);
5067130812Smarcel
5068130812Smarcel  if (!in_thread_list (gdb_threadid))
5069130812Smarcel    add_thread (gdb_threadid);
5070130812Smarcel
5071130812Smarcel  return 0;
5072130812Smarcel}
5073130812Smarcel
5074130812Smarcel/*
5075130812Smarcel * Function: target_find_new_threads
5076130812Smarcel *
5077130812Smarcel * Query all the threads that the target knows about,
5078130812Smarcel * and give them back to GDB to add to its list.
5079130812Smarcel */
5080130812Smarcel
5081130812Smarcelvoid
5082130812Smarcelprocfs_find_new_threads (void)
5083130812Smarcel{
5084130812Smarcel  procinfo *pi;
5085130812Smarcel
5086130812Smarcel  /* Find procinfo for main process */
5087130812Smarcel  pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
5088130812Smarcel  proc_update_threads (pi);
5089130812Smarcel  proc_iterate_over_threads (pi, procfs_notice_thread, NULL);
5090130812Smarcel}
5091130812Smarcel
5092130812Smarcel/*
5093130812Smarcel * Function: target_thread_alive
5094130812Smarcel *
5095130812Smarcel * Return true if the thread is still 'alive'.
5096130812Smarcel *
5097130812Smarcel * This guy doesn't really seem to be doing his job.
5098130812Smarcel * Got to investigate how to tell when a thread is really gone.
5099130812Smarcel */
5100130812Smarcel
5101130812Smarcelstatic int
5102130812Smarcelprocfs_thread_alive (ptid_t ptid)
5103130812Smarcel{
5104130812Smarcel  int proc, thread;
5105130812Smarcel  procinfo *pi;
5106130812Smarcel
5107130812Smarcel  proc    = PIDGET (ptid);
5108130812Smarcel  thread  = TIDGET (ptid);
5109130812Smarcel  /* If I don't know it, it ain't alive! */
5110130812Smarcel  if ((pi = find_procinfo (proc, thread)) == NULL)
5111130812Smarcel    return 0;
5112130812Smarcel
5113130812Smarcel  /* If I can't get its status, it ain't alive!
5114130812Smarcel     What's more, I need to forget about it!  */
5115130812Smarcel  if (!proc_get_status (pi))
5116130812Smarcel    {
5117130812Smarcel      destroy_procinfo (pi);
5118130812Smarcel      return 0;
5119130812Smarcel    }
5120130812Smarcel  /* I couldn't have got its status if it weren't alive, so it's alive.  */
5121130812Smarcel  return 1;
5122130812Smarcel}
5123130812Smarcel
5124130812Smarcel/*
5125130812Smarcel * Function: target_pid_to_str
5126130812Smarcel *
5127130812Smarcel * Return a string to be used to identify the thread in
5128130812Smarcel * the "info threads" display.
5129130812Smarcel */
5130130812Smarcel
5131130812Smarcelchar *
5132130812Smarcelprocfs_pid_to_str (ptid_t ptid)
5133130812Smarcel{
5134130812Smarcel  static char buf[80];
5135130812Smarcel  int proc, thread;
5136130812Smarcel  procinfo *pi;
5137130812Smarcel
5138130812Smarcel  proc    = PIDGET (ptid);
5139130812Smarcel  thread  = TIDGET (ptid);
5140130812Smarcel  pi      = find_procinfo (proc, thread);
5141130812Smarcel
5142130812Smarcel  if (thread == 0)
5143130812Smarcel    sprintf (buf, "Process %d", proc);
5144130812Smarcel  else
5145130812Smarcel    sprintf (buf, "LWP %d", thread);
5146130812Smarcel  return &buf[0];
5147130812Smarcel}
5148130812Smarcel
5149130812Smarcel/*
5150130812Smarcel * Function: procfs_set_watchpoint
5151130812Smarcel * Insert a watchpoint
5152130812Smarcel */
5153130812Smarcel
5154130812Smarcelint
5155130812Smarcelprocfs_set_watchpoint (ptid_t ptid, CORE_ADDR addr, int len, int rwflag,
5156130812Smarcel                       int after)
5157130812Smarcel{
5158130812Smarcel#ifndef UNIXWARE
5159130812Smarcel#ifndef AIX5
5160130812Smarcel  int       pflags = 0;
5161130812Smarcel  procinfo *pi;
5162130812Smarcel
5163130812Smarcel  pi = find_procinfo_or_die (PIDGET (ptid) == -1 ?
5164130812Smarcel			     PIDGET (inferior_ptid) : PIDGET (ptid), 0);
5165130812Smarcel
5166130812Smarcel  /* Translate from GDB's flags to /proc's */
5167130812Smarcel  if (len > 0)	/* len == 0 means delete watchpoint */
5168130812Smarcel    {
5169130812Smarcel      switch (rwflag) {		/* FIXME: need an enum! */
5170130812Smarcel      case hw_write:		/* default watchpoint (write) */
5171130812Smarcel	pflags = WRITE_WATCHFLAG;
5172130812Smarcel	break;
5173130812Smarcel      case hw_read:		/* read watchpoint */
5174130812Smarcel	pflags = READ_WATCHFLAG;
5175130812Smarcel	break;
5176130812Smarcel      case hw_access:		/* access watchpoint */
5177130812Smarcel	pflags = READ_WATCHFLAG | WRITE_WATCHFLAG;
5178130812Smarcel	break;
5179130812Smarcel      case hw_execute:		/* execution HW breakpoint */
5180130812Smarcel	pflags = EXEC_WATCHFLAG;
5181130812Smarcel	break;
5182130812Smarcel      default:			/* Something weird.  Return error. */
5183130812Smarcel	return -1;
5184130812Smarcel      }
5185130812Smarcel      if (after)		/* Stop after r/w access is completed. */
5186130812Smarcel	pflags |= AFTER_WATCHFLAG;
5187130812Smarcel    }
5188130812Smarcel
5189130812Smarcel  if (!proc_set_watchpoint (pi, addr, len, pflags))
5190130812Smarcel    {
5191130812Smarcel      if (errno == E2BIG)	/* Typical error for no resources */
5192130812Smarcel	return -1;		/* fail */
5193130812Smarcel      /* GDB may try to remove the same watchpoint twice.
5194130812Smarcel	 If a remove request returns no match, don't error.  */
5195130812Smarcel      if (errno == ESRCH && len == 0)
5196130812Smarcel	return 0;		/* ignore */
5197130812Smarcel      proc_error (pi, "set_watchpoint", __LINE__);
5198130812Smarcel    }
5199130812Smarcel#endif /* AIX5 */
5200130812Smarcel#endif /* UNIXWARE */
5201130812Smarcel  return 0;
5202130812Smarcel}
5203130812Smarcel
5204130812Smarcel/* Return non-zero if we can set a hardware watchpoint of type TYPE.  TYPE
5205130812Smarcel   is one of bp_hardware_watchpoint, bp_read_watchpoint, bp_write_watchpoint,
5206130812Smarcel   or bp_hardware_watchpoint.  CNT is the number of watchpoints used so
5207130812Smarcel   far.
5208130812Smarcel
5209130812Smarcel   Note:  procfs_can_use_hw_breakpoint() is not yet used by all
5210130812Smarcel   procfs.c targets due to the fact that some of them still define
5211130812Smarcel   TARGET_CAN_USE_HARDWARE_WATCHPOINT.  */
5212130812Smarcel
5213130812Smarcelstatic int
5214130812Smarcelprocfs_can_use_hw_breakpoint (int type, int cnt, int othertype)
5215130812Smarcel{
5216130812Smarcel#ifndef TARGET_HAS_HARDWARE_WATCHPOINTS
5217130812Smarcel  return 0;
5218130812Smarcel#else
5219130812Smarcel  /* Due to the way that proc_set_watchpoint() is implemented, host
5220130812Smarcel     and target pointers must be of the same size.  If they are not,
5221130812Smarcel     we can't use hardware watchpoints.  This limitation is due to the
5222130812Smarcel     fact that proc_set_watchpoint() calls
5223130812Smarcel     procfs_address_to_host_pointer(); a close inspection of
5224130812Smarcel     procfs_address_to_host_pointer will reveal that an internal error
5225130812Smarcel     will be generated when the host and target pointer sizes are
5226130812Smarcel     different.  */
5227130812Smarcel  if (sizeof (void *) != TYPE_LENGTH (builtin_type_void_data_ptr))
5228130812Smarcel    return 0;
5229130812Smarcel
5230130812Smarcel  /* Other tests here???  */
5231130812Smarcel
5232130812Smarcel  return 1;
5233130812Smarcel#endif
5234130812Smarcel}
5235130812Smarcel
5236130812Smarcel/*
5237130812Smarcel * Function: stopped_by_watchpoint
5238130812Smarcel *
5239130812Smarcel * Returns non-zero if process is stopped on a hardware watchpoint fault,
5240130812Smarcel * else returns zero.
5241130812Smarcel */
5242130812Smarcel
5243130812Smarcelint
5244130812Smarcelprocfs_stopped_by_watchpoint (ptid_t ptid)
5245130812Smarcel{
5246130812Smarcel  procinfo *pi;
5247130812Smarcel
5248130812Smarcel  pi = find_procinfo_or_die (PIDGET (ptid) == -1 ?
5249130812Smarcel			     PIDGET (inferior_ptid) : PIDGET (ptid), 0);
5250130812Smarcel
5251130812Smarcel  if (!pi)	/* If no process, then not stopped by watchpoint!  */
5252130812Smarcel    return 0;
5253130812Smarcel
5254130812Smarcel  if (proc_flags (pi) & (PR_STOPPED | PR_ISTOP))
5255130812Smarcel    {
5256130812Smarcel      if (proc_why (pi) == PR_FAULTED)
5257130812Smarcel	{
5258130812Smarcel#ifdef FLTWATCH
5259130812Smarcel	  if (proc_what (pi) == FLTWATCH)
5260130812Smarcel	    return 1;
5261130812Smarcel#endif
5262130812Smarcel#ifdef FLTKWATCH
5263130812Smarcel	  if (proc_what (pi) == FLTKWATCH)
5264130812Smarcel	    return 1;
5265130812Smarcel#endif
5266130812Smarcel	}
5267130812Smarcel    }
5268130812Smarcel  return 0;
5269130812Smarcel}
5270130812Smarcel
5271130812Smarcel#ifdef TM_I386SOL2_H
5272130812Smarcel/*
5273130812Smarcel * Function: procfs_find_LDT_entry
5274130812Smarcel *
5275130812Smarcel * Input:
5276130812Smarcel *   ptid_t ptid;	// The GDB-style pid-plus-LWP.
5277130812Smarcel *
5278130812Smarcel * Return:
5279130812Smarcel *   pointer to the corresponding LDT entry.
5280130812Smarcel */
5281130812Smarcel
5282130812Smarcelstruct ssd *
5283130812Smarcelprocfs_find_LDT_entry (ptid_t ptid)
5284130812Smarcel{
5285130812Smarcel  gdb_gregset_t *gregs;
5286130812Smarcel  int            key;
5287130812Smarcel  procinfo      *pi;
5288130812Smarcel
5289130812Smarcel  /* Find procinfo for the lwp. */
5290130812Smarcel  if ((pi = find_procinfo (PIDGET (ptid), TIDGET (ptid))) == NULL)
5291130812Smarcel    {
5292130812Smarcel      warning ("procfs_find_LDT_entry: could not find procinfo for %d:%d.",
5293130812Smarcel	       PIDGET (ptid), TIDGET (ptid));
5294130812Smarcel      return NULL;
5295130812Smarcel    }
5296130812Smarcel  /* get its general registers. */
5297130812Smarcel  if ((gregs = proc_get_gregs (pi)) == NULL)
5298130812Smarcel    {
5299130812Smarcel      warning ("procfs_find_LDT_entry: could not read gregs for %d:%d.",
5300130812Smarcel	       PIDGET (ptid), TIDGET (ptid));
5301130812Smarcel      return NULL;
5302130812Smarcel    }
5303130812Smarcel  /* Now extract the GS register's lower 16 bits. */
5304130812Smarcel  key = (*gregs)[GS] & 0xffff;
5305130812Smarcel
5306130812Smarcel  /* Find the matching entry and return it. */
5307130812Smarcel  return proc_get_LDT_entry (pi, key);
5308130812Smarcel}
5309130812Smarcel#endif /* TM_I386SOL2_H */
5310130812Smarcel
5311130812Smarcel/*
5312130812Smarcel * Memory Mappings Functions:
5313130812Smarcel */
5314130812Smarcel
5315130812Smarcel/*
5316130812Smarcel * Function: iterate_over_mappings
5317130812Smarcel *
5318130812Smarcel * Call a callback function once for each mapping, passing it the mapping,
5319130812Smarcel * an optional secondary callback function, and some optional opaque data.
5320130812Smarcel * Quit and return the first non-zero value returned from the callback.
5321130812Smarcel *
5322130812Smarcel * Arguments:
5323130812Smarcel *   pi   -- procinfo struct for the process to be mapped.
5324130812Smarcel *   func -- callback function to be called by this iterator.
5325130812Smarcel *   data -- optional opaque data to be passed to the callback function.
5326130812Smarcel *   child_func -- optional secondary function pointer to be passed
5327130812Smarcel *                 to the child function.
5328130812Smarcel *
5329130812Smarcel * Return: First non-zero return value from the callback function,
5330130812Smarcel *         or zero.
5331130812Smarcel */
5332130812Smarcel
5333130812Smarcelstatic int
5334130812Smarceliterate_over_mappings (procinfo *pi, int (*child_func) (), void *data,
5335130812Smarcel		       int (*func) (struct prmap *map,
5336130812Smarcel				    int (*child_func) (),
5337130812Smarcel				    void *data))
5338130812Smarcel{
5339130812Smarcel  char pathname[MAX_PROC_NAME_SIZE];
5340130812Smarcel  struct prmap *prmaps;
5341130812Smarcel  struct prmap *prmap;
5342130812Smarcel  int funcstat;
5343130812Smarcel  int map_fd;
5344130812Smarcel  int nmap;
5345130812Smarcel#ifdef NEW_PROC_API
5346130812Smarcel  struct stat sbuf;
5347130812Smarcel#endif
5348130812Smarcel
5349130812Smarcel  /* Get the number of mappings, allocate space,
5350130812Smarcel     and read the mappings into prmaps.  */
5351130812Smarcel#ifdef NEW_PROC_API
5352130812Smarcel  /* Open map fd. */
5353130812Smarcel  sprintf (pathname, "/proc/%d/map", pi->pid);
5354130812Smarcel  if ((map_fd = open (pathname, O_RDONLY)) < 0)
5355130812Smarcel    proc_error (pi, "iterate_over_mappings (open)", __LINE__);
5356130812Smarcel
5357130812Smarcel  /* Make sure it gets closed again. */
5358130812Smarcel  make_cleanup_close (map_fd);
5359130812Smarcel
5360130812Smarcel  /* Use stat to determine the file size, and compute
5361130812Smarcel     the number of prmap_t objects it contains.  */
5362130812Smarcel  if (fstat (map_fd, &sbuf) != 0)
5363130812Smarcel    proc_error (pi, "iterate_over_mappings (fstat)", __LINE__);
5364130812Smarcel
5365130812Smarcel  nmap = sbuf.st_size / sizeof (prmap_t);
5366130812Smarcel  prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
5367130812Smarcel  if (read (map_fd, (char *) prmaps, nmap * sizeof (*prmaps))
5368130812Smarcel      != (nmap * sizeof (*prmaps)))
5369130812Smarcel    proc_error (pi, "iterate_over_mappings (read)", __LINE__);
5370130812Smarcel#else
5371130812Smarcel  /* Use ioctl command PIOCNMAP to get number of mappings.  */
5372130812Smarcel  if (ioctl (pi->ctl_fd, PIOCNMAP, &nmap) != 0)
5373130812Smarcel    proc_error (pi, "iterate_over_mappings (PIOCNMAP)", __LINE__);
5374130812Smarcel
5375130812Smarcel  prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
5376130812Smarcel  if (ioctl (pi->ctl_fd, PIOCMAP, prmaps) != 0)
5377130812Smarcel    proc_error (pi, "iterate_over_mappings (PIOCMAP)", __LINE__);
5378130812Smarcel#endif
5379130812Smarcel
5380130812Smarcel  for (prmap = prmaps; nmap > 0; prmap++, nmap--)
5381130812Smarcel    if ((funcstat = (*func) (prmap, child_func, data)) != 0)
5382130812Smarcel      return funcstat;
5383130812Smarcel
5384130812Smarcel  return 0;
5385130812Smarcel}
5386130812Smarcel
5387130812Smarcel/*
5388130812Smarcel * Function: solib_mappings_callback
5389130812Smarcel *
5390130812Smarcel * Calls the supplied callback function once for each mapped address
5391130812Smarcel * space in the process.  The callback function  receives an open
5392130812Smarcel * file descriptor for the file corresponding to that mapped
5393130812Smarcel * address space (if there is one), and the base address of the
5394130812Smarcel * mapped space.  Quit when the callback function returns a
5395130812Smarcel * nonzero value, or at teh end of the mappings.
5396130812Smarcel *
5397130812Smarcel * Returns: the first non-zero return value of the callback function,
5398130812Smarcel * or zero.
5399130812Smarcel */
5400130812Smarcel
5401130812Smarcelint solib_mappings_callback (struct prmap *map,
5402130812Smarcel			     int (*func) (int, CORE_ADDR),
5403130812Smarcel			     void *data)
5404130812Smarcel{
5405130812Smarcel  procinfo *pi = data;
5406130812Smarcel  int fd;
5407130812Smarcel
5408130812Smarcel#ifdef NEW_PROC_API
5409130812Smarcel  char name[MAX_PROC_NAME_SIZE + sizeof (map->pr_mapname)];
5410130812Smarcel
5411130812Smarcel  if (map->pr_vaddr == 0 && map->pr_size == 0)
5412130812Smarcel    return -1;		/* sanity */
5413130812Smarcel
5414130812Smarcel  if (map->pr_mapname[0] == 0)
5415130812Smarcel    {
5416130812Smarcel      fd = -1;	/* no map file */
5417130812Smarcel    }
5418130812Smarcel  else
5419130812Smarcel    {
5420130812Smarcel      sprintf (name, "/proc/%d/object/%s", pi->pid, map->pr_mapname);
5421130812Smarcel      /* Note: caller's responsibility to close this fd!  */
5422130812Smarcel      fd = open_with_retry (name, O_RDONLY);
5423130812Smarcel      /* Note: we don't test the above call for failure;
5424130812Smarcel	 we just pass the FD on as given.  Sometimes there is
5425130812Smarcel	 no file, so the open may return failure, but that's
5426130812Smarcel	 not a problem.  */
5427130812Smarcel    }
5428130812Smarcel#else
5429130812Smarcel  fd = ioctl (pi->ctl_fd, PIOCOPENM, &map->pr_vaddr);
5430130812Smarcel  /* Note: we don't test the above call for failure;
5431130812Smarcel     we just pass the FD on as given.  Sometimes there is
5432130812Smarcel     no file, so the ioctl may return failure, but that's
5433130812Smarcel     not a problem.  */
5434130812Smarcel#endif
5435130812Smarcel  return (*func) (fd, (CORE_ADDR) map->pr_vaddr);
5436130812Smarcel}
5437130812Smarcel
5438130812Smarcel/*
5439130812Smarcel * Function: proc_iterate_over_mappings
5440130812Smarcel *
5441130812Smarcel * Uses the unified "iterate_over_mappings" function
5442130812Smarcel * to implement the exported interface to solib-svr4.c.
5443130812Smarcel *
5444130812Smarcel * Given a pointer to a function, call that function once for every
5445130812Smarcel * mapped address space in the process.  The callback function
5446130812Smarcel * receives an open file descriptor for the file corresponding to
5447130812Smarcel * that mapped address space (if there is one), and the base address
5448130812Smarcel * of the mapped space.  Quit when the callback function returns a
5449130812Smarcel * nonzero value, or at teh end of the mappings.
5450130812Smarcel *
5451130812Smarcel * Returns: the first non-zero return value of the callback function,
5452130812Smarcel * or zero.
5453130812Smarcel */
5454130812Smarcel
5455130812Smarcelint
5456130812Smarcelproc_iterate_over_mappings (int (*func) (int, CORE_ADDR))
5457130812Smarcel{
5458130812Smarcel  procinfo *pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
5459130812Smarcel
5460130812Smarcel  return iterate_over_mappings (pi, func, pi, solib_mappings_callback);
5461130812Smarcel}
5462130812Smarcel
5463130812Smarcel/*
5464130812Smarcel * Function: find_memory_regions_callback
5465130812Smarcel *
5466130812Smarcel * Implements the to_find_memory_regions method.
5467130812Smarcel * Calls an external function for each memory region.
5468130812Smarcel * External function will have the signiture:
5469130812Smarcel *
5470130812Smarcel *   int callback (CORE_ADDR vaddr,
5471130812Smarcel *                 unsigned long size,
5472130812Smarcel *                 int read, int write, int execute,
5473130812Smarcel *                 void *data);
5474130812Smarcel *
5475130812Smarcel * Returns the integer value returned by the callback.
5476130812Smarcel */
5477130812Smarcel
5478130812Smarcelstatic int
5479130812Smarcelfind_memory_regions_callback (struct prmap *map,
5480130812Smarcel			      int (*func) (CORE_ADDR,
5481130812Smarcel					   unsigned long,
5482130812Smarcel					   int, int, int,
5483130812Smarcel					   void *),
5484130812Smarcel			      void *data)
5485130812Smarcel{
5486130812Smarcel  return (*func) ((CORE_ADDR) map->pr_vaddr,
5487130812Smarcel		  map->pr_size,
5488130812Smarcel		  (map->pr_mflags & MA_READ) != 0,
5489130812Smarcel		  (map->pr_mflags & MA_WRITE) != 0,
5490130812Smarcel		  (map->pr_mflags & MA_EXEC) != 0,
5491130812Smarcel		  data);
5492130812Smarcel}
5493130812Smarcel
5494130812Smarcel/*
5495130812Smarcel * Function: proc_find_memory_regions
5496130812Smarcel *
5497130812Smarcel * External interface.  Calls a callback function once for each
5498130812Smarcel * mapped memory region in the child process, passing as arguments
5499130812Smarcel *	CORE_ADDR virtual_address,
5500130812Smarcel *	unsigned long size,
5501130812Smarcel *	int read, 	TRUE if region is readable by the child
5502130812Smarcel *	int write, 	TRUE if region is writable by the child
5503130812Smarcel *	int execute	TRUE if region is executable by the child.
5504130812Smarcel *
5505130812Smarcel * Stops iterating and returns the first non-zero value
5506130812Smarcel * returned by the callback.
5507130812Smarcel */
5508130812Smarcel
5509130812Smarcelstatic int
5510130812Smarcelproc_find_memory_regions (int (*func) (CORE_ADDR,
5511130812Smarcel				       unsigned long,
5512130812Smarcel				       int, int, int,
5513130812Smarcel				       void *),
5514130812Smarcel			  void *data)
5515130812Smarcel{
5516130812Smarcel  procinfo *pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
5517130812Smarcel
5518130812Smarcel  return iterate_over_mappings (pi, func, data,
5519130812Smarcel				find_memory_regions_callback);
5520130812Smarcel}
5521130812Smarcel
5522130812Smarcel/*
5523130812Smarcel * Function: mappingflags
5524130812Smarcel *
5525130812Smarcel * Returns an ascii representation of a memory mapping's flags.
5526130812Smarcel */
5527130812Smarcel
5528130812Smarcelstatic char *
5529130812Smarcelmappingflags (long flags)
5530130812Smarcel{
5531130812Smarcel  static char asciiflags[8];
5532130812Smarcel
5533130812Smarcel  strcpy (asciiflags, "-------");
5534130812Smarcel#if defined (MA_PHYS)
5535130812Smarcel  if (flags & MA_PHYS)
5536130812Smarcel    asciiflags[0] = 'd';
5537130812Smarcel#endif
5538130812Smarcel  if (flags & MA_STACK)
5539130812Smarcel    asciiflags[1] = 's';
5540130812Smarcel  if (flags & MA_BREAK)
5541130812Smarcel    asciiflags[2] = 'b';
5542130812Smarcel  if (flags & MA_SHARED)
5543130812Smarcel    asciiflags[3] = 's';
5544130812Smarcel  if (flags & MA_READ)
5545130812Smarcel    asciiflags[4] = 'r';
5546130812Smarcel  if (flags & MA_WRITE)
5547130812Smarcel    asciiflags[5] = 'w';
5548130812Smarcel  if (flags & MA_EXEC)
5549130812Smarcel    asciiflags[6] = 'x';
5550130812Smarcel  return (asciiflags);
5551130812Smarcel}
5552130812Smarcel
5553130812Smarcel/*
5554130812Smarcel * Function: info_mappings_callback
5555130812Smarcel *
5556130812Smarcel * Callback function, does the actual work for 'info proc mappings'.
5557130812Smarcel */
5558130812Smarcel
5559130812Smarcelstatic int
5560130812Smarcelinfo_mappings_callback (struct prmap *map, int (*ignore) (), void *unused)
5561130812Smarcel{
5562130812Smarcel  char *data_fmt_string;
5563130812Smarcel
5564130812Smarcel  if (TARGET_ADDR_BIT == 32)
5565130812Smarcel    data_fmt_string   = "\t%#10lx %#10lx %#10x %#10x %7s\n";
5566130812Smarcel  else
5567130812Smarcel    data_fmt_string   = "  %#18lx %#18lx %#10x %#10x %7s\n";
5568130812Smarcel
5569130812Smarcel  printf_filtered (data_fmt_string,
5570130812Smarcel		   (unsigned long) map->pr_vaddr,
5571130812Smarcel		   (unsigned long) map->pr_vaddr + map->pr_size - 1,
5572130812Smarcel		   map->pr_size,
5573130812Smarcel#ifdef PCAGENT	/* Horrible hack: only defined on Solaris 2.6+ */
5574130812Smarcel		   (unsigned int) map->pr_offset,
5575130812Smarcel#else
5576130812Smarcel		   map->pr_off,
5577130812Smarcel#endif
5578130812Smarcel		   mappingflags (map->pr_mflags));
5579130812Smarcel
5580130812Smarcel  return 0;
5581130812Smarcel}
5582130812Smarcel
5583130812Smarcel/*
5584130812Smarcel * Function: info_proc_mappings
5585130812Smarcel *
5586130812Smarcel * Implement the "info proc mappings" subcommand.
5587130812Smarcel */
5588130812Smarcel
5589130812Smarcelstatic void
5590130812Smarcelinfo_proc_mappings (procinfo *pi, int summary)
5591130812Smarcel{
5592130812Smarcel  char *header_fmt_string;
5593130812Smarcel
5594130812Smarcel  if (TARGET_PTR_BIT == 32)
5595130812Smarcel    header_fmt_string = "\t%10s %10s %10s %10s %7s\n";
5596130812Smarcel  else
5597130812Smarcel    header_fmt_string = "  %18s %18s %10s %10s %7s\n";
5598130812Smarcel
5599130812Smarcel  if (summary)
5600130812Smarcel    return;	/* No output for summary mode. */
5601130812Smarcel
5602130812Smarcel  printf_filtered ("Mapped address spaces:\n\n");
5603130812Smarcel  printf_filtered (header_fmt_string,
5604130812Smarcel		   "Start Addr",
5605130812Smarcel		   "  End Addr",
5606130812Smarcel		   "      Size",
5607130812Smarcel		   "    Offset",
5608130812Smarcel		   "Flags");
5609130812Smarcel
5610130812Smarcel  iterate_over_mappings (pi, NULL, NULL, info_mappings_callback);
5611130812Smarcel  printf_filtered ("\n");
5612130812Smarcel}
5613130812Smarcel
5614130812Smarcel/*
5615130812Smarcel * Function: info_proc_cmd
5616130812Smarcel *
5617130812Smarcel * Implement the "info proc" command.
5618130812Smarcel */
5619130812Smarcel
5620130812Smarcelstatic void
5621130812Smarcelinfo_proc_cmd (char *args, int from_tty)
5622130812Smarcel{
5623130812Smarcel  struct cleanup *old_chain;
5624130812Smarcel  procinfo *process  = NULL;
5625130812Smarcel  procinfo *thread   = NULL;
5626130812Smarcel  char    **argv     = NULL;
5627130812Smarcel  char     *tmp      = NULL;
5628130812Smarcel  int       pid      = 0;
5629130812Smarcel  int       tid      = 0;
5630130812Smarcel  int       mappings = 0;
5631130812Smarcel
5632130812Smarcel  old_chain = make_cleanup (null_cleanup, 0);
5633130812Smarcel  if (args)
5634130812Smarcel    {
5635130812Smarcel      if ((argv = buildargv (args)) == NULL)
5636130812Smarcel	nomem (0);
5637130812Smarcel      else
5638130812Smarcel	make_cleanup_freeargv (argv);
5639130812Smarcel    }
5640130812Smarcel  while (argv != NULL && *argv != NULL)
5641130812Smarcel    {
5642130812Smarcel      if (isdigit (argv[0][0]))
5643130812Smarcel	{
5644130812Smarcel	  pid = strtoul (argv[0], &tmp, 10);
5645130812Smarcel	  if (*tmp == '/')
5646130812Smarcel	    tid = strtoul (++tmp, NULL, 10);
5647130812Smarcel	}
5648130812Smarcel      else if (argv[0][0] == '/')
5649130812Smarcel	{
5650130812Smarcel	  tid = strtoul (argv[0] + 1, NULL, 10);
5651130812Smarcel	}
5652130812Smarcel      else if (strncmp (argv[0], "mappings", strlen (argv[0])) == 0)
5653130812Smarcel	{
5654130812Smarcel	  mappings = 1;
5655130812Smarcel	}
5656130812Smarcel      else
5657130812Smarcel	{
5658130812Smarcel	  /* [...] */
5659130812Smarcel	}
5660130812Smarcel      argv++;
5661130812Smarcel    }
5662130812Smarcel  if (pid == 0)
5663130812Smarcel    pid = PIDGET (inferior_ptid);
5664130812Smarcel  if (pid == 0)
5665130812Smarcel    error ("No current process: you must name one.");
5666130812Smarcel  else
5667130812Smarcel    {
5668130812Smarcel      /* Have pid, will travel.
5669130812Smarcel	 First see if it's a process we're already debugging. */
5670130812Smarcel      process = find_procinfo (pid, 0);
5671130812Smarcel       if (process == NULL)
5672130812Smarcel	 {
5673130812Smarcel	   /* No.  So open a procinfo for it, but
5674130812Smarcel	      remember to close it again when finished.  */
5675130812Smarcel	   process = create_procinfo (pid, 0);
5676130812Smarcel	   make_cleanup (do_destroy_procinfo_cleanup, process);
5677130812Smarcel	   if (!open_procinfo_files (process, FD_CTL))
5678130812Smarcel	     proc_error (process, "info proc, open_procinfo_files", __LINE__);
5679130812Smarcel	 }
5680130812Smarcel    }
5681130812Smarcel  if (tid != 0)
5682130812Smarcel    thread = create_procinfo (pid, tid);
5683130812Smarcel
5684130812Smarcel  if (process)
5685130812Smarcel    {
5686130812Smarcel      printf_filtered ("process %d flags:\n", process->pid);
5687130812Smarcel      proc_prettyprint_flags (proc_flags (process), 1);
5688130812Smarcel      if (proc_flags (process) & (PR_STOPPED | PR_ISTOP))
5689130812Smarcel	proc_prettyprint_why (proc_why (process), proc_what (process), 1);
5690130812Smarcel      if (proc_get_nthreads (process) > 1)
5691130812Smarcel	printf_filtered ("Process has %d threads.\n",
5692130812Smarcel			 proc_get_nthreads (process));
5693130812Smarcel    }
5694130812Smarcel  if (thread)
5695130812Smarcel    {
5696130812Smarcel      printf_filtered ("thread %d flags:\n", thread->tid);
5697130812Smarcel      proc_prettyprint_flags (proc_flags (thread), 1);
5698130812Smarcel      if (proc_flags (thread) & (PR_STOPPED | PR_ISTOP))
5699130812Smarcel	proc_prettyprint_why (proc_why (thread), proc_what (thread), 1);
5700130812Smarcel    }
5701130812Smarcel
5702130812Smarcel  if (mappings)
5703130812Smarcel    {
5704130812Smarcel      info_proc_mappings (process, 0);
5705130812Smarcel    }
5706130812Smarcel
5707130812Smarcel  do_cleanups (old_chain);
5708130812Smarcel}
5709130812Smarcel
5710130812Smarcelstatic void
5711130812Smarcelproc_trace_syscalls (char *args, int from_tty, int entry_or_exit, int mode)
5712130812Smarcel{
5713130812Smarcel  procinfo *pi;
5714130812Smarcel  sysset_t *sysset;
5715130812Smarcel  int       syscallnum = 0;
5716130812Smarcel
5717130812Smarcel  if (PIDGET (inferior_ptid) <= 0)
5718130812Smarcel    error ("you must be debugging a process to use this command.");
5719130812Smarcel
5720130812Smarcel  if (args == NULL || args[0] == 0)
5721130812Smarcel    error_no_arg ("system call to trace");
5722130812Smarcel
5723130812Smarcel  pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
5724130812Smarcel  if (isdigit (args[0]))
5725130812Smarcel    {
5726130812Smarcel      syscallnum = atoi (args);
5727130812Smarcel      if (entry_or_exit == PR_SYSENTRY)
5728130812Smarcel	sysset = proc_get_traced_sysentry (pi, NULL);
5729130812Smarcel      else
5730130812Smarcel	sysset = proc_get_traced_sysexit (pi, NULL);
5731130812Smarcel
5732130812Smarcel      if (sysset == NULL)
5733130812Smarcel	proc_error (pi, "proc-trace, get_traced_sysset", __LINE__);
5734130812Smarcel
5735130812Smarcel      if (mode == FLAG_SET)
5736130812Smarcel	gdb_praddsysset (sysset, syscallnum);
5737130812Smarcel      else
5738130812Smarcel	gdb_prdelsysset (sysset, syscallnum);
5739130812Smarcel
5740130812Smarcel      if (entry_or_exit == PR_SYSENTRY)
5741130812Smarcel	{
5742130812Smarcel	  if (!proc_set_traced_sysentry (pi, sysset))
5743130812Smarcel	    proc_error (pi, "proc-trace, set_traced_sysentry", __LINE__);
5744130812Smarcel	}
5745130812Smarcel      else
5746130812Smarcel	{
5747130812Smarcel	  if (!proc_set_traced_sysexit (pi, sysset))
5748130812Smarcel	    proc_error (pi, "proc-trace, set_traced_sysexit", __LINE__);
5749130812Smarcel	}
5750130812Smarcel    }
5751130812Smarcel}
5752130812Smarcel
5753130812Smarcelstatic void
5754130812Smarcelproc_trace_sysentry_cmd (char *args, int from_tty)
5755130812Smarcel{
5756130812Smarcel  proc_trace_syscalls (args, from_tty, PR_SYSENTRY, FLAG_SET);
5757130812Smarcel}
5758130812Smarcel
5759130812Smarcelstatic void
5760130812Smarcelproc_trace_sysexit_cmd (char *args, int from_tty)
5761130812Smarcel{
5762130812Smarcel  proc_trace_syscalls (args, from_tty, PR_SYSEXIT, FLAG_SET);
5763130812Smarcel}
5764130812Smarcel
5765130812Smarcelstatic void
5766130812Smarcelproc_untrace_sysentry_cmd (char *args, int from_tty)
5767130812Smarcel{
5768130812Smarcel  proc_trace_syscalls (args, from_tty, PR_SYSENTRY, FLAG_RESET);
5769130812Smarcel}
5770130812Smarcel
5771130812Smarcelstatic void
5772130812Smarcelproc_untrace_sysexit_cmd (char *args, int from_tty)
5773130812Smarcel{
5774130812Smarcel  proc_trace_syscalls (args, from_tty, PR_SYSEXIT, FLAG_RESET);
5775130812Smarcel}
5776130812Smarcel
5777130812Smarcel
5778130812Smarcelvoid
5779130812Smarcel_initialize_procfs (void)
5780130812Smarcel{
5781130812Smarcel  init_procfs_ops ();
5782130812Smarcel  add_target (&procfs_ops);
5783130812Smarcel  add_info ("proc", info_proc_cmd,
5784130812Smarcel	    "Show /proc process information about any running process.\n\
5785130812SmarcelSpecify process id, or use the program being debugged by default.\n\
5786130812SmarcelSpecify keyword 'mappings' for detailed info on memory mappings.");
5787130812Smarcel  add_com ("proc-trace-entry", no_class, proc_trace_sysentry_cmd,
5788130812Smarcel	   "Give a trace of entries into the syscall.");
5789130812Smarcel  add_com ("proc-trace-exit", no_class, proc_trace_sysexit_cmd,
5790130812Smarcel	   "Give a trace of exits from the syscall.");
5791130812Smarcel  add_com ("proc-untrace-entry", no_class, proc_untrace_sysentry_cmd,
5792130812Smarcel	   "Cancel a trace of entries into the syscall.");
5793130812Smarcel  add_com ("proc-untrace-exit", no_class, proc_untrace_sysexit_cmd,
5794130812Smarcel	   "Cancel a trace of exits from the syscall.");
5795130812Smarcel}
5796130812Smarcel
5797130812Smarcel/* =================== END, GDB  "MODULE" =================== */
5798130812Smarcel
5799130812Smarcel
5800130812Smarcel
5801130812Smarcel/* miscellaneous stubs:                                             */
5802130812Smarcel/* The following satisfy a few random symbols mostly created by    */
5803130812Smarcel/* the solaris threads implementation, which I will chase down     */
5804130812Smarcel/* later.        */
5805130812Smarcel
5806130812Smarcel/*
5807130812Smarcel * Return a pid for which we guarantee
5808130812Smarcel * we will be able to find a 'live' procinfo.
5809130812Smarcel */
5810130812Smarcel
5811130812Smarcelptid_t
5812130812Smarcelprocfs_first_available (void)
5813130812Smarcel{
5814130812Smarcel  return pid_to_ptid (procinfo_list ? procinfo_list->pid : -1);
5815130812Smarcel}
5816130812Smarcel
5817130812Smarcel/* ===================  GCORE .NOTE "MODULE" =================== */
5818130812Smarcel#if defined (UNIXWARE) || defined (PIOCOPENLWP) || defined (PCAGENT)
5819130812Smarcel/* gcore only implemented on solaris and unixware (so far) */
5820130812Smarcel
5821130812Smarcelstatic char *
5822130812Smarcelprocfs_do_thread_registers (bfd *obfd, ptid_t ptid,
5823130812Smarcel			    char *note_data, int *note_size)
5824130812Smarcel{
5825130812Smarcel  gdb_gregset_t gregs;
5826130812Smarcel  gdb_fpregset_t fpregs;
5827130812Smarcel  unsigned long merged_pid;
5828130812Smarcel
5829130812Smarcel  merged_pid = TIDGET (ptid) << 16 | PIDGET (ptid);
5830130812Smarcel
5831130812Smarcel  fill_gregset (&gregs, -1);
5832130812Smarcel#if defined (UNIXWARE)
5833130812Smarcel  note_data = (char *) elfcore_write_lwpstatus (obfd,
5834130812Smarcel						note_data,
5835130812Smarcel						note_size,
5836130812Smarcel						merged_pid,
5837130812Smarcel						stop_signal,
5838130812Smarcel						&gregs);
5839130812Smarcel#else
5840130812Smarcel  note_data = (char *) elfcore_write_prstatus (obfd,
5841130812Smarcel					       note_data,
5842130812Smarcel					       note_size,
5843130812Smarcel					       merged_pid,
5844130812Smarcel					       stop_signal,
5845130812Smarcel					       &gregs);
5846130812Smarcel#endif
5847130812Smarcel  fill_fpregset (&fpregs, -1);
5848130812Smarcel  note_data = (char *) elfcore_write_prfpreg (obfd,
5849130812Smarcel					      note_data,
5850130812Smarcel					      note_size,
5851130812Smarcel					      &fpregs,
5852130812Smarcel					      sizeof (fpregs));
5853130812Smarcel  return note_data;
5854130812Smarcel}
5855130812Smarcel
5856130812Smarcelstruct procfs_corefile_thread_data {
5857130812Smarcel  bfd *obfd;
5858130812Smarcel  char *note_data;
5859130812Smarcel  int *note_size;
5860130812Smarcel};
5861130812Smarcel
5862130812Smarcelstatic int
5863130812Smarcelprocfs_corefile_thread_callback (procinfo *pi, procinfo *thread, void *data)
5864130812Smarcel{
5865130812Smarcel  struct procfs_corefile_thread_data *args = data;
5866130812Smarcel
5867130812Smarcel  if (pi != NULL && thread->tid != 0)
5868130812Smarcel    {
5869130812Smarcel      ptid_t saved_ptid = inferior_ptid;
5870130812Smarcel      inferior_ptid = MERGEPID (pi->pid, thread->tid);
5871130812Smarcel      args->note_data = procfs_do_thread_registers (args->obfd, inferior_ptid,
5872130812Smarcel						    args->note_data,
5873130812Smarcel						    args->note_size);
5874130812Smarcel      inferior_ptid = saved_ptid;
5875130812Smarcel    }
5876130812Smarcel  return 0;
5877130812Smarcel}
5878130812Smarcel
5879130812Smarcelstatic char *
5880130812Smarcelprocfs_make_note_section (bfd *obfd, int *note_size)
5881130812Smarcel{
5882130812Smarcel  struct cleanup *old_chain;
5883130812Smarcel  gdb_gregset_t gregs;
5884130812Smarcel  gdb_fpregset_t fpregs;
5885130812Smarcel  char fname[16] = {'\0'};
5886130812Smarcel  char psargs[80] = {'\0'};
5887130812Smarcel  procinfo *pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
5888130812Smarcel  char *note_data = NULL;
5889130812Smarcel  char *inf_args;
5890130812Smarcel  struct procfs_corefile_thread_data thread_args;
5891130812Smarcel  char *auxv;
5892130812Smarcel  int auxv_len;
5893130812Smarcel
5894130812Smarcel  if (get_exec_file (0))
5895130812Smarcel    {
5896130812Smarcel      strncpy (fname, strrchr (get_exec_file (0), '/') + 1, sizeof (fname));
5897130812Smarcel      strncpy (psargs, get_exec_file (0),
5898130812Smarcel	       sizeof (psargs));
5899130812Smarcel
5900130812Smarcel      inf_args = get_inferior_args ();
5901130812Smarcel      if (inf_args && *inf_args &&
5902130812Smarcel	  strlen (inf_args) < ((int) sizeof (psargs) - (int) strlen (psargs)))
5903130812Smarcel	{
5904130812Smarcel	  strncat (psargs, " ",
5905130812Smarcel		   sizeof (psargs) - strlen (psargs));
5906130812Smarcel	  strncat (psargs, inf_args,
5907130812Smarcel		   sizeof (psargs) - strlen (psargs));
5908130812Smarcel	}
5909130812Smarcel    }
5910130812Smarcel
5911130812Smarcel  note_data = (char *) elfcore_write_prpsinfo (obfd,
5912130812Smarcel					       note_data,
5913130812Smarcel					       note_size,
5914130812Smarcel					       fname,
5915130812Smarcel					       psargs);
5916130812Smarcel
5917130812Smarcel#ifdef UNIXWARE
5918130812Smarcel  fill_gregset (&gregs, -1);
5919130812Smarcel  note_data = elfcore_write_pstatus (obfd, note_data, note_size,
5920130812Smarcel				     PIDGET (inferior_ptid),
5921130812Smarcel				     stop_signal, &gregs);
5922130812Smarcel#endif
5923130812Smarcel
5924130812Smarcel  thread_args.obfd = obfd;
5925130812Smarcel  thread_args.note_data = note_data;
5926130812Smarcel  thread_args.note_size = note_size;
5927130812Smarcel  proc_iterate_over_threads (pi, procfs_corefile_thread_callback, &thread_args);
5928130812Smarcel
5929130812Smarcel  if (thread_args.note_data == note_data)
5930130812Smarcel    {
5931130812Smarcel      /* iterate_over_threads didn't come up with any threads;
5932130812Smarcel	 just use inferior_ptid. */
5933130812Smarcel      note_data = procfs_do_thread_registers (obfd, inferior_ptid,
5934130812Smarcel					      note_data, note_size);
5935130812Smarcel    }
5936130812Smarcel  else
5937130812Smarcel    {
5938130812Smarcel      note_data = thread_args.note_data;
5939130812Smarcel    }
5940130812Smarcel
5941130812Smarcel  auxv_len = target_auxv_read (&current_target, &auxv);
5942130812Smarcel  if (auxv_len > 0)
5943130812Smarcel    {
5944130812Smarcel      note_data = elfcore_write_note (obfd, note_data, note_size,
5945130812Smarcel				      "CORE", NT_AUXV, auxv, auxv_len);
5946130812Smarcel      xfree (auxv);
5947130812Smarcel    }
5948130812Smarcel
5949130812Smarcel  make_cleanup (xfree, note_data);
5950130812Smarcel  return note_data;
5951130812Smarcel}
5952130812Smarcel#else /* !(Solaris or Unixware) */
5953130812Smarcelstatic char *
5954130812Smarcelprocfs_make_note_section (bfd *obfd, int *note_size)
5955130812Smarcel{
5956130812Smarcel  error ("gcore not implemented for this host.");
5957130812Smarcel  return NULL;	/* lint */
5958130812Smarcel}
5959130812Smarcel#endif /* Solaris or Unixware */
5960130812Smarcel/* ===================  END GCORE .NOTE "MODULE" =================== */
5961