1e93f7393Sniklas /* Machine independent support for SVR4 /proc (process file system) for GDB.
2b725ae77Skettenis
3b725ae77Skettenis Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation,
4b725ae77Skettenis Inc.
5b725ae77Skettenis
6b725ae77Skettenis Written by Michael Snyder at Cygnus Solutions.
7b725ae77Skettenis Based on work by Fred Fish, Stu Grossman, Geoff Noer, and others.
8e93f7393Sniklas
9e93f7393Sniklas This file is part of GDB.
10e93f7393Sniklas
11e93f7393Sniklas This program is free software; you can redistribute it and/or modify
12e93f7393Sniklas it under the terms of the GNU General Public License as published by
13e93f7393Sniklas the Free Software Foundation; either version 2 of the License, or
14e93f7393Sniklas (at your option) any later version.
15e93f7393Sniklas
16e93f7393Sniklas This program is distributed in the hope that it will be useful,
17e93f7393Sniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
18e93f7393Sniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19e93f7393Sniklas GNU General Public License for more details.
20e93f7393Sniklas
21e93f7393Sniklas You should have received a copy of the GNU General Public License
22b725ae77Skettenis along with this program; if not, write to the Free Software Foundation,
23b725ae77Skettenis Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
24e93f7393Sniklas
25e93f7393Sniklas #include "defs.h"
26e93f7393Sniklas #include "inferior.h"
27e93f7393Sniklas #include "target.h"
28e93f7393Sniklas #include "gdbcore.h"
29b725ae77Skettenis #include "elf-bfd.h" /* for elfcore_write_* */
30b725ae77Skettenis #include "gdbcmd.h"
31e93f7393Sniklas #include "gdbthread.h"
32e93f7393Sniklas
33b725ae77Skettenis #if defined (NEW_PROC_API)
34b725ae77Skettenis #define _STRUCTURED_PROC 1 /* Should be done by configure script. */
35e93f7393Sniklas #endif
36e93f7393Sniklas
37b725ae77Skettenis #include <sys/procfs.h>
38b725ae77Skettenis #ifdef HAVE_SYS_FAULT_H
39b725ae77Skettenis #include <sys/fault.h>
40b725ae77Skettenis #endif
41b725ae77Skettenis #ifdef HAVE_SYS_SYSCALL_H
42b725ae77Skettenis #include <sys/syscall.h>
43b725ae77Skettenis #endif
44b725ae77Skettenis #include <sys/errno.h>
45b725ae77Skettenis #include "gdb_wait.h"
46b725ae77Skettenis #include <signal.h>
47b725ae77Skettenis #include <ctype.h>
48b725ae77Skettenis #include "gdb_string.h"
49b725ae77Skettenis #include "gdb_assert.h"
50b725ae77Skettenis #include "inflow.h"
51b725ae77Skettenis #include "auxv.h"
52e93f7393Sniklas
53b725ae77Skettenis /*
54b725ae77Skettenis * PROCFS.C
55b725ae77Skettenis *
56b725ae77Skettenis * This module provides the interface between GDB and the
57b725ae77Skettenis * /proc file system, which is used on many versions of Unix
58b725ae77Skettenis * as a means for debuggers to control other processes.
59b725ae77Skettenis * Examples of the systems that use this interface are:
60b725ae77Skettenis * Irix
61b725ae77Skettenis * Solaris
62b725ae77Skettenis * OSF
63b725ae77Skettenis * Unixware
64b725ae77Skettenis * AIX5
65b725ae77Skettenis *
66b725ae77Skettenis * /proc works by imitating a file system: you open a simulated file
67b725ae77Skettenis * that represents the process you wish to interact with, and
68b725ae77Skettenis * perform operations on that "file" in order to examine or change
69b725ae77Skettenis * the state of the other process.
70b725ae77Skettenis *
71b725ae77Skettenis * The most important thing to know about /proc and this module
72b725ae77Skettenis * is that there are two very different interfaces to /proc:
73b725ae77Skettenis * One that uses the ioctl system call, and
74b725ae77Skettenis * another that uses read and write system calls.
75b725ae77Skettenis * This module has to support both /proc interfaces. This means
76b725ae77Skettenis * that there are two different ways of doing every basic operation.
77b725ae77Skettenis *
78b725ae77Skettenis * In order to keep most of the code simple and clean, I have
79b725ae77Skettenis * defined an interface "layer" which hides all these system calls.
80b725ae77Skettenis * An ifdef (NEW_PROC_API) determines which interface we are using,
81b725ae77Skettenis * and most or all occurrances of this ifdef should be confined to
82b725ae77Skettenis * this interface layer.
83b725ae77Skettenis */
84e93f7393Sniklas
85b725ae77Skettenis
86b725ae77Skettenis /* Determine which /proc API we are using:
87b725ae77Skettenis The ioctl API defines PIOCSTATUS, while
88b725ae77Skettenis the read/write (multiple fd) API never does. */
89b725ae77Skettenis
90b725ae77Skettenis #ifdef NEW_PROC_API
91b725ae77Skettenis #include <sys/types.h>
92b725ae77Skettenis #include "gdb_dirent.h" /* opendir/readdir, for listing the LWP's */
93e93f7393Sniklas #endif
94e93f7393Sniklas
95b725ae77Skettenis #include <fcntl.h> /* for O_RDONLY */
96b725ae77Skettenis #include <unistd.h> /* for "X_OK" */
97b725ae77Skettenis #include "gdb_stat.h" /* for struct stat */
98e93f7393Sniklas
99b725ae77Skettenis /* Note: procfs-utils.h must be included after the above system header
100b725ae77Skettenis files, because it redefines various system calls using macros.
101b725ae77Skettenis This may be incompatible with the prototype declarations. */
102e93f7393Sniklas
103b725ae77Skettenis #include "proc-utils.h"
104b725ae77Skettenis
105b725ae77Skettenis /* Prototypes for supply_gregset etc. */
106b725ae77Skettenis #include "gregset.h"
107b725ae77Skettenis
108b725ae77Skettenis /* =================== TARGET_OPS "MODULE" =================== */
109b725ae77Skettenis
110b725ae77Skettenis /*
111b725ae77Skettenis * This module defines the GDB target vector and its methods.
112b725ae77Skettenis */
113b725ae77Skettenis
114b725ae77Skettenis static void procfs_open (char *, int);
115b725ae77Skettenis static void procfs_attach (char *, int);
116b725ae77Skettenis static void procfs_detach (char *, int);
117b725ae77Skettenis static void procfs_resume (ptid_t, int, enum target_signal);
118b725ae77Skettenis static int procfs_can_run (void);
119b725ae77Skettenis static void procfs_stop (void);
120b725ae77Skettenis static void procfs_files_info (struct target_ops *);
121b725ae77Skettenis static void procfs_fetch_registers (int);
122b725ae77Skettenis static void procfs_store_registers (int);
123b725ae77Skettenis static void procfs_notice_signals (ptid_t);
124b725ae77Skettenis static void procfs_prepare_to_store (void);
125b725ae77Skettenis static void procfs_kill_inferior (void);
126b725ae77Skettenis static void procfs_mourn_inferior (void);
127*63addd46Skettenis static void procfs_create_inferior (char *, char *, char **, int);
128b725ae77Skettenis static ptid_t procfs_wait (ptid_t, struct target_waitstatus *);
129b725ae77Skettenis static int procfs_xfer_memory (CORE_ADDR, char *, int, int,
130b725ae77Skettenis struct mem_attrib *attrib,
131b725ae77Skettenis struct target_ops *);
132b725ae77Skettenis static LONGEST procfs_xfer_partial (struct target_ops *ops,
133b725ae77Skettenis enum target_object object,
134b725ae77Skettenis const char *annex,
135b725ae77Skettenis void *readbuf, const void *writebuf,
136b725ae77Skettenis ULONGEST offset, LONGEST len);
137b725ae77Skettenis
138b725ae77Skettenis static int procfs_thread_alive (ptid_t);
139b725ae77Skettenis
140b725ae77Skettenis void procfs_find_new_threads (void);
141b725ae77Skettenis char *procfs_pid_to_str (ptid_t);
142b725ae77Skettenis
143b725ae77Skettenis static int proc_find_memory_regions (int (*) (CORE_ADDR,
144b725ae77Skettenis unsigned long,
145b725ae77Skettenis int, int, int,
146b725ae77Skettenis void *),
147b725ae77Skettenis void *);
148b725ae77Skettenis
149b725ae77Skettenis static char * procfs_make_note_section (bfd *, int *);
150b725ae77Skettenis
151b725ae77Skettenis static int procfs_can_use_hw_breakpoint (int, int, int);
152b725ae77Skettenis
153b725ae77Skettenis struct target_ops procfs_ops; /* the target vector */
154b725ae77Skettenis
155b725ae77Skettenis static void
init_procfs_ops(void)156b725ae77Skettenis init_procfs_ops (void)
157b725ae77Skettenis {
158b725ae77Skettenis procfs_ops.to_shortname = "procfs";
159b725ae77Skettenis procfs_ops.to_longname = "Unix /proc child process";
160b725ae77Skettenis procfs_ops.to_doc =
161b725ae77Skettenis "Unix /proc child process (started by the \"run\" command).";
162b725ae77Skettenis procfs_ops.to_open = procfs_open;
163b725ae77Skettenis procfs_ops.to_can_run = procfs_can_run;
164b725ae77Skettenis procfs_ops.to_create_inferior = procfs_create_inferior;
165b725ae77Skettenis procfs_ops.to_kill = procfs_kill_inferior;
166b725ae77Skettenis procfs_ops.to_mourn_inferior = procfs_mourn_inferior;
167b725ae77Skettenis procfs_ops.to_attach = procfs_attach;
168b725ae77Skettenis procfs_ops.to_detach = procfs_detach;
169b725ae77Skettenis procfs_ops.to_wait = procfs_wait;
170b725ae77Skettenis procfs_ops.to_resume = procfs_resume;
171b725ae77Skettenis procfs_ops.to_prepare_to_store = procfs_prepare_to_store;
172b725ae77Skettenis procfs_ops.to_fetch_registers = procfs_fetch_registers;
173b725ae77Skettenis procfs_ops.to_store_registers = procfs_store_registers;
174b725ae77Skettenis procfs_ops.to_xfer_partial = procfs_xfer_partial;
175*63addd46Skettenis procfs_ops.deprecated_xfer_memory = procfs_xfer_memory;
176b725ae77Skettenis procfs_ops.to_insert_breakpoint = memory_insert_breakpoint;
177b725ae77Skettenis procfs_ops.to_remove_breakpoint = memory_remove_breakpoint;
178b725ae77Skettenis procfs_ops.to_notice_signals = procfs_notice_signals;
179b725ae77Skettenis procfs_ops.to_files_info = procfs_files_info;
180b725ae77Skettenis procfs_ops.to_stop = procfs_stop;
181b725ae77Skettenis
182b725ae77Skettenis procfs_ops.to_terminal_init = terminal_init_inferior;
183b725ae77Skettenis procfs_ops.to_terminal_inferior = terminal_inferior;
184b725ae77Skettenis procfs_ops.to_terminal_ours_for_output = terminal_ours_for_output;
185b725ae77Skettenis procfs_ops.to_terminal_ours = terminal_ours;
186b725ae77Skettenis procfs_ops.to_terminal_save_ours = terminal_save_ours;
187b725ae77Skettenis procfs_ops.to_terminal_info = child_terminal_info;
188b725ae77Skettenis
189b725ae77Skettenis procfs_ops.to_find_new_threads = procfs_find_new_threads;
190b725ae77Skettenis procfs_ops.to_thread_alive = procfs_thread_alive;
191b725ae77Skettenis procfs_ops.to_pid_to_str = procfs_pid_to_str;
192b725ae77Skettenis
193b725ae77Skettenis procfs_ops.to_has_all_memory = 1;
194b725ae77Skettenis procfs_ops.to_has_memory = 1;
195b725ae77Skettenis procfs_ops.to_has_execution = 1;
196b725ae77Skettenis procfs_ops.to_has_stack = 1;
197b725ae77Skettenis procfs_ops.to_has_registers = 1;
198b725ae77Skettenis procfs_ops.to_stratum = process_stratum;
199b725ae77Skettenis procfs_ops.to_has_thread_control = tc_schedlock;
200b725ae77Skettenis procfs_ops.to_find_memory_regions = proc_find_memory_regions;
201b725ae77Skettenis procfs_ops.to_make_corefile_notes = procfs_make_note_section;
202b725ae77Skettenis procfs_ops.to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint;
203b725ae77Skettenis procfs_ops.to_magic = OPS_MAGIC;
204b725ae77Skettenis }
205b725ae77Skettenis
206b725ae77Skettenis /* =================== END, TARGET_OPS "MODULE" =================== */
207b725ae77Skettenis
208b725ae77Skettenis /*
209b725ae77Skettenis * World Unification:
210b725ae77Skettenis *
211b725ae77Skettenis * Put any typedefs, defines etc. here that are required for
212b725ae77Skettenis * the unification of code that handles different versions of /proc.
213b725ae77Skettenis */
214b725ae77Skettenis
215b725ae77Skettenis #ifdef NEW_PROC_API /* Solaris 7 && 8 method for watchpoints */
216b725ae77Skettenis #ifdef WA_READ
217b725ae77Skettenis enum { READ_WATCHFLAG = WA_READ,
218b725ae77Skettenis WRITE_WATCHFLAG = WA_WRITE,
219b725ae77Skettenis EXEC_WATCHFLAG = WA_EXEC,
220b725ae77Skettenis AFTER_WATCHFLAG = WA_TRAPAFTER
221b725ae77Skettenis };
222b725ae77Skettenis #endif
223b725ae77Skettenis #else /* Irix method for watchpoints */
224b725ae77Skettenis enum { READ_WATCHFLAG = MA_READ,
225b725ae77Skettenis WRITE_WATCHFLAG = MA_WRITE,
226b725ae77Skettenis EXEC_WATCHFLAG = MA_EXEC,
227b725ae77Skettenis AFTER_WATCHFLAG = 0 /* trapafter not implemented */
228b725ae77Skettenis };
229b725ae77Skettenis #endif
230b725ae77Skettenis
231b725ae77Skettenis /* gdb_sigset_t */
232b725ae77Skettenis #ifdef HAVE_PR_SIGSET_T
233b725ae77Skettenis typedef pr_sigset_t gdb_sigset_t;
234b725ae77Skettenis #else
235b725ae77Skettenis typedef sigset_t gdb_sigset_t;
236b725ae77Skettenis #endif
237b725ae77Skettenis
238b725ae77Skettenis /* sigaction */
239b725ae77Skettenis #ifdef HAVE_PR_SIGACTION64_T
240b725ae77Skettenis typedef pr_sigaction64_t gdb_sigaction_t;
241b725ae77Skettenis #else
242b725ae77Skettenis typedef struct sigaction gdb_sigaction_t;
243b725ae77Skettenis #endif
244b725ae77Skettenis
245b725ae77Skettenis /* siginfo */
246b725ae77Skettenis #ifdef HAVE_PR_SIGINFO64_T
247b725ae77Skettenis typedef pr_siginfo64_t gdb_siginfo_t;
248b725ae77Skettenis #else
249b725ae77Skettenis typedef struct siginfo gdb_siginfo_t;
250b725ae77Skettenis #endif
251b725ae77Skettenis
252b725ae77Skettenis /* gdb_premptysysset */
253b725ae77Skettenis #ifdef premptysysset
254b725ae77Skettenis #define gdb_premptysysset premptysysset
255b725ae77Skettenis #else
256b725ae77Skettenis #define gdb_premptysysset premptyset
257b725ae77Skettenis #endif
258b725ae77Skettenis
259b725ae77Skettenis /* praddsysset */
260b725ae77Skettenis #ifdef praddsysset
261b725ae77Skettenis #define gdb_praddsysset praddsysset
262b725ae77Skettenis #else
263b725ae77Skettenis #define gdb_praddsysset praddset
264b725ae77Skettenis #endif
265b725ae77Skettenis
266b725ae77Skettenis /* prdelsysset */
267b725ae77Skettenis #ifdef prdelsysset
268b725ae77Skettenis #define gdb_prdelsysset prdelsysset
269b725ae77Skettenis #else
270b725ae77Skettenis #define gdb_prdelsysset prdelset
271b725ae77Skettenis #endif
272b725ae77Skettenis
273b725ae77Skettenis /* prissyssetmember */
274b725ae77Skettenis #ifdef prissyssetmember
275b725ae77Skettenis #define gdb_pr_issyssetmember prissyssetmember
276b725ae77Skettenis #else
277b725ae77Skettenis #define gdb_pr_issyssetmember prismember
278b725ae77Skettenis #endif
279b725ae77Skettenis
280b725ae77Skettenis /* As a feature test, saying ``#if HAVE_PRSYSENT_T'' everywhere isn't
281b725ae77Skettenis as intuitively descriptive as it could be, so we'll define
282b725ae77Skettenis DYNAMIC_SYSCALLS to mean the same thing. Anyway, at the time of
283b725ae77Skettenis this writing, this feature is only found on AIX5 systems and
284b725ae77Skettenis basically means that the set of syscalls is not fixed. I.e,
285b725ae77Skettenis there's no nice table that one can #include to get all of the
286b725ae77Skettenis syscall numbers. Instead, they're stored in /proc/PID/sysent
287b725ae77Skettenis for each process. We are at least guaranteed that they won't
288b725ae77Skettenis change over the lifetime of the process. But each process could
289b725ae77Skettenis (in theory) have different syscall numbers.
290b725ae77Skettenis */
291b725ae77Skettenis #ifdef HAVE_PRSYSENT_T
292b725ae77Skettenis #define DYNAMIC_SYSCALLS
293b725ae77Skettenis #endif
294b725ae77Skettenis
295b725ae77Skettenis
296b725ae77Skettenis
297b725ae77Skettenis /* =================== STRUCT PROCINFO "MODULE" =================== */
298b725ae77Skettenis
299b725ae77Skettenis /* FIXME: this comment will soon be out of date W.R.T. threads. */
300b725ae77Skettenis
301b725ae77Skettenis /* The procinfo struct is a wrapper to hold all the state information
302b725ae77Skettenis concerning a /proc process. There should be exactly one procinfo
303b725ae77Skettenis for each process, and since GDB currently can debug only one
304b725ae77Skettenis process at a time, that means there should be only one procinfo.
305b725ae77Skettenis All of the LWP's of a process can be accessed indirectly thru the
306b725ae77Skettenis single process procinfo.
307b725ae77Skettenis
308b725ae77Skettenis However, against the day when GDB may debug more than one process,
309b725ae77Skettenis this data structure is kept in a list (which for now will hold no
310b725ae77Skettenis more than one member), and many functions will have a pointer to a
311b725ae77Skettenis procinfo as an argument.
312b725ae77Skettenis
313b725ae77Skettenis There will be a separate procinfo structure for use by the (not yet
314b725ae77Skettenis implemented) "info proc" command, so that we can print useful
315b725ae77Skettenis information about any random process without interfering with the
316b725ae77Skettenis inferior's procinfo information. */
317b725ae77Skettenis
318b725ae77Skettenis #ifdef NEW_PROC_API
319b725ae77Skettenis /* format strings for /proc paths */
320b725ae77Skettenis # ifndef CTL_PROC_NAME_FMT
321b725ae77Skettenis # define MAIN_PROC_NAME_FMT "/proc/%d"
322b725ae77Skettenis # define CTL_PROC_NAME_FMT "/proc/%d/ctl"
323b725ae77Skettenis # define AS_PROC_NAME_FMT "/proc/%d/as"
324b725ae77Skettenis # define MAP_PROC_NAME_FMT "/proc/%d/map"
325b725ae77Skettenis # define STATUS_PROC_NAME_FMT "/proc/%d/status"
326b725ae77Skettenis # define MAX_PROC_NAME_SIZE sizeof("/proc/99999/lwp/8096/lstatus")
327b725ae77Skettenis # endif
328b725ae77Skettenis /* the name of the proc status struct depends on the implementation */
329b725ae77Skettenis typedef pstatus_t gdb_prstatus_t;
330b725ae77Skettenis typedef lwpstatus_t gdb_lwpstatus_t;
331b725ae77Skettenis #else /* ! NEW_PROC_API */
332b725ae77Skettenis /* format strings for /proc paths */
333b725ae77Skettenis # ifndef CTL_PROC_NAME_FMT
334b725ae77Skettenis # define MAIN_PROC_NAME_FMT "/proc/%05d"
335b725ae77Skettenis # define CTL_PROC_NAME_FMT "/proc/%05d"
336b725ae77Skettenis # define AS_PROC_NAME_FMT "/proc/%05d"
337b725ae77Skettenis # define MAP_PROC_NAME_FMT "/proc/%05d"
338b725ae77Skettenis # define STATUS_PROC_NAME_FMT "/proc/%05d"
339b725ae77Skettenis # define MAX_PROC_NAME_SIZE sizeof("/proc/ttttppppp")
340b725ae77Skettenis # endif
341b725ae77Skettenis /* the name of the proc status struct depends on the implementation */
342b725ae77Skettenis typedef prstatus_t gdb_prstatus_t;
343b725ae77Skettenis typedef prstatus_t gdb_lwpstatus_t;
344b725ae77Skettenis #endif /* NEW_PROC_API */
345b725ae77Skettenis
346b725ae77Skettenis typedef struct procinfo {
347e93f7393Sniklas struct procinfo *next;
348b725ae77Skettenis int pid; /* Process ID */
349b725ae77Skettenis int tid; /* Thread/LWP id */
350b725ae77Skettenis
351b725ae77Skettenis /* process state */
352b725ae77Skettenis int was_stopped;
353b725ae77Skettenis int ignore_next_sigstop;
354b725ae77Skettenis
355b725ae77Skettenis /* The following four fd fields may be identical, or may contain
356b725ae77Skettenis several different fd's, depending on the version of /proc
357b725ae77Skettenis (old ioctl or new read/write). */
358b725ae77Skettenis
359b725ae77Skettenis int ctl_fd; /* File descriptor for /proc control file */
360b725ae77Skettenis /*
361b725ae77Skettenis * The next three file descriptors are actually only needed in the
362b725ae77Skettenis * read/write, multiple-file-descriptor implemenation (NEW_PROC_API).
363b725ae77Skettenis * However, to avoid a bunch of #ifdefs in the code, we will use
364b725ae77Skettenis * them uniformly by (in the case of the ioctl single-file-descriptor
365b725ae77Skettenis * implementation) filling them with copies of the control fd.
366b725ae77Skettenis */
367b725ae77Skettenis int status_fd; /* File descriptor for /proc status file */
368b725ae77Skettenis int as_fd; /* File descriptor for /proc as file */
369b725ae77Skettenis
370b725ae77Skettenis char pathname[MAX_PROC_NAME_SIZE]; /* Pathname to /proc entry */
371b725ae77Skettenis
372e93f7393Sniklas fltset_t saved_fltset; /* Saved traced hardware fault set */
373b725ae77Skettenis gdb_sigset_t saved_sigset; /* Saved traced signal set */
374b725ae77Skettenis gdb_sigset_t saved_sighold; /* Saved held signal set */
375b725ae77Skettenis sysset_t *saved_exitset; /* Saved traced system call exit set */
376b725ae77Skettenis sysset_t *saved_entryset; /* Saved traced system call entry set */
377e93f7393Sniklas
378b725ae77Skettenis gdb_prstatus_t prstatus; /* Current process status info */
379e93f7393Sniklas
380b725ae77Skettenis #ifndef NEW_PROC_API
381b725ae77Skettenis gdb_fpregset_t fpregset; /* Current floating point registers */
382e93f7393Sniklas #endif
383e93f7393Sniklas
384b725ae77Skettenis #ifdef DYNAMIC_SYSCALLS
385b725ae77Skettenis int num_syscalls; /* Total number of syscalls */
386b725ae77Skettenis char **syscall_names; /* Syscall number to name map */
387e93f7393Sniklas #endif
388e93f7393Sniklas
389b725ae77Skettenis struct procinfo *thread_list;
390e93f7393Sniklas
391b725ae77Skettenis int status_valid : 1;
392b725ae77Skettenis int gregs_valid : 1;
393b725ae77Skettenis int fpregs_valid : 1;
394b725ae77Skettenis int threads_valid: 1;
395b725ae77Skettenis } procinfo;
396e93f7393Sniklas
397b725ae77Skettenis static char errmsg[128]; /* shared error msg buffer */
398e93f7393Sniklas
399b725ae77Skettenis /* Function prototypes for procinfo module: */
400e93f7393Sniklas
401b725ae77Skettenis static procinfo *find_procinfo_or_die (int pid, int tid);
402b725ae77Skettenis static procinfo *find_procinfo (int pid, int tid);
403b725ae77Skettenis static procinfo *create_procinfo (int pid, int tid);
404b725ae77Skettenis static void destroy_procinfo (procinfo * p);
405b725ae77Skettenis static void do_destroy_procinfo_cleanup (void *);
406b725ae77Skettenis static void dead_procinfo (procinfo * p, char *msg, int killp);
407b725ae77Skettenis static int open_procinfo_files (procinfo * p, int which);
408b725ae77Skettenis static void close_procinfo_files (procinfo * p);
409b725ae77Skettenis static int sysset_t_size (procinfo *p);
410b725ae77Skettenis static sysset_t *sysset_t_alloc (procinfo * pi);
411b725ae77Skettenis #ifdef DYNAMIC_SYSCALLS
412b725ae77Skettenis static void load_syscalls (procinfo *pi);
413b725ae77Skettenis static void free_syscalls (procinfo *pi);
414b725ae77Skettenis static int find_syscall (procinfo *pi, char *name);
415b725ae77Skettenis #endif /* DYNAMIC_SYSCALLS */
416e93f7393Sniklas
417b725ae77Skettenis /* The head of the procinfo list: */
418b725ae77Skettenis static procinfo * procinfo_list;
419e93f7393Sniklas
420e93f7393Sniklas /*
421b725ae77Skettenis * Function: find_procinfo
422b725ae77Skettenis *
423b725ae77Skettenis * Search the procinfo list.
424b725ae77Skettenis *
425b725ae77Skettenis * Returns: pointer to procinfo, or NULL if not found.
426e93f7393Sniklas */
427e93f7393Sniklas
428b725ae77Skettenis static procinfo *
find_procinfo(int pid,int tid)429b725ae77Skettenis find_procinfo (int pid, int tid)
430e93f7393Sniklas {
431b725ae77Skettenis procinfo *pi;
432e93f7393Sniklas
433e93f7393Sniklas for (pi = procinfo_list; pi; pi = pi->next)
434b725ae77Skettenis if (pi->pid == pid)
435b725ae77Skettenis break;
436b725ae77Skettenis
437b725ae77Skettenis if (pi)
438b725ae77Skettenis if (tid)
439e93f7393Sniklas {
440b725ae77Skettenis /* Don't check threads_valid. If we're updating the
441b725ae77Skettenis thread_list, we want to find whatever threads are already
442b725ae77Skettenis here. This means that in general it is the caller's
443b725ae77Skettenis responsibility to check threads_valid and update before
444b725ae77Skettenis calling find_procinfo, if the caller wants to find a new
445b725ae77Skettenis thread. */
446b725ae77Skettenis
447b725ae77Skettenis for (pi = pi->thread_list; pi; pi = pi->next)
448b725ae77Skettenis if (pi->tid == tid)
449e93f7393Sniklas break;
450e93f7393Sniklas }
451e93f7393Sniklas
452e93f7393Sniklas return pi;
453e93f7393Sniklas }
454e93f7393Sniklas
455e93f7393Sniklas /*
456b725ae77Skettenis * Function: find_procinfo_or_die
457b725ae77Skettenis *
458b725ae77Skettenis * Calls find_procinfo, but errors on failure.
459e93f7393Sniklas */
460e93f7393Sniklas
461b725ae77Skettenis static procinfo *
find_procinfo_or_die(int pid,int tid)462b725ae77Skettenis find_procinfo_or_die (int pid, int tid)
463e93f7393Sniklas {
464b725ae77Skettenis procinfo *pi = find_procinfo (pid, tid);
465e93f7393Sniklas
466b725ae77Skettenis if (pi == NULL)
467e93f7393Sniklas {
468b725ae77Skettenis if (tid)
469b725ae77Skettenis error ("procfs: couldn't find pid %d (kernel thread %d) in procinfo list.",
470b725ae77Skettenis pid, tid);
471e93f7393Sniklas else
472b725ae77Skettenis error ("procfs: couldn't find pid %d in procinfo list.", pid);
473e93f7393Sniklas }
474e93f7393Sniklas return pi;
475e93f7393Sniklas }
476e93f7393Sniklas
477b725ae77Skettenis /* open_with_retry() is a wrapper for open(). The appropriate
478b725ae77Skettenis open() call is attempted; if unsuccessful, it will be retried as
479b725ae77Skettenis many times as needed for the EAGAIN and EINTR conditions.
480e93f7393Sniklas
481b725ae77Skettenis For other conditions, open_with_retry() will retry the open() a
482b725ae77Skettenis limited number of times. In addition, a short sleep is imposed
483b725ae77Skettenis prior to retrying the open(). The reason for this sleep is to give
484b725ae77Skettenis the kernel a chance to catch up and create the file in question in
485b725ae77Skettenis the event that GDB "wins" the race to open a file before the kernel
486b725ae77Skettenis has created it. */
487e93f7393Sniklas
488e93f7393Sniklas static int
open_with_retry(const char * pathname,int flags)489b725ae77Skettenis open_with_retry (const char *pathname, int flags)
490e93f7393Sniklas {
491b725ae77Skettenis int retries_remaining, status;
492e93f7393Sniklas
493b725ae77Skettenis retries_remaining = 2;
494e93f7393Sniklas
495b725ae77Skettenis while (1)
496b725ae77Skettenis {
497b725ae77Skettenis status = open (pathname, flags);
498e93f7393Sniklas
499b725ae77Skettenis if (status >= 0 || retries_remaining == 0)
500b725ae77Skettenis break;
501b725ae77Skettenis else if (errno != EINTR && errno != EAGAIN)
502b725ae77Skettenis {
503b725ae77Skettenis retries_remaining--;
504b725ae77Skettenis sleep (1);
505b725ae77Skettenis }
506b725ae77Skettenis }
507b725ae77Skettenis
508b725ae77Skettenis return status;
509e93f7393Sniklas }
510e93f7393Sniklas
511e93f7393Sniklas /*
512b725ae77Skettenis * Function: open_procinfo_files
513b725ae77Skettenis *
514b725ae77Skettenis * Open the file descriptor for the process or LWP.
515b725ae77Skettenis * ifdef NEW_PROC_API, we only open the control file descriptor;
516b725ae77Skettenis * the others are opened lazily as needed.
517b725ae77Skettenis * else (if not NEW_PROC_API), there is only one real
518b725ae77Skettenis * file descriptor, but we keep multiple copies of it so that
519b725ae77Skettenis * the code that uses them does not have to be #ifdef'd.
520b725ae77Skettenis *
521b725ae77Skettenis * Return: file descriptor, or zero for failure.
522e93f7393Sniklas */
523e93f7393Sniklas
524b725ae77Skettenis enum { FD_CTL, FD_STATUS, FD_AS };
525b725ae77Skettenis
526e93f7393Sniklas static int
open_procinfo_files(procinfo * pi,int which)527b725ae77Skettenis open_procinfo_files (procinfo *pi, int which)
528e93f7393Sniklas {
529b725ae77Skettenis #ifdef NEW_PROC_API
530b725ae77Skettenis char tmp[MAX_PROC_NAME_SIZE];
531e93f7393Sniklas #endif
532e93f7393Sniklas int fd;
533e93f7393Sniklas
534b725ae77Skettenis /*
535b725ae77Skettenis * This function is getting ALMOST long enough to break up into several.
536b725ae77Skettenis * Here is some rationale:
537b725ae77Skettenis *
538b725ae77Skettenis * NEW_PROC_API (Solaris 2.6, Solaris 2.7, Unixware):
539b725ae77Skettenis * There are several file descriptors that may need to be open
540b725ae77Skettenis * for any given process or LWP. The ones we're intereted in are:
541b725ae77Skettenis * - control (ctl) write-only change the state
542b725ae77Skettenis * - status (status) read-only query the state
543b725ae77Skettenis * - address space (as) read/write access memory
544b725ae77Skettenis * - map (map) read-only virtual addr map
545b725ae77Skettenis * Most of these are opened lazily as they are needed.
546b725ae77Skettenis * The pathnames for the 'files' for an LWP look slightly
547b725ae77Skettenis * different from those of a first-class process:
548b725ae77Skettenis * Pathnames for a process (<proc-id>):
549b725ae77Skettenis * /proc/<proc-id>/ctl
550b725ae77Skettenis * /proc/<proc-id>/status
551b725ae77Skettenis * /proc/<proc-id>/as
552b725ae77Skettenis * /proc/<proc-id>/map
553b725ae77Skettenis * Pathnames for an LWP (lwp-id):
554b725ae77Skettenis * /proc/<proc-id>/lwp/<lwp-id>/lwpctl
555b725ae77Skettenis * /proc/<proc-id>/lwp/<lwp-id>/lwpstatus
556b725ae77Skettenis * An LWP has no map or address space file descriptor, since
557b725ae77Skettenis * the memory map and address space are shared by all LWPs.
558b725ae77Skettenis *
559b725ae77Skettenis * Everyone else (Solaris 2.5, Irix, OSF)
560b725ae77Skettenis * There is only one file descriptor for each process or LWP.
561b725ae77Skettenis * For convenience, we copy the same file descriptor into all
562b725ae77Skettenis * three fields of the procinfo struct (ctl_fd, status_fd, and
563b725ae77Skettenis * as_fd, see NEW_PROC_API above) so that code that uses them
564b725ae77Skettenis * doesn't need any #ifdef's.
565b725ae77Skettenis * Pathname for all:
566b725ae77Skettenis * /proc/<proc-id>
567b725ae77Skettenis *
568b725ae77Skettenis * Solaris 2.5 LWP's:
569b725ae77Skettenis * Each LWP has an independent file descriptor, but these
570b725ae77Skettenis * are not obtained via the 'open' system call like the rest:
571b725ae77Skettenis * instead, they're obtained thru an ioctl call (PIOCOPENLWP)
572b725ae77Skettenis * to the file descriptor of the parent process.
573b725ae77Skettenis *
574b725ae77Skettenis * OSF threads:
575b725ae77Skettenis * These do not even have their own independent file descriptor.
576b725ae77Skettenis * All operations are carried out on the file descriptor of the
577b725ae77Skettenis * parent process. Therefore we just call open again for each
578b725ae77Skettenis * thread, getting a new handle for the same 'file'.
579b725ae77Skettenis */
580e93f7393Sniklas
581b725ae77Skettenis #ifdef NEW_PROC_API
582b725ae77Skettenis /*
583b725ae77Skettenis * In this case, there are several different file descriptors that
584b725ae77Skettenis * we might be asked to open. The control file descriptor will be
585b725ae77Skettenis * opened early, but the others will be opened lazily as they are
586b725ae77Skettenis * needed.
587b725ae77Skettenis */
588b725ae77Skettenis
589b725ae77Skettenis strcpy (tmp, pi->pathname);
590b725ae77Skettenis switch (which) { /* which file descriptor to open? */
591b725ae77Skettenis case FD_CTL:
592b725ae77Skettenis if (pi->tid)
593b725ae77Skettenis strcat (tmp, "/lwpctl");
594b725ae77Skettenis else
595b725ae77Skettenis strcat (tmp, "/ctl");
596b725ae77Skettenis fd = open_with_retry (tmp, O_WRONLY);
597b725ae77Skettenis if (fd <= 0)
598b725ae77Skettenis return 0; /* fail */
599b725ae77Skettenis pi->ctl_fd = fd;
600b725ae77Skettenis break;
601b725ae77Skettenis case FD_AS:
602b725ae77Skettenis if (pi->tid)
603b725ae77Skettenis return 0; /* there is no 'as' file descriptor for an lwp */
604b725ae77Skettenis strcat (tmp, "/as");
605b725ae77Skettenis fd = open_with_retry (tmp, O_RDWR);
606b725ae77Skettenis if (fd <= 0)
607b725ae77Skettenis return 0; /* fail */
608b725ae77Skettenis pi->as_fd = fd;
609b725ae77Skettenis break;
610b725ae77Skettenis case FD_STATUS:
611b725ae77Skettenis if (pi->tid)
612b725ae77Skettenis strcat (tmp, "/lwpstatus");
613b725ae77Skettenis else
614b725ae77Skettenis strcat (tmp, "/status");
615b725ae77Skettenis fd = open_with_retry (tmp, O_RDONLY);
616b725ae77Skettenis if (fd <= 0)
617b725ae77Skettenis return 0; /* fail */
618b725ae77Skettenis pi->status_fd = fd;
619b725ae77Skettenis break;
620b725ae77Skettenis default:
621b725ae77Skettenis return 0; /* unknown file descriptor */
622b725ae77Skettenis }
623b725ae77Skettenis #else /* not NEW_PROC_API */
624b725ae77Skettenis /*
625b725ae77Skettenis * In this case, there is only one file descriptor for each procinfo
626b725ae77Skettenis * (ie. each process or LWP). In fact, only the file descriptor for
627b725ae77Skettenis * the process can actually be opened by an 'open' system call.
628b725ae77Skettenis * The ones for the LWPs have to be obtained thru an IOCTL call
629b725ae77Skettenis * on the process's file descriptor.
630b725ae77Skettenis *
631b725ae77Skettenis * For convenience, we copy each procinfo's single file descriptor
632b725ae77Skettenis * into all of the fields occupied by the several file descriptors
633b725ae77Skettenis * of the NEW_PROC_API implementation. That way, the code that uses
634b725ae77Skettenis * them can be written without ifdefs.
635b725ae77Skettenis */
636b725ae77Skettenis
637b725ae77Skettenis
638b725ae77Skettenis #ifdef PIOCTSTATUS /* OSF */
639b725ae77Skettenis /* Only one FD; just open it. */
640b725ae77Skettenis if ((fd = open_with_retry (pi->pathname, O_RDWR)) == 0)
641b725ae77Skettenis return 0;
642b725ae77Skettenis #else /* Sol 2.5, Irix, other? */
643b725ae77Skettenis if (pi->tid == 0) /* Master procinfo for the process */
644b725ae77Skettenis {
645b725ae77Skettenis fd = open_with_retry (pi->pathname, O_RDWR);
646b725ae77Skettenis if (fd <= 0)
647b725ae77Skettenis return 0; /* fail */
648b725ae77Skettenis }
649b725ae77Skettenis else /* LWP thread procinfo */
650b725ae77Skettenis {
651b725ae77Skettenis #ifdef PIOCOPENLWP /* Sol 2.5, thread/LWP */
652b725ae77Skettenis procinfo *process;
653b725ae77Skettenis int lwpid = pi->tid;
654b725ae77Skettenis
655b725ae77Skettenis /* Find the procinfo for the entire process. */
656b725ae77Skettenis if ((process = find_procinfo (pi->pid, 0)) == NULL)
657b725ae77Skettenis return 0; /* fail */
658b725ae77Skettenis
659b725ae77Skettenis /* Now obtain the file descriptor for the LWP. */
660b725ae77Skettenis if ((fd = ioctl (process->ctl_fd, PIOCOPENLWP, &lwpid)) <= 0)
661b725ae77Skettenis return 0; /* fail */
662b725ae77Skettenis #else /* Irix, other? */
663b725ae77Skettenis return 0; /* Don't know how to open threads */
664b725ae77Skettenis #endif /* Sol 2.5 PIOCOPENLWP */
665b725ae77Skettenis }
666b725ae77Skettenis #endif /* OSF PIOCTSTATUS */
667b725ae77Skettenis pi->ctl_fd = pi->as_fd = pi->status_fd = fd;
668b725ae77Skettenis #endif /* NEW_PROC_API */
669b725ae77Skettenis
670b725ae77Skettenis return 1; /* success */
671b725ae77Skettenis }
672b725ae77Skettenis
673b725ae77Skettenis /*
674b725ae77Skettenis * Function: create_procinfo
675b725ae77Skettenis *
676b725ae77Skettenis * Allocate a data structure and link it into the procinfo list.
677b725ae77Skettenis * (First tries to find a pre-existing one (FIXME: why?)
678b725ae77Skettenis *
679b725ae77Skettenis * Return: pointer to new procinfo struct.
680b725ae77Skettenis */
681b725ae77Skettenis
682b725ae77Skettenis static procinfo *
create_procinfo(int pid,int tid)683b725ae77Skettenis create_procinfo (int pid, int tid)
684b725ae77Skettenis {
685b725ae77Skettenis procinfo *pi, *parent;
686b725ae77Skettenis
687b725ae77Skettenis if ((pi = find_procinfo (pid, tid)))
688b725ae77Skettenis return pi; /* Already exists, nothing to do. */
689b725ae77Skettenis
690b725ae77Skettenis /* find parent before doing malloc, to save having to cleanup */
691b725ae77Skettenis if (tid != 0)
692b725ae77Skettenis parent = find_procinfo_or_die (pid, 0); /* FIXME: should I
693b725ae77Skettenis create it if it
694b725ae77Skettenis doesn't exist yet? */
695b725ae77Skettenis
696b725ae77Skettenis pi = (procinfo *) xmalloc (sizeof (procinfo));
697b725ae77Skettenis memset (pi, 0, sizeof (procinfo));
698b725ae77Skettenis pi->pid = pid;
699b725ae77Skettenis pi->tid = tid;
700b725ae77Skettenis
701b725ae77Skettenis #ifdef DYNAMIC_SYSCALLS
702b725ae77Skettenis load_syscalls (pi);
703b725ae77Skettenis #endif
704b725ae77Skettenis
705b725ae77Skettenis pi->saved_entryset = sysset_t_alloc (pi);
706b725ae77Skettenis pi->saved_exitset = sysset_t_alloc (pi);
707b725ae77Skettenis
708b725ae77Skettenis /* Chain into list. */
709b725ae77Skettenis if (tid == 0)
710b725ae77Skettenis {
711b725ae77Skettenis sprintf (pi->pathname, MAIN_PROC_NAME_FMT, pid);
712b725ae77Skettenis pi->next = procinfo_list;
713b725ae77Skettenis procinfo_list = pi;
714b725ae77Skettenis }
715b725ae77Skettenis else
716b725ae77Skettenis {
717b725ae77Skettenis #ifdef NEW_PROC_API
718b725ae77Skettenis sprintf (pi->pathname, "/proc/%05d/lwp/%d", pid, tid);
719b725ae77Skettenis #else
720b725ae77Skettenis sprintf (pi->pathname, MAIN_PROC_NAME_FMT, pid);
721b725ae77Skettenis #endif
722b725ae77Skettenis pi->next = parent->thread_list;
723b725ae77Skettenis parent->thread_list = pi;
724b725ae77Skettenis }
725b725ae77Skettenis return pi;
726b725ae77Skettenis }
727b725ae77Skettenis
728b725ae77Skettenis /*
729b725ae77Skettenis * Function: close_procinfo_files
730b725ae77Skettenis *
731b725ae77Skettenis * Close all file descriptors associated with the procinfo
732b725ae77Skettenis */
733b725ae77Skettenis
734b725ae77Skettenis static void
close_procinfo_files(procinfo * pi)735b725ae77Skettenis close_procinfo_files (procinfo *pi)
736b725ae77Skettenis {
737b725ae77Skettenis if (pi->ctl_fd > 0)
738b725ae77Skettenis close (pi->ctl_fd);
739b725ae77Skettenis #ifdef NEW_PROC_API
740b725ae77Skettenis if (pi->as_fd > 0)
741b725ae77Skettenis close (pi->as_fd);
742b725ae77Skettenis if (pi->status_fd > 0)
743b725ae77Skettenis close (pi->status_fd);
744b725ae77Skettenis #endif
745b725ae77Skettenis pi->ctl_fd = pi->as_fd = pi->status_fd = 0;
746b725ae77Skettenis }
747b725ae77Skettenis
748b725ae77Skettenis /*
749b725ae77Skettenis * Function: destroy_procinfo
750b725ae77Skettenis *
751b725ae77Skettenis * Destructor function. Close, unlink and deallocate the object.
752b725ae77Skettenis */
753b725ae77Skettenis
754b725ae77Skettenis static void
destroy_one_procinfo(procinfo ** list,procinfo * pi)755b725ae77Skettenis destroy_one_procinfo (procinfo **list, procinfo *pi)
756b725ae77Skettenis {
757b725ae77Skettenis procinfo *ptr;
758b725ae77Skettenis
759b725ae77Skettenis /* Step one: unlink the procinfo from its list */
760b725ae77Skettenis if (pi == *list)
761b725ae77Skettenis *list = pi->next;
762b725ae77Skettenis else
763b725ae77Skettenis for (ptr = *list; ptr; ptr = ptr->next)
764b725ae77Skettenis if (ptr->next == pi)
765b725ae77Skettenis {
766b725ae77Skettenis ptr->next = pi->next;
767b725ae77Skettenis break;
768b725ae77Skettenis }
769b725ae77Skettenis
770b725ae77Skettenis /* Step two: close any open file descriptors */
771b725ae77Skettenis close_procinfo_files (pi);
772b725ae77Skettenis
773b725ae77Skettenis /* Step three: free the memory. */
774b725ae77Skettenis #ifdef DYNAMIC_SYSCALLS
775b725ae77Skettenis free_syscalls (pi);
776b725ae77Skettenis #endif
777b725ae77Skettenis xfree (pi->saved_entryset);
778b725ae77Skettenis xfree (pi->saved_exitset);
779b725ae77Skettenis xfree (pi);
780b725ae77Skettenis }
781b725ae77Skettenis
782b725ae77Skettenis static void
destroy_procinfo(procinfo * pi)783b725ae77Skettenis destroy_procinfo (procinfo *pi)
784b725ae77Skettenis {
785b725ae77Skettenis procinfo *tmp;
786b725ae77Skettenis
787b725ae77Skettenis if (pi->tid != 0) /* destroy a thread procinfo */
788b725ae77Skettenis {
789b725ae77Skettenis tmp = find_procinfo (pi->pid, 0); /* find the parent process */
790b725ae77Skettenis destroy_one_procinfo (&tmp->thread_list, pi);
791b725ae77Skettenis }
792b725ae77Skettenis else /* destroy a process procinfo and all its threads */
793b725ae77Skettenis {
794b725ae77Skettenis /* First destroy the children, if any; */
795b725ae77Skettenis while (pi->thread_list != NULL)
796b725ae77Skettenis destroy_one_procinfo (&pi->thread_list, pi->thread_list);
797b725ae77Skettenis /* Then destroy the parent. Genocide!!! */
798b725ae77Skettenis destroy_one_procinfo (&procinfo_list, pi);
799b725ae77Skettenis }
800b725ae77Skettenis }
801b725ae77Skettenis
802b725ae77Skettenis static void
do_destroy_procinfo_cleanup(void * pi)803b725ae77Skettenis do_destroy_procinfo_cleanup (void *pi)
804b725ae77Skettenis {
805b725ae77Skettenis destroy_procinfo (pi);
806b725ae77Skettenis }
807b725ae77Skettenis
808b725ae77Skettenis enum { NOKILL, KILL };
809b725ae77Skettenis
810b725ae77Skettenis /*
811b725ae77Skettenis * Function: dead_procinfo
812b725ae77Skettenis *
813b725ae77Skettenis * To be called on a non_recoverable error for a procinfo.
814b725ae77Skettenis * Prints error messages, optionally sends a SIGKILL to the process,
815b725ae77Skettenis * then destroys the data structure.
816b725ae77Skettenis */
817b725ae77Skettenis
818b725ae77Skettenis static void
dead_procinfo(procinfo * pi,char * msg,int kill_p)819b725ae77Skettenis dead_procinfo (procinfo *pi, char *msg, int kill_p)
820b725ae77Skettenis {
821b725ae77Skettenis char procfile[80];
822b725ae77Skettenis
823b725ae77Skettenis if (pi->pathname)
824b725ae77Skettenis {
825b725ae77Skettenis print_sys_errmsg (pi->pathname, errno);
826b725ae77Skettenis }
827b725ae77Skettenis else
828b725ae77Skettenis {
829b725ae77Skettenis sprintf (procfile, "process %d", pi->pid);
830b725ae77Skettenis print_sys_errmsg (procfile, errno);
831b725ae77Skettenis }
832b725ae77Skettenis if (kill_p == KILL)
833b725ae77Skettenis kill (pi->pid, SIGKILL);
834b725ae77Skettenis
835b725ae77Skettenis destroy_procinfo (pi);
836b725ae77Skettenis error (msg);
837b725ae77Skettenis }
838b725ae77Skettenis
839b725ae77Skettenis /*
840b725ae77Skettenis * Function: sysset_t_size
841b725ae77Skettenis *
842b725ae77Skettenis * Returns the (complete) size of a sysset_t struct. Normally, this
843b725ae77Skettenis * is just sizeof (syset_t), but in the case of Monterey/64, the actual
844b725ae77Skettenis * size of sysset_t isn't known until runtime.
845b725ae77Skettenis */
846b725ae77Skettenis
847b725ae77Skettenis static int
sysset_t_size(procinfo * pi)848b725ae77Skettenis sysset_t_size (procinfo * pi)
849b725ae77Skettenis {
850b725ae77Skettenis #ifndef DYNAMIC_SYSCALLS
851b725ae77Skettenis return sizeof (sysset_t);
852b725ae77Skettenis #else
853b725ae77Skettenis return sizeof (sysset_t) - sizeof (uint64_t)
854b725ae77Skettenis + sizeof (uint64_t) * ((pi->num_syscalls + (8 * sizeof (uint64_t) - 1))
855b725ae77Skettenis / (8 * sizeof (uint64_t)));
856b725ae77Skettenis #endif
857b725ae77Skettenis }
858b725ae77Skettenis
859b725ae77Skettenis /* Function: sysset_t_alloc
860b725ae77Skettenis
861b725ae77Skettenis Allocate and (partially) initialize a sysset_t struct. */
862b725ae77Skettenis
863b725ae77Skettenis static sysset_t *
sysset_t_alloc(procinfo * pi)864b725ae77Skettenis sysset_t_alloc (procinfo * pi)
865b725ae77Skettenis {
866b725ae77Skettenis sysset_t *ret;
867b725ae77Skettenis int size = sysset_t_size (pi);
868b725ae77Skettenis ret = xmalloc (size);
869b725ae77Skettenis #ifdef DYNAMIC_SYSCALLS
870b725ae77Skettenis ret->pr_size = (pi->num_syscalls + (8 * sizeof (uint64_t) - 1))
871b725ae77Skettenis / (8 * sizeof (uint64_t));
872b725ae77Skettenis #endif
873b725ae77Skettenis return ret;
874b725ae77Skettenis }
875b725ae77Skettenis
876b725ae77Skettenis #ifdef DYNAMIC_SYSCALLS
877b725ae77Skettenis
878b725ae77Skettenis /* Function: load_syscalls
879b725ae77Skettenis
880b725ae77Skettenis Extract syscall numbers and names from /proc/<pid>/sysent. Initialize
881b725ae77Skettenis pi->num_syscalls with the number of syscalls and pi->syscall_names
882b725ae77Skettenis with the names. (Certain numbers may be skipped in which case the
883b725ae77Skettenis names for these numbers will be left as NULL.) */
884b725ae77Skettenis
885b725ae77Skettenis #define MAX_SYSCALL_NAME_LENGTH 256
886b725ae77Skettenis #define MAX_SYSCALLS 65536
887b725ae77Skettenis
888b725ae77Skettenis static void
load_syscalls(procinfo * pi)889b725ae77Skettenis load_syscalls (procinfo *pi)
890b725ae77Skettenis {
891b725ae77Skettenis char pathname[MAX_PROC_NAME_SIZE];
892b725ae77Skettenis int sysent_fd;
893b725ae77Skettenis prsysent_t header;
894b725ae77Skettenis prsyscall_t *syscalls;
895b725ae77Skettenis int i, size, maxcall;
896b725ae77Skettenis
897b725ae77Skettenis pi->num_syscalls = 0;
898b725ae77Skettenis pi->syscall_names = 0;
899b725ae77Skettenis
900b725ae77Skettenis /* Open the file descriptor for the sysent file */
901b725ae77Skettenis sprintf (pathname, "/proc/%d/sysent", pi->pid);
902b725ae77Skettenis sysent_fd = open_with_retry (pathname, O_RDONLY);
903b725ae77Skettenis if (sysent_fd < 0)
904b725ae77Skettenis {
905b725ae77Skettenis error ("load_syscalls: Can't open /proc/%d/sysent", pi->pid);
906b725ae77Skettenis }
907b725ae77Skettenis
908b725ae77Skettenis size = sizeof header - sizeof (prsyscall_t);
909b725ae77Skettenis if (read (sysent_fd, &header, size) != size)
910b725ae77Skettenis {
911b725ae77Skettenis error ("load_syscalls: Error reading /proc/%d/sysent", pi->pid);
912b725ae77Skettenis }
913b725ae77Skettenis
914b725ae77Skettenis if (header.pr_nsyscalls == 0)
915b725ae77Skettenis {
916b725ae77Skettenis error ("load_syscalls: /proc/%d/sysent contains no syscalls!", pi->pid);
917b725ae77Skettenis }
918b725ae77Skettenis
919b725ae77Skettenis size = header.pr_nsyscalls * sizeof (prsyscall_t);
920b725ae77Skettenis syscalls = xmalloc (size);
921b725ae77Skettenis
922b725ae77Skettenis if (read (sysent_fd, syscalls, size) != size)
923b725ae77Skettenis {
924b725ae77Skettenis xfree (syscalls);
925b725ae77Skettenis error ("load_syscalls: Error reading /proc/%d/sysent", pi->pid);
926b725ae77Skettenis }
927b725ae77Skettenis
928b725ae77Skettenis /* Find maximum syscall number. This may not be the same as
929b725ae77Skettenis pr_nsyscalls since that value refers to the number of entries
930b725ae77Skettenis in the table. (Also, the docs indicate that some system
931b725ae77Skettenis call numbers may be skipped.) */
932b725ae77Skettenis
933b725ae77Skettenis maxcall = syscalls[0].pr_number;
934b725ae77Skettenis
935b725ae77Skettenis for (i = 1; i < header.pr_nsyscalls; i++)
936b725ae77Skettenis if (syscalls[i].pr_number > maxcall
937b725ae77Skettenis && syscalls[i].pr_nameoff > 0
938b725ae77Skettenis && syscalls[i].pr_number < MAX_SYSCALLS)
939b725ae77Skettenis maxcall = syscalls[i].pr_number;
940b725ae77Skettenis
941b725ae77Skettenis pi->num_syscalls = maxcall+1;
942b725ae77Skettenis pi->syscall_names = xmalloc (pi->num_syscalls * sizeof (char *));
943b725ae77Skettenis
944b725ae77Skettenis for (i = 0; i < pi->num_syscalls; i++)
945b725ae77Skettenis pi->syscall_names[i] = NULL;
946b725ae77Skettenis
947b725ae77Skettenis /* Read the syscall names in */
948b725ae77Skettenis for (i = 0; i < header.pr_nsyscalls; i++)
949b725ae77Skettenis {
950b725ae77Skettenis char namebuf[MAX_SYSCALL_NAME_LENGTH];
951b725ae77Skettenis int nread;
952b725ae77Skettenis int callnum;
953b725ae77Skettenis
954b725ae77Skettenis if (syscalls[i].pr_number >= MAX_SYSCALLS
955b725ae77Skettenis || syscalls[i].pr_number < 0
956b725ae77Skettenis || syscalls[i].pr_nameoff <= 0
957b725ae77Skettenis || (lseek (sysent_fd, (off_t) syscalls[i].pr_nameoff, SEEK_SET)
958b725ae77Skettenis != (off_t) syscalls[i].pr_nameoff))
959b725ae77Skettenis continue;
960b725ae77Skettenis
961b725ae77Skettenis nread = read (sysent_fd, namebuf, sizeof namebuf);
962b725ae77Skettenis if (nread <= 0)
963b725ae77Skettenis continue;
964b725ae77Skettenis
965b725ae77Skettenis callnum = syscalls[i].pr_number;
966b725ae77Skettenis
967b725ae77Skettenis if (pi->syscall_names[callnum] != NULL)
968b725ae77Skettenis {
969b725ae77Skettenis /* FIXME: Generate warning */
970b725ae77Skettenis continue;
971b725ae77Skettenis }
972b725ae77Skettenis
973b725ae77Skettenis namebuf[nread-1] = '\0';
974b725ae77Skettenis size = strlen (namebuf) + 1;
975b725ae77Skettenis pi->syscall_names[callnum] = xmalloc (size);
976b725ae77Skettenis strncpy (pi->syscall_names[callnum], namebuf, size-1);
977b725ae77Skettenis pi->syscall_names[callnum][size-1] = '\0';
978b725ae77Skettenis }
979b725ae77Skettenis
980b725ae77Skettenis close (sysent_fd);
981b725ae77Skettenis xfree (syscalls);
982b725ae77Skettenis }
983b725ae77Skettenis
984b725ae77Skettenis /* Function: free_syscalls
985b725ae77Skettenis
986b725ae77Skettenis Free the space allocated for the syscall names from the procinfo
987b725ae77Skettenis structure. */
988b725ae77Skettenis
989b725ae77Skettenis static void
free_syscalls(procinfo * pi)990b725ae77Skettenis free_syscalls (procinfo *pi)
991b725ae77Skettenis {
992b725ae77Skettenis if (pi->syscall_names)
993b725ae77Skettenis {
994b725ae77Skettenis int i;
995b725ae77Skettenis
996b725ae77Skettenis for (i = 0; i < pi->num_syscalls; i++)
997b725ae77Skettenis if (pi->syscall_names[i] != NULL)
998b725ae77Skettenis xfree (pi->syscall_names[i]);
999b725ae77Skettenis
1000b725ae77Skettenis xfree (pi->syscall_names);
1001b725ae77Skettenis pi->syscall_names = 0;
1002b725ae77Skettenis }
1003b725ae77Skettenis }
1004b725ae77Skettenis
1005b725ae77Skettenis /* Function: find_syscall
1006b725ae77Skettenis
1007b725ae77Skettenis Given a name, look up (and return) the corresponding syscall number.
1008b725ae77Skettenis If no match is found, return -1. */
1009b725ae77Skettenis
1010b725ae77Skettenis static int
find_syscall(procinfo * pi,char * name)1011b725ae77Skettenis find_syscall (procinfo *pi, char *name)
1012b725ae77Skettenis {
1013b725ae77Skettenis int i;
1014b725ae77Skettenis for (i = 0; i < pi->num_syscalls; i++)
1015b725ae77Skettenis {
1016b725ae77Skettenis if (pi->syscall_names[i] && strcmp (name, pi->syscall_names[i]) == 0)
1017b725ae77Skettenis return i;
1018b725ae77Skettenis }
1019b725ae77Skettenis return -1;
1020b725ae77Skettenis }
1021b725ae77Skettenis #endif
1022b725ae77Skettenis
1023b725ae77Skettenis /* =================== END, STRUCT PROCINFO "MODULE" =================== */
1024b725ae77Skettenis
1025b725ae77Skettenis /* =================== /proc "MODULE" =================== */
1026b725ae77Skettenis
1027b725ae77Skettenis /*
1028b725ae77Skettenis * This "module" is the interface layer between the /proc system API
1029b725ae77Skettenis * and the gdb target vector functions. This layer consists of
1030b725ae77Skettenis * access functions that encapsulate each of the basic operations
1031b725ae77Skettenis * that we need to use from the /proc API.
1032b725ae77Skettenis *
1033b725ae77Skettenis * The main motivation for this layer is to hide the fact that
1034b725ae77Skettenis * there are two very different implementations of the /proc API.
1035b725ae77Skettenis * Rather than have a bunch of #ifdefs all thru the gdb target vector
1036b725ae77Skettenis * functions, we do our best to hide them all in here.
1037b725ae77Skettenis */
1038b725ae77Skettenis
1039b725ae77Skettenis int proc_get_status (procinfo * pi);
1040b725ae77Skettenis long proc_flags (procinfo * pi);
1041b725ae77Skettenis int proc_why (procinfo * pi);
1042b725ae77Skettenis int proc_what (procinfo * pi);
1043b725ae77Skettenis int proc_set_run_on_last_close (procinfo * pi);
1044b725ae77Skettenis int proc_unset_run_on_last_close (procinfo * pi);
1045b725ae77Skettenis int proc_set_inherit_on_fork (procinfo * pi);
1046b725ae77Skettenis int proc_unset_inherit_on_fork (procinfo * pi);
1047b725ae77Skettenis int proc_set_async (procinfo * pi);
1048b725ae77Skettenis int proc_unset_async (procinfo * pi);
1049b725ae77Skettenis int proc_stop_process (procinfo * pi);
1050b725ae77Skettenis int proc_trace_signal (procinfo * pi, int signo);
1051b725ae77Skettenis int proc_ignore_signal (procinfo * pi, int signo);
1052b725ae77Skettenis int proc_clear_current_fault (procinfo * pi);
1053b725ae77Skettenis int proc_set_current_signal (procinfo * pi, int signo);
1054b725ae77Skettenis int proc_clear_current_signal (procinfo * pi);
1055b725ae77Skettenis int proc_set_gregs (procinfo * pi);
1056b725ae77Skettenis int proc_set_fpregs (procinfo * pi);
1057b725ae77Skettenis int proc_wait_for_stop (procinfo * pi);
1058b725ae77Skettenis int proc_run_process (procinfo * pi, int step, int signo);
1059b725ae77Skettenis int proc_kill (procinfo * pi, int signo);
1060b725ae77Skettenis int proc_parent_pid (procinfo * pi);
1061b725ae77Skettenis int proc_get_nthreads (procinfo * pi);
1062b725ae77Skettenis int proc_get_current_thread (procinfo * pi);
1063b725ae77Skettenis int proc_set_held_signals (procinfo * pi, gdb_sigset_t * sighold);
1064b725ae77Skettenis int proc_set_traced_sysexit (procinfo * pi, sysset_t * sysset);
1065b725ae77Skettenis int proc_set_traced_sysentry (procinfo * pi, sysset_t * sysset);
1066b725ae77Skettenis int proc_set_traced_faults (procinfo * pi, fltset_t * fltset);
1067b725ae77Skettenis int proc_set_traced_signals (procinfo * pi, gdb_sigset_t * sigset);
1068b725ae77Skettenis
1069b725ae77Skettenis int proc_update_threads (procinfo * pi);
1070b725ae77Skettenis int proc_iterate_over_threads (procinfo * pi,
1071b725ae77Skettenis int (*func) (procinfo *, procinfo *, void *),
1072b725ae77Skettenis void *ptr);
1073b725ae77Skettenis
1074b725ae77Skettenis gdb_gregset_t *proc_get_gregs (procinfo * pi);
1075b725ae77Skettenis gdb_fpregset_t *proc_get_fpregs (procinfo * pi);
1076b725ae77Skettenis sysset_t *proc_get_traced_sysexit (procinfo * pi, sysset_t * save);
1077b725ae77Skettenis sysset_t *proc_get_traced_sysentry (procinfo * pi, sysset_t * save);
1078b725ae77Skettenis fltset_t *proc_get_traced_faults (procinfo * pi, fltset_t * save);
1079b725ae77Skettenis gdb_sigset_t *proc_get_traced_signals (procinfo * pi, gdb_sigset_t * save);
1080b725ae77Skettenis gdb_sigset_t *proc_get_held_signals (procinfo * pi, gdb_sigset_t * save);
1081b725ae77Skettenis gdb_sigset_t *proc_get_pending_signals (procinfo * pi, gdb_sigset_t * save);
1082b725ae77Skettenis gdb_sigaction_t *proc_get_signal_actions (procinfo * pi, gdb_sigaction_t *save);
1083b725ae77Skettenis
1084b725ae77Skettenis void proc_warn (procinfo * pi, char *func, int line);
1085b725ae77Skettenis void proc_error (procinfo * pi, char *func, int line);
1086b725ae77Skettenis
1087b725ae77Skettenis void
proc_warn(procinfo * pi,char * func,int line)1088b725ae77Skettenis proc_warn (procinfo *pi, char *func, int line)
1089b725ae77Skettenis {
1090b725ae77Skettenis sprintf (errmsg, "procfs: %s line %d, %s", func, line, pi->pathname);
1091b725ae77Skettenis print_sys_errmsg (errmsg, errno);
1092b725ae77Skettenis }
1093b725ae77Skettenis
1094b725ae77Skettenis void
proc_error(procinfo * pi,char * func,int line)1095b725ae77Skettenis proc_error (procinfo *pi, char *func, int line)
1096b725ae77Skettenis {
1097b725ae77Skettenis sprintf (errmsg, "procfs: %s line %d, %s", func, line, pi->pathname);
1098b725ae77Skettenis perror_with_name (errmsg);
1099b725ae77Skettenis }
1100b725ae77Skettenis
1101b725ae77Skettenis /*
1102b725ae77Skettenis * Function: proc_get_status
1103b725ae77Skettenis *
1104b725ae77Skettenis * Updates the status struct in the procinfo.
1105b725ae77Skettenis * There is a 'valid' flag, to let other functions know when
1106b725ae77Skettenis * this function needs to be called (so the status is only
1107b725ae77Skettenis * read when it is needed). The status file descriptor is
1108b725ae77Skettenis * also only opened when it is needed.
1109b725ae77Skettenis *
1110b725ae77Skettenis * Return: non-zero for success, zero for failure.
1111b725ae77Skettenis */
1112b725ae77Skettenis
1113b725ae77Skettenis int
proc_get_status(procinfo * pi)1114b725ae77Skettenis proc_get_status (procinfo *pi)
1115b725ae77Skettenis {
1116b725ae77Skettenis /* Status file descriptor is opened "lazily" */
1117b725ae77Skettenis if (pi->status_fd == 0 &&
1118b725ae77Skettenis open_procinfo_files (pi, FD_STATUS) == 0)
1119b725ae77Skettenis {
1120b725ae77Skettenis pi->status_valid = 0;
1121b725ae77Skettenis return 0;
1122b725ae77Skettenis }
1123b725ae77Skettenis
1124b725ae77Skettenis #ifdef NEW_PROC_API
1125b725ae77Skettenis if (lseek (pi->status_fd, 0, SEEK_SET) < 0)
1126b725ae77Skettenis pi->status_valid = 0; /* fail */
1127b725ae77Skettenis else
1128b725ae77Skettenis {
1129b725ae77Skettenis /* Sigh... I have to read a different data structure,
1130b725ae77Skettenis depending on whether this is a main process or an LWP. */
1131b725ae77Skettenis if (pi->tid)
1132b725ae77Skettenis pi->status_valid = (read (pi->status_fd,
1133b725ae77Skettenis (char *) &pi->prstatus.pr_lwp,
1134b725ae77Skettenis sizeof (lwpstatus_t))
1135b725ae77Skettenis == sizeof (lwpstatus_t));
1136b725ae77Skettenis else
1137b725ae77Skettenis {
1138b725ae77Skettenis pi->status_valid = (read (pi->status_fd,
1139b725ae77Skettenis (char *) &pi->prstatus,
1140b725ae77Skettenis sizeof (gdb_prstatus_t))
1141b725ae77Skettenis == sizeof (gdb_prstatus_t));
1142b725ae77Skettenis #if 0 /*def UNIXWARE*/
1143b725ae77Skettenis if (pi->status_valid &&
1144b725ae77Skettenis (pi->prstatus.pr_lwp.pr_flags & PR_ISTOP) &&
1145b725ae77Skettenis pi->prstatus.pr_lwp.pr_why == PR_REQUESTED)
1146b725ae77Skettenis /* Unixware peculiarity -- read the damn thing again! */
1147b725ae77Skettenis pi->status_valid = (read (pi->status_fd,
1148b725ae77Skettenis (char *) &pi->prstatus,
1149b725ae77Skettenis sizeof (gdb_prstatus_t))
1150b725ae77Skettenis == sizeof (gdb_prstatus_t));
1151b725ae77Skettenis #endif /* UNIXWARE */
1152b725ae77Skettenis }
1153b725ae77Skettenis }
1154b725ae77Skettenis #else /* ioctl method */
1155b725ae77Skettenis #ifdef PIOCTSTATUS /* osf */
1156b725ae77Skettenis if (pi->tid == 0) /* main process */
1157b725ae77Skettenis {
1158b725ae77Skettenis /* Just read the danged status. Now isn't that simple? */
1159b725ae77Skettenis pi->status_valid =
1160b725ae77Skettenis (ioctl (pi->status_fd, PIOCSTATUS, &pi->prstatus) >= 0);
1161b725ae77Skettenis }
1162b725ae77Skettenis else
1163b725ae77Skettenis {
1164b725ae77Skettenis int win;
1165b725ae77Skettenis struct {
1166b725ae77Skettenis long pr_count;
1167b725ae77Skettenis tid_t pr_error_thread;
1168b725ae77Skettenis struct prstatus status;
1169b725ae77Skettenis } thread_status;
1170b725ae77Skettenis
1171b725ae77Skettenis thread_status.pr_count = 1;
1172b725ae77Skettenis thread_status.status.pr_tid = pi->tid;
1173b725ae77Skettenis win = (ioctl (pi->status_fd, PIOCTSTATUS, &thread_status) >= 0);
1174b725ae77Skettenis if (win)
1175b725ae77Skettenis {
1176b725ae77Skettenis memcpy (&pi->prstatus, &thread_status.status,
1177b725ae77Skettenis sizeof (pi->prstatus));
1178b725ae77Skettenis pi->status_valid = 1;
1179b725ae77Skettenis }
1180b725ae77Skettenis }
1181b725ae77Skettenis #else
1182b725ae77Skettenis /* Just read the danged status. Now isn't that simple? */
1183b725ae77Skettenis pi->status_valid = (ioctl (pi->status_fd, PIOCSTATUS, &pi->prstatus) >= 0);
1184b725ae77Skettenis #endif
1185b725ae77Skettenis #endif
1186b725ae77Skettenis
1187b725ae77Skettenis if (pi->status_valid)
1188b725ae77Skettenis {
1189b725ae77Skettenis PROC_PRETTYFPRINT_STATUS (proc_flags (pi),
1190b725ae77Skettenis proc_why (pi),
1191b725ae77Skettenis proc_what (pi),
1192b725ae77Skettenis proc_get_current_thread (pi));
1193b725ae77Skettenis }
1194b725ae77Skettenis
1195b725ae77Skettenis /* The status struct includes general regs, so mark them valid too */
1196b725ae77Skettenis pi->gregs_valid = pi->status_valid;
1197b725ae77Skettenis #ifdef NEW_PROC_API
1198b725ae77Skettenis /* In the read/write multiple-fd model,
1199b725ae77Skettenis the status struct includes the fp regs too, so mark them valid too */
1200b725ae77Skettenis pi->fpregs_valid = pi->status_valid;
1201b725ae77Skettenis #endif
1202b725ae77Skettenis return pi->status_valid; /* True if success, false if failure. */
1203b725ae77Skettenis }
1204b725ae77Skettenis
1205b725ae77Skettenis /*
1206b725ae77Skettenis * Function: proc_flags
1207b725ae77Skettenis *
1208b725ae77Skettenis * returns the process flags (pr_flags field).
1209b725ae77Skettenis */
1210b725ae77Skettenis
1211b725ae77Skettenis long
proc_flags(procinfo * pi)1212b725ae77Skettenis proc_flags (procinfo *pi)
1213b725ae77Skettenis {
1214b725ae77Skettenis if (!pi->status_valid)
1215b725ae77Skettenis if (!proc_get_status (pi))
1216b725ae77Skettenis return 0; /* FIXME: not a good failure value (but what is?) */
1217b725ae77Skettenis
1218b725ae77Skettenis #ifdef NEW_PROC_API
1219b725ae77Skettenis # ifdef UNIXWARE
1220b725ae77Skettenis /* UnixWare 7.1 puts process status flags, e.g. PR_ASYNC, in
1221b725ae77Skettenis pstatus_t and LWP status flags, e.g. PR_STOPPED, in lwpstatus_t.
1222b725ae77Skettenis The two sets of flags don't overlap. */
1223b725ae77Skettenis return pi->prstatus.pr_flags | pi->prstatus.pr_lwp.pr_flags;
1224b725ae77Skettenis # else
1225b725ae77Skettenis return pi->prstatus.pr_lwp.pr_flags;
1226b725ae77Skettenis # endif
1227b725ae77Skettenis #else
1228b725ae77Skettenis return pi->prstatus.pr_flags;
1229b725ae77Skettenis #endif
1230b725ae77Skettenis }
1231b725ae77Skettenis
1232b725ae77Skettenis /*
1233b725ae77Skettenis * Function: proc_why
1234b725ae77Skettenis *
1235b725ae77Skettenis * returns the pr_why field (why the process stopped).
1236b725ae77Skettenis */
1237b725ae77Skettenis
1238b725ae77Skettenis int
proc_why(procinfo * pi)1239b725ae77Skettenis proc_why (procinfo *pi)
1240b725ae77Skettenis {
1241b725ae77Skettenis if (!pi->status_valid)
1242b725ae77Skettenis if (!proc_get_status (pi))
1243b725ae77Skettenis return 0; /* FIXME: not a good failure value (but what is?) */
1244b725ae77Skettenis
1245b725ae77Skettenis #ifdef NEW_PROC_API
1246b725ae77Skettenis return pi->prstatus.pr_lwp.pr_why;
1247b725ae77Skettenis #else
1248b725ae77Skettenis return pi->prstatus.pr_why;
1249b725ae77Skettenis #endif
1250b725ae77Skettenis }
1251b725ae77Skettenis
1252b725ae77Skettenis /*
1253b725ae77Skettenis * Function: proc_what
1254b725ae77Skettenis *
1255b725ae77Skettenis * returns the pr_what field (details of why the process stopped).
1256b725ae77Skettenis */
1257b725ae77Skettenis
1258b725ae77Skettenis int
proc_what(procinfo * pi)1259b725ae77Skettenis proc_what (procinfo *pi)
1260b725ae77Skettenis {
1261b725ae77Skettenis if (!pi->status_valid)
1262b725ae77Skettenis if (!proc_get_status (pi))
1263b725ae77Skettenis return 0; /* FIXME: not a good failure value (but what is?) */
1264b725ae77Skettenis
1265b725ae77Skettenis #ifdef NEW_PROC_API
1266b725ae77Skettenis return pi->prstatus.pr_lwp.pr_what;
1267b725ae77Skettenis #else
1268b725ae77Skettenis return pi->prstatus.pr_what;
1269b725ae77Skettenis #endif
1270b725ae77Skettenis }
1271b725ae77Skettenis
1272b725ae77Skettenis #ifndef PIOCSSPCACT /* The following is not supported on OSF. */
1273b725ae77Skettenis /*
1274b725ae77Skettenis * Function: proc_nsysarg
1275b725ae77Skettenis *
1276b725ae77Skettenis * returns the pr_nsysarg field (number of args to the current syscall).
1277b725ae77Skettenis */
1278b725ae77Skettenis
1279b725ae77Skettenis int
proc_nsysarg(procinfo * pi)1280b725ae77Skettenis proc_nsysarg (procinfo *pi)
1281b725ae77Skettenis {
1282b725ae77Skettenis if (!pi->status_valid)
1283b725ae77Skettenis if (!proc_get_status (pi))
1284b725ae77Skettenis return 0;
1285b725ae77Skettenis
1286b725ae77Skettenis #ifdef NEW_PROC_API
1287b725ae77Skettenis return pi->prstatus.pr_lwp.pr_nsysarg;
1288b725ae77Skettenis #else
1289b725ae77Skettenis return pi->prstatus.pr_nsysarg;
1290b725ae77Skettenis #endif
1291b725ae77Skettenis }
1292b725ae77Skettenis
1293b725ae77Skettenis /*
1294b725ae77Skettenis * Function: proc_sysargs
1295b725ae77Skettenis *
1296b725ae77Skettenis * returns the pr_sysarg field (pointer to the arguments of current syscall).
1297b725ae77Skettenis */
1298b725ae77Skettenis
1299b725ae77Skettenis long *
proc_sysargs(procinfo * pi)1300b725ae77Skettenis proc_sysargs (procinfo *pi)
1301b725ae77Skettenis {
1302b725ae77Skettenis if (!pi->status_valid)
1303b725ae77Skettenis if (!proc_get_status (pi))
1304b725ae77Skettenis return NULL;
1305b725ae77Skettenis
1306b725ae77Skettenis #ifdef NEW_PROC_API
1307b725ae77Skettenis return (long *) &pi->prstatus.pr_lwp.pr_sysarg;
1308b725ae77Skettenis #else
1309b725ae77Skettenis return (long *) &pi->prstatus.pr_sysarg;
1310b725ae77Skettenis #endif
1311b725ae77Skettenis }
1312b725ae77Skettenis
1313b725ae77Skettenis /*
1314b725ae77Skettenis * Function: proc_syscall
1315b725ae77Skettenis *
1316b725ae77Skettenis * returns the pr_syscall field (id of current syscall if we are in one).
1317b725ae77Skettenis */
1318b725ae77Skettenis
1319b725ae77Skettenis int
proc_syscall(procinfo * pi)1320b725ae77Skettenis proc_syscall (procinfo *pi)
1321b725ae77Skettenis {
1322b725ae77Skettenis if (!pi->status_valid)
1323b725ae77Skettenis if (!proc_get_status (pi))
1324b725ae77Skettenis return 0;
1325b725ae77Skettenis
1326b725ae77Skettenis #ifdef NEW_PROC_API
1327b725ae77Skettenis return pi->prstatus.pr_lwp.pr_syscall;
1328b725ae77Skettenis #else
1329b725ae77Skettenis return pi->prstatus.pr_syscall;
1330b725ae77Skettenis #endif
1331b725ae77Skettenis }
1332b725ae77Skettenis #endif /* PIOCSSPCACT */
1333b725ae77Skettenis
1334b725ae77Skettenis /*
1335b725ae77Skettenis * Function: proc_cursig:
1336b725ae77Skettenis *
1337b725ae77Skettenis * returns the pr_cursig field (current signal).
1338b725ae77Skettenis */
1339b725ae77Skettenis
1340b725ae77Skettenis long
proc_cursig(struct procinfo * pi)1341b725ae77Skettenis proc_cursig (struct procinfo *pi)
1342b725ae77Skettenis {
1343b725ae77Skettenis if (!pi->status_valid)
1344b725ae77Skettenis if (!proc_get_status (pi))
1345b725ae77Skettenis return 0; /* FIXME: not a good failure value (but what is?) */
1346b725ae77Skettenis
1347b725ae77Skettenis #ifdef NEW_PROC_API
1348b725ae77Skettenis return pi->prstatus.pr_lwp.pr_cursig;
1349b725ae77Skettenis #else
1350b725ae77Skettenis return pi->prstatus.pr_cursig;
1351b725ae77Skettenis #endif
1352b725ae77Skettenis }
1353b725ae77Skettenis
1354b725ae77Skettenis /*
1355b725ae77Skettenis * Function: proc_modify_flag
1356b725ae77Skettenis *
1357b725ae77Skettenis * === I appologize for the messiness of this function.
1358b725ae77Skettenis * === This is an area where the different versions of
1359b725ae77Skettenis * === /proc are more inconsistent than usual. MVS
1360b725ae77Skettenis *
1361b725ae77Skettenis * Set or reset any of the following process flags:
1362b725ae77Skettenis * PR_FORK -- forked child will inherit trace flags
1363b725ae77Skettenis * PR_RLC -- traced process runs when last /proc file closed.
1364b725ae77Skettenis * PR_KLC -- traced process is killed when last /proc file closed.
1365b725ae77Skettenis * PR_ASYNC -- LWP's get to run/stop independently.
1366b725ae77Skettenis *
1367b725ae77Skettenis * There are three methods for doing this function:
1368b725ae77Skettenis * 1) Newest: read/write [PCSET/PCRESET/PCUNSET]
1369b725ae77Skettenis * [Sol6, Sol7, UW]
1370b725ae77Skettenis * 2) Middle: PIOCSET/PIOCRESET
1371b725ae77Skettenis * [Irix, Sol5]
1372b725ae77Skettenis * 3) Oldest: PIOCSFORK/PIOCRFORK/PIOCSRLC/PIOCRRLC
1373b725ae77Skettenis * [OSF, Sol5]
1374b725ae77Skettenis *
1375b725ae77Skettenis * Note: Irix does not define PR_ASYNC.
1376b725ae77Skettenis * Note: OSF does not define PR_KLC.
1377b725ae77Skettenis * Note: OSF is the only one that can ONLY use the oldest method.
1378b725ae77Skettenis *
1379b725ae77Skettenis * Arguments:
1380b725ae77Skettenis * pi -- the procinfo
1381b725ae77Skettenis * flag -- one of PR_FORK, PR_RLC, or PR_ASYNC
1382b725ae77Skettenis * mode -- 1 for set, 0 for reset.
1383b725ae77Skettenis *
1384b725ae77Skettenis * Returns non-zero for success, zero for failure.
1385b725ae77Skettenis */
1386b725ae77Skettenis
1387b725ae77Skettenis enum { FLAG_RESET, FLAG_SET };
1388b725ae77Skettenis
1389b725ae77Skettenis static int
proc_modify_flag(procinfo * pi,long flag,long mode)1390b725ae77Skettenis proc_modify_flag (procinfo *pi, long flag, long mode)
1391b725ae77Skettenis {
1392b725ae77Skettenis long win = 0; /* default to fail */
1393b725ae77Skettenis
1394b725ae77Skettenis /*
1395b725ae77Skettenis * These operations affect the process as a whole, and applying
1396b725ae77Skettenis * them to an individual LWP has the same meaning as applying them
1397b725ae77Skettenis * to the main process. Therefore, if we're ever called with a
1398b725ae77Skettenis * pointer to an LWP's procinfo, let's substitute the process's
1399b725ae77Skettenis * procinfo and avoid opening the LWP's file descriptor
1400b725ae77Skettenis * unnecessarily.
1401b725ae77Skettenis */
1402b725ae77Skettenis
1403b725ae77Skettenis if (pi->pid != 0)
1404b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
1405b725ae77Skettenis
1406b725ae77Skettenis #ifdef NEW_PROC_API /* Newest method: UnixWare and newer Solarii */
1407b725ae77Skettenis /* First normalize the PCUNSET/PCRESET command opcode
1408b725ae77Skettenis (which for no obvious reason has a different definition
1409b725ae77Skettenis from one operating system to the next...) */
1410b725ae77Skettenis #ifdef PCUNSET
1411b725ae77Skettenis #define GDBRESET PCUNSET
1412b725ae77Skettenis #else
1413b725ae77Skettenis #ifdef PCRESET
1414b725ae77Skettenis #define GDBRESET PCRESET
1415b725ae77Skettenis #endif
1416b725ae77Skettenis #endif
1417b725ae77Skettenis {
1418b725ae77Skettenis procfs_ctl_t arg[2];
1419b725ae77Skettenis
1420b725ae77Skettenis if (mode == FLAG_SET) /* Set the flag (RLC, FORK, or ASYNC) */
1421b725ae77Skettenis arg[0] = PCSET;
1422b725ae77Skettenis else /* Reset the flag */
1423b725ae77Skettenis arg[0] = GDBRESET;
1424b725ae77Skettenis
1425b725ae77Skettenis arg[1] = flag;
1426b725ae77Skettenis win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg));
1427b725ae77Skettenis }
1428b725ae77Skettenis #else
1429b725ae77Skettenis #ifdef PIOCSET /* Irix/Sol5 method */
1430b725ae77Skettenis if (mode == FLAG_SET) /* Set the flag (hopefully RLC, FORK, or ASYNC) */
1431b725ae77Skettenis {
1432b725ae77Skettenis win = (ioctl (pi->ctl_fd, PIOCSET, &flag) >= 0);
1433b725ae77Skettenis }
1434b725ae77Skettenis else /* Reset the flag */
1435b725ae77Skettenis {
1436b725ae77Skettenis win = (ioctl (pi->ctl_fd, PIOCRESET, &flag) >= 0);
1437b725ae77Skettenis }
1438b725ae77Skettenis
1439b725ae77Skettenis #else
1440b725ae77Skettenis #ifdef PIOCSRLC /* Oldest method: OSF */
1441b725ae77Skettenis switch (flag) {
1442b725ae77Skettenis case PR_RLC:
1443b725ae77Skettenis if (mode == FLAG_SET) /* Set run-on-last-close */
1444b725ae77Skettenis {
1445b725ae77Skettenis win = (ioctl (pi->ctl_fd, PIOCSRLC, NULL) >= 0);
1446b725ae77Skettenis }
1447b725ae77Skettenis else /* Clear run-on-last-close */
1448b725ae77Skettenis {
1449b725ae77Skettenis win = (ioctl (pi->ctl_fd, PIOCRRLC, NULL) >= 0);
1450b725ae77Skettenis }
1451b725ae77Skettenis break;
1452b725ae77Skettenis case PR_FORK:
1453b725ae77Skettenis if (mode == FLAG_SET) /* Set inherit-on-fork */
1454b725ae77Skettenis {
1455b725ae77Skettenis win = (ioctl (pi->ctl_fd, PIOCSFORK, NULL) >= 0);
1456b725ae77Skettenis }
1457b725ae77Skettenis else /* Clear inherit-on-fork */
1458b725ae77Skettenis {
1459b725ae77Skettenis win = (ioctl (pi->ctl_fd, PIOCRFORK, NULL) >= 0);
1460b725ae77Skettenis }
1461b725ae77Skettenis break;
1462b725ae77Skettenis default:
1463b725ae77Skettenis win = 0; /* fail -- unknown flag (can't do PR_ASYNC) */
1464b725ae77Skettenis break;
1465b725ae77Skettenis }
1466b725ae77Skettenis #endif
1467b725ae77Skettenis #endif
1468b725ae77Skettenis #endif
1469b725ae77Skettenis #undef GDBRESET
1470b725ae77Skettenis /* The above operation renders the procinfo's cached pstatus obsolete. */
1471b725ae77Skettenis pi->status_valid = 0;
1472b725ae77Skettenis
1473b725ae77Skettenis if (!win)
1474b725ae77Skettenis warning ("procfs: modify_flag failed to turn %s %s",
1475b725ae77Skettenis flag == PR_FORK ? "PR_FORK" :
1476b725ae77Skettenis flag == PR_RLC ? "PR_RLC" :
1477b725ae77Skettenis #ifdef PR_ASYNC
1478b725ae77Skettenis flag == PR_ASYNC ? "PR_ASYNC" :
1479b725ae77Skettenis #endif
1480b725ae77Skettenis #ifdef PR_KLC
1481b725ae77Skettenis flag == PR_KLC ? "PR_KLC" :
1482b725ae77Skettenis #endif
1483b725ae77Skettenis "<unknown flag>",
1484b725ae77Skettenis mode == FLAG_RESET ? "off" : "on");
1485b725ae77Skettenis
1486b725ae77Skettenis return win;
1487b725ae77Skettenis }
1488b725ae77Skettenis
1489b725ae77Skettenis /*
1490b725ae77Skettenis * Function: proc_set_run_on_last_close
1491b725ae77Skettenis *
1492b725ae77Skettenis * Set the run_on_last_close flag.
1493b725ae77Skettenis * Process with all threads will become runnable
1494b725ae77Skettenis * when debugger closes all /proc fds.
1495b725ae77Skettenis *
1496b725ae77Skettenis * Returns non-zero for success, zero for failure.
1497b725ae77Skettenis */
1498b725ae77Skettenis
1499b725ae77Skettenis int
proc_set_run_on_last_close(procinfo * pi)1500b725ae77Skettenis proc_set_run_on_last_close (procinfo *pi)
1501b725ae77Skettenis {
1502b725ae77Skettenis return proc_modify_flag (pi, PR_RLC, FLAG_SET);
1503b725ae77Skettenis }
1504b725ae77Skettenis
1505b725ae77Skettenis /*
1506b725ae77Skettenis * Function: proc_unset_run_on_last_close
1507b725ae77Skettenis *
1508b725ae77Skettenis * Reset the run_on_last_close flag.
1509b725ae77Skettenis * Process will NOT become runnable
1510b725ae77Skettenis * when debugger closes its file handles.
1511b725ae77Skettenis *
1512b725ae77Skettenis * Returns non-zero for success, zero for failure.
1513b725ae77Skettenis */
1514b725ae77Skettenis
1515b725ae77Skettenis int
proc_unset_run_on_last_close(procinfo * pi)1516b725ae77Skettenis proc_unset_run_on_last_close (procinfo *pi)
1517b725ae77Skettenis {
1518b725ae77Skettenis return proc_modify_flag (pi, PR_RLC, FLAG_RESET);
1519b725ae77Skettenis }
1520b725ae77Skettenis
1521b725ae77Skettenis #ifdef PR_KLC
1522b725ae77Skettenis /*
1523b725ae77Skettenis * Function: proc_set_kill_on_last_close
1524b725ae77Skettenis *
1525b725ae77Skettenis * Set the kill_on_last_close flag.
1526b725ae77Skettenis * Process with all threads will be killed when debugger
1527b725ae77Skettenis * closes all /proc fds (or debugger exits or dies).
1528b725ae77Skettenis *
1529b725ae77Skettenis * Returns non-zero for success, zero for failure.
1530b725ae77Skettenis */
1531b725ae77Skettenis
1532b725ae77Skettenis int
proc_set_kill_on_last_close(procinfo * pi)1533b725ae77Skettenis proc_set_kill_on_last_close (procinfo *pi)
1534b725ae77Skettenis {
1535b725ae77Skettenis return proc_modify_flag (pi, PR_KLC, FLAG_SET);
1536b725ae77Skettenis }
1537b725ae77Skettenis
1538b725ae77Skettenis /*
1539b725ae77Skettenis * Function: proc_unset_kill_on_last_close
1540b725ae77Skettenis *
1541b725ae77Skettenis * Reset the kill_on_last_close flag.
1542b725ae77Skettenis * Process will NOT be killed when debugger
1543b725ae77Skettenis * closes its file handles (or exits or dies).
1544b725ae77Skettenis *
1545b725ae77Skettenis * Returns non-zero for success, zero for failure.
1546b725ae77Skettenis */
1547b725ae77Skettenis
1548b725ae77Skettenis int
proc_unset_kill_on_last_close(procinfo * pi)1549b725ae77Skettenis proc_unset_kill_on_last_close (procinfo *pi)
1550b725ae77Skettenis {
1551b725ae77Skettenis return proc_modify_flag (pi, PR_KLC, FLAG_RESET);
1552b725ae77Skettenis }
1553b725ae77Skettenis #endif /* PR_KLC */
1554b725ae77Skettenis
1555b725ae77Skettenis /*
1556b725ae77Skettenis * Function: proc_set_inherit_on_fork
1557b725ae77Skettenis *
1558b725ae77Skettenis * Set inherit_on_fork flag.
1559b725ae77Skettenis * If the process forks a child while we are registered for events
1560b725ae77Skettenis * in the parent, then we will also recieve events from the child.
1561b725ae77Skettenis *
1562b725ae77Skettenis * Returns non-zero for success, zero for failure.
1563b725ae77Skettenis */
1564b725ae77Skettenis
1565b725ae77Skettenis int
proc_set_inherit_on_fork(procinfo * pi)1566b725ae77Skettenis proc_set_inherit_on_fork (procinfo *pi)
1567b725ae77Skettenis {
1568b725ae77Skettenis return proc_modify_flag (pi, PR_FORK, FLAG_SET);
1569b725ae77Skettenis }
1570b725ae77Skettenis
1571b725ae77Skettenis /*
1572b725ae77Skettenis * Function: proc_unset_inherit_on_fork
1573b725ae77Skettenis *
1574b725ae77Skettenis * Reset inherit_on_fork flag.
1575b725ae77Skettenis * If the process forks a child while we are registered for events
1576b725ae77Skettenis * in the parent, then we will NOT recieve events from the child.
1577b725ae77Skettenis *
1578b725ae77Skettenis * Returns non-zero for success, zero for failure.
1579b725ae77Skettenis */
1580b725ae77Skettenis
1581b725ae77Skettenis int
proc_unset_inherit_on_fork(procinfo * pi)1582b725ae77Skettenis proc_unset_inherit_on_fork (procinfo *pi)
1583b725ae77Skettenis {
1584b725ae77Skettenis return proc_modify_flag (pi, PR_FORK, FLAG_RESET);
1585b725ae77Skettenis }
1586b725ae77Skettenis
1587b725ae77Skettenis #ifdef PR_ASYNC
1588b725ae77Skettenis /*
1589b725ae77Skettenis * Function: proc_set_async
1590b725ae77Skettenis *
1591b725ae77Skettenis * Set PR_ASYNC flag.
1592b725ae77Skettenis * If one LWP stops because of a debug event (signal etc.),
1593b725ae77Skettenis * the remaining LWPs will continue to run.
1594b725ae77Skettenis *
1595b725ae77Skettenis * Returns non-zero for success, zero for failure.
1596b725ae77Skettenis */
1597b725ae77Skettenis
1598b725ae77Skettenis int
proc_set_async(procinfo * pi)1599b725ae77Skettenis proc_set_async (procinfo *pi)
1600b725ae77Skettenis {
1601b725ae77Skettenis return proc_modify_flag (pi, PR_ASYNC, FLAG_SET);
1602b725ae77Skettenis }
1603b725ae77Skettenis
1604b725ae77Skettenis /*
1605b725ae77Skettenis * Function: proc_unset_async
1606b725ae77Skettenis *
1607b725ae77Skettenis * Reset PR_ASYNC flag.
1608b725ae77Skettenis * If one LWP stops because of a debug event (signal etc.),
1609b725ae77Skettenis * then all other LWPs will stop as well.
1610b725ae77Skettenis *
1611b725ae77Skettenis * Returns non-zero for success, zero for failure.
1612b725ae77Skettenis */
1613b725ae77Skettenis
1614b725ae77Skettenis int
proc_unset_async(procinfo * pi)1615b725ae77Skettenis proc_unset_async (procinfo *pi)
1616b725ae77Skettenis {
1617b725ae77Skettenis return proc_modify_flag (pi, PR_ASYNC, FLAG_RESET);
1618b725ae77Skettenis }
1619b725ae77Skettenis #endif /* PR_ASYNC */
1620b725ae77Skettenis
1621b725ae77Skettenis /*
1622b725ae77Skettenis * Function: proc_stop_process
1623b725ae77Skettenis *
1624b725ae77Skettenis * Request the process/LWP to stop. Does not wait.
1625b725ae77Skettenis * Returns non-zero for success, zero for failure.
1626b725ae77Skettenis */
1627b725ae77Skettenis
1628b725ae77Skettenis int
proc_stop_process(procinfo * pi)1629b725ae77Skettenis proc_stop_process (procinfo *pi)
1630b725ae77Skettenis {
1631b725ae77Skettenis int win;
1632b725ae77Skettenis
1633b725ae77Skettenis /*
1634b725ae77Skettenis * We might conceivably apply this operation to an LWP, and
1635b725ae77Skettenis * the LWP's ctl file descriptor might not be open.
1636b725ae77Skettenis */
1637b725ae77Skettenis
1638b725ae77Skettenis if (pi->ctl_fd == 0 &&
1639b725ae77Skettenis open_procinfo_files (pi, FD_CTL) == 0)
1640b725ae77Skettenis return 0;
1641b725ae77Skettenis else
1642b725ae77Skettenis {
1643b725ae77Skettenis #ifdef NEW_PROC_API
1644b725ae77Skettenis procfs_ctl_t cmd = PCSTOP;
1645b725ae77Skettenis win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd));
1646b725ae77Skettenis #else /* ioctl method */
1647b725ae77Skettenis win = (ioctl (pi->ctl_fd, PIOCSTOP, &pi->prstatus) >= 0);
1648b725ae77Skettenis /* Note: the call also reads the prstatus. */
1649b725ae77Skettenis if (win)
1650b725ae77Skettenis {
1651b725ae77Skettenis pi->status_valid = 1;
1652b725ae77Skettenis PROC_PRETTYFPRINT_STATUS (proc_flags (pi),
1653b725ae77Skettenis proc_why (pi),
1654b725ae77Skettenis proc_what (pi),
1655b725ae77Skettenis proc_get_current_thread (pi));
1656b725ae77Skettenis }
1657b725ae77Skettenis #endif
1658b725ae77Skettenis }
1659b725ae77Skettenis
1660b725ae77Skettenis return win;
1661b725ae77Skettenis }
1662b725ae77Skettenis
1663b725ae77Skettenis /*
1664b725ae77Skettenis * Function: proc_wait_for_stop
1665b725ae77Skettenis *
1666b725ae77Skettenis * Wait for the process or LWP to stop (block until it does).
1667b725ae77Skettenis * Returns non-zero for success, zero for failure.
1668b725ae77Skettenis */
1669b725ae77Skettenis
1670b725ae77Skettenis int
proc_wait_for_stop(procinfo * pi)1671b725ae77Skettenis proc_wait_for_stop (procinfo *pi)
1672b725ae77Skettenis {
1673b725ae77Skettenis int win;
1674b725ae77Skettenis
1675b725ae77Skettenis /*
1676b725ae77Skettenis * We should never have to apply this operation to any procinfo
1677b725ae77Skettenis * except the one for the main process. If that ever changes
1678b725ae77Skettenis * for any reason, then take out the following clause and
1679b725ae77Skettenis * replace it with one that makes sure the ctl_fd is open.
1680b725ae77Skettenis */
1681b725ae77Skettenis
1682b725ae77Skettenis if (pi->tid != 0)
1683b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
1684b725ae77Skettenis
1685b725ae77Skettenis #ifdef NEW_PROC_API
1686b725ae77Skettenis {
1687b725ae77Skettenis procfs_ctl_t cmd = PCWSTOP;
1688b725ae77Skettenis win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd));
1689b725ae77Skettenis /* We been runnin' and we stopped -- need to update status. */
1690b725ae77Skettenis pi->status_valid = 0;
1691b725ae77Skettenis }
1692b725ae77Skettenis #else /* ioctl method */
1693b725ae77Skettenis win = (ioctl (pi->ctl_fd, PIOCWSTOP, &pi->prstatus) >= 0);
1694b725ae77Skettenis /* Above call also refreshes the prstatus. */
1695b725ae77Skettenis if (win)
1696b725ae77Skettenis {
1697b725ae77Skettenis pi->status_valid = 1;
1698b725ae77Skettenis PROC_PRETTYFPRINT_STATUS (proc_flags (pi),
1699b725ae77Skettenis proc_why (pi),
1700b725ae77Skettenis proc_what (pi),
1701b725ae77Skettenis proc_get_current_thread (pi));
1702b725ae77Skettenis }
1703b725ae77Skettenis #endif
1704b725ae77Skettenis
1705b725ae77Skettenis return win;
1706b725ae77Skettenis }
1707b725ae77Skettenis
1708b725ae77Skettenis /*
1709b725ae77Skettenis * Function: proc_run_process
1710b725ae77Skettenis *
1711b725ae77Skettenis * Make the process or LWP runnable.
1712b725ae77Skettenis * Options (not all are implemented):
1713b725ae77Skettenis * - single-step
1714b725ae77Skettenis * - clear current fault
1715b725ae77Skettenis * - clear current signal
1716b725ae77Skettenis * - abort the current system call
1717b725ae77Skettenis * - stop as soon as finished with system call
1718b725ae77Skettenis * - (ioctl): set traced signal set
1719b725ae77Skettenis * - (ioctl): set held signal set
1720b725ae77Skettenis * - (ioctl): set traced fault set
1721b725ae77Skettenis * - (ioctl): set start pc (vaddr)
1722b725ae77Skettenis * Always clear the current fault.
1723b725ae77Skettenis * Clear the current signal if 'signo' is zero.
1724b725ae77Skettenis *
1725b725ae77Skettenis * Arguments:
1726b725ae77Skettenis * pi the process or LWP to operate on.
1727b725ae77Skettenis * step if true, set the process or LWP to trap after one instr.
1728b725ae77Skettenis * signo if zero, clear the current signal if any.
1729b725ae77Skettenis * if non-zero, set the current signal to this one.
1730b725ae77Skettenis *
1731b725ae77Skettenis * Returns non-zero for success, zero for failure.
1732b725ae77Skettenis */
1733b725ae77Skettenis
1734b725ae77Skettenis int
proc_run_process(procinfo * pi,int step,int signo)1735b725ae77Skettenis proc_run_process (procinfo *pi, int step, int signo)
1736b725ae77Skettenis {
1737b725ae77Skettenis int win;
1738b725ae77Skettenis int runflags;
1739b725ae77Skettenis
1740b725ae77Skettenis /*
1741b725ae77Skettenis * We will probably have to apply this operation to individual threads,
1742b725ae77Skettenis * so make sure the control file descriptor is open.
1743b725ae77Skettenis */
1744b725ae77Skettenis
1745b725ae77Skettenis if (pi->ctl_fd == 0 &&
1746b725ae77Skettenis open_procinfo_files (pi, FD_CTL) == 0)
1747b725ae77Skettenis {
1748b725ae77Skettenis return 0;
1749b725ae77Skettenis }
1750b725ae77Skettenis
1751b725ae77Skettenis runflags = PRCFAULT; /* always clear current fault */
1752b725ae77Skettenis if (step)
1753b725ae77Skettenis runflags |= PRSTEP;
1754b725ae77Skettenis if (signo == 0)
1755b725ae77Skettenis runflags |= PRCSIG;
1756b725ae77Skettenis else if (signo != -1) /* -1 means do nothing W.R.T. signals */
1757b725ae77Skettenis proc_set_current_signal (pi, signo);
1758b725ae77Skettenis
1759b725ae77Skettenis #ifdef NEW_PROC_API
1760b725ae77Skettenis {
1761b725ae77Skettenis procfs_ctl_t cmd[2];
1762b725ae77Skettenis
1763b725ae77Skettenis cmd[0] = PCRUN;
1764b725ae77Skettenis cmd[1] = runflags;
1765b725ae77Skettenis win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd));
1766b725ae77Skettenis }
1767b725ae77Skettenis #else /* ioctl method */
1768b725ae77Skettenis {
1769b725ae77Skettenis prrun_t prrun;
1770b725ae77Skettenis
1771b725ae77Skettenis memset (&prrun, 0, sizeof (prrun));
1772b725ae77Skettenis prrun.pr_flags = runflags;
1773b725ae77Skettenis win = (ioctl (pi->ctl_fd, PIOCRUN, &prrun) >= 0);
1774b725ae77Skettenis }
1775b725ae77Skettenis #endif
1776b725ae77Skettenis
1777b725ae77Skettenis return win;
1778b725ae77Skettenis }
1779b725ae77Skettenis
1780b725ae77Skettenis /*
1781b725ae77Skettenis * Function: proc_set_traced_signals
1782b725ae77Skettenis *
1783b725ae77Skettenis * Register to trace signals in the process or LWP.
1784b725ae77Skettenis * Returns non-zero for success, zero for failure.
1785b725ae77Skettenis */
1786b725ae77Skettenis
1787b725ae77Skettenis int
proc_set_traced_signals(procinfo * pi,gdb_sigset_t * sigset)1788b725ae77Skettenis proc_set_traced_signals (procinfo *pi, gdb_sigset_t *sigset)
1789b725ae77Skettenis {
1790b725ae77Skettenis int win;
1791b725ae77Skettenis
1792b725ae77Skettenis /*
1793b725ae77Skettenis * We should never have to apply this operation to any procinfo
1794b725ae77Skettenis * except the one for the main process. If that ever changes
1795b725ae77Skettenis * for any reason, then take out the following clause and
1796b725ae77Skettenis * replace it with one that makes sure the ctl_fd is open.
1797b725ae77Skettenis */
1798b725ae77Skettenis
1799b725ae77Skettenis if (pi->tid != 0)
1800b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
1801b725ae77Skettenis
1802b725ae77Skettenis #ifdef NEW_PROC_API
1803b725ae77Skettenis {
1804b725ae77Skettenis struct {
1805b725ae77Skettenis procfs_ctl_t cmd;
1806b725ae77Skettenis /* Use char array to avoid alignment issues. */
1807b725ae77Skettenis char sigset[sizeof (gdb_sigset_t)];
1808b725ae77Skettenis } arg;
1809b725ae77Skettenis
1810b725ae77Skettenis arg.cmd = PCSTRACE;
1811b725ae77Skettenis memcpy (&arg.sigset, sigset, sizeof (gdb_sigset_t));
1812b725ae77Skettenis
1813b725ae77Skettenis win = (write (pi->ctl_fd, (char *) &arg, sizeof (arg)) == sizeof (arg));
1814b725ae77Skettenis }
1815b725ae77Skettenis #else /* ioctl method */
1816b725ae77Skettenis win = (ioctl (pi->ctl_fd, PIOCSTRACE, sigset) >= 0);
1817b725ae77Skettenis #endif
1818b725ae77Skettenis /* The above operation renders the procinfo's cached pstatus obsolete. */
1819b725ae77Skettenis pi->status_valid = 0;
1820b725ae77Skettenis
1821b725ae77Skettenis if (!win)
1822b725ae77Skettenis warning ("procfs: set_traced_signals failed");
1823b725ae77Skettenis return win;
1824b725ae77Skettenis }
1825b725ae77Skettenis
1826b725ae77Skettenis /*
1827b725ae77Skettenis * Function: proc_set_traced_faults
1828b725ae77Skettenis *
1829b725ae77Skettenis * Register to trace hardware faults in the process or LWP.
1830b725ae77Skettenis * Returns non-zero for success, zero for failure.
1831b725ae77Skettenis */
1832b725ae77Skettenis
1833b725ae77Skettenis int
proc_set_traced_faults(procinfo * pi,fltset_t * fltset)1834b725ae77Skettenis proc_set_traced_faults (procinfo *pi, fltset_t *fltset)
1835b725ae77Skettenis {
1836b725ae77Skettenis int win;
1837b725ae77Skettenis
1838b725ae77Skettenis /*
1839b725ae77Skettenis * We should never have to apply this operation to any procinfo
1840b725ae77Skettenis * except the one for the main process. If that ever changes
1841b725ae77Skettenis * for any reason, then take out the following clause and
1842b725ae77Skettenis * replace it with one that makes sure the ctl_fd is open.
1843b725ae77Skettenis */
1844b725ae77Skettenis
1845b725ae77Skettenis if (pi->tid != 0)
1846b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
1847b725ae77Skettenis
1848b725ae77Skettenis #ifdef NEW_PROC_API
1849b725ae77Skettenis {
1850b725ae77Skettenis struct {
1851b725ae77Skettenis procfs_ctl_t cmd;
1852b725ae77Skettenis /* Use char array to avoid alignment issues. */
1853b725ae77Skettenis char fltset[sizeof (fltset_t)];
1854b725ae77Skettenis } arg;
1855b725ae77Skettenis
1856b725ae77Skettenis arg.cmd = PCSFAULT;
1857b725ae77Skettenis memcpy (&arg.fltset, fltset, sizeof (fltset_t));
1858b725ae77Skettenis
1859b725ae77Skettenis win = (write (pi->ctl_fd, (char *) &arg, sizeof (arg)) == sizeof (arg));
1860b725ae77Skettenis }
1861b725ae77Skettenis #else /* ioctl method */
1862b725ae77Skettenis win = (ioctl (pi->ctl_fd, PIOCSFAULT, fltset) >= 0);
1863b725ae77Skettenis #endif
1864b725ae77Skettenis /* The above operation renders the procinfo's cached pstatus obsolete. */
1865b725ae77Skettenis pi->status_valid = 0;
1866b725ae77Skettenis
1867b725ae77Skettenis return win;
1868b725ae77Skettenis }
1869b725ae77Skettenis
1870b725ae77Skettenis /*
1871b725ae77Skettenis * Function: proc_set_traced_sysentry
1872b725ae77Skettenis *
1873b725ae77Skettenis * Register to trace entry to system calls in the process or LWP.
1874b725ae77Skettenis * Returns non-zero for success, zero for failure.
1875b725ae77Skettenis */
1876b725ae77Skettenis
1877b725ae77Skettenis int
proc_set_traced_sysentry(procinfo * pi,sysset_t * sysset)1878b725ae77Skettenis proc_set_traced_sysentry (procinfo *pi, sysset_t *sysset)
1879b725ae77Skettenis {
1880b725ae77Skettenis int win;
1881b725ae77Skettenis
1882b725ae77Skettenis /*
1883b725ae77Skettenis * We should never have to apply this operation to any procinfo
1884b725ae77Skettenis * except the one for the main process. If that ever changes
1885b725ae77Skettenis * for any reason, then take out the following clause and
1886b725ae77Skettenis * replace it with one that makes sure the ctl_fd is open.
1887b725ae77Skettenis */
1888b725ae77Skettenis
1889b725ae77Skettenis if (pi->tid != 0)
1890b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
1891b725ae77Skettenis
1892b725ae77Skettenis #ifdef NEW_PROC_API
1893b725ae77Skettenis {
1894b725ae77Skettenis struct gdb_proc_ctl_pcsentry {
1895b725ae77Skettenis procfs_ctl_t cmd;
1896b725ae77Skettenis /* Use char array to avoid alignment issues. */
1897b725ae77Skettenis char sysset[sizeof (sysset_t)];
1898b725ae77Skettenis } *argp;
1899b725ae77Skettenis int argp_size = sizeof (struct gdb_proc_ctl_pcsentry)
1900b725ae77Skettenis - sizeof (sysset_t)
1901b725ae77Skettenis + sysset_t_size (pi);
1902b725ae77Skettenis
1903b725ae77Skettenis argp = xmalloc (argp_size);
1904b725ae77Skettenis
1905b725ae77Skettenis argp->cmd = PCSENTRY;
1906b725ae77Skettenis memcpy (&argp->sysset, sysset, sysset_t_size (pi));
1907b725ae77Skettenis
1908b725ae77Skettenis win = (write (pi->ctl_fd, (char *) argp, argp_size) == argp_size);
1909b725ae77Skettenis xfree (argp);
1910b725ae77Skettenis }
1911b725ae77Skettenis #else /* ioctl method */
1912b725ae77Skettenis win = (ioctl (pi->ctl_fd, PIOCSENTRY, sysset) >= 0);
1913b725ae77Skettenis #endif
1914b725ae77Skettenis /* The above operation renders the procinfo's cached pstatus obsolete. */
1915b725ae77Skettenis pi->status_valid = 0;
1916b725ae77Skettenis
1917b725ae77Skettenis return win;
1918b725ae77Skettenis }
1919b725ae77Skettenis
1920b725ae77Skettenis /*
1921b725ae77Skettenis * Function: proc_set_traced_sysexit
1922b725ae77Skettenis *
1923b725ae77Skettenis * Register to trace exit from system calls in the process or LWP.
1924b725ae77Skettenis * Returns non-zero for success, zero for failure.
1925b725ae77Skettenis */
1926b725ae77Skettenis
1927b725ae77Skettenis int
proc_set_traced_sysexit(procinfo * pi,sysset_t * sysset)1928b725ae77Skettenis proc_set_traced_sysexit (procinfo *pi, sysset_t *sysset)
1929b725ae77Skettenis {
1930b725ae77Skettenis int win;
1931b725ae77Skettenis
1932b725ae77Skettenis /*
1933b725ae77Skettenis * We should never have to apply this operation to any procinfo
1934b725ae77Skettenis * except the one for the main process. If that ever changes
1935b725ae77Skettenis * for any reason, then take out the following clause and
1936b725ae77Skettenis * replace it with one that makes sure the ctl_fd is open.
1937b725ae77Skettenis */
1938b725ae77Skettenis
1939b725ae77Skettenis if (pi->tid != 0)
1940b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
1941b725ae77Skettenis
1942b725ae77Skettenis #ifdef NEW_PROC_API
1943b725ae77Skettenis {
1944b725ae77Skettenis struct gdb_proc_ctl_pcsexit {
1945b725ae77Skettenis procfs_ctl_t cmd;
1946b725ae77Skettenis /* Use char array to avoid alignment issues. */
1947b725ae77Skettenis char sysset[sizeof (sysset_t)];
1948b725ae77Skettenis } *argp;
1949b725ae77Skettenis int argp_size = sizeof (struct gdb_proc_ctl_pcsexit)
1950b725ae77Skettenis - sizeof (sysset_t)
1951b725ae77Skettenis + sysset_t_size (pi);
1952b725ae77Skettenis
1953b725ae77Skettenis argp = xmalloc (argp_size);
1954b725ae77Skettenis
1955b725ae77Skettenis argp->cmd = PCSEXIT;
1956b725ae77Skettenis memcpy (&argp->sysset, sysset, sysset_t_size (pi));
1957b725ae77Skettenis
1958b725ae77Skettenis win = (write (pi->ctl_fd, (char *) argp, argp_size) == argp_size);
1959b725ae77Skettenis xfree (argp);
1960b725ae77Skettenis }
1961b725ae77Skettenis #else /* ioctl method */
1962b725ae77Skettenis win = (ioctl (pi->ctl_fd, PIOCSEXIT, sysset) >= 0);
1963b725ae77Skettenis #endif
1964b725ae77Skettenis /* The above operation renders the procinfo's cached pstatus obsolete. */
1965b725ae77Skettenis pi->status_valid = 0;
1966b725ae77Skettenis
1967b725ae77Skettenis return win;
1968b725ae77Skettenis }
1969b725ae77Skettenis
1970b725ae77Skettenis /*
1971b725ae77Skettenis * Function: proc_set_held_signals
1972b725ae77Skettenis *
1973b725ae77Skettenis * Specify the set of blocked / held signals in the process or LWP.
1974b725ae77Skettenis * Returns non-zero for success, zero for failure.
1975b725ae77Skettenis */
1976b725ae77Skettenis
1977b725ae77Skettenis int
proc_set_held_signals(procinfo * pi,gdb_sigset_t * sighold)1978b725ae77Skettenis proc_set_held_signals (procinfo *pi, gdb_sigset_t *sighold)
1979b725ae77Skettenis {
1980b725ae77Skettenis int win;
1981b725ae77Skettenis
1982b725ae77Skettenis /*
1983b725ae77Skettenis * We should never have to apply this operation to any procinfo
1984b725ae77Skettenis * except the one for the main process. If that ever changes
1985b725ae77Skettenis * for any reason, then take out the following clause and
1986b725ae77Skettenis * replace it with one that makes sure the ctl_fd is open.
1987b725ae77Skettenis */
1988b725ae77Skettenis
1989b725ae77Skettenis if (pi->tid != 0)
1990b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
1991b725ae77Skettenis
1992b725ae77Skettenis #ifdef NEW_PROC_API
1993b725ae77Skettenis {
1994b725ae77Skettenis struct {
1995b725ae77Skettenis procfs_ctl_t cmd;
1996b725ae77Skettenis /* Use char array to avoid alignment issues. */
1997b725ae77Skettenis char hold[sizeof (gdb_sigset_t)];
1998b725ae77Skettenis } arg;
1999b725ae77Skettenis
2000b725ae77Skettenis arg.cmd = PCSHOLD;
2001b725ae77Skettenis memcpy (&arg.hold, sighold, sizeof (gdb_sigset_t));
2002b725ae77Skettenis win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg));
2003b725ae77Skettenis }
2004b725ae77Skettenis #else
2005b725ae77Skettenis win = (ioctl (pi->ctl_fd, PIOCSHOLD, sighold) >= 0);
2006b725ae77Skettenis #endif
2007b725ae77Skettenis /* The above operation renders the procinfo's cached pstatus obsolete. */
2008b725ae77Skettenis pi->status_valid = 0;
2009b725ae77Skettenis
2010b725ae77Skettenis return win;
2011b725ae77Skettenis }
2012b725ae77Skettenis
2013b725ae77Skettenis /*
2014b725ae77Skettenis * Function: proc_get_pending_signals
2015b725ae77Skettenis *
2016b725ae77Skettenis * returns the set of signals that are pending in the process or LWP.
2017b725ae77Skettenis * Will also copy the sigset if 'save' is non-zero.
2018b725ae77Skettenis */
2019b725ae77Skettenis
2020b725ae77Skettenis gdb_sigset_t *
proc_get_pending_signals(procinfo * pi,gdb_sigset_t * save)2021b725ae77Skettenis proc_get_pending_signals (procinfo *pi, gdb_sigset_t *save)
2022b725ae77Skettenis {
2023b725ae77Skettenis gdb_sigset_t *ret = NULL;
2024b725ae77Skettenis
2025b725ae77Skettenis /*
2026b725ae77Skettenis * We should never have to apply this operation to any procinfo
2027b725ae77Skettenis * except the one for the main process. If that ever changes
2028b725ae77Skettenis * for any reason, then take out the following clause and
2029b725ae77Skettenis * replace it with one that makes sure the ctl_fd is open.
2030b725ae77Skettenis */
2031b725ae77Skettenis
2032b725ae77Skettenis if (pi->tid != 0)
2033b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
2034b725ae77Skettenis
2035b725ae77Skettenis if (!pi->status_valid)
2036b725ae77Skettenis if (!proc_get_status (pi))
2037b725ae77Skettenis return NULL;
2038b725ae77Skettenis
2039b725ae77Skettenis #ifdef NEW_PROC_API
2040b725ae77Skettenis ret = &pi->prstatus.pr_lwp.pr_lwppend;
2041b725ae77Skettenis #else
2042b725ae77Skettenis ret = &pi->prstatus.pr_sigpend;
2043b725ae77Skettenis #endif
2044b725ae77Skettenis if (save && ret)
2045b725ae77Skettenis memcpy (save, ret, sizeof (gdb_sigset_t));
2046b725ae77Skettenis
2047b725ae77Skettenis return ret;
2048b725ae77Skettenis }
2049b725ae77Skettenis
2050b725ae77Skettenis /*
2051b725ae77Skettenis * Function: proc_get_signal_actions
2052b725ae77Skettenis *
2053b725ae77Skettenis * returns the set of signal actions.
2054b725ae77Skettenis * Will also copy the sigactionset if 'save' is non-zero.
2055b725ae77Skettenis */
2056b725ae77Skettenis
2057b725ae77Skettenis gdb_sigaction_t *
proc_get_signal_actions(procinfo * pi,gdb_sigaction_t * save)2058b725ae77Skettenis proc_get_signal_actions (procinfo *pi, gdb_sigaction_t *save)
2059b725ae77Skettenis {
2060b725ae77Skettenis gdb_sigaction_t *ret = NULL;
2061b725ae77Skettenis
2062b725ae77Skettenis /*
2063b725ae77Skettenis * We should never have to apply this operation to any procinfo
2064b725ae77Skettenis * except the one for the main process. If that ever changes
2065b725ae77Skettenis * for any reason, then take out the following clause and
2066b725ae77Skettenis * replace it with one that makes sure the ctl_fd is open.
2067b725ae77Skettenis */
2068b725ae77Skettenis
2069b725ae77Skettenis if (pi->tid != 0)
2070b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
2071b725ae77Skettenis
2072b725ae77Skettenis if (!pi->status_valid)
2073b725ae77Skettenis if (!proc_get_status (pi))
2074b725ae77Skettenis return NULL;
2075b725ae77Skettenis
2076b725ae77Skettenis #ifdef NEW_PROC_API
2077b725ae77Skettenis ret = &pi->prstatus.pr_lwp.pr_action;
2078b725ae77Skettenis #else
2079b725ae77Skettenis ret = &pi->prstatus.pr_action;
2080b725ae77Skettenis #endif
2081b725ae77Skettenis if (save && ret)
2082b725ae77Skettenis memcpy (save, ret, sizeof (gdb_sigaction_t));
2083b725ae77Skettenis
2084b725ae77Skettenis return ret;
2085b725ae77Skettenis }
2086b725ae77Skettenis
2087b725ae77Skettenis /*
2088b725ae77Skettenis * Function: proc_get_held_signals
2089b725ae77Skettenis *
2090b725ae77Skettenis * returns the set of signals that are held / blocked.
2091b725ae77Skettenis * Will also copy the sigset if 'save' is non-zero.
2092b725ae77Skettenis */
2093b725ae77Skettenis
2094b725ae77Skettenis gdb_sigset_t *
proc_get_held_signals(procinfo * pi,gdb_sigset_t * save)2095b725ae77Skettenis proc_get_held_signals (procinfo *pi, gdb_sigset_t *save)
2096b725ae77Skettenis {
2097b725ae77Skettenis gdb_sigset_t *ret = NULL;
2098b725ae77Skettenis
2099b725ae77Skettenis /*
2100b725ae77Skettenis * We should never have to apply this operation to any procinfo
2101b725ae77Skettenis * except the one for the main process. If that ever changes
2102b725ae77Skettenis * for any reason, then take out the following clause and
2103b725ae77Skettenis * replace it with one that makes sure the ctl_fd is open.
2104b725ae77Skettenis */
2105b725ae77Skettenis
2106b725ae77Skettenis if (pi->tid != 0)
2107b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
2108b725ae77Skettenis
2109b725ae77Skettenis #ifdef NEW_PROC_API
2110b725ae77Skettenis if (!pi->status_valid)
2111b725ae77Skettenis if (!proc_get_status (pi))
2112b725ae77Skettenis return NULL;
2113b725ae77Skettenis
2114b725ae77Skettenis #ifdef UNIXWARE
2115b725ae77Skettenis ret = &pi->prstatus.pr_lwp.pr_context.uc_sigmask;
2116b725ae77Skettenis #else
2117b725ae77Skettenis ret = &pi->prstatus.pr_lwp.pr_lwphold;
2118b725ae77Skettenis #endif /* UNIXWARE */
2119b725ae77Skettenis #else /* not NEW_PROC_API */
2120b725ae77Skettenis {
2121b725ae77Skettenis static gdb_sigset_t sigheld;
2122b725ae77Skettenis
2123b725ae77Skettenis if (ioctl (pi->ctl_fd, PIOCGHOLD, &sigheld) >= 0)
2124b725ae77Skettenis ret = &sigheld;
2125b725ae77Skettenis }
2126b725ae77Skettenis #endif /* NEW_PROC_API */
2127b725ae77Skettenis if (save && ret)
2128b725ae77Skettenis memcpy (save, ret, sizeof (gdb_sigset_t));
2129b725ae77Skettenis
2130b725ae77Skettenis return ret;
2131b725ae77Skettenis }
2132b725ae77Skettenis
2133b725ae77Skettenis /*
2134b725ae77Skettenis * Function: proc_get_traced_signals
2135b725ae77Skettenis *
2136b725ae77Skettenis * returns the set of signals that are traced / debugged.
2137b725ae77Skettenis * Will also copy the sigset if 'save' is non-zero.
2138b725ae77Skettenis */
2139b725ae77Skettenis
2140b725ae77Skettenis gdb_sigset_t *
proc_get_traced_signals(procinfo * pi,gdb_sigset_t * save)2141b725ae77Skettenis proc_get_traced_signals (procinfo *pi, gdb_sigset_t *save)
2142b725ae77Skettenis {
2143b725ae77Skettenis gdb_sigset_t *ret = NULL;
2144b725ae77Skettenis
2145b725ae77Skettenis /*
2146b725ae77Skettenis * We should never have to apply this operation to any procinfo
2147b725ae77Skettenis * except the one for the main process. If that ever changes
2148b725ae77Skettenis * for any reason, then take out the following clause and
2149b725ae77Skettenis * replace it with one that makes sure the ctl_fd is open.
2150b725ae77Skettenis */
2151b725ae77Skettenis
2152b725ae77Skettenis if (pi->tid != 0)
2153b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
2154b725ae77Skettenis
2155b725ae77Skettenis #ifdef NEW_PROC_API
2156b725ae77Skettenis if (!pi->status_valid)
2157b725ae77Skettenis if (!proc_get_status (pi))
2158b725ae77Skettenis return NULL;
2159b725ae77Skettenis
2160b725ae77Skettenis ret = &pi->prstatus.pr_sigtrace;
2161b725ae77Skettenis #else
2162b725ae77Skettenis {
2163b725ae77Skettenis static gdb_sigset_t sigtrace;
2164b725ae77Skettenis
2165b725ae77Skettenis if (ioctl (pi->ctl_fd, PIOCGTRACE, &sigtrace) >= 0)
2166b725ae77Skettenis ret = &sigtrace;
2167b725ae77Skettenis }
2168b725ae77Skettenis #endif
2169b725ae77Skettenis if (save && ret)
2170b725ae77Skettenis memcpy (save, ret, sizeof (gdb_sigset_t));
2171b725ae77Skettenis
2172b725ae77Skettenis return ret;
2173b725ae77Skettenis }
2174b725ae77Skettenis
2175b725ae77Skettenis /*
2176b725ae77Skettenis * Function: proc_trace_signal
2177b725ae77Skettenis *
2178b725ae77Skettenis * Add 'signo' to the set of signals that are traced.
2179b725ae77Skettenis * Returns non-zero for success, zero for failure.
2180b725ae77Skettenis */
2181b725ae77Skettenis
2182b725ae77Skettenis int
proc_trace_signal(procinfo * pi,int signo)2183b725ae77Skettenis proc_trace_signal (procinfo *pi, int signo)
2184b725ae77Skettenis {
2185b725ae77Skettenis gdb_sigset_t temp;
2186b725ae77Skettenis
2187b725ae77Skettenis /*
2188b725ae77Skettenis * We should never have to apply this operation to any procinfo
2189b725ae77Skettenis * except the one for the main process. If that ever changes
2190b725ae77Skettenis * for any reason, then take out the following clause and
2191b725ae77Skettenis * replace it with one that makes sure the ctl_fd is open.
2192b725ae77Skettenis */
2193b725ae77Skettenis
2194b725ae77Skettenis if (pi->tid != 0)
2195b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
2196b725ae77Skettenis
2197b725ae77Skettenis if (pi)
2198b725ae77Skettenis {
2199b725ae77Skettenis if (proc_get_traced_signals (pi, &temp))
2200b725ae77Skettenis {
2201b725ae77Skettenis praddset (&temp, signo);
2202b725ae77Skettenis return proc_set_traced_signals (pi, &temp);
2203b725ae77Skettenis }
2204b725ae77Skettenis }
2205b725ae77Skettenis
2206b725ae77Skettenis return 0; /* failure */
2207b725ae77Skettenis }
2208b725ae77Skettenis
2209b725ae77Skettenis /*
2210b725ae77Skettenis * Function: proc_ignore_signal
2211b725ae77Skettenis *
2212b725ae77Skettenis * Remove 'signo' from the set of signals that are traced.
2213b725ae77Skettenis * Returns non-zero for success, zero for failure.
2214b725ae77Skettenis */
2215b725ae77Skettenis
2216b725ae77Skettenis int
proc_ignore_signal(procinfo * pi,int signo)2217b725ae77Skettenis proc_ignore_signal (procinfo *pi, int signo)
2218b725ae77Skettenis {
2219b725ae77Skettenis gdb_sigset_t temp;
2220b725ae77Skettenis
2221b725ae77Skettenis /*
2222b725ae77Skettenis * We should never have to apply this operation to any procinfo
2223b725ae77Skettenis * except the one for the main process. If that ever changes
2224b725ae77Skettenis * for any reason, then take out the following clause and
2225b725ae77Skettenis * replace it with one that makes sure the ctl_fd is open.
2226b725ae77Skettenis */
2227b725ae77Skettenis
2228b725ae77Skettenis if (pi->tid != 0)
2229b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
2230b725ae77Skettenis
2231b725ae77Skettenis if (pi)
2232b725ae77Skettenis {
2233b725ae77Skettenis if (proc_get_traced_signals (pi, &temp))
2234b725ae77Skettenis {
2235b725ae77Skettenis prdelset (&temp, signo);
2236b725ae77Skettenis return proc_set_traced_signals (pi, &temp);
2237b725ae77Skettenis }
2238b725ae77Skettenis }
2239b725ae77Skettenis
2240b725ae77Skettenis return 0; /* failure */
2241b725ae77Skettenis }
2242b725ae77Skettenis
2243b725ae77Skettenis /*
2244b725ae77Skettenis * Function: proc_get_traced_faults
2245b725ae77Skettenis *
2246b725ae77Skettenis * returns the set of hardware faults that are traced /debugged.
2247b725ae77Skettenis * Will also copy the faultset if 'save' is non-zero.
2248b725ae77Skettenis */
2249b725ae77Skettenis
2250b725ae77Skettenis fltset_t *
proc_get_traced_faults(procinfo * pi,fltset_t * save)2251b725ae77Skettenis proc_get_traced_faults (procinfo *pi, fltset_t *save)
2252b725ae77Skettenis {
2253b725ae77Skettenis fltset_t *ret = NULL;
2254b725ae77Skettenis
2255b725ae77Skettenis /*
2256b725ae77Skettenis * We should never have to apply this operation to any procinfo
2257b725ae77Skettenis * except the one for the main process. If that ever changes
2258b725ae77Skettenis * for any reason, then take out the following clause and
2259b725ae77Skettenis * replace it with one that makes sure the ctl_fd is open.
2260b725ae77Skettenis */
2261b725ae77Skettenis
2262b725ae77Skettenis if (pi->tid != 0)
2263b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
2264b725ae77Skettenis
2265b725ae77Skettenis #ifdef NEW_PROC_API
2266b725ae77Skettenis if (!pi->status_valid)
2267b725ae77Skettenis if (!proc_get_status (pi))
2268b725ae77Skettenis return NULL;
2269b725ae77Skettenis
2270b725ae77Skettenis ret = &pi->prstatus.pr_flttrace;
2271b725ae77Skettenis #else
2272b725ae77Skettenis {
2273b725ae77Skettenis static fltset_t flttrace;
2274b725ae77Skettenis
2275b725ae77Skettenis if (ioctl (pi->ctl_fd, PIOCGFAULT, &flttrace) >= 0)
2276b725ae77Skettenis ret = &flttrace;
2277b725ae77Skettenis }
2278b725ae77Skettenis #endif
2279b725ae77Skettenis if (save && ret)
2280b725ae77Skettenis memcpy (save, ret, sizeof (fltset_t));
2281b725ae77Skettenis
2282b725ae77Skettenis return ret;
2283b725ae77Skettenis }
2284b725ae77Skettenis
2285b725ae77Skettenis /*
2286b725ae77Skettenis * Function: proc_get_traced_sysentry
2287b725ae77Skettenis *
2288b725ae77Skettenis * returns the set of syscalls that are traced /debugged on entry.
2289b725ae77Skettenis * Will also copy the syscall set if 'save' is non-zero.
2290b725ae77Skettenis */
2291b725ae77Skettenis
2292b725ae77Skettenis sysset_t *
proc_get_traced_sysentry(procinfo * pi,sysset_t * save)2293b725ae77Skettenis proc_get_traced_sysentry (procinfo *pi, sysset_t *save)
2294b725ae77Skettenis {
2295b725ae77Skettenis sysset_t *ret = NULL;
2296b725ae77Skettenis
2297b725ae77Skettenis /*
2298b725ae77Skettenis * We should never have to apply this operation to any procinfo
2299b725ae77Skettenis * except the one for the main process. If that ever changes
2300b725ae77Skettenis * for any reason, then take out the following clause and
2301b725ae77Skettenis * replace it with one that makes sure the ctl_fd is open.
2302b725ae77Skettenis */
2303b725ae77Skettenis
2304b725ae77Skettenis if (pi->tid != 0)
2305b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
2306b725ae77Skettenis
2307b725ae77Skettenis #ifdef NEW_PROC_API
2308b725ae77Skettenis if (!pi->status_valid)
2309b725ae77Skettenis if (!proc_get_status (pi))
2310b725ae77Skettenis return NULL;
2311b725ae77Skettenis
2312b725ae77Skettenis #ifndef DYNAMIC_SYSCALLS
2313b725ae77Skettenis ret = &pi->prstatus.pr_sysentry;
2314b725ae77Skettenis #else /* DYNAMIC_SYSCALLS */
2315b725ae77Skettenis {
2316b725ae77Skettenis static sysset_t *sysentry;
2317b725ae77Skettenis size_t size;
2318b725ae77Skettenis
2319b725ae77Skettenis if (!sysentry)
2320b725ae77Skettenis sysentry = sysset_t_alloc (pi);
2321b725ae77Skettenis ret = sysentry;
2322b725ae77Skettenis if (pi->status_fd == 0 && open_procinfo_files (pi, FD_STATUS) == 0)
2323b725ae77Skettenis return NULL;
2324b725ae77Skettenis if (pi->prstatus.pr_sysentry_offset == 0)
2325b725ae77Skettenis {
2326b725ae77Skettenis gdb_premptysysset (sysentry);
2327b725ae77Skettenis }
2328b725ae77Skettenis else
2329b725ae77Skettenis {
2330b725ae77Skettenis int rsize;
2331b725ae77Skettenis
2332b725ae77Skettenis if (lseek (pi->status_fd, (off_t) pi->prstatus.pr_sysentry_offset,
2333b725ae77Skettenis SEEK_SET)
2334b725ae77Skettenis != (off_t) pi->prstatus.pr_sysentry_offset)
2335b725ae77Skettenis return NULL;
2336b725ae77Skettenis size = sysset_t_size (pi);
2337b725ae77Skettenis gdb_premptysysset (sysentry);
2338b725ae77Skettenis rsize = read (pi->status_fd, sysentry, size);
2339b725ae77Skettenis if (rsize < 0)
2340b725ae77Skettenis return NULL;
2341b725ae77Skettenis }
2342b725ae77Skettenis }
2343b725ae77Skettenis #endif /* DYNAMIC_SYSCALLS */
2344b725ae77Skettenis #else /* !NEW_PROC_API */
2345b725ae77Skettenis {
2346b725ae77Skettenis static sysset_t sysentry;
2347b725ae77Skettenis
2348b725ae77Skettenis if (ioctl (pi->ctl_fd, PIOCGENTRY, &sysentry) >= 0)
2349b725ae77Skettenis ret = &sysentry;
2350b725ae77Skettenis }
2351b725ae77Skettenis #endif /* NEW_PROC_API */
2352b725ae77Skettenis if (save && ret)
2353b725ae77Skettenis memcpy (save, ret, sysset_t_size (pi));
2354b725ae77Skettenis
2355b725ae77Skettenis return ret;
2356b725ae77Skettenis }
2357b725ae77Skettenis
2358b725ae77Skettenis /*
2359b725ae77Skettenis * Function: proc_get_traced_sysexit
2360b725ae77Skettenis *
2361b725ae77Skettenis * returns the set of syscalls that are traced /debugged on exit.
2362b725ae77Skettenis * Will also copy the syscall set if 'save' is non-zero.
2363b725ae77Skettenis */
2364b725ae77Skettenis
2365b725ae77Skettenis sysset_t *
proc_get_traced_sysexit(procinfo * pi,sysset_t * save)2366b725ae77Skettenis proc_get_traced_sysexit (procinfo *pi, sysset_t *save)
2367b725ae77Skettenis {
2368b725ae77Skettenis sysset_t * ret = NULL;
2369b725ae77Skettenis
2370b725ae77Skettenis /*
2371b725ae77Skettenis * We should never have to apply this operation to any procinfo
2372b725ae77Skettenis * except the one for the main process. If that ever changes
2373b725ae77Skettenis * for any reason, then take out the following clause and
2374b725ae77Skettenis * replace it with one that makes sure the ctl_fd is open.
2375b725ae77Skettenis */
2376b725ae77Skettenis
2377b725ae77Skettenis if (pi->tid != 0)
2378b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
2379b725ae77Skettenis
2380b725ae77Skettenis #ifdef NEW_PROC_API
2381b725ae77Skettenis if (!pi->status_valid)
2382b725ae77Skettenis if (!proc_get_status (pi))
2383b725ae77Skettenis return NULL;
2384b725ae77Skettenis
2385b725ae77Skettenis #ifndef DYNAMIC_SYSCALLS
2386b725ae77Skettenis ret = &pi->prstatus.pr_sysexit;
2387b725ae77Skettenis #else /* DYNAMIC_SYSCALLS */
2388b725ae77Skettenis {
2389b725ae77Skettenis static sysset_t *sysexit;
2390b725ae77Skettenis size_t size;
2391b725ae77Skettenis
2392b725ae77Skettenis if (!sysexit)
2393b725ae77Skettenis sysexit = sysset_t_alloc (pi);
2394b725ae77Skettenis ret = sysexit;
2395b725ae77Skettenis if (pi->status_fd == 0 && open_procinfo_files (pi, FD_STATUS) == 0)
2396b725ae77Skettenis return NULL;
2397b725ae77Skettenis if (pi->prstatus.pr_sysexit_offset == 0)
2398b725ae77Skettenis {
2399b725ae77Skettenis gdb_premptysysset (sysexit);
2400b725ae77Skettenis }
2401b725ae77Skettenis else
2402b725ae77Skettenis {
2403b725ae77Skettenis int rsize;
2404b725ae77Skettenis
2405b725ae77Skettenis if (lseek (pi->status_fd, (off_t) pi->prstatus.pr_sysexit_offset, SEEK_SET)
2406b725ae77Skettenis != (off_t) pi->prstatus.pr_sysexit_offset)
2407b725ae77Skettenis return NULL;
2408b725ae77Skettenis size = sysset_t_size (pi);
2409b725ae77Skettenis gdb_premptysysset (sysexit);
2410b725ae77Skettenis rsize = read (pi->status_fd, sysexit, size);
2411b725ae77Skettenis if (rsize < 0)
2412b725ae77Skettenis return NULL;
2413b725ae77Skettenis }
2414b725ae77Skettenis }
2415b725ae77Skettenis #endif /* DYNAMIC_SYSCALLS */
2416b725ae77Skettenis #else
2417b725ae77Skettenis {
2418b725ae77Skettenis static sysset_t sysexit;
2419b725ae77Skettenis
2420b725ae77Skettenis if (ioctl (pi->ctl_fd, PIOCGEXIT, &sysexit) >= 0)
2421b725ae77Skettenis ret = &sysexit;
2422b725ae77Skettenis }
2423b725ae77Skettenis #endif
2424b725ae77Skettenis if (save && ret)
2425b725ae77Skettenis memcpy (save, ret, sysset_t_size (pi));
2426b725ae77Skettenis
2427b725ae77Skettenis return ret;
2428b725ae77Skettenis }
2429b725ae77Skettenis
2430b725ae77Skettenis /*
2431b725ae77Skettenis * Function: proc_clear_current_fault
2432b725ae77Skettenis *
2433b725ae77Skettenis * The current fault (if any) is cleared; the associated signal
2434b725ae77Skettenis * will not be sent to the process or LWP when it resumes.
2435b725ae77Skettenis * Returns non-zero for success, zero for failure.
2436b725ae77Skettenis */
2437b725ae77Skettenis
2438b725ae77Skettenis int
proc_clear_current_fault(procinfo * pi)2439b725ae77Skettenis proc_clear_current_fault (procinfo *pi)
2440b725ae77Skettenis {
2441b725ae77Skettenis int win;
2442b725ae77Skettenis
2443b725ae77Skettenis /*
2444b725ae77Skettenis * We should never have to apply this operation to any procinfo
2445b725ae77Skettenis * except the one for the main process. If that ever changes
2446b725ae77Skettenis * for any reason, then take out the following clause and
2447b725ae77Skettenis * replace it with one that makes sure the ctl_fd is open.
2448b725ae77Skettenis */
2449b725ae77Skettenis
2450b725ae77Skettenis if (pi->tid != 0)
2451b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
2452b725ae77Skettenis
2453b725ae77Skettenis #ifdef NEW_PROC_API
2454b725ae77Skettenis {
2455b725ae77Skettenis procfs_ctl_t cmd = PCCFAULT;
2456b725ae77Skettenis win = (write (pi->ctl_fd, (void *) &cmd, sizeof (cmd)) == sizeof (cmd));
2457b725ae77Skettenis }
2458b725ae77Skettenis #else
2459b725ae77Skettenis win = (ioctl (pi->ctl_fd, PIOCCFAULT, 0) >= 0);
2460b725ae77Skettenis #endif
2461b725ae77Skettenis
2462b725ae77Skettenis return win;
2463b725ae77Skettenis }
2464b725ae77Skettenis
2465b725ae77Skettenis /*
2466b725ae77Skettenis * Function: proc_set_current_signal
2467b725ae77Skettenis *
2468b725ae77Skettenis * Set the "current signal" that will be delivered next to the process.
2469b725ae77Skettenis * NOTE: semantics are different from those of KILL.
2470b725ae77Skettenis * This signal will be delivered to the process or LWP
2471b725ae77Skettenis * immediately when it is resumed (even if the signal is held/blocked);
2472b725ae77Skettenis * it will NOT immediately cause another event of interest, and will NOT
2473b725ae77Skettenis * first trap back to the debugger.
2474b725ae77Skettenis *
2475b725ae77Skettenis * Returns non-zero for success, zero for failure.
2476b725ae77Skettenis */
2477b725ae77Skettenis
2478b725ae77Skettenis int
proc_set_current_signal(procinfo * pi,int signo)2479b725ae77Skettenis proc_set_current_signal (procinfo *pi, int signo)
2480b725ae77Skettenis {
2481b725ae77Skettenis int win;
2482b725ae77Skettenis struct {
2483b725ae77Skettenis procfs_ctl_t cmd;
2484b725ae77Skettenis /* Use char array to avoid alignment issues. */
2485b725ae77Skettenis char sinfo[sizeof (gdb_siginfo_t)];
2486b725ae77Skettenis } arg;
2487b725ae77Skettenis gdb_siginfo_t *mysinfo;
2488b725ae77Skettenis
2489b725ae77Skettenis /*
2490b725ae77Skettenis * We should never have to apply this operation to any procinfo
2491b725ae77Skettenis * except the one for the main process. If that ever changes
2492b725ae77Skettenis * for any reason, then take out the following clause and
2493b725ae77Skettenis * replace it with one that makes sure the ctl_fd is open.
2494b725ae77Skettenis */
2495b725ae77Skettenis
2496b725ae77Skettenis if (pi->tid != 0)
2497b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
2498b725ae77Skettenis
2499b725ae77Skettenis #ifdef PROCFS_DONT_PIOCSSIG_CURSIG
2500b725ae77Skettenis /* With Alpha OSF/1 procfs, the kernel gets really confused if it
2501b725ae77Skettenis * receives a PIOCSSIG with a signal identical to the current signal,
2502b725ae77Skettenis * it messes up the current signal. Work around the kernel bug.
2503b725ae77Skettenis */
2504b725ae77Skettenis if (signo > 0 &&
2505b725ae77Skettenis signo == proc_cursig (pi))
2506b725ae77Skettenis return 1; /* I assume this is a success? */
2507b725ae77Skettenis #endif
2508b725ae77Skettenis
2509b725ae77Skettenis /* The pointer is just a type alias. */
2510b725ae77Skettenis mysinfo = (gdb_siginfo_t *) &arg.sinfo;
2511b725ae77Skettenis mysinfo->si_signo = signo;
2512b725ae77Skettenis mysinfo->si_code = 0;
2513b725ae77Skettenis mysinfo->si_pid = getpid (); /* ?why? */
2514b725ae77Skettenis mysinfo->si_uid = getuid (); /* ?why? */
2515b725ae77Skettenis
2516b725ae77Skettenis #ifdef NEW_PROC_API
2517b725ae77Skettenis arg.cmd = PCSSIG;
2518b725ae77Skettenis win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg));
2519b725ae77Skettenis #else
2520b725ae77Skettenis win = (ioctl (pi->ctl_fd, PIOCSSIG, (void *) &arg.sinfo) >= 0);
2521b725ae77Skettenis #endif
2522b725ae77Skettenis
2523b725ae77Skettenis return win;
2524b725ae77Skettenis }
2525b725ae77Skettenis
2526b725ae77Skettenis /*
2527b725ae77Skettenis * Function: proc_clear_current_signal
2528b725ae77Skettenis *
2529b725ae77Skettenis * The current signal (if any) is cleared, and
2530b725ae77Skettenis * is not sent to the process or LWP when it resumes.
2531b725ae77Skettenis * Returns non-zero for success, zero for failure.
2532b725ae77Skettenis */
2533b725ae77Skettenis
2534b725ae77Skettenis int
proc_clear_current_signal(procinfo * pi)2535b725ae77Skettenis proc_clear_current_signal (procinfo *pi)
2536b725ae77Skettenis {
2537b725ae77Skettenis int win;
2538b725ae77Skettenis
2539b725ae77Skettenis /*
2540b725ae77Skettenis * We should never have to apply this operation to any procinfo
2541b725ae77Skettenis * except the one for the main process. If that ever changes
2542b725ae77Skettenis * for any reason, then take out the following clause and
2543b725ae77Skettenis * replace it with one that makes sure the ctl_fd is open.
2544b725ae77Skettenis */
2545b725ae77Skettenis
2546b725ae77Skettenis if (pi->tid != 0)
2547b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
2548b725ae77Skettenis
2549b725ae77Skettenis #ifdef NEW_PROC_API
2550b725ae77Skettenis {
2551b725ae77Skettenis struct {
2552b725ae77Skettenis procfs_ctl_t cmd;
2553b725ae77Skettenis /* Use char array to avoid alignment issues. */
2554b725ae77Skettenis char sinfo[sizeof (gdb_siginfo_t)];
2555b725ae77Skettenis } arg;
2556b725ae77Skettenis gdb_siginfo_t *mysinfo;
2557b725ae77Skettenis
2558b725ae77Skettenis arg.cmd = PCSSIG;
2559b725ae77Skettenis /* The pointer is just a type alias. */
2560b725ae77Skettenis mysinfo = (gdb_siginfo_t *) &arg.sinfo;
2561b725ae77Skettenis mysinfo->si_signo = 0;
2562b725ae77Skettenis mysinfo->si_code = 0;
2563b725ae77Skettenis mysinfo->si_errno = 0;
2564b725ae77Skettenis mysinfo->si_pid = getpid (); /* ?why? */
2565b725ae77Skettenis mysinfo->si_uid = getuid (); /* ?why? */
2566b725ae77Skettenis
2567b725ae77Skettenis win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg));
2568b725ae77Skettenis }
2569b725ae77Skettenis #else
2570b725ae77Skettenis win = (ioctl (pi->ctl_fd, PIOCSSIG, 0) >= 0);
2571b725ae77Skettenis #endif
2572b725ae77Skettenis
2573b725ae77Skettenis return win;
2574b725ae77Skettenis }
2575b725ae77Skettenis
2576b725ae77Skettenis /*
2577b725ae77Skettenis * Function: proc_get_gregs
2578b725ae77Skettenis *
2579b725ae77Skettenis * Get the general registers for the process or LWP.
2580b725ae77Skettenis * Returns non-zero for success, zero for failure.
2581b725ae77Skettenis */
2582b725ae77Skettenis
2583b725ae77Skettenis gdb_gregset_t *
proc_get_gregs(procinfo * pi)2584b725ae77Skettenis proc_get_gregs (procinfo *pi)
2585b725ae77Skettenis {
2586b725ae77Skettenis if (!pi->status_valid || !pi->gregs_valid)
2587b725ae77Skettenis if (!proc_get_status (pi))
2588b725ae77Skettenis return NULL;
2589b725ae77Skettenis
2590b725ae77Skettenis /*
2591b725ae77Skettenis * OK, sorry about the ifdef's.
2592b725ae77Skettenis * There's three cases instead of two, because
2593b725ae77Skettenis * in this instance Unixware and Solaris/RW differ.
2594b725ae77Skettenis */
2595b725ae77Skettenis
2596b725ae77Skettenis #ifdef NEW_PROC_API
2597b725ae77Skettenis #ifdef UNIXWARE /* ugh, a true architecture dependency */
2598b725ae77Skettenis return &pi->prstatus.pr_lwp.pr_context.uc_mcontext.gregs;
2599b725ae77Skettenis #else /* not Unixware */
2600b725ae77Skettenis return &pi->prstatus.pr_lwp.pr_reg;
2601b725ae77Skettenis #endif /* Unixware */
2602b725ae77Skettenis #else /* not NEW_PROC_API */
2603b725ae77Skettenis return &pi->prstatus.pr_reg;
2604b725ae77Skettenis #endif /* NEW_PROC_API */
2605b725ae77Skettenis }
2606b725ae77Skettenis
2607b725ae77Skettenis /*
2608b725ae77Skettenis * Function: proc_get_fpregs
2609b725ae77Skettenis *
2610b725ae77Skettenis * Get the floating point registers for the process or LWP.
2611b725ae77Skettenis * Returns non-zero for success, zero for failure.
2612b725ae77Skettenis */
2613b725ae77Skettenis
2614b725ae77Skettenis gdb_fpregset_t *
proc_get_fpregs(procinfo * pi)2615b725ae77Skettenis proc_get_fpregs (procinfo *pi)
2616b725ae77Skettenis {
2617b725ae77Skettenis #ifdef NEW_PROC_API
2618b725ae77Skettenis if (!pi->status_valid || !pi->fpregs_valid)
2619b725ae77Skettenis if (!proc_get_status (pi))
2620b725ae77Skettenis return NULL;
2621b725ae77Skettenis
2622b725ae77Skettenis #ifdef UNIXWARE /* a true architecture dependency */
2623b725ae77Skettenis return &pi->prstatus.pr_lwp.pr_context.uc_mcontext.fpregs;
2624b725ae77Skettenis #else
2625b725ae77Skettenis return &pi->prstatus.pr_lwp.pr_fpreg;
2626b725ae77Skettenis #endif /* Unixware */
2627b725ae77Skettenis
2628b725ae77Skettenis #else /* not NEW_PROC_API */
2629b725ae77Skettenis if (pi->fpregs_valid)
2630b725ae77Skettenis return &pi->fpregset; /* already got 'em */
2631b725ae77Skettenis else
2632b725ae77Skettenis {
2633b725ae77Skettenis if (pi->ctl_fd == 0 &&
2634b725ae77Skettenis open_procinfo_files (pi, FD_CTL) == 0)
2635b725ae77Skettenis {
2636b725ae77Skettenis return NULL;
2637b725ae77Skettenis }
2638b725ae77Skettenis else
2639b725ae77Skettenis {
2640b725ae77Skettenis #ifdef PIOCTGFPREG
2641b725ae77Skettenis struct {
2642b725ae77Skettenis long pr_count;
2643b725ae77Skettenis tid_t pr_error_thread;
2644b725ae77Skettenis tfpregset_t thread_1;
2645b725ae77Skettenis } thread_fpregs;
2646b725ae77Skettenis
2647b725ae77Skettenis thread_fpregs.pr_count = 1;
2648b725ae77Skettenis thread_fpregs.thread_1.tid = pi->tid;
2649b725ae77Skettenis
2650b725ae77Skettenis if (pi->tid == 0 &&
2651b725ae77Skettenis ioctl (pi->ctl_fd, PIOCGFPREG, &pi->fpregset) >= 0)
2652b725ae77Skettenis {
2653b725ae77Skettenis pi->fpregs_valid = 1;
2654b725ae77Skettenis return &pi->fpregset; /* got 'em now! */
2655b725ae77Skettenis }
2656b725ae77Skettenis else if (pi->tid != 0 &&
2657b725ae77Skettenis ioctl (pi->ctl_fd, PIOCTGFPREG, &thread_fpregs) >= 0)
2658b725ae77Skettenis {
2659b725ae77Skettenis memcpy (&pi->fpregset, &thread_fpregs.thread_1.pr_fpregs,
2660b725ae77Skettenis sizeof (pi->fpregset));
2661b725ae77Skettenis pi->fpregs_valid = 1;
2662b725ae77Skettenis return &pi->fpregset; /* got 'em now! */
2663b725ae77Skettenis }
2664b725ae77Skettenis else
2665b725ae77Skettenis {
2666b725ae77Skettenis return NULL;
2667b725ae77Skettenis }
2668b725ae77Skettenis #else
2669b725ae77Skettenis if (ioctl (pi->ctl_fd, PIOCGFPREG, &pi->fpregset) >= 0)
2670b725ae77Skettenis {
2671b725ae77Skettenis pi->fpregs_valid = 1;
2672b725ae77Skettenis return &pi->fpregset; /* got 'em now! */
2673b725ae77Skettenis }
2674b725ae77Skettenis else
2675b725ae77Skettenis {
2676b725ae77Skettenis return NULL;
2677b725ae77Skettenis }
2678b725ae77Skettenis #endif
2679b725ae77Skettenis }
2680b725ae77Skettenis }
2681b725ae77Skettenis #endif
2682b725ae77Skettenis }
2683b725ae77Skettenis
2684b725ae77Skettenis /*
2685b725ae77Skettenis * Function: proc_set_gregs
2686b725ae77Skettenis *
2687b725ae77Skettenis * Write the general registers back to the process or LWP.
2688b725ae77Skettenis * Returns non-zero for success, zero for failure.
2689b725ae77Skettenis */
2690b725ae77Skettenis
2691b725ae77Skettenis int
proc_set_gregs(procinfo * pi)2692b725ae77Skettenis proc_set_gregs (procinfo *pi)
2693b725ae77Skettenis {
2694b725ae77Skettenis gdb_gregset_t *gregs;
2695b725ae77Skettenis int win;
2696b725ae77Skettenis
2697b725ae77Skettenis if ((gregs = proc_get_gregs (pi)) == NULL)
2698b725ae77Skettenis return 0; /* get_regs has already warned */
2699b725ae77Skettenis
2700b725ae77Skettenis if (pi->ctl_fd == 0 &&
2701b725ae77Skettenis open_procinfo_files (pi, FD_CTL) == 0)
2702b725ae77Skettenis {
2703b725ae77Skettenis return 0;
2704b725ae77Skettenis }
2705b725ae77Skettenis else
2706b725ae77Skettenis {
2707b725ae77Skettenis #ifdef NEW_PROC_API
2708b725ae77Skettenis struct {
2709b725ae77Skettenis procfs_ctl_t cmd;
2710b725ae77Skettenis /* Use char array to avoid alignment issues. */
2711b725ae77Skettenis char gregs[sizeof (gdb_gregset_t)];
2712b725ae77Skettenis } arg;
2713b725ae77Skettenis
2714b725ae77Skettenis arg.cmd = PCSREG;
2715b725ae77Skettenis memcpy (&arg.gregs, gregs, sizeof (arg.gregs));
2716b725ae77Skettenis win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg));
2717b725ae77Skettenis #else
2718b725ae77Skettenis win = (ioctl (pi->ctl_fd, PIOCSREG, gregs) >= 0);
2719b725ae77Skettenis #endif
2720b725ae77Skettenis }
2721b725ae77Skettenis
2722b725ae77Skettenis /* Policy: writing the regs invalidates our cache. */
2723b725ae77Skettenis pi->gregs_valid = 0;
2724b725ae77Skettenis return win;
2725b725ae77Skettenis }
2726b725ae77Skettenis
2727b725ae77Skettenis /*
2728b725ae77Skettenis * Function: proc_set_fpregs
2729b725ae77Skettenis *
2730b725ae77Skettenis * Modify the floating point register set of the process or LWP.
2731b725ae77Skettenis * Returns non-zero for success, zero for failure.
2732b725ae77Skettenis */
2733b725ae77Skettenis
2734b725ae77Skettenis int
proc_set_fpregs(procinfo * pi)2735b725ae77Skettenis proc_set_fpregs (procinfo *pi)
2736b725ae77Skettenis {
2737b725ae77Skettenis gdb_fpregset_t *fpregs;
2738b725ae77Skettenis int win;
2739b725ae77Skettenis
2740b725ae77Skettenis if ((fpregs = proc_get_fpregs (pi)) == NULL)
2741b725ae77Skettenis return 0; /* get_fpregs has already warned */
2742b725ae77Skettenis
2743b725ae77Skettenis if (pi->ctl_fd == 0 &&
2744b725ae77Skettenis open_procinfo_files (pi, FD_CTL) == 0)
2745b725ae77Skettenis {
2746b725ae77Skettenis return 0;
2747b725ae77Skettenis }
2748b725ae77Skettenis else
2749b725ae77Skettenis {
2750b725ae77Skettenis #ifdef NEW_PROC_API
2751b725ae77Skettenis struct {
2752b725ae77Skettenis procfs_ctl_t cmd;
2753b725ae77Skettenis /* Use char array to avoid alignment issues. */
2754b725ae77Skettenis char fpregs[sizeof (gdb_fpregset_t)];
2755b725ae77Skettenis } arg;
2756b725ae77Skettenis
2757b725ae77Skettenis arg.cmd = PCSFPREG;
2758b725ae77Skettenis memcpy (&arg.fpregs, fpregs, sizeof (arg.fpregs));
2759b725ae77Skettenis win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg));
2760b725ae77Skettenis #else
2761b725ae77Skettenis #ifdef PIOCTSFPREG
2762b725ae77Skettenis if (pi->tid == 0)
2763b725ae77Skettenis win = (ioctl (pi->ctl_fd, PIOCSFPREG, fpregs) >= 0);
2764b725ae77Skettenis else
2765b725ae77Skettenis {
2766b725ae77Skettenis struct {
2767b725ae77Skettenis long pr_count;
2768b725ae77Skettenis tid_t pr_error_thread;
2769b725ae77Skettenis tfpregset_t thread_1;
2770b725ae77Skettenis } thread_fpregs;
2771b725ae77Skettenis
2772b725ae77Skettenis thread_fpregs.pr_count = 1;
2773b725ae77Skettenis thread_fpregs.thread_1.tid = pi->tid;
2774b725ae77Skettenis memcpy (&thread_fpregs.thread_1.pr_fpregs, fpregs,
2775b725ae77Skettenis sizeof (*fpregs));
2776b725ae77Skettenis win = (ioctl (pi->ctl_fd, PIOCTSFPREG, &thread_fpregs) >= 0);
2777b725ae77Skettenis }
2778b725ae77Skettenis #else
2779b725ae77Skettenis win = (ioctl (pi->ctl_fd, PIOCSFPREG, fpregs) >= 0);
2780b725ae77Skettenis #endif /* osf PIOCTSFPREG */
2781b725ae77Skettenis #endif /* NEW_PROC_API */
2782b725ae77Skettenis }
2783b725ae77Skettenis
2784b725ae77Skettenis /* Policy: writing the regs invalidates our cache. */
2785b725ae77Skettenis pi->fpregs_valid = 0;
2786b725ae77Skettenis return win;
2787b725ae77Skettenis }
2788b725ae77Skettenis
2789b725ae77Skettenis /*
2790b725ae77Skettenis * Function: proc_kill
2791b725ae77Skettenis *
2792b725ae77Skettenis * Send a signal to the proc or lwp with the semantics of "kill()".
2793b725ae77Skettenis * Returns non-zero for success, zero for failure.
2794b725ae77Skettenis */
2795b725ae77Skettenis
2796b725ae77Skettenis int
proc_kill(procinfo * pi,int signo)2797b725ae77Skettenis proc_kill (procinfo *pi, int signo)
2798b725ae77Skettenis {
2799b725ae77Skettenis int win;
2800b725ae77Skettenis
2801b725ae77Skettenis /*
2802b725ae77Skettenis * We might conceivably apply this operation to an LWP, and
2803b725ae77Skettenis * the LWP's ctl file descriptor might not be open.
2804b725ae77Skettenis */
2805b725ae77Skettenis
2806b725ae77Skettenis if (pi->ctl_fd == 0 &&
2807b725ae77Skettenis open_procinfo_files (pi, FD_CTL) == 0)
2808b725ae77Skettenis {
2809b725ae77Skettenis return 0;
2810b725ae77Skettenis }
2811b725ae77Skettenis else
2812b725ae77Skettenis {
2813b725ae77Skettenis #ifdef NEW_PROC_API
2814b725ae77Skettenis procfs_ctl_t cmd[2];
2815b725ae77Skettenis
2816b725ae77Skettenis cmd[0] = PCKILL;
2817b725ae77Skettenis cmd[1] = signo;
2818b725ae77Skettenis win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd));
2819b725ae77Skettenis #else /* ioctl method */
2820b725ae77Skettenis /* FIXME: do I need the Alpha OSF fixups present in
2821b725ae77Skettenis procfs.c/unconditionally_kill_inferior? Perhaps only for SIGKILL? */
2822b725ae77Skettenis win = (ioctl (pi->ctl_fd, PIOCKILL, &signo) >= 0);
2823b725ae77Skettenis #endif
2824b725ae77Skettenis }
2825b725ae77Skettenis
2826b725ae77Skettenis return win;
2827b725ae77Skettenis }
2828b725ae77Skettenis
2829b725ae77Skettenis /*
2830b725ae77Skettenis * Function: proc_parent_pid
2831b725ae77Skettenis *
2832b725ae77Skettenis * Find the pid of the process that started this one.
2833b725ae77Skettenis * Returns the parent process pid, or zero.
2834b725ae77Skettenis */
2835b725ae77Skettenis
2836b725ae77Skettenis int
proc_parent_pid(procinfo * pi)2837b725ae77Skettenis proc_parent_pid (procinfo *pi)
2838b725ae77Skettenis {
2839b725ae77Skettenis /*
2840b725ae77Skettenis * We should never have to apply this operation to any procinfo
2841b725ae77Skettenis * except the one for the main process. If that ever changes
2842b725ae77Skettenis * for any reason, then take out the following clause and
2843b725ae77Skettenis * replace it with one that makes sure the ctl_fd is open.
2844b725ae77Skettenis */
2845b725ae77Skettenis
2846b725ae77Skettenis if (pi->tid != 0)
2847b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
2848b725ae77Skettenis
2849b725ae77Skettenis if (!pi->status_valid)
2850b725ae77Skettenis if (!proc_get_status (pi))
2851b725ae77Skettenis return 0;
2852b725ae77Skettenis
2853b725ae77Skettenis return pi->prstatus.pr_ppid;
2854b725ae77Skettenis }
2855b725ae77Skettenis
2856b725ae77Skettenis
2857b725ae77Skettenis /* Convert a target address (a.k.a. CORE_ADDR) into a host address
2858b725ae77Skettenis (a.k.a void pointer)! */
2859b725ae77Skettenis
2860b725ae77Skettenis static void *
procfs_address_to_host_pointer(CORE_ADDR addr)2861b725ae77Skettenis procfs_address_to_host_pointer (CORE_ADDR addr)
2862b725ae77Skettenis {
2863b725ae77Skettenis void *ptr;
2864b725ae77Skettenis
2865b725ae77Skettenis gdb_assert (sizeof (ptr) == TYPE_LENGTH (builtin_type_void_data_ptr));
2866b725ae77Skettenis ADDRESS_TO_POINTER (builtin_type_void_data_ptr, &ptr, addr);
2867b725ae77Skettenis return ptr;
2868b725ae77Skettenis }
2869b725ae77Skettenis
2870b725ae77Skettenis /*
2871b725ae77Skettenis * Function: proc_set_watchpoint
2872b725ae77Skettenis *
2873b725ae77Skettenis */
2874b725ae77Skettenis
2875b725ae77Skettenis int
proc_set_watchpoint(procinfo * pi,CORE_ADDR addr,int len,int wflags)2876b725ae77Skettenis proc_set_watchpoint (procinfo *pi, CORE_ADDR addr, int len, int wflags)
2877b725ae77Skettenis {
2878b725ae77Skettenis #if !defined (TARGET_HAS_HARDWARE_WATCHPOINTS)
2879b725ae77Skettenis return 0;
2880b725ae77Skettenis #else
2881b725ae77Skettenis /* Horrible hack! Detect Solaris 2.5, because this doesn't work on 2.5 */
2882b725ae77Skettenis #if defined (PIOCOPENLWP) || defined (UNIXWARE) /* Solaris 2.5: bail out */
2883b725ae77Skettenis return 0;
2884b725ae77Skettenis #else
2885b725ae77Skettenis struct {
2886b725ae77Skettenis procfs_ctl_t cmd;
2887b725ae77Skettenis char watch[sizeof (prwatch_t)];
2888b725ae77Skettenis } arg;
2889b725ae77Skettenis prwatch_t *pwatch;
2890b725ae77Skettenis
2891b725ae77Skettenis pwatch = (prwatch_t *) &arg.watch;
2892b725ae77Skettenis /* NOTE: cagney/2003-02-01: Even more horrible hack. Need to
2893b725ae77Skettenis convert a target address into something that can be stored in a
2894b725ae77Skettenis native data structure. */
2895b725ae77Skettenis #ifdef PCAGENT /* Horrible hack: only defined on Solaris 2.6+ */
2896b725ae77Skettenis pwatch->pr_vaddr = (uintptr_t) procfs_address_to_host_pointer (addr);
2897b725ae77Skettenis #else
2898b725ae77Skettenis pwatch->pr_vaddr = (caddr_t) procfs_address_to_host_pointer (addr);
2899b725ae77Skettenis #endif
2900b725ae77Skettenis pwatch->pr_size = len;
2901b725ae77Skettenis pwatch->pr_wflags = wflags;
2902b725ae77Skettenis #if defined(NEW_PROC_API) && defined (PCWATCH)
2903b725ae77Skettenis arg.cmd = PCWATCH;
2904b725ae77Skettenis return (write (pi->ctl_fd, &arg, sizeof (arg)) == sizeof (arg));
2905b725ae77Skettenis #else
2906b725ae77Skettenis #if defined (PIOCSWATCH)
2907b725ae77Skettenis return (ioctl (pi->ctl_fd, PIOCSWATCH, pwatch) >= 0);
2908b725ae77Skettenis #else
2909b725ae77Skettenis return 0; /* Fail */
2910b725ae77Skettenis #endif
2911b725ae77Skettenis #endif
2912b725ae77Skettenis #endif
2913b725ae77Skettenis #endif
2914b725ae77Skettenis }
2915b725ae77Skettenis
2916b725ae77Skettenis #ifdef TM_I386SOL2_H /* Is it hokey to use this? */
2917b725ae77Skettenis
2918b725ae77Skettenis #include <sys/sysi86.h>
2919b725ae77Skettenis
2920b725ae77Skettenis /*
2921b725ae77Skettenis * Function: proc_get_LDT_entry
2922b725ae77Skettenis *
2923b725ae77Skettenis * Inputs:
2924b725ae77Skettenis * procinfo *pi;
2925b725ae77Skettenis * int key;
2926b725ae77Skettenis *
2927b725ae77Skettenis * The 'key' is actually the value of the lower 16 bits of
2928b725ae77Skettenis * the GS register for the LWP that we're interested in.
2929b725ae77Skettenis *
2930b725ae77Skettenis * Return: matching ssh struct (LDT entry).
2931b725ae77Skettenis */
2932b725ae77Skettenis
2933b725ae77Skettenis struct ssd *
proc_get_LDT_entry(procinfo * pi,int key)2934b725ae77Skettenis proc_get_LDT_entry (procinfo *pi, int key)
2935b725ae77Skettenis {
2936b725ae77Skettenis static struct ssd *ldt_entry = NULL;
2937b725ae77Skettenis #ifdef NEW_PROC_API
2938b725ae77Skettenis char pathname[MAX_PROC_NAME_SIZE];
2939b725ae77Skettenis struct cleanup *old_chain = NULL;
2940b725ae77Skettenis int fd;
2941b725ae77Skettenis
2942b725ae77Skettenis /* Allocate space for one LDT entry.
2943b725ae77Skettenis This alloc must persist, because we return a pointer to it. */
2944b725ae77Skettenis if (ldt_entry == NULL)
2945b725ae77Skettenis ldt_entry = (struct ssd *) xmalloc (sizeof (struct ssd));
2946b725ae77Skettenis
2947b725ae77Skettenis /* Open the file descriptor for the LDT table. */
2948b725ae77Skettenis sprintf (pathname, "/proc/%d/ldt", pi->pid);
2949b725ae77Skettenis if ((fd = open_with_retry (pathname, O_RDONLY)) < 0)
2950b725ae77Skettenis {
2951b725ae77Skettenis proc_warn (pi, "proc_get_LDT_entry (open)", __LINE__);
2952b725ae77Skettenis return NULL;
2953b725ae77Skettenis }
2954b725ae77Skettenis /* Make sure it gets closed again! */
2955b725ae77Skettenis old_chain = make_cleanup_close (fd);
2956b725ae77Skettenis
2957b725ae77Skettenis /* Now 'read' thru the table, find a match and return it. */
2958b725ae77Skettenis while (read (fd, ldt_entry, sizeof (struct ssd)) == sizeof (struct ssd))
2959b725ae77Skettenis {
2960b725ae77Skettenis if (ldt_entry->sel == 0 &&
2961b725ae77Skettenis ldt_entry->bo == 0 &&
2962b725ae77Skettenis ldt_entry->acc1 == 0 &&
2963b725ae77Skettenis ldt_entry->acc2 == 0)
2964b725ae77Skettenis break; /* end of table */
2965b725ae77Skettenis /* If key matches, return this entry. */
2966b725ae77Skettenis if (ldt_entry->sel == key)
2967b725ae77Skettenis return ldt_entry;
2968b725ae77Skettenis }
2969b725ae77Skettenis /* Loop ended, match not found. */
2970b725ae77Skettenis return NULL;
2971b725ae77Skettenis #else
2972b725ae77Skettenis int nldt, i;
2973b725ae77Skettenis static int nalloc = 0;
2974b725ae77Skettenis
2975b725ae77Skettenis /* Get the number of LDT entries. */
2976b725ae77Skettenis if (ioctl (pi->ctl_fd, PIOCNLDT, &nldt) < 0)
2977b725ae77Skettenis {
2978b725ae77Skettenis proc_warn (pi, "proc_get_LDT_entry (PIOCNLDT)", __LINE__);
2979b725ae77Skettenis return NULL;
2980b725ae77Skettenis }
2981b725ae77Skettenis
2982b725ae77Skettenis /* Allocate space for the number of LDT entries. */
2983b725ae77Skettenis /* This alloc has to persist, 'cause we return a pointer to it. */
2984b725ae77Skettenis if (nldt > nalloc)
2985b725ae77Skettenis {
2986b725ae77Skettenis ldt_entry = (struct ssd *)
2987b725ae77Skettenis xrealloc (ldt_entry, (nldt + 1) * sizeof (struct ssd));
2988b725ae77Skettenis nalloc = nldt;
2989b725ae77Skettenis }
2990b725ae77Skettenis
2991b725ae77Skettenis /* Read the whole table in one gulp. */
2992b725ae77Skettenis if (ioctl (pi->ctl_fd, PIOCLDT, ldt_entry) < 0)
2993b725ae77Skettenis {
2994b725ae77Skettenis proc_warn (pi, "proc_get_LDT_entry (PIOCLDT)", __LINE__);
2995b725ae77Skettenis return NULL;
2996b725ae77Skettenis }
2997b725ae77Skettenis
2998b725ae77Skettenis /* Search the table and return the (first) entry matching 'key'. */
2999b725ae77Skettenis for (i = 0; i < nldt; i++)
3000b725ae77Skettenis if (ldt_entry[i].sel == key)
3001b725ae77Skettenis return &ldt_entry[i];
3002b725ae77Skettenis
3003b725ae77Skettenis /* Loop ended, match not found. */
3004b725ae77Skettenis return NULL;
3005b725ae77Skettenis #endif
3006b725ae77Skettenis }
3007b725ae77Skettenis
3008b725ae77Skettenis #endif /* TM_I386SOL2_H */
3009b725ae77Skettenis
3010b725ae77Skettenis /* =============== END, non-thread part of /proc "MODULE" =============== */
3011b725ae77Skettenis
3012b725ae77Skettenis /* =================== Thread "MODULE" =================== */
3013b725ae77Skettenis
3014b725ae77Skettenis /* NOTE: you'll see more ifdefs and duplication of functions here,
3015b725ae77Skettenis since there is a different way to do threads on every OS. */
3016b725ae77Skettenis
3017b725ae77Skettenis /*
3018b725ae77Skettenis * Function: proc_get_nthreads
3019b725ae77Skettenis *
3020b725ae77Skettenis * Return the number of threads for the process
3021b725ae77Skettenis */
3022b725ae77Skettenis
3023b725ae77Skettenis #if defined (PIOCNTHR) && defined (PIOCTLIST)
3024b725ae77Skettenis /*
3025b725ae77Skettenis * OSF version
3026b725ae77Skettenis */
3027b725ae77Skettenis int
proc_get_nthreads(procinfo * pi)3028b725ae77Skettenis proc_get_nthreads (procinfo *pi)
3029b725ae77Skettenis {
3030b725ae77Skettenis int nthreads = 0;
3031b725ae77Skettenis
3032b725ae77Skettenis if (ioctl (pi->ctl_fd, PIOCNTHR, &nthreads) < 0)
3033b725ae77Skettenis proc_warn (pi, "procfs: PIOCNTHR failed", __LINE__);
3034b725ae77Skettenis
3035b725ae77Skettenis return nthreads;
3036b725ae77Skettenis }
3037b725ae77Skettenis
3038b725ae77Skettenis #else
3039b725ae77Skettenis #if defined (SYS_lwpcreate) || defined (SYS_lwp_create) /* FIXME: multiple */
3040b725ae77Skettenis /*
3041b725ae77Skettenis * Solaris and Unixware version
3042b725ae77Skettenis */
3043b725ae77Skettenis int
proc_get_nthreads(procinfo * pi)3044b725ae77Skettenis proc_get_nthreads (procinfo *pi)
3045b725ae77Skettenis {
3046b725ae77Skettenis if (!pi->status_valid)
3047b725ae77Skettenis if (!proc_get_status (pi))
3048b725ae77Skettenis return 0;
3049b725ae77Skettenis
3050b725ae77Skettenis /*
3051b725ae77Skettenis * NEW_PROC_API: only works for the process procinfo,
3052b725ae77Skettenis * because the LWP procinfos do not get prstatus filled in.
3053b725ae77Skettenis */
3054b725ae77Skettenis #ifdef NEW_PROC_API
3055b725ae77Skettenis if (pi->tid != 0) /* find the parent process procinfo */
3056b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
3057b725ae77Skettenis #endif
3058b725ae77Skettenis return pi->prstatus.pr_nlwp;
3059b725ae77Skettenis }
3060b725ae77Skettenis
3061b725ae77Skettenis #else
3062b725ae77Skettenis /*
3063b725ae77Skettenis * Default version
3064b725ae77Skettenis */
3065b725ae77Skettenis int
proc_get_nthreads(procinfo * pi)3066b725ae77Skettenis proc_get_nthreads (procinfo *pi)
3067b725ae77Skettenis {
3068b725ae77Skettenis return 0;
3069b725ae77Skettenis }
3070b725ae77Skettenis #endif
3071b725ae77Skettenis #endif
3072b725ae77Skettenis
3073b725ae77Skettenis /*
3074b725ae77Skettenis * Function: proc_get_current_thread (LWP version)
3075b725ae77Skettenis *
3076b725ae77Skettenis * Return the ID of the thread that had an event of interest.
3077b725ae77Skettenis * (ie. the one that hit a breakpoint or other traced event).
3078b725ae77Skettenis * All other things being equal, this should be the ID of a
3079b725ae77Skettenis * thread that is currently executing.
3080b725ae77Skettenis */
3081b725ae77Skettenis
3082b725ae77Skettenis #if defined (SYS_lwpcreate) || defined (SYS_lwp_create) /* FIXME: multiple */
3083b725ae77Skettenis /*
3084b725ae77Skettenis * Solaris and Unixware version
3085b725ae77Skettenis */
3086b725ae77Skettenis int
proc_get_current_thread(procinfo * pi)3087b725ae77Skettenis proc_get_current_thread (procinfo *pi)
3088b725ae77Skettenis {
3089b725ae77Skettenis /*
3090b725ae77Skettenis * Note: this should be applied to the root procinfo for the process,
3091b725ae77Skettenis * not to the procinfo for an LWP. If applied to the procinfo for
3092b725ae77Skettenis * an LWP, it will simply return that LWP's ID. In that case,
3093b725ae77Skettenis * find the parent process procinfo.
3094b725ae77Skettenis */
3095b725ae77Skettenis
3096b725ae77Skettenis if (pi->tid != 0)
3097b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
3098b725ae77Skettenis
3099b725ae77Skettenis if (!pi->status_valid)
3100b725ae77Skettenis if (!proc_get_status (pi))
3101b725ae77Skettenis return 0;
3102b725ae77Skettenis
3103b725ae77Skettenis #ifdef NEW_PROC_API
3104b725ae77Skettenis return pi->prstatus.pr_lwp.pr_lwpid;
3105b725ae77Skettenis #else
3106b725ae77Skettenis return pi->prstatus.pr_who;
3107b725ae77Skettenis #endif
3108b725ae77Skettenis }
3109b725ae77Skettenis
3110b725ae77Skettenis #else
3111b725ae77Skettenis #if defined (PIOCNTHR) && defined (PIOCTLIST)
3112b725ae77Skettenis /*
3113b725ae77Skettenis * OSF version
3114b725ae77Skettenis */
3115b725ae77Skettenis int
proc_get_current_thread(procinfo * pi)3116b725ae77Skettenis proc_get_current_thread (procinfo *pi)
3117b725ae77Skettenis {
3118b725ae77Skettenis #if 0 /* FIXME: not ready for prime time? */
3119b725ae77Skettenis return pi->prstatus.pr_tid;
3120b725ae77Skettenis #else
3121b725ae77Skettenis return 0;
3122b725ae77Skettenis #endif
3123b725ae77Skettenis }
3124b725ae77Skettenis
3125b725ae77Skettenis #else
3126b725ae77Skettenis /*
3127b725ae77Skettenis * Default version
3128b725ae77Skettenis */
3129b725ae77Skettenis int
proc_get_current_thread(procinfo * pi)3130b725ae77Skettenis proc_get_current_thread (procinfo *pi)
3131b725ae77Skettenis {
3132b725ae77Skettenis return 0;
3133b725ae77Skettenis }
3134b725ae77Skettenis
3135b725ae77Skettenis #endif
3136b725ae77Skettenis #endif
3137b725ae77Skettenis
3138b725ae77Skettenis /*
3139b725ae77Skettenis * Function: proc_update_threads
3140b725ae77Skettenis *
3141b725ae77Skettenis * Discover the IDs of all the threads within the process, and
3142b725ae77Skettenis * create a procinfo for each of them (chained to the parent).
3143b725ae77Skettenis *
3144b725ae77Skettenis * This unfortunately requires a different method on every OS.
3145b725ae77Skettenis *
3146b725ae77Skettenis * Return: non-zero for success, zero for failure.
3147b725ae77Skettenis */
3148b725ae77Skettenis
3149b725ae77Skettenis int
proc_delete_dead_threads(procinfo * parent,procinfo * thread,void * ignore)3150b725ae77Skettenis proc_delete_dead_threads (procinfo *parent, procinfo *thread, void *ignore)
3151b725ae77Skettenis {
3152b725ae77Skettenis if (thread && parent) /* sanity */
3153b725ae77Skettenis {
3154b725ae77Skettenis thread->status_valid = 0;
3155b725ae77Skettenis if (!proc_get_status (thread))
3156b725ae77Skettenis destroy_one_procinfo (&parent->thread_list, thread);
3157b725ae77Skettenis }
3158b725ae77Skettenis return 0; /* keep iterating */
3159b725ae77Skettenis }
3160b725ae77Skettenis
3161b725ae77Skettenis #if defined (PIOCLSTATUS)
3162b725ae77Skettenis /*
3163b725ae77Skettenis * Solaris 2.5 (ioctl) version
3164b725ae77Skettenis */
3165b725ae77Skettenis int
proc_update_threads(procinfo * pi)3166b725ae77Skettenis proc_update_threads (procinfo *pi)
3167b725ae77Skettenis {
3168b725ae77Skettenis gdb_prstatus_t *prstatus;
3169b725ae77Skettenis struct cleanup *old_chain = NULL;
3170b725ae77Skettenis procinfo *thread;
3171b725ae77Skettenis int nlwp, i;
3172b725ae77Skettenis
3173b725ae77Skettenis /*
3174b725ae77Skettenis * We should never have to apply this operation to any procinfo
3175b725ae77Skettenis * except the one for the main process. If that ever changes
3176b725ae77Skettenis * for any reason, then take out the following clause and
3177b725ae77Skettenis * replace it with one that makes sure the ctl_fd is open.
3178b725ae77Skettenis */
3179b725ae77Skettenis
3180b725ae77Skettenis if (pi->tid != 0)
3181b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
3182b725ae77Skettenis
3183b725ae77Skettenis proc_iterate_over_threads (pi, proc_delete_dead_threads, NULL);
3184b725ae77Skettenis
3185b725ae77Skettenis if ((nlwp = proc_get_nthreads (pi)) <= 1)
3186b725ae77Skettenis return 1; /* Process is not multi-threaded; nothing to do. */
3187b725ae77Skettenis
3188b725ae77Skettenis prstatus = xmalloc (sizeof (gdb_prstatus_t) * (nlwp + 1));
3189b725ae77Skettenis
3190b725ae77Skettenis old_chain = make_cleanup (xfree, prstatus);
3191b725ae77Skettenis if (ioctl (pi->ctl_fd, PIOCLSTATUS, prstatus) < 0)
3192b725ae77Skettenis proc_error (pi, "update_threads (PIOCLSTATUS)", __LINE__);
3193b725ae77Skettenis
3194b725ae77Skettenis /* Skip element zero, which represents the process as a whole. */
3195b725ae77Skettenis for (i = 1; i < nlwp + 1; i++)
3196b725ae77Skettenis {
3197b725ae77Skettenis if ((thread = create_procinfo (pi->pid, prstatus[i].pr_who)) == NULL)
3198b725ae77Skettenis proc_error (pi, "update_threads, create_procinfo", __LINE__);
3199b725ae77Skettenis
3200b725ae77Skettenis memcpy (&thread->prstatus, &prstatus[i], sizeof (*prstatus));
3201b725ae77Skettenis thread->status_valid = 1;
3202b725ae77Skettenis }
3203b725ae77Skettenis pi->threads_valid = 1;
3204b725ae77Skettenis do_cleanups (old_chain);
3205b725ae77Skettenis return 1;
3206b725ae77Skettenis }
3207b725ae77Skettenis #else
3208b725ae77Skettenis #ifdef NEW_PROC_API
3209b725ae77Skettenis /*
3210b725ae77Skettenis * Unixware and Solaris 6 (and later) version
3211b725ae77Skettenis */
3212b725ae77Skettenis static void
do_closedir_cleanup(void * dir)3213b725ae77Skettenis do_closedir_cleanup (void *dir)
3214b725ae77Skettenis {
3215b725ae77Skettenis closedir (dir);
3216b725ae77Skettenis }
3217b725ae77Skettenis
3218b725ae77Skettenis int
proc_update_threads(procinfo * pi)3219b725ae77Skettenis proc_update_threads (procinfo *pi)
3220b725ae77Skettenis {
3221b725ae77Skettenis char pathname[MAX_PROC_NAME_SIZE + 16];
3222b725ae77Skettenis struct dirent *direntry;
3223b725ae77Skettenis struct cleanup *old_chain = NULL;
3224b725ae77Skettenis procinfo *thread;
3225b725ae77Skettenis DIR *dirp;
3226b725ae77Skettenis int lwpid;
3227b725ae77Skettenis
3228b725ae77Skettenis /*
3229b725ae77Skettenis * We should never have to apply this operation to any procinfo
3230b725ae77Skettenis * except the one for the main process. If that ever changes
3231b725ae77Skettenis * for any reason, then take out the following clause and
3232b725ae77Skettenis * replace it with one that makes sure the ctl_fd is open.
3233b725ae77Skettenis */
3234b725ae77Skettenis
3235b725ae77Skettenis if (pi->tid != 0)
3236b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
3237b725ae77Skettenis
3238b725ae77Skettenis proc_iterate_over_threads (pi, proc_delete_dead_threads, NULL);
3239b725ae77Skettenis
3240b725ae77Skettenis /*
3241b725ae77Skettenis * Unixware
3242b725ae77Skettenis *
3243b725ae77Skettenis * Note: this brute-force method is the only way I know of
3244b725ae77Skettenis * to accomplish this task on Unixware. This method will
3245b725ae77Skettenis * also work on Solaris 2.6 and 2.7. There is a much simpler
3246b725ae77Skettenis * and more elegant way to do this on Solaris, but the margins
3247b725ae77Skettenis * of this manuscript are too small to write it here... ;-)
3248b725ae77Skettenis */
3249b725ae77Skettenis
3250b725ae77Skettenis strcpy (pathname, pi->pathname);
3251b725ae77Skettenis strcat (pathname, "/lwp");
3252b725ae77Skettenis if ((dirp = opendir (pathname)) == NULL)
3253b725ae77Skettenis proc_error (pi, "update_threads, opendir", __LINE__);
3254b725ae77Skettenis
3255b725ae77Skettenis old_chain = make_cleanup (do_closedir_cleanup, dirp);
3256b725ae77Skettenis while ((direntry = readdir (dirp)) != NULL)
3257b725ae77Skettenis if (direntry->d_name[0] != '.') /* skip '.' and '..' */
3258b725ae77Skettenis {
3259b725ae77Skettenis lwpid = atoi (&direntry->d_name[0]);
3260b725ae77Skettenis if ((thread = create_procinfo (pi->pid, lwpid)) == NULL)
3261b725ae77Skettenis proc_error (pi, "update_threads, create_procinfo", __LINE__);
3262b725ae77Skettenis }
3263b725ae77Skettenis pi->threads_valid = 1;
3264b725ae77Skettenis do_cleanups (old_chain);
3265b725ae77Skettenis return 1;
3266b725ae77Skettenis }
3267b725ae77Skettenis #else
3268b725ae77Skettenis #ifdef PIOCTLIST
3269b725ae77Skettenis /*
3270b725ae77Skettenis * OSF version
3271b725ae77Skettenis */
3272b725ae77Skettenis int
proc_update_threads(procinfo * pi)3273b725ae77Skettenis proc_update_threads (procinfo *pi)
3274b725ae77Skettenis {
3275b725ae77Skettenis int nthreads, i;
3276b725ae77Skettenis tid_t *threads;
3277b725ae77Skettenis
3278b725ae77Skettenis /*
3279b725ae77Skettenis * We should never have to apply this operation to any procinfo
3280b725ae77Skettenis * except the one for the main process. If that ever changes
3281b725ae77Skettenis * for any reason, then take out the following clause and
3282b725ae77Skettenis * replace it with one that makes sure the ctl_fd is open.
3283b725ae77Skettenis */
3284b725ae77Skettenis
3285b725ae77Skettenis if (pi->tid != 0)
3286b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
3287b725ae77Skettenis
3288b725ae77Skettenis proc_iterate_over_threads (pi, proc_delete_dead_threads, NULL);
3289b725ae77Skettenis
3290b725ae77Skettenis nthreads = proc_get_nthreads (pi);
3291b725ae77Skettenis if (nthreads < 2)
3292b725ae77Skettenis return 0; /* nothing to do for 1 or fewer threads */
3293b725ae77Skettenis
3294b725ae77Skettenis threads = xmalloc (nthreads * sizeof (tid_t));
3295b725ae77Skettenis
3296b725ae77Skettenis if (ioctl (pi->ctl_fd, PIOCTLIST, threads) < 0)
3297b725ae77Skettenis proc_error (pi, "procfs: update_threads (PIOCTLIST)", __LINE__);
3298b725ae77Skettenis
3299b725ae77Skettenis for (i = 0; i < nthreads; i++)
3300b725ae77Skettenis {
3301b725ae77Skettenis if (!find_procinfo (pi->pid, threads[i]))
3302b725ae77Skettenis if (!create_procinfo (pi->pid, threads[i]))
3303b725ae77Skettenis proc_error (pi, "update_threads, create_procinfo", __LINE__);
3304b725ae77Skettenis }
3305b725ae77Skettenis pi->threads_valid = 1;
3306b725ae77Skettenis return 1;
3307b725ae77Skettenis }
3308b725ae77Skettenis #else
3309b725ae77Skettenis /*
3310b725ae77Skettenis * Default version
3311b725ae77Skettenis */
3312b725ae77Skettenis int
proc_update_threads(procinfo * pi)3313b725ae77Skettenis proc_update_threads (procinfo *pi)
3314b725ae77Skettenis {
3315b725ae77Skettenis return 0;
3316b725ae77Skettenis }
3317b725ae77Skettenis #endif /* OSF PIOCTLIST */
3318b725ae77Skettenis #endif /* NEW_PROC_API */
3319b725ae77Skettenis #endif /* SOL 2.5 PIOCLSTATUS */
3320b725ae77Skettenis
3321b725ae77Skettenis /*
3322b725ae77Skettenis * Function: proc_iterate_over_threads
3323b725ae77Skettenis *
3324b725ae77Skettenis * Description:
3325b725ae77Skettenis * Given a pointer to a function, call that function once
3326b725ae77Skettenis * for each lwp in the procinfo list, until the function
3327b725ae77Skettenis * returns non-zero, in which event return the value
3328b725ae77Skettenis * returned by the function.
3329b725ae77Skettenis *
3330b725ae77Skettenis * Note: this function does NOT call update_threads.
3331b725ae77Skettenis * If you want to discover new threads first, you must
3332b725ae77Skettenis * call that function explicitly. This function just makes
3333b725ae77Skettenis * a quick pass over the currently-known procinfos.
3334b725ae77Skettenis *
3335b725ae77Skettenis * Arguments:
3336b725ae77Skettenis * pi - parent process procinfo
3337b725ae77Skettenis * func - per-thread function
3338b725ae77Skettenis * ptr - opaque parameter for function.
3339b725ae77Skettenis *
3340b725ae77Skettenis * Return:
3341b725ae77Skettenis * First non-zero return value from the callee, or zero.
3342b725ae77Skettenis */
3343b725ae77Skettenis
3344b725ae77Skettenis int
proc_iterate_over_threads(procinfo * pi,int (* func)(procinfo *,procinfo *,void *),void * ptr)3345b725ae77Skettenis proc_iterate_over_threads (procinfo *pi,
3346b725ae77Skettenis int (*func) (procinfo *, procinfo *, void *),
3347b725ae77Skettenis void *ptr)
3348b725ae77Skettenis {
3349b725ae77Skettenis procinfo *thread, *next;
3350b725ae77Skettenis int retval = 0;
3351b725ae77Skettenis
3352b725ae77Skettenis /*
3353b725ae77Skettenis * We should never have to apply this operation to any procinfo
3354b725ae77Skettenis * except the one for the main process. If that ever changes
3355b725ae77Skettenis * for any reason, then take out the following clause and
3356b725ae77Skettenis * replace it with one that makes sure the ctl_fd is open.
3357b725ae77Skettenis */
3358b725ae77Skettenis
3359b725ae77Skettenis if (pi->tid != 0)
3360b725ae77Skettenis pi = find_procinfo_or_die (pi->pid, 0);
3361b725ae77Skettenis
3362b725ae77Skettenis for (thread = pi->thread_list; thread != NULL; thread = next)
3363b725ae77Skettenis {
3364b725ae77Skettenis next = thread->next; /* in case thread is destroyed */
3365b725ae77Skettenis if ((retval = (*func) (pi, thread, ptr)) != 0)
3366b725ae77Skettenis break;
3367b725ae77Skettenis }
3368b725ae77Skettenis
3369b725ae77Skettenis return retval;
3370b725ae77Skettenis }
3371b725ae77Skettenis
3372b725ae77Skettenis /* =================== END, Thread "MODULE" =================== */
3373b725ae77Skettenis
3374b725ae77Skettenis /* =================== END, /proc "MODULE" =================== */
3375b725ae77Skettenis
3376b725ae77Skettenis /* =================== GDB "MODULE" =================== */
3377b725ae77Skettenis
3378b725ae77Skettenis /*
3379b725ae77Skettenis * Here are all of the gdb target vector functions and their friends.
3380b725ae77Skettenis */
3381b725ae77Skettenis
3382b725ae77Skettenis static ptid_t do_attach (ptid_t ptid);
3383b725ae77Skettenis static void do_detach (int signo);
3384b725ae77Skettenis static int register_gdb_signals (procinfo *, gdb_sigset_t *);
3385*63addd46Skettenis static void proc_trace_syscalls_1 (procinfo *pi, int syscallnum,
3386*63addd46Skettenis int entry_or_exit, int mode, int from_tty);
3387*63addd46Skettenis static int insert_dbx_link_breakpoint (procinfo *pi);
3388*63addd46Skettenis static void remove_dbx_link_breakpoint (void);
3389*63addd46Skettenis
3390*63addd46Skettenis /* On mips-irix, we need to insert a breakpoint at __dbx_link during
3391*63addd46Skettenis the startup phase. The following two variables are used to record
3392*63addd46Skettenis the address of the breakpoint, and the code that was replaced by
3393*63addd46Skettenis a breakpoint. */
3394*63addd46Skettenis static int dbx_link_bpt_addr = 0;
3395*63addd46Skettenis static char dbx_link_shadow_contents[BREAKPOINT_MAX];
3396b725ae77Skettenis
3397b725ae77Skettenis /*
3398b725ae77Skettenis * Function: procfs_debug_inferior
3399b725ae77Skettenis *
3400b725ae77Skettenis * Sets up the inferior to be debugged.
3401b725ae77Skettenis * Registers to trace signals, hardware faults, and syscalls.
3402b725ae77Skettenis * Note: does not set RLC flag: caller may want to customize that.
3403b725ae77Skettenis *
3404b725ae77Skettenis * Returns: zero for success (note! unlike most functions in this module)
3405b725ae77Skettenis * On failure, returns the LINE NUMBER where it failed!
3406b725ae77Skettenis */
3407b725ae77Skettenis
3408b725ae77Skettenis static int
procfs_debug_inferior(procinfo * pi)3409b725ae77Skettenis procfs_debug_inferior (procinfo *pi)
3410b725ae77Skettenis {
3411b725ae77Skettenis fltset_t traced_faults;
3412b725ae77Skettenis gdb_sigset_t traced_signals;
3413b725ae77Skettenis sysset_t *traced_syscall_entries;
3414b725ae77Skettenis sysset_t *traced_syscall_exits;
3415b725ae77Skettenis int status;
3416b725ae77Skettenis
3417b725ae77Skettenis #ifdef PROCFS_DONT_TRACE_FAULTS
3418b725ae77Skettenis /* On some systems (OSF), we don't trace hardware faults.
3419b725ae77Skettenis Apparently it's enough that we catch them as signals.
3420b725ae77Skettenis Wonder why we don't just do that in general? */
3421b725ae77Skettenis premptyset (&traced_faults); /* don't trace faults. */
3422b725ae77Skettenis #else
3423b725ae77Skettenis /* Register to trace hardware faults in the child. */
3424b725ae77Skettenis prfillset (&traced_faults); /* trace all faults... */
3425b725ae77Skettenis prdelset (&traced_faults, FLTPAGE); /* except page fault. */
3426b725ae77Skettenis #endif
3427b725ae77Skettenis if (!proc_set_traced_faults (pi, &traced_faults))
3428b725ae77Skettenis return __LINE__;
3429b725ae77Skettenis
3430b725ae77Skettenis /* Register to trace selected signals in the child. */
3431b725ae77Skettenis premptyset (&traced_signals);
3432b725ae77Skettenis if (!register_gdb_signals (pi, &traced_signals))
3433b725ae77Skettenis return __LINE__;
3434b725ae77Skettenis
3435b725ae77Skettenis
3436b725ae77Skettenis /* Register to trace the 'exit' system call (on entry). */
3437b725ae77Skettenis traced_syscall_entries = sysset_t_alloc (pi);
3438b725ae77Skettenis gdb_premptysysset (traced_syscall_entries);
3439b725ae77Skettenis #ifdef SYS_exit
3440b725ae77Skettenis gdb_praddsysset (traced_syscall_entries, SYS_exit);
3441b725ae77Skettenis #endif
3442b725ae77Skettenis #ifdef SYS_lwpexit
3443b725ae77Skettenis gdb_praddsysset (traced_syscall_entries, SYS_lwpexit); /* And _lwp_exit... */
3444b725ae77Skettenis #endif
3445b725ae77Skettenis #ifdef SYS_lwp_exit
3446b725ae77Skettenis gdb_praddsysset (traced_syscall_entries, SYS_lwp_exit);
3447b725ae77Skettenis #endif
3448b725ae77Skettenis #ifdef DYNAMIC_SYSCALLS
3449b725ae77Skettenis {
3450b725ae77Skettenis int callnum = find_syscall (pi, "_exit");
3451b725ae77Skettenis if (callnum >= 0)
3452b725ae77Skettenis gdb_praddsysset (traced_syscall_entries, callnum);
3453b725ae77Skettenis }
3454b725ae77Skettenis #endif
3455b725ae77Skettenis
3456b725ae77Skettenis status = proc_set_traced_sysentry (pi, traced_syscall_entries);
3457b725ae77Skettenis xfree (traced_syscall_entries);
3458b725ae77Skettenis if (!status)
3459b725ae77Skettenis return __LINE__;
3460b725ae77Skettenis
3461b725ae77Skettenis #ifdef PRFS_STOPEXEC /* defined on OSF */
3462b725ae77Skettenis /* OSF method for tracing exec syscalls. Quoting:
3463b725ae77Skettenis Under Alpha OSF/1 we have to use a PIOCSSPCACT ioctl to trace
3464b725ae77Skettenis exits from exec system calls because of the user level loader. */
3465b725ae77Skettenis /* FIXME: make nice and maybe move into an access function. */
3466e93f7393Sniklas {
3467e93f7393Sniklas int prfs_flags;
3468e93f7393Sniklas
3469b725ae77Skettenis if (ioctl (pi->ctl_fd, PIOCGSPCACT, &prfs_flags) < 0)
3470b725ae77Skettenis return __LINE__;
3471b725ae77Skettenis
3472b725ae77Skettenis prfs_flags |= PRFS_STOPEXEC;
3473b725ae77Skettenis
3474b725ae77Skettenis if (ioctl (pi->ctl_fd, PIOCSSPCACT, &prfs_flags) < 0)
3475b725ae77Skettenis return __LINE__;
3476e93f7393Sniklas }
3477b725ae77Skettenis #else /* not PRFS_STOPEXEC */
3478b725ae77Skettenis /* Everyone else's (except OSF) method for tracing exec syscalls */
3479e93f7393Sniklas /* GW: Rationale...
3480e93f7393Sniklas Not all systems with /proc have all the exec* syscalls with the same
3481e93f7393Sniklas names. On the SGI, for example, there is no SYS_exec, but there
3482e93f7393Sniklas *is* a SYS_execv. So, we try to account for that. */
3483e93f7393Sniklas
3484b725ae77Skettenis traced_syscall_exits = sysset_t_alloc (pi);
3485b725ae77Skettenis gdb_premptysysset (traced_syscall_exits);
3486e93f7393Sniklas #ifdef SYS_exec
3487b725ae77Skettenis gdb_praddsysset (traced_syscall_exits, SYS_exec);
3488e93f7393Sniklas #endif
3489e93f7393Sniklas #ifdef SYS_execve
3490b725ae77Skettenis gdb_praddsysset (traced_syscall_exits, SYS_execve);
3491e93f7393Sniklas #endif
3492e93f7393Sniklas #ifdef SYS_execv
3493b725ae77Skettenis gdb_praddsysset (traced_syscall_exits, SYS_execv);
3494e93f7393Sniklas #endif
3495e93f7393Sniklas
3496b725ae77Skettenis #ifdef SYS_lwpcreate
3497b725ae77Skettenis gdb_praddsysset (traced_syscall_exits, SYS_lwpcreate);
3498b725ae77Skettenis gdb_praddsysset (traced_syscall_exits, SYS_lwpexit);
3499b725ae77Skettenis #endif
3500b725ae77Skettenis
3501b725ae77Skettenis #ifdef SYS_lwp_create /* FIXME: once only, please */
3502b725ae77Skettenis gdb_praddsysset (traced_syscall_exits, SYS_lwp_create);
3503b725ae77Skettenis gdb_praddsysset (traced_syscall_exits, SYS_lwp_exit);
3504b725ae77Skettenis #endif
3505b725ae77Skettenis
3506b725ae77Skettenis #ifdef DYNAMIC_SYSCALLS
3507e93f7393Sniklas {
3508b725ae77Skettenis int callnum = find_syscall (pi, "execve");
3509b725ae77Skettenis if (callnum >= 0)
3510b725ae77Skettenis gdb_praddsysset (traced_syscall_exits, callnum);
3511b725ae77Skettenis callnum = find_syscall (pi, "ra_execve");
3512b725ae77Skettenis if (callnum >= 0)
3513b725ae77Skettenis gdb_praddsysset (traced_syscall_exits, callnum);
3514e93f7393Sniklas }
3515b725ae77Skettenis #endif
3516e93f7393Sniklas
3517b725ae77Skettenis status = proc_set_traced_sysexit (pi, traced_syscall_exits);
3518b725ae77Skettenis xfree (traced_syscall_exits);
3519b725ae77Skettenis if (!status)
3520b725ae77Skettenis return __LINE__;
3521e93f7393Sniklas
3522b725ae77Skettenis #endif /* PRFS_STOPEXEC */
3523b725ae77Skettenis return 0;
3524e93f7393Sniklas }
3525e93f7393Sniklas
3526e93f7393Sniklas static void
procfs_attach(char * args,int from_tty)3527b725ae77Skettenis procfs_attach (char *args, int from_tty)
3528e93f7393Sniklas {
3529e93f7393Sniklas char *exec_file;
3530e93f7393Sniklas int pid;
3531e93f7393Sniklas
3532e93f7393Sniklas if (!args)
3533e93f7393Sniklas error_no_arg ("process-id to attach");
3534e93f7393Sniklas
3535e93f7393Sniklas pid = atoi (args);
3536b725ae77Skettenis if (pid == getpid ())
3537b725ae77Skettenis error ("Attaching GDB to itself is not a good idea...");
3538e93f7393Sniklas
3539e93f7393Sniklas if (from_tty)
3540e93f7393Sniklas {
3541b725ae77Skettenis exec_file = get_exec_file (0);
3542e93f7393Sniklas
3543e93f7393Sniklas if (exec_file)
3544b725ae77Skettenis printf_filtered ("Attaching to program `%s', %s\n",
3545b725ae77Skettenis exec_file, target_pid_to_str (pid_to_ptid (pid)));
3546e93f7393Sniklas else
3547b725ae77Skettenis printf_filtered ("Attaching to %s\n",
3548b725ae77Skettenis target_pid_to_str (pid_to_ptid (pid)));
3549e93f7393Sniklas
3550b725ae77Skettenis fflush (stdout);
3551e93f7393Sniklas }
3552b725ae77Skettenis inferior_ptid = do_attach (pid_to_ptid (pid));
3553e93f7393Sniklas push_target (&procfs_ops);
3554e93f7393Sniklas }
3555e93f7393Sniklas
3556e93f7393Sniklas static void
procfs_detach(char * args,int from_tty)3557b725ae77Skettenis procfs_detach (char *args, int from_tty)
3558e93f7393Sniklas {
3559*63addd46Skettenis int sig = 0;
3560*63addd46Skettenis
3561*63addd46Skettenis if (args)
3562*63addd46Skettenis sig = atoi (args);
3563e93f7393Sniklas
3564e93f7393Sniklas if (from_tty)
3565e93f7393Sniklas {
3566*63addd46Skettenis int pid = PIDGET (inferior_ptid);
3567*63addd46Skettenis char *exec_file;
3568e93f7393Sniklas
3569*63addd46Skettenis exec_file = get_exec_file (0);
3570*63addd46Skettenis if (exec_file == NULL)
3571*63addd46Skettenis exec_file = "";
3572*63addd46Skettenis
3573*63addd46Skettenis printf_filtered ("Detaching from program: %s, %s\n", exec_file,
3574*63addd46Skettenis target_pid_to_str (pid_to_ptid (pid)));
3575*63addd46Skettenis gdb_flush (gdb_stdout);
3576*63addd46Skettenis }
3577*63addd46Skettenis
3578*63addd46Skettenis do_detach (sig);
3579*63addd46Skettenis
3580b725ae77Skettenis inferior_ptid = null_ptid;
3581*63addd46Skettenis unpush_target (&procfs_ops);
3582e93f7393Sniklas }
3583e93f7393Sniklas
3584b725ae77Skettenis static ptid_t
do_attach(ptid_t ptid)3585b725ae77Skettenis do_attach (ptid_t ptid)
3586b725ae77Skettenis {
3587b725ae77Skettenis procinfo *pi;
3588b725ae77Skettenis int fail;
3589b725ae77Skettenis
3590b725ae77Skettenis if ((pi = create_procinfo (PIDGET (ptid), 0)) == NULL)
3591b725ae77Skettenis perror ("procfs: out of memory in 'attach'");
3592b725ae77Skettenis
3593b725ae77Skettenis if (!open_procinfo_files (pi, FD_CTL))
3594b725ae77Skettenis {
3595b725ae77Skettenis fprintf_filtered (gdb_stderr, "procfs:%d -- ", __LINE__);
3596b725ae77Skettenis sprintf (errmsg, "do_attach: couldn't open /proc file for process %d",
3597b725ae77Skettenis PIDGET (ptid));
3598b725ae77Skettenis dead_procinfo (pi, errmsg, NOKILL);
3599b725ae77Skettenis }
3600b725ae77Skettenis
3601b725ae77Skettenis /* Stop the process (if it isn't already stopped). */
3602b725ae77Skettenis if (proc_flags (pi) & (PR_STOPPED | PR_ISTOP))
3603b725ae77Skettenis {
3604b725ae77Skettenis pi->was_stopped = 1;
3605b725ae77Skettenis proc_prettyprint_why (proc_why (pi), proc_what (pi), 1);
3606b725ae77Skettenis }
3607b725ae77Skettenis else
3608b725ae77Skettenis {
3609b725ae77Skettenis pi->was_stopped = 0;
3610b725ae77Skettenis /* Set the process to run again when we close it. */
3611b725ae77Skettenis if (!proc_set_run_on_last_close (pi))
3612b725ae77Skettenis dead_procinfo (pi, "do_attach: couldn't set RLC.", NOKILL);
3613b725ae77Skettenis
3614b725ae77Skettenis /* Now stop the process. */
3615b725ae77Skettenis if (!proc_stop_process (pi))
3616b725ae77Skettenis dead_procinfo (pi, "do_attach: couldn't stop the process.", NOKILL);
3617b725ae77Skettenis pi->ignore_next_sigstop = 1;
3618b725ae77Skettenis }
3619b725ae77Skettenis /* Save some of the /proc state to be restored if we detach. */
3620b725ae77Skettenis if (!proc_get_traced_faults (pi, &pi->saved_fltset))
3621b725ae77Skettenis dead_procinfo (pi, "do_attach: couldn't save traced faults.", NOKILL);
3622b725ae77Skettenis if (!proc_get_traced_signals (pi, &pi->saved_sigset))
3623b725ae77Skettenis dead_procinfo (pi, "do_attach: couldn't save traced signals.", NOKILL);
3624b725ae77Skettenis if (!proc_get_traced_sysentry (pi, pi->saved_entryset))
3625b725ae77Skettenis dead_procinfo (pi, "do_attach: couldn't save traced syscall entries.",
3626b725ae77Skettenis NOKILL);
3627b725ae77Skettenis if (!proc_get_traced_sysexit (pi, pi->saved_exitset))
3628b725ae77Skettenis dead_procinfo (pi, "do_attach: couldn't save traced syscall exits.",
3629b725ae77Skettenis NOKILL);
3630b725ae77Skettenis if (!proc_get_held_signals (pi, &pi->saved_sighold))
3631b725ae77Skettenis dead_procinfo (pi, "do_attach: couldn't save held signals.", NOKILL);
3632b725ae77Skettenis
3633b725ae77Skettenis if ((fail = procfs_debug_inferior (pi)) != 0)
3634b725ae77Skettenis dead_procinfo (pi, "do_attach: failed in procfs_debug_inferior", NOKILL);
3635b725ae77Skettenis
3636b725ae77Skettenis /* Let GDB know that the inferior was attached. */
3637b725ae77Skettenis attach_flag = 1;
3638b725ae77Skettenis return MERGEPID (pi->pid, proc_get_current_thread (pi));
3639b725ae77Skettenis }
3640e93f7393Sniklas
3641e93f7393Sniklas static void
do_detach(int signo)3642b725ae77Skettenis do_detach (int signo)
3643b725ae77Skettenis {
3644b725ae77Skettenis procinfo *pi;
3645b725ae77Skettenis
3646b725ae77Skettenis /* Find procinfo for the main process */
3647b725ae77Skettenis pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0); /* FIXME: threads */
3648b725ae77Skettenis if (signo)
3649b725ae77Skettenis if (!proc_set_current_signal (pi, signo))
3650b725ae77Skettenis proc_warn (pi, "do_detach, set_current_signal", __LINE__);
3651b725ae77Skettenis
3652b725ae77Skettenis if (!proc_set_traced_signals (pi, &pi->saved_sigset))
3653b725ae77Skettenis proc_warn (pi, "do_detach, set_traced_signal", __LINE__);
3654b725ae77Skettenis
3655b725ae77Skettenis if (!proc_set_traced_faults (pi, &pi->saved_fltset))
3656b725ae77Skettenis proc_warn (pi, "do_detach, set_traced_faults", __LINE__);
3657b725ae77Skettenis
3658b725ae77Skettenis if (!proc_set_traced_sysentry (pi, pi->saved_entryset))
3659b725ae77Skettenis proc_warn (pi, "do_detach, set_traced_sysentry", __LINE__);
3660b725ae77Skettenis
3661b725ae77Skettenis if (!proc_set_traced_sysexit (pi, pi->saved_exitset))
3662b725ae77Skettenis proc_warn (pi, "do_detach, set_traced_sysexit", __LINE__);
3663b725ae77Skettenis
3664b725ae77Skettenis if (!proc_set_held_signals (pi, &pi->saved_sighold))
3665b725ae77Skettenis proc_warn (pi, "do_detach, set_held_signals", __LINE__);
3666b725ae77Skettenis
3667b725ae77Skettenis if (signo || (proc_flags (pi) & (PR_STOPPED | PR_ISTOP)))
3668b725ae77Skettenis if (signo || !(pi->was_stopped) ||
3669b725ae77Skettenis query ("Was stopped when attached, make it runnable again? "))
3670b725ae77Skettenis {
3671b725ae77Skettenis /* Clear any pending signal. */
3672b725ae77Skettenis if (!proc_clear_current_fault (pi))
3673b725ae77Skettenis proc_warn (pi, "do_detach, clear_current_fault", __LINE__);
3674b725ae77Skettenis
3675b725ae77Skettenis if (signo == 0 && !proc_clear_current_signal (pi))
3676b725ae77Skettenis proc_warn (pi, "do_detach, clear_current_signal", __LINE__);
3677b725ae77Skettenis
3678b725ae77Skettenis if (!proc_set_run_on_last_close (pi))
3679b725ae77Skettenis proc_warn (pi, "do_detach, set_rlc", __LINE__);
3680b725ae77Skettenis }
3681b725ae77Skettenis
3682b725ae77Skettenis attach_flag = 0;
3683b725ae77Skettenis destroy_procinfo (pi);
3684b725ae77Skettenis }
3685b725ae77Skettenis
3686b725ae77Skettenis /*
3687b725ae77Skettenis * fetch_registers
3688b725ae77Skettenis *
3689b725ae77Skettenis * Since the /proc interface cannot give us individual registers,
3690b725ae77Skettenis * we pay no attention to the (regno) argument, and just fetch them all.
3691b725ae77Skettenis * This results in the possibility that we will do unnecessarily many
3692b725ae77Skettenis * fetches, since we may be called repeatedly for individual registers.
3693b725ae77Skettenis * So we cache the results, and mark the cache invalid when the process
3694b725ae77Skettenis * is resumed.
3695b725ae77Skettenis */
3696b725ae77Skettenis
3697b725ae77Skettenis static void
procfs_fetch_registers(int regno)3698b725ae77Skettenis procfs_fetch_registers (int regno)
3699b725ae77Skettenis {
3700b725ae77Skettenis gdb_fpregset_t *fpregs;
3701b725ae77Skettenis gdb_gregset_t *gregs;
3702b725ae77Skettenis procinfo *pi;
3703b725ae77Skettenis int pid;
3704b725ae77Skettenis int tid;
3705b725ae77Skettenis
3706b725ae77Skettenis pid = PIDGET (inferior_ptid);
3707b725ae77Skettenis tid = TIDGET (inferior_ptid);
3708b725ae77Skettenis
3709b725ae77Skettenis /* First look up procinfo for the main process. */
3710b725ae77Skettenis pi = find_procinfo_or_die (pid, 0);
3711b725ae77Skettenis
3712b725ae77Skettenis /* If the event thread is not the same as GDB's requested thread
3713b725ae77Skettenis (ie. inferior_ptid), then look up procinfo for the requested
3714b725ae77Skettenis thread. */
3715b725ae77Skettenis if ((tid != 0) &&
3716b725ae77Skettenis (tid != proc_get_current_thread (pi)))
3717b725ae77Skettenis pi = find_procinfo_or_die (pid, tid);
3718b725ae77Skettenis
3719b725ae77Skettenis if (pi == NULL)
3720b725ae77Skettenis error ("procfs: fetch_registers failed to find procinfo for %s",
3721b725ae77Skettenis target_pid_to_str (inferior_ptid));
3722b725ae77Skettenis
3723b725ae77Skettenis if ((gregs = proc_get_gregs (pi)) == NULL)
3724b725ae77Skettenis proc_error (pi, "fetch_registers, get_gregs", __LINE__);
3725b725ae77Skettenis
3726b725ae77Skettenis supply_gregset (gregs);
3727b725ae77Skettenis
3728b725ae77Skettenis if (FP0_REGNUM >= 0) /* need floating point? */
3729b725ae77Skettenis {
3730b725ae77Skettenis if ((regno >= 0 && regno < FP0_REGNUM)
3731b725ae77Skettenis || regno == PC_REGNUM
3732b725ae77Skettenis || regno == DEPRECATED_FP_REGNUM
3733b725ae77Skettenis || regno == SP_REGNUM)
3734b725ae77Skettenis return; /* not a floating point register */
3735b725ae77Skettenis
3736b725ae77Skettenis if ((fpregs = proc_get_fpregs (pi)) == NULL)
3737b725ae77Skettenis proc_error (pi, "fetch_registers, get_fpregs", __LINE__);
3738b725ae77Skettenis
3739b725ae77Skettenis supply_fpregset (fpregs);
3740b725ae77Skettenis }
3741b725ae77Skettenis }
3742b725ae77Skettenis
3743b725ae77Skettenis /* Get ready to modify the registers array. On machines which store
3744b725ae77Skettenis individual registers, this doesn't need to do anything. On
3745b725ae77Skettenis machines which store all the registers in one fell swoop, such as
3746b725ae77Skettenis /proc, this makes sure that registers contains all the registers
3747b725ae77Skettenis from the program being debugged. */
3748b725ae77Skettenis
3749b725ae77Skettenis static void
procfs_prepare_to_store(void)3750b725ae77Skettenis procfs_prepare_to_store (void)
3751e93f7393Sniklas {
3752e93f7393Sniklas #ifdef CHILD_PREPARE_TO_STORE
3753e93f7393Sniklas CHILD_PREPARE_TO_STORE ();
3754e93f7393Sniklas #endif
3755e93f7393Sniklas }
3756e93f7393Sniklas
3757b725ae77Skettenis /*
3758b725ae77Skettenis * store_registers
3759b725ae77Skettenis *
3760b725ae77Skettenis * Since the /proc interface will not read individual registers,
3761b725ae77Skettenis * we will cache these requests until the process is resumed, and
3762b725ae77Skettenis * only then write them back to the inferior process.
3763b725ae77Skettenis *
3764b725ae77Skettenis * FIXME: is that a really bad idea? Have to think about cases
3765b725ae77Skettenis * where writing one register might affect the value of others, etc.
3766b725ae77Skettenis */
3767e93f7393Sniklas
3768e93f7393Sniklas static void
procfs_store_registers(int regno)3769b725ae77Skettenis procfs_store_registers (int regno)
3770e93f7393Sniklas {
3771b725ae77Skettenis gdb_fpregset_t *fpregs;
3772b725ae77Skettenis gdb_gregset_t *gregs;
3773b725ae77Skettenis procinfo *pi;
3774b725ae77Skettenis int pid;
3775b725ae77Skettenis int tid;
3776b725ae77Skettenis
3777b725ae77Skettenis pid = PIDGET (inferior_ptid);
3778b725ae77Skettenis tid = TIDGET (inferior_ptid);
3779b725ae77Skettenis
3780b725ae77Skettenis /* First find procinfo for main process */
3781b725ae77Skettenis pi = find_procinfo_or_die (pid, 0);
3782b725ae77Skettenis
3783b725ae77Skettenis /* If current lwp for process is not the same as requested thread
3784b725ae77Skettenis (ie. inferior_ptid), then find procinfo for the requested thread. */
3785b725ae77Skettenis
3786b725ae77Skettenis if ((tid != 0) &&
3787b725ae77Skettenis (tid != proc_get_current_thread (pi)))
3788b725ae77Skettenis pi = find_procinfo_or_die (pid, tid);
3789b725ae77Skettenis
3790b725ae77Skettenis if (pi == NULL)
3791b725ae77Skettenis error ("procfs: store_registers: failed to find procinfo for %s",
3792b725ae77Skettenis target_pid_to_str (inferior_ptid));
3793b725ae77Skettenis
3794b725ae77Skettenis if ((gregs = proc_get_gregs (pi)) == NULL)
3795b725ae77Skettenis proc_error (pi, "store_registers, get_gregs", __LINE__);
3796b725ae77Skettenis
3797b725ae77Skettenis fill_gregset (gregs, regno);
3798b725ae77Skettenis if (!proc_set_gregs (pi))
3799b725ae77Skettenis proc_error (pi, "store_registers, set_gregs", __LINE__);
3800b725ae77Skettenis
3801b725ae77Skettenis if (FP0_REGNUM >= 0) /* need floating point? */
3802b725ae77Skettenis {
3803b725ae77Skettenis if ((regno >= 0 && regno < FP0_REGNUM)
3804b725ae77Skettenis || regno == PC_REGNUM
3805b725ae77Skettenis || regno == DEPRECATED_FP_REGNUM
3806b725ae77Skettenis || regno == SP_REGNUM)
3807b725ae77Skettenis return; /* not a floating point register */
3808b725ae77Skettenis
3809b725ae77Skettenis if ((fpregs = proc_get_fpregs (pi)) == NULL)
3810b725ae77Skettenis proc_error (pi, "store_registers, get_fpregs", __LINE__);
3811b725ae77Skettenis
3812b725ae77Skettenis fill_fpregset (fpregs, regno);
3813b725ae77Skettenis if (!proc_set_fpregs (pi))
3814b725ae77Skettenis proc_error (pi, "store_registers, set_fpregs", __LINE__);
3815b725ae77Skettenis }
3816e93f7393Sniklas }
3817e93f7393Sniklas
3818b725ae77Skettenis static int
syscall_is_lwp_exit(procinfo * pi,int scall)3819b725ae77Skettenis syscall_is_lwp_exit (procinfo *pi, int scall)
3820b725ae77Skettenis {
3821b725ae77Skettenis
3822b725ae77Skettenis #ifdef SYS_lwp_exit
3823b725ae77Skettenis if (scall == SYS_lwp_exit)
3824b725ae77Skettenis return 1;
3825b725ae77Skettenis #endif
3826b725ae77Skettenis #ifdef SYS_lwpexit
3827b725ae77Skettenis if (scall == SYS_lwpexit)
3828b725ae77Skettenis return 1;
3829b725ae77Skettenis #endif
3830b725ae77Skettenis return 0;
3831b725ae77Skettenis }
3832b725ae77Skettenis
3833b725ae77Skettenis static int
syscall_is_exit(procinfo * pi,int scall)3834b725ae77Skettenis syscall_is_exit (procinfo *pi, int scall)
3835b725ae77Skettenis {
3836b725ae77Skettenis #ifdef SYS_exit
3837b725ae77Skettenis if (scall == SYS_exit)
3838b725ae77Skettenis return 1;
3839b725ae77Skettenis #endif
3840b725ae77Skettenis #ifdef DYNAMIC_SYSCALLS
3841b725ae77Skettenis if (find_syscall (pi, "_exit") == scall)
3842b725ae77Skettenis return 1;
3843b725ae77Skettenis #endif
3844b725ae77Skettenis return 0;
3845b725ae77Skettenis }
3846b725ae77Skettenis
3847b725ae77Skettenis static int
syscall_is_exec(procinfo * pi,int scall)3848b725ae77Skettenis syscall_is_exec (procinfo *pi, int scall)
3849b725ae77Skettenis {
3850b725ae77Skettenis #ifdef SYS_exec
3851b725ae77Skettenis if (scall == SYS_exec)
3852b725ae77Skettenis return 1;
3853b725ae77Skettenis #endif
3854b725ae77Skettenis #ifdef SYS_execv
3855b725ae77Skettenis if (scall == SYS_execv)
3856b725ae77Skettenis return 1;
3857b725ae77Skettenis #endif
3858b725ae77Skettenis #ifdef SYS_execve
3859b725ae77Skettenis if (scall == SYS_execve)
3860b725ae77Skettenis return 1;
3861b725ae77Skettenis #endif
3862b725ae77Skettenis #ifdef DYNAMIC_SYSCALLS
3863b725ae77Skettenis if (find_syscall (pi, "_execve"))
3864b725ae77Skettenis return 1;
3865b725ae77Skettenis if (find_syscall (pi, "ra_execve"))
3866b725ae77Skettenis return 1;
3867b725ae77Skettenis #endif
3868b725ae77Skettenis return 0;
3869b725ae77Skettenis }
3870b725ae77Skettenis
3871b725ae77Skettenis static int
syscall_is_lwp_create(procinfo * pi,int scall)3872b725ae77Skettenis syscall_is_lwp_create (procinfo *pi, int scall)
3873b725ae77Skettenis {
3874b725ae77Skettenis #ifdef SYS_lwp_create
3875b725ae77Skettenis if (scall == SYS_lwp_create)
3876b725ae77Skettenis return 1;
3877b725ae77Skettenis #endif
3878b725ae77Skettenis #ifdef SYS_lwpcreate
3879b725ae77Skettenis if (scall == SYS_lwpcreate)
3880b725ae77Skettenis return 1;
3881b725ae77Skettenis #endif
3882b725ae77Skettenis return 0;
3883b725ae77Skettenis }
3884b725ae77Skettenis
3885b725ae77Skettenis /*
3886b725ae77Skettenis * Function: target_wait
3887b725ae77Skettenis *
3888b725ae77Skettenis * Retrieve the next stop event from the child process.
3889b725ae77Skettenis * If child has not stopped yet, wait for it to stop.
3890b725ae77Skettenis * Translate /proc eventcodes (or possibly wait eventcodes)
3891b725ae77Skettenis * into gdb internal event codes.
3892b725ae77Skettenis *
3893b725ae77Skettenis * Return: id of process (and possibly thread) that incurred the event.
3894b725ae77Skettenis * event codes are returned thru a pointer parameter.
3895b725ae77Skettenis */
3896b725ae77Skettenis
3897b725ae77Skettenis static ptid_t
procfs_wait(ptid_t ptid,struct target_waitstatus * status)3898b725ae77Skettenis procfs_wait (ptid_t ptid, struct target_waitstatus *status)
3899b725ae77Skettenis {
3900b725ae77Skettenis /* First cut: loosely based on original version 2.1 */
3901b725ae77Skettenis procinfo *pi;
3902b725ae77Skettenis int wstat;
3903b725ae77Skettenis int temp_tid;
3904b725ae77Skettenis ptid_t retval, temp_ptid;
3905b725ae77Skettenis int why, what, flags;
3906b725ae77Skettenis int retry = 0;
3907b725ae77Skettenis
3908b725ae77Skettenis wait_again:
3909b725ae77Skettenis
3910b725ae77Skettenis retry++;
3911b725ae77Skettenis wstat = 0;
3912b725ae77Skettenis retval = pid_to_ptid (-1);
3913b725ae77Skettenis
3914b725ae77Skettenis /* Find procinfo for main process */
3915b725ae77Skettenis pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
3916b725ae77Skettenis if (pi)
3917b725ae77Skettenis {
3918b725ae77Skettenis /* We must assume that the status is stale now... */
3919b725ae77Skettenis pi->status_valid = 0;
3920b725ae77Skettenis pi->gregs_valid = 0;
3921b725ae77Skettenis pi->fpregs_valid = 0;
3922b725ae77Skettenis
3923b725ae77Skettenis #if 0 /* just try this out... */
3924b725ae77Skettenis flags = proc_flags (pi);
3925b725ae77Skettenis why = proc_why (pi);
3926b725ae77Skettenis if ((flags & PR_STOPPED) && (why == PR_REQUESTED))
3927b725ae77Skettenis pi->status_valid = 0; /* re-read again, IMMEDIATELY... */
3928b725ae77Skettenis #endif
3929b725ae77Skettenis /* If child is not stopped, wait for it to stop. */
3930b725ae77Skettenis if (!(proc_flags (pi) & (PR_STOPPED | PR_ISTOP)) &&
3931b725ae77Skettenis !proc_wait_for_stop (pi))
3932b725ae77Skettenis {
3933b725ae77Skettenis /* wait_for_stop failed: has the child terminated? */
3934b725ae77Skettenis if (errno == ENOENT)
3935b725ae77Skettenis {
3936b725ae77Skettenis int wait_retval;
3937b725ae77Skettenis
3938b725ae77Skettenis /* /proc file not found; presumably child has terminated. */
3939b725ae77Skettenis wait_retval = wait (&wstat); /* "wait" for the child's exit */
3940b725ae77Skettenis
3941b725ae77Skettenis if (wait_retval != PIDGET (inferior_ptid)) /* wrong child? */
3942b725ae77Skettenis error ("procfs: couldn't stop process %d: wait returned %d\n",
3943b725ae77Skettenis PIDGET (inferior_ptid), wait_retval);
3944b725ae77Skettenis /* FIXME: might I not just use waitpid?
3945b725ae77Skettenis Or try find_procinfo to see if I know about this child? */
3946b725ae77Skettenis retval = pid_to_ptid (wait_retval);
3947b725ae77Skettenis }
3948b725ae77Skettenis else if (errno == EINTR)
3949b725ae77Skettenis goto wait_again;
3950b725ae77Skettenis else
3951b725ae77Skettenis {
3952b725ae77Skettenis /* Unknown error from wait_for_stop. */
3953b725ae77Skettenis proc_error (pi, "target_wait (wait_for_stop)", __LINE__);
3954b725ae77Skettenis }
3955b725ae77Skettenis }
3956b725ae77Skettenis else
3957b725ae77Skettenis {
3958b725ae77Skettenis /* This long block is reached if either:
3959b725ae77Skettenis a) the child was already stopped, or
3960b725ae77Skettenis b) we successfully waited for the child with wait_for_stop.
3961b725ae77Skettenis This block will analyze the /proc status, and translate it
3962b725ae77Skettenis into a waitstatus for GDB.
3963b725ae77Skettenis
3964b725ae77Skettenis If we actually had to call wait because the /proc file
3965b725ae77Skettenis is gone (child terminated), then we skip this block,
3966b725ae77Skettenis because we already have a waitstatus. */
3967b725ae77Skettenis
3968b725ae77Skettenis flags = proc_flags (pi);
3969b725ae77Skettenis why = proc_why (pi);
3970b725ae77Skettenis what = proc_what (pi);
3971b725ae77Skettenis
3972b725ae77Skettenis if (flags & (PR_STOPPED | PR_ISTOP))
3973b725ae77Skettenis {
3974b725ae77Skettenis #ifdef PR_ASYNC
3975b725ae77Skettenis /* If it's running async (for single_thread control),
3976b725ae77Skettenis set it back to normal again. */
3977b725ae77Skettenis if (flags & PR_ASYNC)
3978b725ae77Skettenis if (!proc_unset_async (pi))
3979b725ae77Skettenis proc_error (pi, "target_wait, unset_async", __LINE__);
3980b725ae77Skettenis #endif
3981b725ae77Skettenis
3982b725ae77Skettenis if (info_verbose)
3983b725ae77Skettenis proc_prettyprint_why (why, what, 1);
3984b725ae77Skettenis
3985b725ae77Skettenis /* The 'pid' we will return to GDB is composed of
3986b725ae77Skettenis the process ID plus the lwp ID. */
3987b725ae77Skettenis retval = MERGEPID (pi->pid, proc_get_current_thread (pi));
3988b725ae77Skettenis
3989b725ae77Skettenis switch (why) {
3990b725ae77Skettenis case PR_SIGNALLED:
3991b725ae77Skettenis wstat = (what << 8) | 0177;
3992b725ae77Skettenis break;
3993b725ae77Skettenis case PR_SYSENTRY:
3994b725ae77Skettenis if (syscall_is_lwp_exit (pi, what))
3995b725ae77Skettenis {
3996b725ae77Skettenis printf_filtered ("[%s exited]\n",
3997b725ae77Skettenis target_pid_to_str (retval));
3998b725ae77Skettenis delete_thread (retval);
3999b725ae77Skettenis status->kind = TARGET_WAITKIND_SPURIOUS;
4000b725ae77Skettenis return retval;
4001b725ae77Skettenis }
4002b725ae77Skettenis else if (syscall_is_exit (pi, what))
4003b725ae77Skettenis {
4004b725ae77Skettenis /* Handle SYS_exit call only */
4005b725ae77Skettenis /* Stopped at entry to SYS_exit.
4006b725ae77Skettenis Make it runnable, resume it, then use
4007b725ae77Skettenis the wait system call to get its exit code.
4008b725ae77Skettenis Proc_run_process always clears the current
4009b725ae77Skettenis fault and signal.
4010b725ae77Skettenis Then return its exit status. */
4011b725ae77Skettenis pi->status_valid = 0;
4012b725ae77Skettenis wstat = 0;
4013b725ae77Skettenis /* FIXME: what we should do is return
4014b725ae77Skettenis TARGET_WAITKIND_SPURIOUS. */
4015b725ae77Skettenis if (!proc_run_process (pi, 0, 0))
4016b725ae77Skettenis proc_error (pi, "target_wait, run_process", __LINE__);
4017b725ae77Skettenis if (attach_flag)
4018b725ae77Skettenis {
4019b725ae77Skettenis /* Don't call wait: simulate waiting for exit,
4020b725ae77Skettenis return a "success" exit code. Bogus: what if
4021b725ae77Skettenis it returns something else? */
4022b725ae77Skettenis wstat = 0;
4023b725ae77Skettenis retval = inferior_ptid; /* ? ? ? */
4024b725ae77Skettenis }
4025b725ae77Skettenis else
4026b725ae77Skettenis {
4027b725ae77Skettenis int temp = wait (&wstat);
4028b725ae77Skettenis
4029b725ae77Skettenis /* FIXME: shouldn't I make sure I get the right
4030b725ae77Skettenis event from the right process? If (for
4031b725ae77Skettenis instance) I have killed an earlier inferior
4032b725ae77Skettenis process but failed to clean up after it
4033b725ae77Skettenis somehow, I could get its termination event
4034b725ae77Skettenis here. */
4035b725ae77Skettenis
4036b725ae77Skettenis /* If wait returns -1, that's what we return to GDB. */
4037b725ae77Skettenis if (temp < 0)
4038b725ae77Skettenis retval = pid_to_ptid (temp);
4039b725ae77Skettenis }
4040b725ae77Skettenis }
4041b725ae77Skettenis else
4042b725ae77Skettenis {
4043b725ae77Skettenis printf_filtered ("procfs: trapped on entry to ");
4044b725ae77Skettenis proc_prettyprint_syscall (proc_what (pi), 0);
4045b725ae77Skettenis printf_filtered ("\n");
4046b725ae77Skettenis #ifndef PIOCSSPCACT
4047b725ae77Skettenis {
4048b725ae77Skettenis long i, nsysargs, *sysargs;
4049b725ae77Skettenis
4050b725ae77Skettenis if ((nsysargs = proc_nsysarg (pi)) > 0 &&
4051b725ae77Skettenis (sysargs = proc_sysargs (pi)) != NULL)
4052b725ae77Skettenis {
4053b725ae77Skettenis printf_filtered ("%ld syscall arguments:\n", nsysargs);
4054b725ae77Skettenis for (i = 0; i < nsysargs; i++)
4055b725ae77Skettenis printf_filtered ("#%ld: 0x%08lx\n",
4056b725ae77Skettenis i, sysargs[i]);
4057b725ae77Skettenis }
4058b725ae77Skettenis
4059b725ae77Skettenis }
4060b725ae77Skettenis #endif
4061b725ae77Skettenis if (status)
4062b725ae77Skettenis {
4063b725ae77Skettenis /* How to exit gracefully, returning "unknown event" */
4064b725ae77Skettenis status->kind = TARGET_WAITKIND_SPURIOUS;
4065b725ae77Skettenis return inferior_ptid;
4066b725ae77Skettenis }
4067b725ae77Skettenis else
4068b725ae77Skettenis {
4069b725ae77Skettenis /* How to keep going without returning to wfi: */
4070b725ae77Skettenis target_resume (ptid, 0, TARGET_SIGNAL_0);
4071b725ae77Skettenis goto wait_again;
4072b725ae77Skettenis }
4073b725ae77Skettenis }
4074b725ae77Skettenis break;
4075b725ae77Skettenis case PR_SYSEXIT:
4076b725ae77Skettenis if (syscall_is_exec (pi, what))
4077b725ae77Skettenis {
4078b725ae77Skettenis /* Hopefully this is our own "fork-child" execing
4079b725ae77Skettenis the real child. Hoax this event into a trap, and
4080b725ae77Skettenis GDB will see the child about to execute its start
4081b725ae77Skettenis address. */
4082b725ae77Skettenis wstat = (SIGTRAP << 8) | 0177;
4083b725ae77Skettenis }
4084*63addd46Skettenis #ifdef SYS_syssgi
4085*63addd46Skettenis else if (what == SYS_syssgi)
4086*63addd46Skettenis {
4087*63addd46Skettenis /* see if we can break on dbx_link(). If yes, then
4088*63addd46Skettenis we no longer need the SYS_syssgi notifications. */
4089*63addd46Skettenis if (insert_dbx_link_breakpoint (pi))
4090*63addd46Skettenis proc_trace_syscalls_1 (pi, SYS_syssgi, PR_SYSEXIT,
4091*63addd46Skettenis FLAG_RESET, 0);
4092*63addd46Skettenis
4093*63addd46Skettenis /* This is an internal event and should be transparent
4094*63addd46Skettenis to wfi, so resume the execution and wait again. See
4095*63addd46Skettenis comment in procfs_init_inferior() for more details. */
4096*63addd46Skettenis target_resume (ptid, 0, TARGET_SIGNAL_0);
4097*63addd46Skettenis goto wait_again;
4098*63addd46Skettenis }
4099*63addd46Skettenis #endif
4100b725ae77Skettenis else if (syscall_is_lwp_create (pi, what))
4101b725ae77Skettenis {
4102b725ae77Skettenis /*
4103b725ae77Skettenis * This syscall is somewhat like fork/exec.
4104b725ae77Skettenis * We will get the event twice: once for the parent LWP,
4105b725ae77Skettenis * and once for the child. We should already know about
4106b725ae77Skettenis * the parent LWP, but the child will be new to us. So,
4107b725ae77Skettenis * whenever we get this event, if it represents a new
4108b725ae77Skettenis * thread, simply add the thread to the list.
4109b725ae77Skettenis */
4110b725ae77Skettenis
4111b725ae77Skettenis /* If not in procinfo list, add it. */
4112b725ae77Skettenis temp_tid = proc_get_current_thread (pi);
4113b725ae77Skettenis if (!find_procinfo (pi->pid, temp_tid))
4114b725ae77Skettenis create_procinfo (pi->pid, temp_tid);
4115b725ae77Skettenis
4116b725ae77Skettenis temp_ptid = MERGEPID (pi->pid, temp_tid);
4117b725ae77Skettenis /* If not in GDB's thread list, add it. */
4118b725ae77Skettenis if (!in_thread_list (temp_ptid))
4119b725ae77Skettenis {
4120b725ae77Skettenis printf_filtered ("[New %s]\n",
4121b725ae77Skettenis target_pid_to_str (temp_ptid));
4122b725ae77Skettenis add_thread (temp_ptid);
4123b725ae77Skettenis }
4124b725ae77Skettenis /* Return to WFI, but tell it to immediately resume. */
4125b725ae77Skettenis status->kind = TARGET_WAITKIND_SPURIOUS;
4126b725ae77Skettenis return inferior_ptid;
4127b725ae77Skettenis }
4128b725ae77Skettenis else if (syscall_is_lwp_exit (pi, what))
4129b725ae77Skettenis {
4130b725ae77Skettenis printf_filtered ("[%s exited]\n",
4131b725ae77Skettenis target_pid_to_str (retval));
4132b725ae77Skettenis delete_thread (retval);
4133b725ae77Skettenis status->kind = TARGET_WAITKIND_SPURIOUS;
4134b725ae77Skettenis return retval;
4135b725ae77Skettenis }
4136b725ae77Skettenis else if (0)
4137b725ae77Skettenis {
4138b725ae77Skettenis /* FIXME: Do we need to handle SYS_sproc,
4139b725ae77Skettenis SYS_fork, or SYS_vfork here? The old procfs
4140b725ae77Skettenis seemed to use this event to handle threads on
4141b725ae77Skettenis older (non-LWP) systems, where I'm assuming
4142b725ae77Skettenis that threads were actually separate processes.
4143b725ae77Skettenis Irix, maybe? Anyway, low priority for now. */
4144b725ae77Skettenis }
4145b725ae77Skettenis else
4146b725ae77Skettenis {
4147b725ae77Skettenis printf_filtered ("procfs: trapped on exit from ");
4148b725ae77Skettenis proc_prettyprint_syscall (proc_what (pi), 0);
4149b725ae77Skettenis printf_filtered ("\n");
4150b725ae77Skettenis #ifndef PIOCSSPCACT
4151b725ae77Skettenis {
4152b725ae77Skettenis long i, nsysargs, *sysargs;
4153b725ae77Skettenis
4154b725ae77Skettenis if ((nsysargs = proc_nsysarg (pi)) > 0 &&
4155b725ae77Skettenis (sysargs = proc_sysargs (pi)) != NULL)
4156b725ae77Skettenis {
4157b725ae77Skettenis printf_filtered ("%ld syscall arguments:\n", nsysargs);
4158b725ae77Skettenis for (i = 0; i < nsysargs; i++)
4159b725ae77Skettenis printf_filtered ("#%ld: 0x%08lx\n",
4160b725ae77Skettenis i, sysargs[i]);
4161b725ae77Skettenis }
4162b725ae77Skettenis }
4163b725ae77Skettenis #endif
4164b725ae77Skettenis status->kind = TARGET_WAITKIND_SPURIOUS;
4165b725ae77Skettenis return inferior_ptid;
4166b725ae77Skettenis }
4167b725ae77Skettenis break;
4168b725ae77Skettenis case PR_REQUESTED:
4169b725ae77Skettenis #if 0 /* FIXME */
4170b725ae77Skettenis wstat = (SIGSTOP << 8) | 0177;
4171b725ae77Skettenis break;
4172b725ae77Skettenis #else
4173b725ae77Skettenis if (retry < 5)
4174b725ae77Skettenis {
4175b725ae77Skettenis printf_filtered ("Retry #%d:\n", retry);
4176b725ae77Skettenis pi->status_valid = 0;
4177b725ae77Skettenis goto wait_again;
4178b725ae77Skettenis }
4179b725ae77Skettenis else
4180b725ae77Skettenis {
4181b725ae77Skettenis /* If not in procinfo list, add it. */
4182b725ae77Skettenis temp_tid = proc_get_current_thread (pi);
4183b725ae77Skettenis if (!find_procinfo (pi->pid, temp_tid))
4184b725ae77Skettenis create_procinfo (pi->pid, temp_tid);
4185b725ae77Skettenis
4186b725ae77Skettenis /* If not in GDB's thread list, add it. */
4187b725ae77Skettenis temp_ptid = MERGEPID (pi->pid, temp_tid);
4188b725ae77Skettenis if (!in_thread_list (temp_ptid))
4189b725ae77Skettenis {
4190b725ae77Skettenis printf_filtered ("[New %s]\n",
4191b725ae77Skettenis target_pid_to_str (temp_ptid));
4192b725ae77Skettenis add_thread (temp_ptid);
4193b725ae77Skettenis }
4194b725ae77Skettenis
4195b725ae77Skettenis status->kind = TARGET_WAITKIND_STOPPED;
4196b725ae77Skettenis status->value.sig = 0;
4197b725ae77Skettenis return retval;
4198b725ae77Skettenis }
4199b725ae77Skettenis #endif
4200b725ae77Skettenis case PR_JOBCONTROL:
4201b725ae77Skettenis wstat = (what << 8) | 0177;
4202b725ae77Skettenis break;
4203b725ae77Skettenis case PR_FAULTED:
4204b725ae77Skettenis switch (what) {
4205b725ae77Skettenis #ifdef FLTWATCH
4206b725ae77Skettenis case FLTWATCH:
4207b725ae77Skettenis wstat = (SIGTRAP << 8) | 0177;
4208b725ae77Skettenis break;
4209b725ae77Skettenis #endif
4210b725ae77Skettenis #ifdef FLTKWATCH
4211b725ae77Skettenis case FLTKWATCH:
4212b725ae77Skettenis wstat = (SIGTRAP << 8) | 0177;
4213b725ae77Skettenis break;
4214b725ae77Skettenis #endif
4215b725ae77Skettenis /* FIXME: use si_signo where possible. */
4216b725ae77Skettenis case FLTPRIV:
4217b725ae77Skettenis #if (FLTILL != FLTPRIV) /* avoid "duplicate case" error */
4218b725ae77Skettenis case FLTILL:
4219b725ae77Skettenis #endif
4220b725ae77Skettenis wstat = (SIGILL << 8) | 0177;
4221b725ae77Skettenis break;
4222b725ae77Skettenis case FLTBPT:
4223b725ae77Skettenis #if (FLTTRACE != FLTBPT) /* avoid "duplicate case" error */
4224b725ae77Skettenis case FLTTRACE:
4225b725ae77Skettenis #endif
4226*63addd46Skettenis /* If we hit our __dbx_link() internal breakpoint,
4227*63addd46Skettenis then remove it. See comments in procfs_init_inferior()
4228*63addd46Skettenis for more details. */
4229*63addd46Skettenis if (dbx_link_bpt_addr != 0
4230*63addd46Skettenis && dbx_link_bpt_addr == read_pc ())
4231*63addd46Skettenis remove_dbx_link_breakpoint ();
4232*63addd46Skettenis
4233b725ae77Skettenis wstat = (SIGTRAP << 8) | 0177;
4234b725ae77Skettenis break;
4235b725ae77Skettenis case FLTSTACK:
4236b725ae77Skettenis case FLTACCESS:
4237b725ae77Skettenis #if (FLTBOUNDS != FLTSTACK) /* avoid "duplicate case" error */
4238b725ae77Skettenis case FLTBOUNDS:
4239b725ae77Skettenis #endif
4240b725ae77Skettenis wstat = (SIGSEGV << 8) | 0177;
4241b725ae77Skettenis break;
4242b725ae77Skettenis case FLTIOVF:
4243b725ae77Skettenis case FLTIZDIV:
4244b725ae77Skettenis #if (FLTFPE != FLTIOVF) /* avoid "duplicate case" error */
4245b725ae77Skettenis case FLTFPE:
4246b725ae77Skettenis #endif
4247b725ae77Skettenis wstat = (SIGFPE << 8) | 0177;
4248b725ae77Skettenis break;
4249b725ae77Skettenis case FLTPAGE: /* Recoverable page fault */
4250b725ae77Skettenis default: /* FIXME: use si_signo if possible for fault */
4251b725ae77Skettenis retval = pid_to_ptid (-1);
4252b725ae77Skettenis printf_filtered ("procfs:%d -- ", __LINE__);
4253b725ae77Skettenis printf_filtered ("child stopped for unknown reason:\n");
4254b725ae77Skettenis proc_prettyprint_why (why, what, 1);
4255b725ae77Skettenis error ("... giving up...");
4256b725ae77Skettenis break;
4257b725ae77Skettenis }
4258b725ae77Skettenis break; /* case PR_FAULTED: */
4259b725ae77Skettenis default: /* switch (why) unmatched */
4260b725ae77Skettenis printf_filtered ("procfs:%d -- ", __LINE__);
4261b725ae77Skettenis printf_filtered ("child stopped for unknown reason:\n");
4262b725ae77Skettenis proc_prettyprint_why (why, what, 1);
4263b725ae77Skettenis error ("... giving up...");
4264b725ae77Skettenis break;
4265b725ae77Skettenis }
4266b725ae77Skettenis /*
4267b725ae77Skettenis * Got this far without error:
4268b725ae77Skettenis * If retval isn't in the threads database, add it.
4269b725ae77Skettenis */
4270b725ae77Skettenis if (PIDGET (retval) > 0 &&
4271b725ae77Skettenis !ptid_equal (retval, inferior_ptid) &&
4272b725ae77Skettenis !in_thread_list (retval))
4273b725ae77Skettenis {
4274b725ae77Skettenis /*
4275b725ae77Skettenis * We have a new thread.
4276b725ae77Skettenis * We need to add it both to GDB's list and to our own.
4277b725ae77Skettenis * If we don't create a procinfo, resume may be unhappy
4278b725ae77Skettenis * later.
4279b725ae77Skettenis */
4280b725ae77Skettenis printf_filtered ("[New %s]\n", target_pid_to_str (retval));
4281b725ae77Skettenis add_thread (retval);
4282b725ae77Skettenis if (find_procinfo (PIDGET (retval), TIDGET (retval)) == NULL)
4283b725ae77Skettenis create_procinfo (PIDGET (retval), TIDGET (retval));
4284b725ae77Skettenis
4285b725ae77Skettenis /* In addition, it's possible that this is the first
4286b725ae77Skettenis * new thread we've seen, in which case we may not
4287b725ae77Skettenis * have created entries for inferior_ptid yet.
4288b725ae77Skettenis */
4289b725ae77Skettenis if (TIDGET (inferior_ptid) != 0)
4290b725ae77Skettenis {
4291b725ae77Skettenis if (!in_thread_list (inferior_ptid))
4292b725ae77Skettenis add_thread (inferior_ptid);
4293b725ae77Skettenis if (find_procinfo (PIDGET (inferior_ptid),
4294b725ae77Skettenis TIDGET (inferior_ptid)) == NULL)
4295b725ae77Skettenis create_procinfo (PIDGET (inferior_ptid),
4296b725ae77Skettenis TIDGET (inferior_ptid));
4297b725ae77Skettenis }
4298b725ae77Skettenis }
4299b725ae77Skettenis }
4300b725ae77Skettenis else /* flags do not indicate STOPPED */
4301b725ae77Skettenis {
4302b725ae77Skettenis /* surely this can't happen... */
4303b725ae77Skettenis printf_filtered ("procfs:%d -- process not stopped.\n",
4304b725ae77Skettenis __LINE__);
4305b725ae77Skettenis proc_prettyprint_flags (flags, 1);
4306b725ae77Skettenis error ("procfs: ...giving up...");
4307b725ae77Skettenis }
4308b725ae77Skettenis }
4309b725ae77Skettenis
4310b725ae77Skettenis if (status)
4311b725ae77Skettenis store_waitstatus (status, wstat);
4312b725ae77Skettenis }
4313b725ae77Skettenis
4314b725ae77Skettenis return retval;
4315b725ae77Skettenis }
4316b725ae77Skettenis
4317b725ae77Skettenis /* Perform a partial transfer to/from the specified object. For
4318b725ae77Skettenis memory transfers, fall back to the old memory xfer functions. */
4319b725ae77Skettenis
4320b725ae77Skettenis static LONGEST
procfs_xfer_partial(struct target_ops * ops,enum target_object object,const char * annex,void * readbuf,const void * writebuf,ULONGEST offset,LONGEST len)4321b725ae77Skettenis procfs_xfer_partial (struct target_ops *ops, enum target_object object,
4322b725ae77Skettenis const char *annex, void *readbuf,
4323b725ae77Skettenis const void *writebuf, ULONGEST offset, LONGEST len)
4324b725ae77Skettenis {
4325b725ae77Skettenis switch (object)
4326b725ae77Skettenis {
4327b725ae77Skettenis case TARGET_OBJECT_MEMORY:
4328b725ae77Skettenis if (readbuf)
4329*63addd46Skettenis return (*ops->deprecated_xfer_memory) (offset, readbuf, len,
4330*63addd46Skettenis 0/*write*/, NULL, ops);
4331b725ae77Skettenis if (writebuf)
4332*63addd46Skettenis return (*ops->deprecated_xfer_memory) (offset, writebuf, len,
4333*63addd46Skettenis 1/*write*/, NULL, ops);
4334b725ae77Skettenis return -1;
4335b725ae77Skettenis
4336b725ae77Skettenis #ifdef NEW_PROC_API
4337b725ae77Skettenis case TARGET_OBJECT_AUXV:
4338b725ae77Skettenis return procfs_xfer_auxv (ops, object, annex, readbuf, writebuf,
4339b725ae77Skettenis offset, len);
4340b725ae77Skettenis #endif
4341b725ae77Skettenis
4342b725ae77Skettenis default:
4343b725ae77Skettenis if (ops->beneath != NULL)
4344b725ae77Skettenis return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
4345b725ae77Skettenis readbuf, writebuf, offset, len);
4346b725ae77Skettenis return -1;
4347b725ae77Skettenis }
4348b725ae77Skettenis }
4349b725ae77Skettenis
4350b725ae77Skettenis
4351b725ae77Skettenis /* Transfer LEN bytes between GDB address MYADDR and target address
4352b725ae77Skettenis MEMADDR. If DOWRITE is non-zero, transfer them to the target,
4353b725ae77Skettenis otherwise transfer them from the target. TARGET is unused.
4354b725ae77Skettenis
4355b725ae77Skettenis The return value is 0 if an error occurred or no bytes were
4356b725ae77Skettenis transferred. Otherwise, it will be a positive value which
4357b725ae77Skettenis indicates the number of bytes transferred between gdb and the
4358b725ae77Skettenis target. (Note that the interface also makes provisions for
4359b725ae77Skettenis negative values, but this capability isn't implemented here.) */
4360b725ae77Skettenis
4361b725ae77Skettenis static int
procfs_xfer_memory(CORE_ADDR memaddr,char * myaddr,int len,int dowrite,struct mem_attrib * attrib,struct target_ops * target)4362b725ae77Skettenis procfs_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int dowrite,
4363b725ae77Skettenis struct mem_attrib *attrib, struct target_ops *target)
4364b725ae77Skettenis {
4365b725ae77Skettenis procinfo *pi;
4366b725ae77Skettenis int nbytes = 0;
4367b725ae77Skettenis
4368b725ae77Skettenis /* Find procinfo for main process */
4369b725ae77Skettenis pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
4370b725ae77Skettenis if (pi->as_fd == 0 &&
4371b725ae77Skettenis open_procinfo_files (pi, FD_AS) == 0)
4372b725ae77Skettenis {
4373b725ae77Skettenis proc_warn (pi, "xfer_memory, open_proc_files", __LINE__);
4374b725ae77Skettenis return 0;
4375b725ae77Skettenis }
4376b725ae77Skettenis
4377b725ae77Skettenis if (lseek (pi->as_fd, (off_t) memaddr, SEEK_SET) == (off_t) memaddr)
4378b725ae77Skettenis {
4379b725ae77Skettenis if (dowrite)
4380b725ae77Skettenis {
4381b725ae77Skettenis #ifdef NEW_PROC_API
4382b725ae77Skettenis PROCFS_NOTE ("write memory: ");
4383b725ae77Skettenis #else
4384b725ae77Skettenis PROCFS_NOTE ("write memory: \n");
4385b725ae77Skettenis #endif
4386b725ae77Skettenis nbytes = write (pi->as_fd, myaddr, len);
4387b725ae77Skettenis }
4388b725ae77Skettenis else
4389b725ae77Skettenis {
4390b725ae77Skettenis PROCFS_NOTE ("read memory: \n");
4391b725ae77Skettenis nbytes = read (pi->as_fd, myaddr, len);
4392b725ae77Skettenis }
4393b725ae77Skettenis if (nbytes < 0)
4394b725ae77Skettenis {
4395b725ae77Skettenis nbytes = 0;
4396b725ae77Skettenis }
4397b725ae77Skettenis }
4398b725ae77Skettenis return nbytes;
4399b725ae77Skettenis }
4400b725ae77Skettenis
4401b725ae77Skettenis /*
4402b725ae77Skettenis * Function: invalidate_cache
4403b725ae77Skettenis *
4404b725ae77Skettenis * Called by target_resume before making child runnable.
4405b725ae77Skettenis * Mark cached registers and status's invalid.
4406b725ae77Skettenis * If there are "dirty" caches that need to be written back
4407b725ae77Skettenis * to the child process, do that.
4408b725ae77Skettenis *
4409b725ae77Skettenis * File descriptors are also cached.
4410b725ae77Skettenis * As they are a limited resource, we cannot hold onto them indefinitely.
4411b725ae77Skettenis * However, as they are expensive to open, we don't want to throw them
4412b725ae77Skettenis * away indescriminately either. As a compromise, we will keep the
4413b725ae77Skettenis * file descriptors for the parent process, but discard any file
4414b725ae77Skettenis * descriptors we may have accumulated for the threads.
4415b725ae77Skettenis *
4416b725ae77Skettenis * Return value:
4417b725ae77Skettenis * As this function is called by iterate_over_threads, it always
4418b725ae77Skettenis * returns zero (so that iterate_over_threads will keep iterating).
4419b725ae77Skettenis */
4420b725ae77Skettenis
4421b725ae77Skettenis
4422b725ae77Skettenis static int
invalidate_cache(procinfo * parent,procinfo * pi,void * ptr)4423b725ae77Skettenis invalidate_cache (procinfo *parent, procinfo *pi, void *ptr)
4424b725ae77Skettenis {
4425b725ae77Skettenis /*
4426b725ae77Skettenis * About to run the child; invalidate caches and do any other cleanup.
4427b725ae77Skettenis */
4428b725ae77Skettenis
4429b725ae77Skettenis #if 0
4430b725ae77Skettenis if (pi->gregs_dirty)
4431b725ae77Skettenis if (parent == NULL ||
4432b725ae77Skettenis proc_get_current_thread (parent) != pi->tid)
4433b725ae77Skettenis if (!proc_set_gregs (pi)) /* flush gregs cache */
4434b725ae77Skettenis proc_warn (pi, "target_resume, set_gregs",
4435b725ae77Skettenis __LINE__);
4436b725ae77Skettenis if (FP0_REGNUM >= 0)
4437b725ae77Skettenis if (pi->fpregs_dirty)
4438b725ae77Skettenis if (parent == NULL ||
4439b725ae77Skettenis proc_get_current_thread (parent) != pi->tid)
4440b725ae77Skettenis if (!proc_set_fpregs (pi)) /* flush fpregs cache */
4441b725ae77Skettenis proc_warn (pi, "target_resume, set_fpregs",
4442b725ae77Skettenis __LINE__);
4443b725ae77Skettenis #endif
4444b725ae77Skettenis
4445b725ae77Skettenis if (parent != NULL)
4446b725ae77Skettenis {
4447b725ae77Skettenis /* The presence of a parent indicates that this is an LWP.
4448b725ae77Skettenis Close any file descriptors that it might have open.
4449b725ae77Skettenis We don't do this to the master (parent) procinfo. */
4450b725ae77Skettenis
4451b725ae77Skettenis close_procinfo_files (pi);
4452b725ae77Skettenis }
4453b725ae77Skettenis pi->gregs_valid = 0;
4454b725ae77Skettenis pi->fpregs_valid = 0;
4455b725ae77Skettenis #if 0
4456b725ae77Skettenis pi->gregs_dirty = 0;
4457b725ae77Skettenis pi->fpregs_dirty = 0;
4458b725ae77Skettenis #endif
4459b725ae77Skettenis pi->status_valid = 0;
4460b725ae77Skettenis pi->threads_valid = 0;
4461b725ae77Skettenis
4462b725ae77Skettenis return 0;
4463b725ae77Skettenis }
4464b725ae77Skettenis
4465b725ae77Skettenis #if 0
4466b725ae77Skettenis /*
4467b725ae77Skettenis * Function: make_signal_thread_runnable
4468b725ae77Skettenis *
4469b725ae77Skettenis * A callback function for iterate_over_threads.
4470b725ae77Skettenis * Find the asynchronous signal thread, and make it runnable.
4471b725ae77Skettenis * See if that helps matters any.
4472b725ae77Skettenis */
4473b725ae77Skettenis
4474b725ae77Skettenis static int
4475b725ae77Skettenis make_signal_thread_runnable (procinfo *process, procinfo *pi, void *ptr)
4476b725ae77Skettenis {
4477b725ae77Skettenis #ifdef PR_ASLWP
4478b725ae77Skettenis if (proc_flags (pi) & PR_ASLWP)
4479b725ae77Skettenis {
4480b725ae77Skettenis if (!proc_run_process (pi, 0, -1))
4481b725ae77Skettenis proc_error (pi, "make_signal_thread_runnable", __LINE__);
4482b725ae77Skettenis return 1;
4483b725ae77Skettenis }
4484b725ae77Skettenis #endif
4485b725ae77Skettenis return 0;
4486b725ae77Skettenis }
4487b725ae77Skettenis #endif
4488b725ae77Skettenis
4489b725ae77Skettenis /*
4490b725ae77Skettenis * Function: target_resume
4491b725ae77Skettenis *
4492b725ae77Skettenis * Make the child process runnable. Normally we will then call
4493b725ae77Skettenis * procfs_wait and wait for it to stop again (unles gdb is async).
4494b725ae77Skettenis *
4495b725ae77Skettenis * Arguments:
4496b725ae77Skettenis * step: if true, then arrange for the child to stop again
4497b725ae77Skettenis * after executing a single instruction.
4498b725ae77Skettenis * signo: if zero, then cancel any pending signal.
4499b725ae77Skettenis * If non-zero, then arrange for the indicated signal
4500b725ae77Skettenis * to be delivered to the child when it runs.
4501b725ae77Skettenis * pid: if -1, then allow any child thread to run.
4502b725ae77Skettenis * if non-zero, then allow only the indicated thread to run.
4503b725ae77Skettenis ******* (not implemented yet)
4504b725ae77Skettenis */
4505b725ae77Skettenis
4506e93f7393Sniklas static void
procfs_resume(ptid_t ptid,int step,enum target_signal signo)4507b725ae77Skettenis procfs_resume (ptid_t ptid, int step, enum target_signal signo)
4508b725ae77Skettenis {
4509b725ae77Skettenis procinfo *pi, *thread;
4510b725ae77Skettenis int native_signo;
4511b725ae77Skettenis
4512b725ae77Skettenis /* 2.1:
4513b725ae77Skettenis prrun.prflags |= PRSVADDR;
4514b725ae77Skettenis prrun.pr_vaddr = $PC; set resume address
4515b725ae77Skettenis prrun.prflags |= PRSTRACE; trace signals in pr_trace (all)
4516b725ae77Skettenis prrun.prflags |= PRSFAULT; trace faults in pr_fault (all but PAGE)
4517b725ae77Skettenis prrun.prflags |= PRCFAULT; clear current fault.
4518b725ae77Skettenis
4519b725ae77Skettenis PRSTRACE and PRSFAULT can be done by other means
4520b725ae77Skettenis (proc_trace_signals, proc_trace_faults)
4521b725ae77Skettenis PRSVADDR is unnecessary.
4522b725ae77Skettenis PRCFAULT may be replaced by a PIOCCFAULT call (proc_clear_current_fault)
4523b725ae77Skettenis This basically leaves PRSTEP and PRCSIG.
4524b725ae77Skettenis PRCSIG is like PIOCSSIG (proc_clear_current_signal).
4525b725ae77Skettenis So basically PR_STEP is the sole argument that must be passed
4526b725ae77Skettenis to proc_run_process (for use in the prrun struct by ioctl). */
4527b725ae77Skettenis
4528b725ae77Skettenis /* Find procinfo for main process */
4529b725ae77Skettenis pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
4530b725ae77Skettenis
4531b725ae77Skettenis /* First cut: ignore pid argument */
4532b725ae77Skettenis errno = 0;
4533b725ae77Skettenis
4534b725ae77Skettenis /* Convert signal to host numbering. */
4535b725ae77Skettenis if (signo == 0 ||
4536b725ae77Skettenis (signo == TARGET_SIGNAL_STOP && pi->ignore_next_sigstop))
4537b725ae77Skettenis native_signo = 0;
4538b725ae77Skettenis else
4539b725ae77Skettenis native_signo = target_signal_to_host (signo);
4540b725ae77Skettenis
4541b725ae77Skettenis pi->ignore_next_sigstop = 0;
4542b725ae77Skettenis
4543b725ae77Skettenis /* Running the process voids all cached registers and status. */
4544b725ae77Skettenis /* Void the threads' caches first */
4545b725ae77Skettenis proc_iterate_over_threads (pi, invalidate_cache, NULL);
4546b725ae77Skettenis /* Void the process procinfo's caches. */
4547b725ae77Skettenis invalidate_cache (NULL, pi, NULL);
4548b725ae77Skettenis
4549b725ae77Skettenis if (PIDGET (ptid) != -1)
4550b725ae77Skettenis {
4551b725ae77Skettenis /* Resume a specific thread, presumably suppressing the others. */
4552b725ae77Skettenis thread = find_procinfo (PIDGET (ptid), TIDGET (ptid));
4553b725ae77Skettenis if (thread != NULL)
4554b725ae77Skettenis {
4555b725ae77Skettenis if (thread->tid != 0)
4556b725ae77Skettenis {
4557b725ae77Skettenis /* We're to resume a specific thread, and not the others.
4558b725ae77Skettenis * Set the child process's PR_ASYNC flag.
4559b725ae77Skettenis */
4560b725ae77Skettenis #ifdef PR_ASYNC
4561b725ae77Skettenis if (!proc_set_async (pi))
4562b725ae77Skettenis proc_error (pi, "target_resume, set_async", __LINE__);
4563b725ae77Skettenis #endif
4564b725ae77Skettenis #if 0
4565b725ae77Skettenis proc_iterate_over_threads (pi,
4566b725ae77Skettenis make_signal_thread_runnable,
4567b725ae77Skettenis NULL);
4568b725ae77Skettenis #endif
4569b725ae77Skettenis pi = thread; /* substitute the thread's procinfo for run */
4570b725ae77Skettenis }
4571b725ae77Skettenis }
4572b725ae77Skettenis }
4573b725ae77Skettenis
4574b725ae77Skettenis if (!proc_run_process (pi, step, native_signo))
4575b725ae77Skettenis {
4576b725ae77Skettenis if (errno == EBUSY)
4577b725ae77Skettenis warning ("resume: target already running. Pretend to resume, and hope for the best!\n");
4578b725ae77Skettenis else
4579b725ae77Skettenis proc_error (pi, "target_resume", __LINE__);
4580b725ae77Skettenis }
4581b725ae77Skettenis }
4582b725ae77Skettenis
4583b725ae77Skettenis /*
4584b725ae77Skettenis * Function: register_gdb_signals
4585b725ae77Skettenis *
4586b725ae77Skettenis * Traverse the list of signals that GDB knows about
4587b725ae77Skettenis * (see "handle" command), and arrange for the target
4588b725ae77Skettenis * to be stopped or not, according to these settings.
4589b725ae77Skettenis *
4590b725ae77Skettenis * Returns non-zero for success, zero for failure.
4591b725ae77Skettenis */
4592b725ae77Skettenis
4593b725ae77Skettenis static int
register_gdb_signals(procinfo * pi,gdb_sigset_t * signals)4594b725ae77Skettenis register_gdb_signals (procinfo *pi, gdb_sigset_t *signals)
4595b725ae77Skettenis {
4596b725ae77Skettenis int signo;
4597b725ae77Skettenis
4598b725ae77Skettenis for (signo = 0; signo < NSIG; signo ++)
4599b725ae77Skettenis if (signal_stop_state (target_signal_from_host (signo)) == 0 &&
4600b725ae77Skettenis signal_print_state (target_signal_from_host (signo)) == 0 &&
4601b725ae77Skettenis signal_pass_state (target_signal_from_host (signo)) == 1)
4602b725ae77Skettenis prdelset (signals, signo);
4603b725ae77Skettenis else
4604b725ae77Skettenis praddset (signals, signo);
4605b725ae77Skettenis
4606b725ae77Skettenis return proc_set_traced_signals (pi, signals);
4607b725ae77Skettenis }
4608b725ae77Skettenis
4609b725ae77Skettenis /*
4610b725ae77Skettenis * Function: target_notice_signals
4611b725ae77Skettenis *
4612b725ae77Skettenis * Set up to trace signals in the child process.
4613b725ae77Skettenis */
4614b725ae77Skettenis
4615b725ae77Skettenis static void
procfs_notice_signals(ptid_t ptid)4616b725ae77Skettenis procfs_notice_signals (ptid_t ptid)
4617b725ae77Skettenis {
4618b725ae77Skettenis gdb_sigset_t signals;
4619b725ae77Skettenis procinfo *pi = find_procinfo_or_die (PIDGET (ptid), 0);
4620b725ae77Skettenis
4621b725ae77Skettenis if (proc_get_traced_signals (pi, &signals) &&
4622b725ae77Skettenis register_gdb_signals (pi, &signals))
4623b725ae77Skettenis return;
4624b725ae77Skettenis else
4625b725ae77Skettenis proc_error (pi, "notice_signals", __LINE__);
4626b725ae77Skettenis }
4627b725ae77Skettenis
4628b725ae77Skettenis /*
4629b725ae77Skettenis * Function: target_files_info
4630b725ae77Skettenis *
4631b725ae77Skettenis * Print status information about the child process.
4632b725ae77Skettenis */
4633b725ae77Skettenis
4634b725ae77Skettenis static void
procfs_files_info(struct target_ops * ignore)4635b725ae77Skettenis procfs_files_info (struct target_ops *ignore)
4636b725ae77Skettenis {
4637b725ae77Skettenis printf_filtered ("\tUsing the running image of %s %s via /proc.\n",
4638b725ae77Skettenis attach_flag? "attached": "child",
4639b725ae77Skettenis target_pid_to_str (inferior_ptid));
4640b725ae77Skettenis }
4641b725ae77Skettenis
4642b725ae77Skettenis /*
4643b725ae77Skettenis * Function: target_open
4644b725ae77Skettenis *
4645b725ae77Skettenis * A dummy: you don't open procfs.
4646b725ae77Skettenis */
4647b725ae77Skettenis
4648b725ae77Skettenis static void
procfs_open(char * args,int from_tty)4649b725ae77Skettenis procfs_open (char *args, int from_tty)
4650e93f7393Sniklas {
4651e93f7393Sniklas error ("Use the \"run\" command to start a Unix child process.");
4652e93f7393Sniklas }
4653e93f7393Sniklas
4654e93f7393Sniklas /*
4655b725ae77Skettenis * Function: target_can_run
4656b725ae77Skettenis *
4657b725ae77Skettenis * This tells GDB that this target vector can be invoked
4658b725ae77Skettenis * for "run" or "attach".
4659e93f7393Sniklas */
4660e93f7393Sniklas
4661b725ae77Skettenis int procfs_suppress_run = 0; /* Non-zero if procfs should pretend not to
4662b725ae77Skettenis be a runnable target. Used by targets
4663b725ae77Skettenis that can sit atop procfs, such as solaris
4664b725ae77Skettenis thread support. */
4665b725ae77Skettenis
4666b725ae77Skettenis
4667e93f7393Sniklas static int
procfs_can_run(void)4668b725ae77Skettenis procfs_can_run (void)
4669e93f7393Sniklas {
4670b725ae77Skettenis /* This variable is controlled by modules that sit atop procfs that
4671b725ae77Skettenis may layer their own process structure atop that provided here.
4672b725ae77Skettenis sol-thread.c does this because of the Solaris two-level thread
4673b725ae77Skettenis model. */
4674e93f7393Sniklas
4675b725ae77Skettenis /* NOTE: possibly obsolete -- use the thread_stratum approach instead. */
4676e93f7393Sniklas
4677b725ae77Skettenis return !procfs_suppress_run;
4678e93f7393Sniklas }
4679e93f7393Sniklas
4680e93f7393Sniklas /*
4681b725ae77Skettenis * Function: target_stop
4682b725ae77Skettenis *
4683b725ae77Skettenis * Stop the child process asynchronously, as when the
4684b725ae77Skettenis * gdb user types control-c or presses a "stop" button.
4685b725ae77Skettenis *
4686b725ae77Skettenis * Works by sending kill(SIGINT) to the child's process group.
4687e93f7393Sniklas */
4688e93f7393Sniklas
4689e93f7393Sniklas static void
procfs_stop(void)4690b725ae77Skettenis procfs_stop (void)
4691e93f7393Sniklas {
4692b725ae77Skettenis kill (-inferior_process_group, SIGINT);
4693e93f7393Sniklas }
4694e93f7393Sniklas
4695b725ae77Skettenis /*
4696b725ae77Skettenis * Function: unconditionally_kill_inferior
4697b725ae77Skettenis *
4698b725ae77Skettenis * Make it die. Wait for it to die. Clean up after it.
4699b725ae77Skettenis * Note: this should only be applied to the real process,
4700b725ae77Skettenis * not to an LWP, because of the check for parent-process.
4701b725ae77Skettenis * If we need this to work for an LWP, it needs some more logic.
4702b725ae77Skettenis */
4703e93f7393Sniklas
4704b725ae77Skettenis static void
unconditionally_kill_inferior(procinfo * pi)4705b725ae77Skettenis unconditionally_kill_inferior (procinfo *pi)
4706e93f7393Sniklas {
4707b725ae77Skettenis int parent_pid;
4708e93f7393Sniklas
4709b725ae77Skettenis parent_pid = proc_parent_pid (pi);
4710b725ae77Skettenis #ifdef PROCFS_NEED_CLEAR_CURSIG_FOR_KILL
4711b725ae77Skettenis /* FIXME: use access functions */
4712b725ae77Skettenis /* Alpha OSF/1-3.x procfs needs a clear of the current signal
4713b725ae77Skettenis before the PIOCKILL, otherwise it might generate a corrupted core
4714b725ae77Skettenis file for the inferior. */
4715b725ae77Skettenis if (ioctl (pi->ctl_fd, PIOCSSIG, NULL) < 0)
4716e93f7393Sniklas {
4717b725ae77Skettenis printf_filtered ("unconditionally_kill: SSIG failed!\n");
4718b725ae77Skettenis }
4719b725ae77Skettenis #endif
4720b725ae77Skettenis #ifdef PROCFS_NEED_PIOCSSIG_FOR_KILL
4721b725ae77Skettenis /* Alpha OSF/1-2.x procfs needs a PIOCSSIG call with a SIGKILL signal
4722b725ae77Skettenis to kill the inferior, otherwise it might remain stopped with a
4723b725ae77Skettenis pending SIGKILL.
4724b725ae77Skettenis We do not check the result of the PIOCSSIG, the inferior might have
4725b725ae77Skettenis died already. */
4726b725ae77Skettenis {
4727b725ae77Skettenis gdb_siginfo_t newsiginfo;
4728b725ae77Skettenis
4729b725ae77Skettenis memset ((char *) &newsiginfo, 0, sizeof (newsiginfo));
4730b725ae77Skettenis newsiginfo.si_signo = SIGKILL;
4731b725ae77Skettenis newsiginfo.si_code = 0;
4732b725ae77Skettenis newsiginfo.si_errno = 0;
4733b725ae77Skettenis newsiginfo.si_pid = getpid ();
4734b725ae77Skettenis newsiginfo.si_uid = getuid ();
4735b725ae77Skettenis /* FIXME: use proc_set_current_signal */
4736b725ae77Skettenis ioctl (pi->ctl_fd, PIOCSSIG, &newsiginfo);
4737b725ae77Skettenis }
4738b725ae77Skettenis #else /* PROCFS_NEED_PIOCSSIG_FOR_KILL */
4739b725ae77Skettenis if (!proc_kill (pi, SIGKILL))
4740b725ae77Skettenis proc_error (pi, "unconditionally_kill, proc_kill", __LINE__);
4741b725ae77Skettenis #endif /* PROCFS_NEED_PIOCSSIG_FOR_KILL */
4742b725ae77Skettenis destroy_procinfo (pi);
4743b725ae77Skettenis
4744b725ae77Skettenis /* If pi is GDB's child, wait for it to die. */
4745b725ae77Skettenis if (parent_pid == getpid ())
4746b725ae77Skettenis /* FIXME: should we use waitpid to make sure we get the right event?
4747b725ae77Skettenis Should we check the returned event? */
4748b725ae77Skettenis {
4749b725ae77Skettenis #if 0
4750b725ae77Skettenis int status, ret;
4751b725ae77Skettenis
4752b725ae77Skettenis ret = waitpid (pi->pid, &status, 0);
4753b725ae77Skettenis #else
4754b725ae77Skettenis wait (NULL);
4755b725ae77Skettenis #endif
4756b725ae77Skettenis }
4757b725ae77Skettenis }
4758b725ae77Skettenis
4759b725ae77Skettenis /*
4760b725ae77Skettenis * Function: target_kill_inferior
4761b725ae77Skettenis *
4762b725ae77Skettenis * We're done debugging it, and we want it to go away.
4763b725ae77Skettenis * Then we want GDB to forget all about it.
4764b725ae77Skettenis */
4765b725ae77Skettenis
4766b725ae77Skettenis static void
procfs_kill_inferior(void)4767b725ae77Skettenis procfs_kill_inferior (void)
4768b725ae77Skettenis {
4769b725ae77Skettenis if (!ptid_equal (inferior_ptid, null_ptid)) /* ? */
4770b725ae77Skettenis {
4771b725ae77Skettenis /* Find procinfo for main process */
4772b725ae77Skettenis procinfo *pi = find_procinfo (PIDGET (inferior_ptid), 0);
4773e93f7393Sniklas
4774e93f7393Sniklas if (pi)
4775b725ae77Skettenis unconditionally_kill_inferior (pi);
4776b725ae77Skettenis target_mourn_inferior ();
4777e93f7393Sniklas }
4778e93f7393Sniklas }
4779e93f7393Sniklas
4780e93f7393Sniklas /*
4781b725ae77Skettenis * Function: target_mourn_inferior
4782b725ae77Skettenis *
4783b725ae77Skettenis * Forget we ever debugged this thing!
4784e93f7393Sniklas */
4785e93f7393Sniklas
4786e93f7393Sniklas static void
procfs_mourn_inferior(void)4787b725ae77Skettenis procfs_mourn_inferior (void)
4788e93f7393Sniklas {
4789b725ae77Skettenis procinfo *pi;
4790e93f7393Sniklas
4791b725ae77Skettenis if (!ptid_equal (inferior_ptid, null_ptid))
4792e93f7393Sniklas {
4793b725ae77Skettenis /* Find procinfo for main process */
4794b725ae77Skettenis pi = find_procinfo (PIDGET (inferior_ptid), 0);
4795b725ae77Skettenis if (pi)
4796b725ae77Skettenis destroy_procinfo (pi);
4797e93f7393Sniklas }
4798b725ae77Skettenis unpush_target (&procfs_ops);
4799b725ae77Skettenis generic_mourn_inferior ();
4800e93f7393Sniklas }
4801e93f7393Sniklas
4802e93f7393Sniklas /*
4803b725ae77Skettenis * Function: init_inferior
4804b725ae77Skettenis *
4805b725ae77Skettenis * When GDB forks to create a runnable inferior process,
4806b725ae77Skettenis * this function is called on the parent side of the fork.
4807b725ae77Skettenis * It's job is to do whatever is necessary to make the child
4808b725ae77Skettenis * ready to be debugged, and then wait for the child to synchronize.
4809e93f7393Sniklas */
4810e93f7393Sniklas
4811e93f7393Sniklas static void
procfs_init_inferior(int pid)4812b725ae77Skettenis procfs_init_inferior (int pid)
4813e93f7393Sniklas {
4814b725ae77Skettenis procinfo *pi;
4815b725ae77Skettenis gdb_sigset_t signals;
4816b725ae77Skettenis int fail;
4817b725ae77Skettenis
4818b725ae77Skettenis /* This routine called on the parent side (GDB side)
4819b725ae77Skettenis after GDB forks the inferior. */
4820b725ae77Skettenis
4821b725ae77Skettenis push_target (&procfs_ops);
4822b725ae77Skettenis
4823b725ae77Skettenis if ((pi = create_procinfo (pid, 0)) == NULL)
4824b725ae77Skettenis perror ("procfs: out of memory in 'init_inferior'");
4825b725ae77Skettenis
4826b725ae77Skettenis if (!open_procinfo_files (pi, FD_CTL))
4827b725ae77Skettenis proc_error (pi, "init_inferior, open_proc_files", __LINE__);
4828b725ae77Skettenis
4829b725ae77Skettenis /*
4830b725ae77Skettenis xmalloc // done
4831b725ae77Skettenis open_procinfo_files // done
4832b725ae77Skettenis link list // done
4833b725ae77Skettenis prfillset (trace)
4834b725ae77Skettenis procfs_notice_signals
4835b725ae77Skettenis prfillset (fault)
4836b725ae77Skettenis prdelset (FLTPAGE)
4837b725ae77Skettenis PIOCWSTOP
4838b725ae77Skettenis PIOCSFAULT
4839b725ae77Skettenis */
4840b725ae77Skettenis
4841b725ae77Skettenis /* If not stopped yet, wait for it to stop. */
4842b725ae77Skettenis if (!(proc_flags (pi) & PR_STOPPED) &&
4843b725ae77Skettenis !(proc_wait_for_stop (pi)))
4844b725ae77Skettenis dead_procinfo (pi, "init_inferior: wait_for_stop failed", KILL);
4845b725ae77Skettenis
4846b725ae77Skettenis /* Save some of the /proc state to be restored if we detach. */
4847b725ae77Skettenis /* FIXME: Why? In case another debugger was debugging it?
4848b725ae77Skettenis We're it's parent, for Ghu's sake! */
4849b725ae77Skettenis if (!proc_get_traced_signals (pi, &pi->saved_sigset))
4850b725ae77Skettenis proc_error (pi, "init_inferior, get_traced_signals", __LINE__);
4851b725ae77Skettenis if (!proc_get_held_signals (pi, &pi->saved_sighold))
4852b725ae77Skettenis proc_error (pi, "init_inferior, get_held_signals", __LINE__);
4853b725ae77Skettenis if (!proc_get_traced_faults (pi, &pi->saved_fltset))
4854b725ae77Skettenis proc_error (pi, "init_inferior, get_traced_faults", __LINE__);
4855b725ae77Skettenis if (!proc_get_traced_sysentry (pi, pi->saved_entryset))
4856b725ae77Skettenis proc_error (pi, "init_inferior, get_traced_sysentry", __LINE__);
4857b725ae77Skettenis if (!proc_get_traced_sysexit (pi, pi->saved_exitset))
4858b725ae77Skettenis proc_error (pi, "init_inferior, get_traced_sysexit", __LINE__);
4859b725ae77Skettenis
4860b725ae77Skettenis /* Register to trace selected signals in the child. */
4861b725ae77Skettenis prfillset (&signals);
4862b725ae77Skettenis if (!register_gdb_signals (pi, &signals))
4863b725ae77Skettenis proc_error (pi, "init_inferior, register_signals", __LINE__);
4864b725ae77Skettenis
4865b725ae77Skettenis if ((fail = procfs_debug_inferior (pi)) != 0)
4866b725ae77Skettenis proc_error (pi, "init_inferior (procfs_debug_inferior)", fail);
4867b725ae77Skettenis
4868b725ae77Skettenis /* FIXME: logically, we should really be turning OFF run-on-last-close,
4869b725ae77Skettenis and possibly even turning ON kill-on-last-close at this point. But
4870b725ae77Skettenis I can't make that change without careful testing which I don't have
4871b725ae77Skettenis time to do right now... */
4872b725ae77Skettenis /* Turn on run-on-last-close flag so that the child
4873b725ae77Skettenis will die if GDB goes away for some reason. */
4874b725ae77Skettenis if (!proc_set_run_on_last_close (pi))
4875b725ae77Skettenis proc_error (pi, "init_inferior, set_RLC", __LINE__);
4876b725ae77Skettenis
4877b725ae77Skettenis /* The 'process ID' we return to GDB is composed of
4878b725ae77Skettenis the actual process ID plus the lwp ID. */
4879b725ae77Skettenis inferior_ptid = MERGEPID (pi->pid, proc_get_current_thread (pi));
4880b725ae77Skettenis
4881b725ae77Skettenis /* Typically two, one trap to exec the shell, one to exec the
4882b725ae77Skettenis program being debugged. Defined by "inferior.h". */
4883b725ae77Skettenis startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
4884*63addd46Skettenis
4885*63addd46Skettenis #ifdef SYS_syssgi
4886*63addd46Skettenis /* On mips-irix, we need to stop the inferior early enough during
4887*63addd46Skettenis the startup phase in order to be able to load the shared library
4888*63addd46Skettenis symbols and insert the breakpoints that are located in these shared
4889*63addd46Skettenis libraries. Stopping at the program entry point is not good enough
4890*63addd46Skettenis because the -init code is executed before the execution reaches
4891*63addd46Skettenis that point.
4892*63addd46Skettenis
4893*63addd46Skettenis So what we need to do is to insert a breakpoint in the runtime
4894*63addd46Skettenis loader (rld), more precisely in __dbx_link(). This procedure is
4895*63addd46Skettenis called by rld once all shared libraries have been mapped, but before
4896*63addd46Skettenis the -init code is executed. Unfortuantely, this is not straightforward,
4897*63addd46Skettenis as rld is not part of the executable we are running, and thus we need
4898*63addd46Skettenis the inferior to run until rld itself has been mapped in memory.
4899*63addd46Skettenis
4900*63addd46Skettenis For this, we trace all syssgi() syscall exit events. Each time
4901*63addd46Skettenis we detect such an event, we iterate over each text memory maps,
4902*63addd46Skettenis get its associated fd, and scan the symbol table for __dbx_link().
4903*63addd46Skettenis When found, we know that rld has been mapped, and that we can insert
4904*63addd46Skettenis the breakpoint at the symbol address. Once the dbx_link() breakpoint
4905*63addd46Skettenis has been inserted, the syssgi() notifications are no longer necessary,
4906*63addd46Skettenis so they should be canceled. */
4907*63addd46Skettenis proc_trace_syscalls_1 (pi, SYS_syssgi, PR_SYSEXIT, FLAG_SET, 0);
4908*63addd46Skettenis dbx_link_bpt_addr = 0;
4909*63addd46Skettenis #endif
4910e93f7393Sniklas }
4911e93f7393Sniklas
4912e93f7393Sniklas /*
4913b725ae77Skettenis * Function: set_exec_trap
4914b725ae77Skettenis *
4915b725ae77Skettenis * When GDB forks to create a new process, this function is called
4916b725ae77Skettenis * on the child side of the fork before GDB exec's the user program.
4917b725ae77Skettenis * Its job is to make the child minimally debuggable, so that the
4918b725ae77Skettenis * parent GDB process can connect to the child and take over.
4919b725ae77Skettenis * This function should do only the minimum to make that possible,
4920b725ae77Skettenis * and to synchronize with the parent process. The parent process
4921b725ae77Skettenis * should take care of the details.
4922e93f7393Sniklas */
4923e93f7393Sniklas
4924e93f7393Sniklas static void
procfs_set_exec_trap(void)4925b725ae77Skettenis procfs_set_exec_trap (void)
4926e93f7393Sniklas {
4927b725ae77Skettenis /* This routine called on the child side (inferior side)
4928b725ae77Skettenis after GDB forks the inferior. It must use only local variables,
4929b725ae77Skettenis because it may be sharing data space with its parent. */
4930e93f7393Sniklas
4931b725ae77Skettenis procinfo *pi;
4932b725ae77Skettenis sysset_t *exitset;
4933e93f7393Sniklas
4934b725ae77Skettenis if ((pi = create_procinfo (getpid (), 0)) == NULL)
4935b725ae77Skettenis perror_with_name ("procfs: create_procinfo failed in child.");
4936e93f7393Sniklas
4937b725ae77Skettenis if (open_procinfo_files (pi, FD_CTL) == 0)
4938b725ae77Skettenis {
4939b725ae77Skettenis proc_warn (pi, "set_exec_trap, open_proc_files", __LINE__);
4940b725ae77Skettenis gdb_flush (gdb_stderr);
4941b725ae77Skettenis /* no need to call "dead_procinfo", because we're going to exit. */
4942b725ae77Skettenis _exit (127);
4943b725ae77Skettenis }
4944e93f7393Sniklas
4945b725ae77Skettenis #ifdef PRFS_STOPEXEC /* defined on OSF */
4946b725ae77Skettenis /* OSF method for tracing exec syscalls. Quoting:
4947b725ae77Skettenis Under Alpha OSF/1 we have to use a PIOCSSPCACT ioctl to trace
4948b725ae77Skettenis exits from exec system calls because of the user level loader. */
4949b725ae77Skettenis /* FIXME: make nice and maybe move into an access function. */
4950b725ae77Skettenis {
4951b725ae77Skettenis int prfs_flags;
4952e93f7393Sniklas
4953b725ae77Skettenis if (ioctl (pi->ctl_fd, PIOCGSPCACT, &prfs_flags) < 0)
4954b725ae77Skettenis {
4955b725ae77Skettenis proc_warn (pi, "set_exec_trap (PIOCGSPCACT)", __LINE__);
4956b725ae77Skettenis gdb_flush (gdb_stderr);
4957b725ae77Skettenis _exit (127);
4958b725ae77Skettenis }
4959b725ae77Skettenis prfs_flags |= PRFS_STOPEXEC;
4960e93f7393Sniklas
4961b725ae77Skettenis if (ioctl (pi->ctl_fd, PIOCSSPCACT, &prfs_flags) < 0)
4962b725ae77Skettenis {
4963b725ae77Skettenis proc_warn (pi, "set_exec_trap (PIOCSSPCACT)", __LINE__);
4964b725ae77Skettenis gdb_flush (gdb_stderr);
4965b725ae77Skettenis _exit (127);
4966b725ae77Skettenis }
4967b725ae77Skettenis }
4968b725ae77Skettenis #else /* not PRFS_STOPEXEC */
4969b725ae77Skettenis /* Everyone else's (except OSF) method for tracing exec syscalls */
4970b725ae77Skettenis /* GW: Rationale...
4971b725ae77Skettenis Not all systems with /proc have all the exec* syscalls with the same
4972b725ae77Skettenis names. On the SGI, for example, there is no SYS_exec, but there
4973b725ae77Skettenis *is* a SYS_execv. So, we try to account for that. */
4974b725ae77Skettenis
4975b725ae77Skettenis exitset = sysset_t_alloc (pi);
4976b725ae77Skettenis gdb_premptysysset (exitset);
4977b725ae77Skettenis #ifdef SYS_exec
4978b725ae77Skettenis gdb_praddsysset (exitset, SYS_exec);
4979b725ae77Skettenis #endif
4980b725ae77Skettenis #ifdef SYS_execve
4981b725ae77Skettenis gdb_praddsysset (exitset, SYS_execve);
4982b725ae77Skettenis #endif
4983b725ae77Skettenis #ifdef SYS_execv
4984b725ae77Skettenis gdb_praddsysset (exitset, SYS_execv);
4985b725ae77Skettenis #endif
4986b725ae77Skettenis #ifdef DYNAMIC_SYSCALLS
4987b725ae77Skettenis {
4988b725ae77Skettenis int callnum = find_syscall (pi, "execve");
4989b725ae77Skettenis
4990b725ae77Skettenis if (callnum >= 0)
4991b725ae77Skettenis gdb_praddsysset (exitset, callnum);
4992b725ae77Skettenis
4993b725ae77Skettenis callnum = find_syscall (pi, "ra_execve");
4994b725ae77Skettenis if (callnum >= 0)
4995b725ae77Skettenis gdb_praddsysset (exitset, callnum);
4996b725ae77Skettenis }
4997b725ae77Skettenis #endif /* DYNAMIC_SYSCALLS */
4998b725ae77Skettenis
4999b725ae77Skettenis if (!proc_set_traced_sysexit (pi, exitset))
5000b725ae77Skettenis {
5001b725ae77Skettenis proc_warn (pi, "set_exec_trap, set_traced_sysexit", __LINE__);
5002b725ae77Skettenis gdb_flush (gdb_stderr);
5003b725ae77Skettenis _exit (127);
5004b725ae77Skettenis }
5005b725ae77Skettenis #endif /* PRFS_STOPEXEC */
5006b725ae77Skettenis
5007b725ae77Skettenis /* FIXME: should this be done in the parent instead? */
5008b725ae77Skettenis /* Turn off inherit on fork flag so that all grand-children
5009b725ae77Skettenis of gdb start with tracing flags cleared. */
5010b725ae77Skettenis if (!proc_unset_inherit_on_fork (pi))
5011b725ae77Skettenis proc_warn (pi, "set_exec_trap, unset_inherit", __LINE__);
5012b725ae77Skettenis
5013b725ae77Skettenis /* Turn off run on last close flag, so that the child process
5014b725ae77Skettenis cannot run away just because we close our handle on it.
5015b725ae77Skettenis We want it to wait for the parent to attach. */
5016b725ae77Skettenis if (!proc_unset_run_on_last_close (pi))
5017b725ae77Skettenis proc_warn (pi, "set_exec_trap, unset_RLC", __LINE__);
5018b725ae77Skettenis
5019b725ae77Skettenis /* FIXME: No need to destroy the procinfo --
5020b725ae77Skettenis we have our own address space, and we're about to do an exec! */
5021b725ae77Skettenis /*destroy_procinfo (pi);*/
5022e93f7393Sniklas }
5023e93f7393Sniklas
5024e93f7393Sniklas /*
5025b725ae77Skettenis * Function: create_inferior
5026b725ae77Skettenis *
5027b725ae77Skettenis * This function is called BEFORE gdb forks the inferior process.
5028b725ae77Skettenis * Its only real responsibility is to set things up for the fork,
5029b725ae77Skettenis * and tell GDB which two functions to call after the fork (one
5030b725ae77Skettenis * for the parent, and one for the child).
5031b725ae77Skettenis *
5032b725ae77Skettenis * This function does a complicated search for a unix shell program,
5033b725ae77Skettenis * which it then uses to parse arguments and environment variables
5034b725ae77Skettenis * to be sent to the child. I wonder whether this code could not
5035b725ae77Skettenis * be abstracted out and shared with other unix targets such as
5036b725ae77Skettenis * infptrace?
5037e93f7393Sniklas */
5038e93f7393Sniklas
5039e93f7393Sniklas static void
procfs_create_inferior(char * exec_file,char * allargs,char ** env,int from_tty)5040*63addd46Skettenis procfs_create_inferior (char *exec_file, char *allargs, char **env,
5041*63addd46Skettenis int from_tty)
5042e93f7393Sniklas {
5043e93f7393Sniklas char *shell_file = getenv ("SHELL");
5044e93f7393Sniklas char *tryname;
5045e93f7393Sniklas if (shell_file != NULL && strchr (shell_file, '/') == NULL)
5046e93f7393Sniklas {
5047e93f7393Sniklas
5048e93f7393Sniklas /* We will be looking down the PATH to find shell_file. If we
5049e93f7393Sniklas just do this the normal way (via execlp, which operates by
5050e93f7393Sniklas attempting an exec for each element of the PATH until it
5051e93f7393Sniklas finds one which succeeds), then there will be an exec for
5052e93f7393Sniklas each failed attempt, each of which will cause a PR_SYSEXIT
5053e93f7393Sniklas stop, and we won't know how to distinguish the PR_SYSEXIT's
5054e93f7393Sniklas for these failed execs with the ones for successful execs
5055e93f7393Sniklas (whether the exec has succeeded is stored at that time in the
5056e93f7393Sniklas carry bit or some such architecture-specific and
5057e93f7393Sniklas non-ABI-specified place).
5058e93f7393Sniklas
5059e93f7393Sniklas So I can't think of anything better than to search the PATH
5060e93f7393Sniklas now. This has several disadvantages: (1) There is a race
5061e93f7393Sniklas condition; if we find a file now and it is deleted before we
5062e93f7393Sniklas exec it, we lose, even if the deletion leaves a valid file
5063e93f7393Sniklas further down in the PATH, (2) there is no way to know exactly
5064e93f7393Sniklas what an executable (in the sense of "capable of being
5065e93f7393Sniklas exec'd") file is. Using access() loses because it may lose
5066e93f7393Sniklas if the caller is the superuser; failing to use it loses if
5067e93f7393Sniklas there are ACLs or some such. */
5068e93f7393Sniklas
5069e93f7393Sniklas char *p;
5070e93f7393Sniklas char *p1;
5071e93f7393Sniklas /* FIXME-maybe: might want "set path" command so user can change what
5072e93f7393Sniklas path is used from within GDB. */
5073e93f7393Sniklas char *path = getenv ("PATH");
5074e93f7393Sniklas int len;
5075e93f7393Sniklas struct stat statbuf;
5076e93f7393Sniklas
5077e93f7393Sniklas if (path == NULL)
5078e93f7393Sniklas path = "/bin:/usr/bin";
5079e93f7393Sniklas
5080e93f7393Sniklas tryname = alloca (strlen (path) + strlen (shell_file) + 2);
5081e93f7393Sniklas for (p = path; p != NULL; p = p1 ? p1 + 1: NULL)
5082e93f7393Sniklas {
5083e93f7393Sniklas p1 = strchr (p, ':');
5084e93f7393Sniklas if (p1 != NULL)
5085e93f7393Sniklas len = p1 - p;
5086e93f7393Sniklas else
5087e93f7393Sniklas len = strlen (p);
5088e93f7393Sniklas strncpy (tryname, p, len);
5089e93f7393Sniklas tryname[len] = '\0';
5090e93f7393Sniklas strcat (tryname, "/");
5091e93f7393Sniklas strcat (tryname, shell_file);
5092e93f7393Sniklas if (access (tryname, X_OK) < 0)
5093e93f7393Sniklas continue;
5094e93f7393Sniklas if (stat (tryname, &statbuf) < 0)
5095e93f7393Sniklas continue;
5096e93f7393Sniklas if (!S_ISREG (statbuf.st_mode))
5097e93f7393Sniklas /* We certainly need to reject directories. I'm not quite
5098e93f7393Sniklas as sure about FIFOs, sockets, etc., but I kind of doubt
5099e93f7393Sniklas that people want to exec() these things. */
5100e93f7393Sniklas continue;
5101e93f7393Sniklas break;
5102e93f7393Sniklas }
5103e93f7393Sniklas if (p == NULL)
5104e93f7393Sniklas /* Not found. This must be an error rather than merely passing
5105e93f7393Sniklas the file to execlp(), because execlp() would try all the
5106e93f7393Sniklas exec()s, causing GDB to get confused. */
5107b725ae77Skettenis error ("procfs:%d -- Can't find shell %s in PATH",
5108b725ae77Skettenis __LINE__, shell_file);
5109e93f7393Sniklas
5110e93f7393Sniklas shell_file = tryname;
5111e93f7393Sniklas }
5112e93f7393Sniklas
5113b725ae77Skettenis fork_inferior (exec_file, allargs, env, procfs_set_exec_trap,
5114b725ae77Skettenis procfs_init_inferior, NULL, shell_file);
5115e93f7393Sniklas
5116*63addd46Skettenis #ifdef SYS_syssgi
5117*63addd46Skettenis /* Make sure to cancel the syssgi() syscall-exit notifications.
5118*63addd46Skettenis They should normally have been removed by now, but they may still
5119*63addd46Skettenis be activated if the inferior doesn't use shared libraries, or if
5120*63addd46Skettenis we didn't locate __dbx_link, or if we never stopped in __dbx_link.
5121*63addd46Skettenis See procfs_init_inferior() for more details. */
5122*63addd46Skettenis proc_trace_syscalls_1 (find_procinfo_or_die (PIDGET (inferior_ptid), 0),
5123*63addd46Skettenis SYS_syssgi, PR_SYSEXIT, FLAG_RESET, 0);
5124*63addd46Skettenis #endif
5125*63addd46Skettenis
5126e93f7393Sniklas /* We are at the first instruction we care about. */
5127e93f7393Sniklas /* Pedal to the metal... */
5128e93f7393Sniklas
5129e93f7393Sniklas proceed ((CORE_ADDR) -1, TARGET_SIGNAL_0, 0);
5130e93f7393Sniklas }
5131e93f7393Sniklas
5132b725ae77Skettenis /*
5133b725ae77Skettenis * Function: notice_thread
5134b725ae77Skettenis *
5135b725ae77Skettenis * Callback for find_new_threads.
5136b725ae77Skettenis * Calls "add_thread".
5137b725ae77Skettenis */
5138e93f7393Sniklas
5139e93f7393Sniklas static int
procfs_notice_thread(procinfo * pi,procinfo * thread,void * ptr)5140b725ae77Skettenis procfs_notice_thread (procinfo *pi, procinfo *thread, void *ptr)
5141e93f7393Sniklas {
5142b725ae77Skettenis ptid_t gdb_threadid = MERGEPID (pi->pid, thread->tid);
5143b725ae77Skettenis
5144b725ae77Skettenis if (!in_thread_list (gdb_threadid))
5145b725ae77Skettenis add_thread (gdb_threadid);
5146b725ae77Skettenis
5147b725ae77Skettenis return 0;
5148b725ae77Skettenis }
5149b725ae77Skettenis
5150b725ae77Skettenis /*
5151b725ae77Skettenis * Function: target_find_new_threads
5152b725ae77Skettenis *
5153b725ae77Skettenis * Query all the threads that the target knows about,
5154b725ae77Skettenis * and give them back to GDB to add to its list.
5155b725ae77Skettenis */
5156b725ae77Skettenis
5157b725ae77Skettenis void
procfs_find_new_threads(void)5158b725ae77Skettenis procfs_find_new_threads (void)
5159b725ae77Skettenis {
5160b725ae77Skettenis procinfo *pi;
5161b725ae77Skettenis
5162b725ae77Skettenis /* Find procinfo for main process */
5163b725ae77Skettenis pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
5164b725ae77Skettenis proc_update_threads (pi);
5165b725ae77Skettenis proc_iterate_over_threads (pi, procfs_notice_thread, NULL);
5166b725ae77Skettenis }
5167b725ae77Skettenis
5168b725ae77Skettenis /*
5169b725ae77Skettenis * Function: target_thread_alive
5170b725ae77Skettenis *
5171b725ae77Skettenis * Return true if the thread is still 'alive'.
5172b725ae77Skettenis *
5173b725ae77Skettenis * This guy doesn't really seem to be doing his job.
5174b725ae77Skettenis * Got to investigate how to tell when a thread is really gone.
5175b725ae77Skettenis */
5176b725ae77Skettenis
5177b725ae77Skettenis static int
procfs_thread_alive(ptid_t ptid)5178b725ae77Skettenis procfs_thread_alive (ptid_t ptid)
5179b725ae77Skettenis {
5180b725ae77Skettenis int proc, thread;
5181b725ae77Skettenis procinfo *pi;
5182b725ae77Skettenis
5183b725ae77Skettenis proc = PIDGET (ptid);
5184b725ae77Skettenis thread = TIDGET (ptid);
5185b725ae77Skettenis /* If I don't know it, it ain't alive! */
5186b725ae77Skettenis if ((pi = find_procinfo (proc, thread)) == NULL)
5187b725ae77Skettenis return 0;
5188b725ae77Skettenis
5189b725ae77Skettenis /* If I can't get its status, it ain't alive!
5190b725ae77Skettenis What's more, I need to forget about it! */
5191b725ae77Skettenis if (!proc_get_status (pi))
5192b725ae77Skettenis {
5193b725ae77Skettenis destroy_procinfo (pi);
5194b725ae77Skettenis return 0;
5195b725ae77Skettenis }
5196b725ae77Skettenis /* I couldn't have got its status if it weren't alive, so it's alive. */
5197e93f7393Sniklas return 1;
5198e93f7393Sniklas }
5199e93f7393Sniklas
5200*63addd46Skettenis /* Convert PTID to a string. Returns the string in a static buffer. */
5201e93f7393Sniklas
5202e93f7393Sniklas char *
procfs_pid_to_str(ptid_t ptid)5203b725ae77Skettenis procfs_pid_to_str (ptid_t ptid)
5204e93f7393Sniklas {
5205b725ae77Skettenis static char buf[80];
5206e93f7393Sniklas
5207*63addd46Skettenis if (TIDGET (ptid) == 0)
5208*63addd46Skettenis sprintf (buf, "process %d", PIDGET (ptid));
5209b725ae77Skettenis else
5210*63addd46Skettenis sprintf (buf, "LWP %ld", TIDGET (ptid));
5211*63addd46Skettenis
5212*63addd46Skettenis return buf;
5213e93f7393Sniklas }
5214e93f7393Sniklas
5215b725ae77Skettenis /*
5216b725ae77Skettenis * Function: procfs_set_watchpoint
5217b725ae77Skettenis * Insert a watchpoint
5218b725ae77Skettenis */
5219b725ae77Skettenis
5220b725ae77Skettenis int
procfs_set_watchpoint(ptid_t ptid,CORE_ADDR addr,int len,int rwflag,int after)5221b725ae77Skettenis procfs_set_watchpoint (ptid_t ptid, CORE_ADDR addr, int len, int rwflag,
5222b725ae77Skettenis int after)
5223e93f7393Sniklas {
5224b725ae77Skettenis #ifndef UNIXWARE
5225b725ae77Skettenis #ifndef AIX5
5226b725ae77Skettenis int pflags = 0;
5227b725ae77Skettenis procinfo *pi;
5228e93f7393Sniklas
5229b725ae77Skettenis pi = find_procinfo_or_die (PIDGET (ptid) == -1 ?
5230b725ae77Skettenis PIDGET (inferior_ptid) : PIDGET (ptid), 0);
5231b725ae77Skettenis
5232b725ae77Skettenis /* Translate from GDB's flags to /proc's */
5233b725ae77Skettenis if (len > 0) /* len == 0 means delete watchpoint */
5234b725ae77Skettenis {
5235b725ae77Skettenis switch (rwflag) { /* FIXME: need an enum! */
5236b725ae77Skettenis case hw_write: /* default watchpoint (write) */
5237b725ae77Skettenis pflags = WRITE_WATCHFLAG;
5238b725ae77Skettenis break;
5239b725ae77Skettenis case hw_read: /* read watchpoint */
5240b725ae77Skettenis pflags = READ_WATCHFLAG;
5241b725ae77Skettenis break;
5242b725ae77Skettenis case hw_access: /* access watchpoint */
5243b725ae77Skettenis pflags = READ_WATCHFLAG | WRITE_WATCHFLAG;
5244b725ae77Skettenis break;
5245b725ae77Skettenis case hw_execute: /* execution HW breakpoint */
5246b725ae77Skettenis pflags = EXEC_WATCHFLAG;
5247b725ae77Skettenis break;
5248b725ae77Skettenis default: /* Something weird. Return error. */
5249b725ae77Skettenis return -1;
5250b725ae77Skettenis }
5251b725ae77Skettenis if (after) /* Stop after r/w access is completed. */
5252b725ae77Skettenis pflags |= AFTER_WATCHFLAG;
5253b725ae77Skettenis }
5254b725ae77Skettenis
5255b725ae77Skettenis if (!proc_set_watchpoint (pi, addr, len, pflags))
5256b725ae77Skettenis {
5257b725ae77Skettenis if (errno == E2BIG) /* Typical error for no resources */
5258b725ae77Skettenis return -1; /* fail */
5259b725ae77Skettenis /* GDB may try to remove the same watchpoint twice.
5260b725ae77Skettenis If a remove request returns no match, don't error. */
5261b725ae77Skettenis if (errno == ESRCH && len == 0)
5262b725ae77Skettenis return 0; /* ignore */
5263b725ae77Skettenis proc_error (pi, "set_watchpoint", __LINE__);
5264b725ae77Skettenis }
5265b725ae77Skettenis #endif /* AIX5 */
5266b725ae77Skettenis #endif /* UNIXWARE */
5267b725ae77Skettenis return 0;
5268b725ae77Skettenis }
5269b725ae77Skettenis
5270b725ae77Skettenis /* Return non-zero if we can set a hardware watchpoint of type TYPE. TYPE
5271b725ae77Skettenis is one of bp_hardware_watchpoint, bp_read_watchpoint, bp_write_watchpoint,
5272b725ae77Skettenis or bp_hardware_watchpoint. CNT is the number of watchpoints used so
5273b725ae77Skettenis far.
5274b725ae77Skettenis
5275b725ae77Skettenis Note: procfs_can_use_hw_breakpoint() is not yet used by all
5276b725ae77Skettenis procfs.c targets due to the fact that some of them still define
5277b725ae77Skettenis TARGET_CAN_USE_HARDWARE_WATCHPOINT. */
5278b725ae77Skettenis
5279b725ae77Skettenis static int
procfs_can_use_hw_breakpoint(int type,int cnt,int othertype)5280b725ae77Skettenis procfs_can_use_hw_breakpoint (int type, int cnt, int othertype)
5281b725ae77Skettenis {
5282b725ae77Skettenis #ifndef TARGET_HAS_HARDWARE_WATCHPOINTS
5283b725ae77Skettenis return 0;
5284b725ae77Skettenis #else
5285b725ae77Skettenis /* Due to the way that proc_set_watchpoint() is implemented, host
5286b725ae77Skettenis and target pointers must be of the same size. If they are not,
5287b725ae77Skettenis we can't use hardware watchpoints. This limitation is due to the
5288b725ae77Skettenis fact that proc_set_watchpoint() calls
5289b725ae77Skettenis procfs_address_to_host_pointer(); a close inspection of
5290b725ae77Skettenis procfs_address_to_host_pointer will reveal that an internal error
5291b725ae77Skettenis will be generated when the host and target pointer sizes are
5292b725ae77Skettenis different. */
5293b725ae77Skettenis if (sizeof (void *) != TYPE_LENGTH (builtin_type_void_data_ptr))
5294b725ae77Skettenis return 0;
5295b725ae77Skettenis
5296b725ae77Skettenis /* Other tests here??? */
5297b725ae77Skettenis
5298b725ae77Skettenis return 1;
5299b725ae77Skettenis #endif
5300b725ae77Skettenis }
5301b725ae77Skettenis
5302b725ae77Skettenis /*
5303b725ae77Skettenis * Function: stopped_by_watchpoint
5304b725ae77Skettenis *
5305b725ae77Skettenis * Returns non-zero if process is stopped on a hardware watchpoint fault,
5306b725ae77Skettenis * else returns zero.
5307b725ae77Skettenis */
5308b725ae77Skettenis
5309b725ae77Skettenis int
procfs_stopped_by_watchpoint(ptid_t ptid)5310b725ae77Skettenis procfs_stopped_by_watchpoint (ptid_t ptid)
5311b725ae77Skettenis {
5312b725ae77Skettenis procinfo *pi;
5313b725ae77Skettenis
5314b725ae77Skettenis pi = find_procinfo_or_die (PIDGET (ptid) == -1 ?
5315b725ae77Skettenis PIDGET (inferior_ptid) : PIDGET (ptid), 0);
5316b725ae77Skettenis
5317b725ae77Skettenis if (!pi) /* If no process, then not stopped by watchpoint! */
5318b725ae77Skettenis return 0;
5319b725ae77Skettenis
5320b725ae77Skettenis if (proc_flags (pi) & (PR_STOPPED | PR_ISTOP))
5321b725ae77Skettenis {
5322b725ae77Skettenis if (proc_why (pi) == PR_FAULTED)
5323b725ae77Skettenis {
5324b725ae77Skettenis #ifdef FLTWATCH
5325b725ae77Skettenis if (proc_what (pi) == FLTWATCH)
5326b725ae77Skettenis return 1;
5327b725ae77Skettenis #endif
5328b725ae77Skettenis #ifdef FLTKWATCH
5329b725ae77Skettenis if (proc_what (pi) == FLTKWATCH)
5330b725ae77Skettenis return 1;
5331b725ae77Skettenis #endif
5332b725ae77Skettenis }
5333b725ae77Skettenis }
5334b725ae77Skettenis return 0;
5335b725ae77Skettenis }
5336b725ae77Skettenis
5337b725ae77Skettenis #ifdef TM_I386SOL2_H
5338b725ae77Skettenis /*
5339b725ae77Skettenis * Function: procfs_find_LDT_entry
5340b725ae77Skettenis *
5341b725ae77Skettenis * Input:
5342b725ae77Skettenis * ptid_t ptid; // The GDB-style pid-plus-LWP.
5343b725ae77Skettenis *
5344b725ae77Skettenis * Return:
5345b725ae77Skettenis * pointer to the corresponding LDT entry.
5346b725ae77Skettenis */
5347b725ae77Skettenis
5348b725ae77Skettenis struct ssd *
procfs_find_LDT_entry(ptid_t ptid)5349b725ae77Skettenis procfs_find_LDT_entry (ptid_t ptid)
5350b725ae77Skettenis {
5351b725ae77Skettenis gdb_gregset_t *gregs;
5352b725ae77Skettenis int key;
5353b725ae77Skettenis procinfo *pi;
5354b725ae77Skettenis
5355b725ae77Skettenis /* Find procinfo for the lwp. */
5356b725ae77Skettenis if ((pi = find_procinfo (PIDGET (ptid), TIDGET (ptid))) == NULL)
5357b725ae77Skettenis {
5358b725ae77Skettenis warning ("procfs_find_LDT_entry: could not find procinfo for %d:%d.",
5359b725ae77Skettenis PIDGET (ptid), TIDGET (ptid));
5360b725ae77Skettenis return NULL;
5361b725ae77Skettenis }
5362b725ae77Skettenis /* get its general registers. */
5363b725ae77Skettenis if ((gregs = proc_get_gregs (pi)) == NULL)
5364b725ae77Skettenis {
5365b725ae77Skettenis warning ("procfs_find_LDT_entry: could not read gregs for %d:%d.",
5366b725ae77Skettenis PIDGET (ptid), TIDGET (ptid));
5367b725ae77Skettenis return NULL;
5368b725ae77Skettenis }
5369b725ae77Skettenis /* Now extract the GS register's lower 16 bits. */
5370b725ae77Skettenis key = (*gregs)[GS] & 0xffff;
5371b725ae77Skettenis
5372b725ae77Skettenis /* Find the matching entry and return it. */
5373b725ae77Skettenis return proc_get_LDT_entry (pi, key);
5374b725ae77Skettenis }
5375b725ae77Skettenis #endif /* TM_I386SOL2_H */
5376b725ae77Skettenis
5377b725ae77Skettenis /*
5378b725ae77Skettenis * Memory Mappings Functions:
5379b725ae77Skettenis */
5380b725ae77Skettenis
5381b725ae77Skettenis /*
5382b725ae77Skettenis * Function: iterate_over_mappings
5383b725ae77Skettenis *
5384b725ae77Skettenis * Call a callback function once for each mapping, passing it the mapping,
5385b725ae77Skettenis * an optional secondary callback function, and some optional opaque data.
5386b725ae77Skettenis * Quit and return the first non-zero value returned from the callback.
5387b725ae77Skettenis *
5388b725ae77Skettenis * Arguments:
5389b725ae77Skettenis * pi -- procinfo struct for the process to be mapped.
5390b725ae77Skettenis * func -- callback function to be called by this iterator.
5391b725ae77Skettenis * data -- optional opaque data to be passed to the callback function.
5392b725ae77Skettenis * child_func -- optional secondary function pointer to be passed
5393b725ae77Skettenis * to the child function.
5394b725ae77Skettenis *
5395b725ae77Skettenis * Return: First non-zero return value from the callback function,
5396b725ae77Skettenis * or zero.
5397b725ae77Skettenis */
5398b725ae77Skettenis
5399b725ae77Skettenis static int
iterate_over_mappings(procinfo * pi,int (* child_func)(),void * data,int (* func)(struct prmap * map,int (* child_func)(),void * data))5400b725ae77Skettenis iterate_over_mappings (procinfo *pi, int (*child_func) (), void *data,
5401b725ae77Skettenis int (*func) (struct prmap *map,
5402b725ae77Skettenis int (*child_func) (),
5403b725ae77Skettenis void *data))
5404b725ae77Skettenis {
5405b725ae77Skettenis char pathname[MAX_PROC_NAME_SIZE];
5406b725ae77Skettenis struct prmap *prmaps;
5407b725ae77Skettenis struct prmap *prmap;
5408b725ae77Skettenis int funcstat;
5409b725ae77Skettenis int map_fd;
5410b725ae77Skettenis int nmap;
5411b725ae77Skettenis #ifdef NEW_PROC_API
5412b725ae77Skettenis struct stat sbuf;
5413e93f7393Sniklas #endif
5414e93f7393Sniklas
5415b725ae77Skettenis /* Get the number of mappings, allocate space,
5416b725ae77Skettenis and read the mappings into prmaps. */
5417b725ae77Skettenis #ifdef NEW_PROC_API
5418b725ae77Skettenis /* Open map fd. */
5419b725ae77Skettenis sprintf (pathname, "/proc/%d/map", pi->pid);
5420b725ae77Skettenis if ((map_fd = open (pathname, O_RDONLY)) < 0)
5421b725ae77Skettenis proc_error (pi, "iterate_over_mappings (open)", __LINE__);
5422e93f7393Sniklas
5423b725ae77Skettenis /* Make sure it gets closed again. */
5424b725ae77Skettenis make_cleanup_close (map_fd);
5425e93f7393Sniklas
5426b725ae77Skettenis /* Use stat to determine the file size, and compute
5427b725ae77Skettenis the number of prmap_t objects it contains. */
5428b725ae77Skettenis if (fstat (map_fd, &sbuf) != 0)
5429b725ae77Skettenis proc_error (pi, "iterate_over_mappings (fstat)", __LINE__);
5430b725ae77Skettenis
5431b725ae77Skettenis nmap = sbuf.st_size / sizeof (prmap_t);
5432b725ae77Skettenis prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
5433b725ae77Skettenis if (read (map_fd, (char *) prmaps, nmap * sizeof (*prmaps))
5434b725ae77Skettenis != (nmap * sizeof (*prmaps)))
5435b725ae77Skettenis proc_error (pi, "iterate_over_mappings (read)", __LINE__);
5436b725ae77Skettenis #else
5437b725ae77Skettenis /* Use ioctl command PIOCNMAP to get number of mappings. */
5438b725ae77Skettenis if (ioctl (pi->ctl_fd, PIOCNMAP, &nmap) != 0)
5439b725ae77Skettenis proc_error (pi, "iterate_over_mappings (PIOCNMAP)", __LINE__);
5440b725ae77Skettenis
5441b725ae77Skettenis prmaps = (struct prmap *) alloca ((nmap + 1) * sizeof (*prmaps));
5442b725ae77Skettenis if (ioctl (pi->ctl_fd, PIOCMAP, prmaps) != 0)
5443b725ae77Skettenis proc_error (pi, "iterate_over_mappings (PIOCMAP)", __LINE__);
5444b725ae77Skettenis #endif
5445b725ae77Skettenis
5446b725ae77Skettenis for (prmap = prmaps; nmap > 0; prmap++, nmap--)
5447b725ae77Skettenis if ((funcstat = (*func) (prmap, child_func, data)) != 0)
5448b725ae77Skettenis return funcstat;
5449b725ae77Skettenis
5450b725ae77Skettenis return 0;
5451e93f7393Sniklas }
5452b725ae77Skettenis
5453b725ae77Skettenis /*
5454b725ae77Skettenis * Function: solib_mappings_callback
5455b725ae77Skettenis *
5456b725ae77Skettenis * Calls the supplied callback function once for each mapped address
5457b725ae77Skettenis * space in the process. The callback function receives an open
5458b725ae77Skettenis * file descriptor for the file corresponding to that mapped
5459b725ae77Skettenis * address space (if there is one), and the base address of the
5460b725ae77Skettenis * mapped space. Quit when the callback function returns a
5461b725ae77Skettenis * nonzero value, or at teh end of the mappings.
5462b725ae77Skettenis *
5463b725ae77Skettenis * Returns: the first non-zero return value of the callback function,
5464b725ae77Skettenis * or zero.
5465b725ae77Skettenis */
5466b725ae77Skettenis
solib_mappings_callback(struct prmap * map,int (* func)(int,CORE_ADDR),void * data)5467b725ae77Skettenis int solib_mappings_callback (struct prmap *map,
5468b725ae77Skettenis int (*func) (int, CORE_ADDR),
5469b725ae77Skettenis void *data)
5470b725ae77Skettenis {
5471b725ae77Skettenis procinfo *pi = data;
5472b725ae77Skettenis int fd;
5473b725ae77Skettenis
5474b725ae77Skettenis #ifdef NEW_PROC_API
5475b725ae77Skettenis char name[MAX_PROC_NAME_SIZE + sizeof (map->pr_mapname)];
5476b725ae77Skettenis
5477b725ae77Skettenis if (map->pr_vaddr == 0 && map->pr_size == 0)
5478b725ae77Skettenis return -1; /* sanity */
5479b725ae77Skettenis
5480b725ae77Skettenis if (map->pr_mapname[0] == 0)
5481b725ae77Skettenis {
5482b725ae77Skettenis fd = -1; /* no map file */
5483b725ae77Skettenis }
5484b725ae77Skettenis else
5485b725ae77Skettenis {
5486b725ae77Skettenis sprintf (name, "/proc/%d/object/%s", pi->pid, map->pr_mapname);
5487b725ae77Skettenis /* Note: caller's responsibility to close this fd! */
5488b725ae77Skettenis fd = open_with_retry (name, O_RDONLY);
5489b725ae77Skettenis /* Note: we don't test the above call for failure;
5490b725ae77Skettenis we just pass the FD on as given. Sometimes there is
5491b725ae77Skettenis no file, so the open may return failure, but that's
5492b725ae77Skettenis not a problem. */
5493b725ae77Skettenis }
5494b725ae77Skettenis #else
5495b725ae77Skettenis fd = ioctl (pi->ctl_fd, PIOCOPENM, &map->pr_vaddr);
5496b725ae77Skettenis /* Note: we don't test the above call for failure;
5497b725ae77Skettenis we just pass the FD on as given. Sometimes there is
5498b725ae77Skettenis no file, so the ioctl may return failure, but that's
5499b725ae77Skettenis not a problem. */
5500b725ae77Skettenis #endif
5501b725ae77Skettenis return (*func) (fd, (CORE_ADDR) map->pr_vaddr);
5502b725ae77Skettenis }
5503b725ae77Skettenis
5504b725ae77Skettenis /*
5505b725ae77Skettenis * Function: proc_iterate_over_mappings
5506b725ae77Skettenis *
5507b725ae77Skettenis * Uses the unified "iterate_over_mappings" function
5508b725ae77Skettenis * to implement the exported interface to solib-svr4.c.
5509b725ae77Skettenis *
5510b725ae77Skettenis * Given a pointer to a function, call that function once for every
5511b725ae77Skettenis * mapped address space in the process. The callback function
5512b725ae77Skettenis * receives an open file descriptor for the file corresponding to
5513b725ae77Skettenis * that mapped address space (if there is one), and the base address
5514b725ae77Skettenis * of the mapped space. Quit when the callback function returns a
5515b725ae77Skettenis * nonzero value, or at teh end of the mappings.
5516b725ae77Skettenis *
5517b725ae77Skettenis * Returns: the first non-zero return value of the callback function,
5518b725ae77Skettenis * or zero.
5519b725ae77Skettenis */
5520b725ae77Skettenis
5521b725ae77Skettenis int
proc_iterate_over_mappings(int (* func)(int,CORE_ADDR))5522b725ae77Skettenis proc_iterate_over_mappings (int (*func) (int, CORE_ADDR))
5523b725ae77Skettenis {
5524b725ae77Skettenis procinfo *pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
5525b725ae77Skettenis
5526b725ae77Skettenis return iterate_over_mappings (pi, func, pi, solib_mappings_callback);
5527b725ae77Skettenis }
5528b725ae77Skettenis
5529b725ae77Skettenis /*
5530b725ae77Skettenis * Function: find_memory_regions_callback
5531b725ae77Skettenis *
5532b725ae77Skettenis * Implements the to_find_memory_regions method.
5533b725ae77Skettenis * Calls an external function for each memory region.
5534b725ae77Skettenis * External function will have the signiture:
5535b725ae77Skettenis *
5536b725ae77Skettenis * int callback (CORE_ADDR vaddr,
5537b725ae77Skettenis * unsigned long size,
5538b725ae77Skettenis * int read, int write, int execute,
5539b725ae77Skettenis * void *data);
5540b725ae77Skettenis *
5541b725ae77Skettenis * Returns the integer value returned by the callback.
5542b725ae77Skettenis */
5543b725ae77Skettenis
5544b725ae77Skettenis static int
find_memory_regions_callback(struct prmap * map,int (* func)(CORE_ADDR,unsigned long,int,int,int,void *),void * data)5545b725ae77Skettenis find_memory_regions_callback (struct prmap *map,
5546b725ae77Skettenis int (*func) (CORE_ADDR,
5547b725ae77Skettenis unsigned long,
5548b725ae77Skettenis int, int, int,
5549b725ae77Skettenis void *),
5550b725ae77Skettenis void *data)
5551b725ae77Skettenis {
5552b725ae77Skettenis return (*func) ((CORE_ADDR) map->pr_vaddr,
5553b725ae77Skettenis map->pr_size,
5554b725ae77Skettenis (map->pr_mflags & MA_READ) != 0,
5555b725ae77Skettenis (map->pr_mflags & MA_WRITE) != 0,
5556b725ae77Skettenis (map->pr_mflags & MA_EXEC) != 0,
5557b725ae77Skettenis data);
5558b725ae77Skettenis }
5559b725ae77Skettenis
5560b725ae77Skettenis /*
5561b725ae77Skettenis * Function: proc_find_memory_regions
5562b725ae77Skettenis *
5563b725ae77Skettenis * External interface. Calls a callback function once for each
5564b725ae77Skettenis * mapped memory region in the child process, passing as arguments
5565b725ae77Skettenis * CORE_ADDR virtual_address,
5566b725ae77Skettenis * unsigned long size,
5567b725ae77Skettenis * int read, TRUE if region is readable by the child
5568b725ae77Skettenis * int write, TRUE if region is writable by the child
5569b725ae77Skettenis * int execute TRUE if region is executable by the child.
5570b725ae77Skettenis *
5571b725ae77Skettenis * Stops iterating and returns the first non-zero value
5572b725ae77Skettenis * returned by the callback.
5573b725ae77Skettenis */
5574b725ae77Skettenis
5575b725ae77Skettenis static int
proc_find_memory_regions(int (* func)(CORE_ADDR,unsigned long,int,int,int,void *),void * data)5576b725ae77Skettenis proc_find_memory_regions (int (*func) (CORE_ADDR,
5577b725ae77Skettenis unsigned long,
5578b725ae77Skettenis int, int, int,
5579b725ae77Skettenis void *),
5580b725ae77Skettenis void *data)
5581b725ae77Skettenis {
5582b725ae77Skettenis procinfo *pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
5583b725ae77Skettenis
5584b725ae77Skettenis return iterate_over_mappings (pi, func, data,
5585b725ae77Skettenis find_memory_regions_callback);
5586b725ae77Skettenis }
5587b725ae77Skettenis
5588*63addd46Skettenis /* Remove the breakpoint that we inserted in __dbx_link().
5589*63addd46Skettenis Does nothing if the breakpoint hasn't been inserted or has already
5590*63addd46Skettenis been removed. */
5591*63addd46Skettenis
5592*63addd46Skettenis static void
remove_dbx_link_breakpoint(void)5593*63addd46Skettenis remove_dbx_link_breakpoint (void)
5594*63addd46Skettenis {
5595*63addd46Skettenis if (dbx_link_bpt_addr == 0)
5596*63addd46Skettenis return;
5597*63addd46Skettenis
5598*63addd46Skettenis if (memory_remove_breakpoint (dbx_link_bpt_addr,
5599*63addd46Skettenis dbx_link_shadow_contents) != 0)
5600*63addd46Skettenis warning ("Unable to remove __dbx_link breakpoint.");
5601*63addd46Skettenis
5602*63addd46Skettenis dbx_link_bpt_addr = 0;
5603*63addd46Skettenis }
5604*63addd46Skettenis
5605*63addd46Skettenis /* Return the address of the __dbx_link() function in the file
5606*63addd46Skettenis refernced by ABFD by scanning its symbol table. Return 0 if
5607*63addd46Skettenis the symbol was not found. */
5608*63addd46Skettenis
5609*63addd46Skettenis static CORE_ADDR
dbx_link_addr(bfd * abfd)5610*63addd46Skettenis dbx_link_addr (bfd *abfd)
5611*63addd46Skettenis {
5612*63addd46Skettenis long storage_needed;
5613*63addd46Skettenis asymbol **symbol_table;
5614*63addd46Skettenis long number_of_symbols;
5615*63addd46Skettenis long i;
5616*63addd46Skettenis
5617*63addd46Skettenis storage_needed = bfd_get_symtab_upper_bound (abfd);
5618*63addd46Skettenis if (storage_needed <= 0)
5619*63addd46Skettenis return 0;
5620*63addd46Skettenis
5621*63addd46Skettenis symbol_table = (asymbol **) xmalloc (storage_needed);
5622*63addd46Skettenis make_cleanup (xfree, symbol_table);
5623*63addd46Skettenis
5624*63addd46Skettenis number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
5625*63addd46Skettenis
5626*63addd46Skettenis for (i = 0; i < number_of_symbols; i++)
5627*63addd46Skettenis {
5628*63addd46Skettenis asymbol *sym = symbol_table[i];
5629*63addd46Skettenis
5630*63addd46Skettenis if ((sym->flags & BSF_GLOBAL)
5631*63addd46Skettenis && sym->name != NULL && strcmp (sym->name, "__dbx_link") == 0)
5632*63addd46Skettenis return (sym->value + sym->section->vma);
5633*63addd46Skettenis }
5634*63addd46Skettenis
5635*63addd46Skettenis /* Symbol not found, return NULL. */
5636*63addd46Skettenis return 0;
5637*63addd46Skettenis }
5638*63addd46Skettenis
5639*63addd46Skettenis /* Search the symbol table of the file referenced by FD for a symbol
5640*63addd46Skettenis named __dbx_link(). If found, then insert a breakpoint at this location,
5641*63addd46Skettenis and return nonzero. Return zero otherwise. */
5642*63addd46Skettenis
5643*63addd46Skettenis static int
insert_dbx_link_bpt_in_file(int fd,CORE_ADDR ignored)5644*63addd46Skettenis insert_dbx_link_bpt_in_file (int fd, CORE_ADDR ignored)
5645*63addd46Skettenis {
5646*63addd46Skettenis bfd *abfd;
5647*63addd46Skettenis long storage_needed;
5648*63addd46Skettenis CORE_ADDR sym_addr;
5649*63addd46Skettenis
5650*63addd46Skettenis abfd = bfd_fdopenr ("unamed", 0, fd);
5651*63addd46Skettenis if (abfd == NULL)
5652*63addd46Skettenis {
5653*63addd46Skettenis warning ("Failed to create a bfd: %s.\n", bfd_errmsg (bfd_get_error ()));
5654*63addd46Skettenis return 0;
5655*63addd46Skettenis }
5656*63addd46Skettenis
5657*63addd46Skettenis if (!bfd_check_format (abfd, bfd_object))
5658*63addd46Skettenis {
5659*63addd46Skettenis /* Not the correct format, so we can not possibly find the dbx_link
5660*63addd46Skettenis symbol in it. */
5661*63addd46Skettenis bfd_close (abfd);
5662*63addd46Skettenis return 0;
5663*63addd46Skettenis }
5664*63addd46Skettenis
5665*63addd46Skettenis sym_addr = dbx_link_addr (abfd);
5666*63addd46Skettenis if (sym_addr != 0)
5667*63addd46Skettenis {
5668*63addd46Skettenis /* Insert the breakpoint. */
5669*63addd46Skettenis dbx_link_bpt_addr = sym_addr;
5670*63addd46Skettenis if (target_insert_breakpoint (sym_addr, dbx_link_shadow_contents) != 0)
5671*63addd46Skettenis {
5672*63addd46Skettenis warning ("Failed to insert dbx_link breakpoint.");
5673*63addd46Skettenis bfd_close (abfd);
5674*63addd46Skettenis return 0;
5675*63addd46Skettenis }
5676*63addd46Skettenis bfd_close (abfd);
5677*63addd46Skettenis return 1;
5678*63addd46Skettenis }
5679*63addd46Skettenis
5680*63addd46Skettenis bfd_close (abfd);
5681*63addd46Skettenis return 0;
5682*63addd46Skettenis }
5683*63addd46Skettenis
5684*63addd46Skettenis /* If the given memory region MAP contains a symbol named __dbx_link,
5685*63addd46Skettenis insert a breakpoint at this location and return nonzero. Return
5686*63addd46Skettenis zero otherwise. */
5687*63addd46Skettenis
5688*63addd46Skettenis static int
insert_dbx_link_bpt_in_region(struct prmap * map,int (* child_func)(),void * data)5689*63addd46Skettenis insert_dbx_link_bpt_in_region (struct prmap *map,
5690*63addd46Skettenis int (*child_func) (),
5691*63addd46Skettenis void *data)
5692*63addd46Skettenis {
5693*63addd46Skettenis procinfo *pi = (procinfo *) data;
5694*63addd46Skettenis
5695*63addd46Skettenis /* We know the symbol we're looking for is in a text region, so
5696*63addd46Skettenis only look for it if the region is a text one. */
5697*63addd46Skettenis if (map->pr_mflags & MA_EXEC)
5698*63addd46Skettenis return solib_mappings_callback (map, insert_dbx_link_bpt_in_file, pi);
5699*63addd46Skettenis
5700*63addd46Skettenis return 0;
5701*63addd46Skettenis }
5702*63addd46Skettenis
5703*63addd46Skettenis /* Search all memory regions for a symbol named __dbx_link. If found,
5704*63addd46Skettenis insert a breakpoint at its location, and return nonzero. Return zero
5705*63addd46Skettenis otherwise. */
5706*63addd46Skettenis
5707*63addd46Skettenis static int
insert_dbx_link_breakpoint(procinfo * pi)5708*63addd46Skettenis insert_dbx_link_breakpoint (procinfo *pi)
5709*63addd46Skettenis {
5710*63addd46Skettenis return iterate_over_mappings (pi, NULL, pi, insert_dbx_link_bpt_in_region);
5711*63addd46Skettenis }
5712*63addd46Skettenis
5713b725ae77Skettenis /*
5714b725ae77Skettenis * Function: mappingflags
5715b725ae77Skettenis *
5716b725ae77Skettenis * Returns an ascii representation of a memory mapping's flags.
5717b725ae77Skettenis */
5718b725ae77Skettenis
5719b725ae77Skettenis static char *
mappingflags(long flags)5720b725ae77Skettenis mappingflags (long flags)
5721b725ae77Skettenis {
5722b725ae77Skettenis static char asciiflags[8];
5723b725ae77Skettenis
5724b725ae77Skettenis strcpy (asciiflags, "-------");
5725b725ae77Skettenis #if defined (MA_PHYS)
5726b725ae77Skettenis if (flags & MA_PHYS)
5727b725ae77Skettenis asciiflags[0] = 'd';
5728b725ae77Skettenis #endif
5729b725ae77Skettenis if (flags & MA_STACK)
5730b725ae77Skettenis asciiflags[1] = 's';
5731b725ae77Skettenis if (flags & MA_BREAK)
5732b725ae77Skettenis asciiflags[2] = 'b';
5733b725ae77Skettenis if (flags & MA_SHARED)
5734b725ae77Skettenis asciiflags[3] = 's';
5735b725ae77Skettenis if (flags & MA_READ)
5736b725ae77Skettenis asciiflags[4] = 'r';
5737b725ae77Skettenis if (flags & MA_WRITE)
5738b725ae77Skettenis asciiflags[5] = 'w';
5739b725ae77Skettenis if (flags & MA_EXEC)
5740b725ae77Skettenis asciiflags[6] = 'x';
5741b725ae77Skettenis return (asciiflags);
5742b725ae77Skettenis }
5743b725ae77Skettenis
5744b725ae77Skettenis /*
5745b725ae77Skettenis * Function: info_mappings_callback
5746b725ae77Skettenis *
5747b725ae77Skettenis * Callback function, does the actual work for 'info proc mappings'.
5748b725ae77Skettenis */
5749b725ae77Skettenis
5750b725ae77Skettenis static int
info_mappings_callback(struct prmap * map,int (* ignore)(),void * unused)5751b725ae77Skettenis info_mappings_callback (struct prmap *map, int (*ignore) (), void *unused)
5752b725ae77Skettenis {
5753b725ae77Skettenis char *data_fmt_string;
5754b725ae77Skettenis
5755b725ae77Skettenis if (TARGET_ADDR_BIT == 32)
5756b725ae77Skettenis data_fmt_string = "\t%#10lx %#10lx %#10x %#10x %7s\n";
5757b725ae77Skettenis else
5758b725ae77Skettenis data_fmt_string = " %#18lx %#18lx %#10x %#10x %7s\n";
5759b725ae77Skettenis
5760b725ae77Skettenis printf_filtered (data_fmt_string,
5761b725ae77Skettenis (unsigned long) map->pr_vaddr,
5762b725ae77Skettenis (unsigned long) map->pr_vaddr + map->pr_size - 1,
5763b725ae77Skettenis map->pr_size,
5764b725ae77Skettenis #ifdef PCAGENT /* Horrible hack: only defined on Solaris 2.6+ */
5765b725ae77Skettenis (unsigned int) map->pr_offset,
5766b725ae77Skettenis #else
5767b725ae77Skettenis map->pr_off,
5768b725ae77Skettenis #endif
5769b725ae77Skettenis mappingflags (map->pr_mflags));
5770b725ae77Skettenis
5771b725ae77Skettenis return 0;
5772b725ae77Skettenis }
5773b725ae77Skettenis
5774b725ae77Skettenis /*
5775b725ae77Skettenis * Function: info_proc_mappings
5776b725ae77Skettenis *
5777b725ae77Skettenis * Implement the "info proc mappings" subcommand.
5778b725ae77Skettenis */
5779b725ae77Skettenis
5780b725ae77Skettenis static void
info_proc_mappings(procinfo * pi,int summary)5781b725ae77Skettenis info_proc_mappings (procinfo *pi, int summary)
5782b725ae77Skettenis {
5783b725ae77Skettenis char *header_fmt_string;
5784b725ae77Skettenis
5785b725ae77Skettenis if (TARGET_PTR_BIT == 32)
5786b725ae77Skettenis header_fmt_string = "\t%10s %10s %10s %10s %7s\n";
5787b725ae77Skettenis else
5788b725ae77Skettenis header_fmt_string = " %18s %18s %10s %10s %7s\n";
5789b725ae77Skettenis
5790b725ae77Skettenis if (summary)
5791b725ae77Skettenis return; /* No output for summary mode. */
5792b725ae77Skettenis
5793b725ae77Skettenis printf_filtered ("Mapped address spaces:\n\n");
5794b725ae77Skettenis printf_filtered (header_fmt_string,
5795b725ae77Skettenis "Start Addr",
5796b725ae77Skettenis " End Addr",
5797b725ae77Skettenis " Size",
5798b725ae77Skettenis " Offset",
5799b725ae77Skettenis "Flags");
5800b725ae77Skettenis
5801b725ae77Skettenis iterate_over_mappings (pi, NULL, NULL, info_mappings_callback);
5802b725ae77Skettenis printf_filtered ("\n");
5803b725ae77Skettenis }
5804b725ae77Skettenis
5805b725ae77Skettenis /*
5806b725ae77Skettenis * Function: info_proc_cmd
5807b725ae77Skettenis *
5808b725ae77Skettenis * Implement the "info proc" command.
5809b725ae77Skettenis */
5810b725ae77Skettenis
5811b725ae77Skettenis static void
info_proc_cmd(char * args,int from_tty)5812b725ae77Skettenis info_proc_cmd (char *args, int from_tty)
5813b725ae77Skettenis {
5814b725ae77Skettenis struct cleanup *old_chain;
5815b725ae77Skettenis procinfo *process = NULL;
5816b725ae77Skettenis procinfo *thread = NULL;
5817b725ae77Skettenis char **argv = NULL;
5818b725ae77Skettenis char *tmp = NULL;
5819b725ae77Skettenis int pid = 0;
5820b725ae77Skettenis int tid = 0;
5821b725ae77Skettenis int mappings = 0;
5822b725ae77Skettenis
5823b725ae77Skettenis old_chain = make_cleanup (null_cleanup, 0);
5824b725ae77Skettenis if (args)
5825b725ae77Skettenis {
5826b725ae77Skettenis if ((argv = buildargv (args)) == NULL)
5827b725ae77Skettenis nomem (0);
5828b725ae77Skettenis else
5829b725ae77Skettenis make_cleanup_freeargv (argv);
5830b725ae77Skettenis }
5831b725ae77Skettenis while (argv != NULL && *argv != NULL)
5832b725ae77Skettenis {
5833b725ae77Skettenis if (isdigit (argv[0][0]))
5834b725ae77Skettenis {
5835b725ae77Skettenis pid = strtoul (argv[0], &tmp, 10);
5836b725ae77Skettenis if (*tmp == '/')
5837b725ae77Skettenis tid = strtoul (++tmp, NULL, 10);
5838b725ae77Skettenis }
5839b725ae77Skettenis else if (argv[0][0] == '/')
5840b725ae77Skettenis {
5841b725ae77Skettenis tid = strtoul (argv[0] + 1, NULL, 10);
5842b725ae77Skettenis }
5843b725ae77Skettenis else if (strncmp (argv[0], "mappings", strlen (argv[0])) == 0)
5844b725ae77Skettenis {
5845b725ae77Skettenis mappings = 1;
5846b725ae77Skettenis }
5847b725ae77Skettenis else
5848b725ae77Skettenis {
5849b725ae77Skettenis /* [...] */
5850b725ae77Skettenis }
5851b725ae77Skettenis argv++;
5852b725ae77Skettenis }
5853b725ae77Skettenis if (pid == 0)
5854b725ae77Skettenis pid = PIDGET (inferior_ptid);
5855b725ae77Skettenis if (pid == 0)
5856b725ae77Skettenis error ("No current process: you must name one.");
5857b725ae77Skettenis else
5858b725ae77Skettenis {
5859b725ae77Skettenis /* Have pid, will travel.
5860b725ae77Skettenis First see if it's a process we're already debugging. */
5861b725ae77Skettenis process = find_procinfo (pid, 0);
5862b725ae77Skettenis if (process == NULL)
5863b725ae77Skettenis {
5864b725ae77Skettenis /* No. So open a procinfo for it, but
5865b725ae77Skettenis remember to close it again when finished. */
5866b725ae77Skettenis process = create_procinfo (pid, 0);
5867b725ae77Skettenis make_cleanup (do_destroy_procinfo_cleanup, process);
5868b725ae77Skettenis if (!open_procinfo_files (process, FD_CTL))
5869b725ae77Skettenis proc_error (process, "info proc, open_procinfo_files", __LINE__);
5870b725ae77Skettenis }
5871b725ae77Skettenis }
5872b725ae77Skettenis if (tid != 0)
5873b725ae77Skettenis thread = create_procinfo (pid, tid);
5874b725ae77Skettenis
5875b725ae77Skettenis if (process)
5876b725ae77Skettenis {
5877b725ae77Skettenis printf_filtered ("process %d flags:\n", process->pid);
5878b725ae77Skettenis proc_prettyprint_flags (proc_flags (process), 1);
5879b725ae77Skettenis if (proc_flags (process) & (PR_STOPPED | PR_ISTOP))
5880b725ae77Skettenis proc_prettyprint_why (proc_why (process), proc_what (process), 1);
5881b725ae77Skettenis if (proc_get_nthreads (process) > 1)
5882b725ae77Skettenis printf_filtered ("Process has %d threads.\n",
5883b725ae77Skettenis proc_get_nthreads (process));
5884b725ae77Skettenis }
5885b725ae77Skettenis if (thread)
5886b725ae77Skettenis {
5887b725ae77Skettenis printf_filtered ("thread %d flags:\n", thread->tid);
5888b725ae77Skettenis proc_prettyprint_flags (proc_flags (thread), 1);
5889b725ae77Skettenis if (proc_flags (thread) & (PR_STOPPED | PR_ISTOP))
5890b725ae77Skettenis proc_prettyprint_why (proc_why (thread), proc_what (thread), 1);
5891b725ae77Skettenis }
5892b725ae77Skettenis
5893b725ae77Skettenis if (mappings)
5894b725ae77Skettenis {
5895b725ae77Skettenis info_proc_mappings (process, 0);
5896b725ae77Skettenis }
5897b725ae77Skettenis
5898b725ae77Skettenis do_cleanups (old_chain);
5899b725ae77Skettenis }
5900b725ae77Skettenis
5901*63addd46Skettenis /* Modify the status of the system call identified by SYSCALLNUM in
5902*63addd46Skettenis the set of syscalls that are currently traced/debugged.
5903*63addd46Skettenis
5904*63addd46Skettenis If ENTRY_OR_EXIT is set to PR_SYSENTRY, then the entry syscalls set
5905*63addd46Skettenis will be updated. Otherwise, the exit syscalls set will be updated.
5906*63addd46Skettenis
5907*63addd46Skettenis If MODE is FLAG_SET, then traces will be enabled. Otherwise, they
5908*63addd46Skettenis will be disabled. */
5909*63addd46Skettenis
5910b725ae77Skettenis static void
proc_trace_syscalls_1(procinfo * pi,int syscallnum,int entry_or_exit,int mode,int from_tty)5911*63addd46Skettenis proc_trace_syscalls_1 (procinfo *pi, int syscallnum, int entry_or_exit,
5912*63addd46Skettenis int mode, int from_tty)
5913b725ae77Skettenis {
5914b725ae77Skettenis sysset_t *sysset;
5915b725ae77Skettenis
5916b725ae77Skettenis if (entry_or_exit == PR_SYSENTRY)
5917b725ae77Skettenis sysset = proc_get_traced_sysentry (pi, NULL);
5918b725ae77Skettenis else
5919b725ae77Skettenis sysset = proc_get_traced_sysexit (pi, NULL);
5920b725ae77Skettenis
5921b725ae77Skettenis if (sysset == NULL)
5922b725ae77Skettenis proc_error (pi, "proc-trace, get_traced_sysset", __LINE__);
5923b725ae77Skettenis
5924b725ae77Skettenis if (mode == FLAG_SET)
5925b725ae77Skettenis gdb_praddsysset (sysset, syscallnum);
5926b725ae77Skettenis else
5927b725ae77Skettenis gdb_prdelsysset (sysset, syscallnum);
5928b725ae77Skettenis
5929b725ae77Skettenis if (entry_or_exit == PR_SYSENTRY)
5930b725ae77Skettenis {
5931b725ae77Skettenis if (!proc_set_traced_sysentry (pi, sysset))
5932b725ae77Skettenis proc_error (pi, "proc-trace, set_traced_sysentry", __LINE__);
5933b725ae77Skettenis }
5934b725ae77Skettenis else
5935b725ae77Skettenis {
5936b725ae77Skettenis if (!proc_set_traced_sysexit (pi, sysset))
5937b725ae77Skettenis proc_error (pi, "proc-trace, set_traced_sysexit", __LINE__);
5938b725ae77Skettenis }
5939b725ae77Skettenis }
5940*63addd46Skettenis
5941*63addd46Skettenis static void
proc_trace_syscalls(char * args,int from_tty,int entry_or_exit,int mode)5942*63addd46Skettenis proc_trace_syscalls (char *args, int from_tty, int entry_or_exit, int mode)
5943*63addd46Skettenis {
5944*63addd46Skettenis procinfo *pi;
5945*63addd46Skettenis
5946*63addd46Skettenis if (PIDGET (inferior_ptid) <= 0)
5947*63addd46Skettenis error ("you must be debugging a process to use this command.");
5948*63addd46Skettenis
5949*63addd46Skettenis if (args == NULL || args[0] == 0)
5950*63addd46Skettenis error_no_arg ("system call to trace");
5951*63addd46Skettenis
5952*63addd46Skettenis pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
5953*63addd46Skettenis if (isdigit (args[0]))
5954*63addd46Skettenis {
5955*63addd46Skettenis const int syscallnum = atoi (args);
5956*63addd46Skettenis
5957*63addd46Skettenis proc_trace_syscalls_1 (pi, syscallnum, entry_or_exit, mode, from_tty);
5958*63addd46Skettenis }
5959b725ae77Skettenis }
5960b725ae77Skettenis
5961b725ae77Skettenis static void
proc_trace_sysentry_cmd(char * args,int from_tty)5962b725ae77Skettenis proc_trace_sysentry_cmd (char *args, int from_tty)
5963b725ae77Skettenis {
5964b725ae77Skettenis proc_trace_syscalls (args, from_tty, PR_SYSENTRY, FLAG_SET);
5965b725ae77Skettenis }
5966b725ae77Skettenis
5967b725ae77Skettenis static void
proc_trace_sysexit_cmd(char * args,int from_tty)5968b725ae77Skettenis proc_trace_sysexit_cmd (char *args, int from_tty)
5969b725ae77Skettenis {
5970b725ae77Skettenis proc_trace_syscalls (args, from_tty, PR_SYSEXIT, FLAG_SET);
5971b725ae77Skettenis }
5972b725ae77Skettenis
5973b725ae77Skettenis static void
proc_untrace_sysentry_cmd(char * args,int from_tty)5974b725ae77Skettenis proc_untrace_sysentry_cmd (char *args, int from_tty)
5975b725ae77Skettenis {
5976b725ae77Skettenis proc_trace_syscalls (args, from_tty, PR_SYSENTRY, FLAG_RESET);
5977b725ae77Skettenis }
5978b725ae77Skettenis
5979b725ae77Skettenis static void
proc_untrace_sysexit_cmd(char * args,int from_tty)5980b725ae77Skettenis proc_untrace_sysexit_cmd (char *args, int from_tty)
5981b725ae77Skettenis {
5982b725ae77Skettenis proc_trace_syscalls (args, from_tty, PR_SYSEXIT, FLAG_RESET);
5983b725ae77Skettenis }
5984b725ae77Skettenis
5985b725ae77Skettenis
5986b725ae77Skettenis void
_initialize_procfs(void)5987b725ae77Skettenis _initialize_procfs (void)
5988b725ae77Skettenis {
5989b725ae77Skettenis init_procfs_ops ();
5990b725ae77Skettenis add_target (&procfs_ops);
5991b725ae77Skettenis add_info ("proc", info_proc_cmd,
5992b725ae77Skettenis "Show /proc process information about any running process.\n\
5993b725ae77Skettenis Specify process id, or use the program being debugged by default.\n\
5994b725ae77Skettenis Specify keyword 'mappings' for detailed info on memory mappings.");
5995b725ae77Skettenis add_com ("proc-trace-entry", no_class, proc_trace_sysentry_cmd,
5996b725ae77Skettenis "Give a trace of entries into the syscall.");
5997b725ae77Skettenis add_com ("proc-trace-exit", no_class, proc_trace_sysexit_cmd,
5998b725ae77Skettenis "Give a trace of exits from the syscall.");
5999b725ae77Skettenis add_com ("proc-untrace-entry", no_class, proc_untrace_sysentry_cmd,
6000b725ae77Skettenis "Cancel a trace of entries into the syscall.");
6001b725ae77Skettenis add_com ("proc-untrace-exit", no_class, proc_untrace_sysexit_cmd,
6002b725ae77Skettenis "Cancel a trace of exits from the syscall.");
6003b725ae77Skettenis }
6004b725ae77Skettenis
6005b725ae77Skettenis /* =================== END, GDB "MODULE" =================== */
6006b725ae77Skettenis
6007b725ae77Skettenis
6008b725ae77Skettenis
6009b725ae77Skettenis /* miscellaneous stubs: */
6010b725ae77Skettenis /* The following satisfy a few random symbols mostly created by */
6011b725ae77Skettenis /* the solaris threads implementation, which I will chase down */
6012b725ae77Skettenis /* later. */
6013b725ae77Skettenis
6014b725ae77Skettenis /*
6015b725ae77Skettenis * Return a pid for which we guarantee
6016b725ae77Skettenis * we will be able to find a 'live' procinfo.
6017b725ae77Skettenis */
6018b725ae77Skettenis
6019b725ae77Skettenis ptid_t
procfs_first_available(void)6020b725ae77Skettenis procfs_first_available (void)
6021b725ae77Skettenis {
6022b725ae77Skettenis return pid_to_ptid (procinfo_list ? procinfo_list->pid : -1);
6023b725ae77Skettenis }
6024b725ae77Skettenis
6025b725ae77Skettenis /* =================== GCORE .NOTE "MODULE" =================== */
6026b725ae77Skettenis #if defined (UNIXWARE) || defined (PIOCOPENLWP) || defined (PCAGENT)
6027b725ae77Skettenis /* gcore only implemented on solaris and unixware (so far) */
6028b725ae77Skettenis
6029b725ae77Skettenis static char *
procfs_do_thread_registers(bfd * obfd,ptid_t ptid,char * note_data,int * note_size)6030b725ae77Skettenis procfs_do_thread_registers (bfd *obfd, ptid_t ptid,
6031b725ae77Skettenis char *note_data, int *note_size)
6032b725ae77Skettenis {
6033b725ae77Skettenis gdb_gregset_t gregs;
6034b725ae77Skettenis gdb_fpregset_t fpregs;
6035b725ae77Skettenis unsigned long merged_pid;
6036b725ae77Skettenis
6037b725ae77Skettenis merged_pid = TIDGET (ptid) << 16 | PIDGET (ptid);
6038b725ae77Skettenis
6039b725ae77Skettenis fill_gregset (&gregs, -1);
6040b725ae77Skettenis #if defined (UNIXWARE)
6041b725ae77Skettenis note_data = (char *) elfcore_write_lwpstatus (obfd,
6042b725ae77Skettenis note_data,
6043b725ae77Skettenis note_size,
6044b725ae77Skettenis merged_pid,
6045b725ae77Skettenis stop_signal,
6046b725ae77Skettenis &gregs);
6047b725ae77Skettenis #else
6048b725ae77Skettenis note_data = (char *) elfcore_write_prstatus (obfd,
6049b725ae77Skettenis note_data,
6050b725ae77Skettenis note_size,
6051b725ae77Skettenis merged_pid,
6052b725ae77Skettenis stop_signal,
6053b725ae77Skettenis &gregs);
6054b725ae77Skettenis #endif
6055b725ae77Skettenis fill_fpregset (&fpregs, -1);
6056b725ae77Skettenis note_data = (char *) elfcore_write_prfpreg (obfd,
6057b725ae77Skettenis note_data,
6058b725ae77Skettenis note_size,
6059b725ae77Skettenis &fpregs,
6060b725ae77Skettenis sizeof (fpregs));
6061b725ae77Skettenis return note_data;
6062b725ae77Skettenis }
6063b725ae77Skettenis
6064b725ae77Skettenis struct procfs_corefile_thread_data {
6065b725ae77Skettenis bfd *obfd;
6066b725ae77Skettenis char *note_data;
6067b725ae77Skettenis int *note_size;
6068b725ae77Skettenis };
6069b725ae77Skettenis
6070b725ae77Skettenis static int
procfs_corefile_thread_callback(procinfo * pi,procinfo * thread,void * data)6071b725ae77Skettenis procfs_corefile_thread_callback (procinfo *pi, procinfo *thread, void *data)
6072b725ae77Skettenis {
6073b725ae77Skettenis struct procfs_corefile_thread_data *args = data;
6074b725ae77Skettenis
6075b725ae77Skettenis if (pi != NULL && thread->tid != 0)
6076b725ae77Skettenis {
6077b725ae77Skettenis ptid_t saved_ptid = inferior_ptid;
6078b725ae77Skettenis inferior_ptid = MERGEPID (pi->pid, thread->tid);
6079b725ae77Skettenis args->note_data = procfs_do_thread_registers (args->obfd, inferior_ptid,
6080b725ae77Skettenis args->note_data,
6081b725ae77Skettenis args->note_size);
6082b725ae77Skettenis inferior_ptid = saved_ptid;
6083b725ae77Skettenis }
6084b725ae77Skettenis return 0;
6085b725ae77Skettenis }
6086b725ae77Skettenis
6087b725ae77Skettenis static char *
procfs_make_note_section(bfd * obfd,int * note_size)6088b725ae77Skettenis procfs_make_note_section (bfd *obfd, int *note_size)
6089b725ae77Skettenis {
6090b725ae77Skettenis struct cleanup *old_chain;
6091b725ae77Skettenis gdb_gregset_t gregs;
6092b725ae77Skettenis gdb_fpregset_t fpregs;
6093b725ae77Skettenis char fname[16] = {'\0'};
6094b725ae77Skettenis char psargs[80] = {'\0'};
6095b725ae77Skettenis procinfo *pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
6096b725ae77Skettenis char *note_data = NULL;
6097b725ae77Skettenis char *inf_args;
6098b725ae77Skettenis struct procfs_corefile_thread_data thread_args;
6099b725ae77Skettenis char *auxv;
6100b725ae77Skettenis int auxv_len;
6101b725ae77Skettenis
6102b725ae77Skettenis if (get_exec_file (0))
6103b725ae77Skettenis {
6104b725ae77Skettenis strncpy (fname, strrchr (get_exec_file (0), '/') + 1, sizeof (fname));
6105b725ae77Skettenis strncpy (psargs, get_exec_file (0),
6106b725ae77Skettenis sizeof (psargs));
6107b725ae77Skettenis
6108b725ae77Skettenis inf_args = get_inferior_args ();
6109b725ae77Skettenis if (inf_args && *inf_args &&
6110b725ae77Skettenis strlen (inf_args) < ((int) sizeof (psargs) - (int) strlen (psargs)))
6111b725ae77Skettenis {
6112b725ae77Skettenis strncat (psargs, " ",
6113b725ae77Skettenis sizeof (psargs) - strlen (psargs));
6114b725ae77Skettenis strncat (psargs, inf_args,
6115b725ae77Skettenis sizeof (psargs) - strlen (psargs));
6116b725ae77Skettenis }
6117b725ae77Skettenis }
6118b725ae77Skettenis
6119b725ae77Skettenis note_data = (char *) elfcore_write_prpsinfo (obfd,
6120b725ae77Skettenis note_data,
6121b725ae77Skettenis note_size,
6122b725ae77Skettenis fname,
6123b725ae77Skettenis psargs);
6124b725ae77Skettenis
6125b725ae77Skettenis #ifdef UNIXWARE
6126b725ae77Skettenis fill_gregset (&gregs, -1);
6127b725ae77Skettenis note_data = elfcore_write_pstatus (obfd, note_data, note_size,
6128b725ae77Skettenis PIDGET (inferior_ptid),
6129b725ae77Skettenis stop_signal, &gregs);
6130b725ae77Skettenis #endif
6131b725ae77Skettenis
6132b725ae77Skettenis thread_args.obfd = obfd;
6133b725ae77Skettenis thread_args.note_data = note_data;
6134b725ae77Skettenis thread_args.note_size = note_size;
6135b725ae77Skettenis proc_iterate_over_threads (pi, procfs_corefile_thread_callback, &thread_args);
6136b725ae77Skettenis
6137b725ae77Skettenis if (thread_args.note_data == note_data)
6138b725ae77Skettenis {
6139b725ae77Skettenis /* iterate_over_threads didn't come up with any threads;
6140b725ae77Skettenis just use inferior_ptid. */
6141b725ae77Skettenis note_data = procfs_do_thread_registers (obfd, inferior_ptid,
6142b725ae77Skettenis note_data, note_size);
6143b725ae77Skettenis }
6144b725ae77Skettenis else
6145b725ae77Skettenis {
6146b725ae77Skettenis note_data = thread_args.note_data;
6147b725ae77Skettenis }
6148b725ae77Skettenis
6149b725ae77Skettenis auxv_len = target_auxv_read (¤t_target, &auxv);
6150b725ae77Skettenis if (auxv_len > 0)
6151b725ae77Skettenis {
6152b725ae77Skettenis note_data = elfcore_write_note (obfd, note_data, note_size,
6153b725ae77Skettenis "CORE", NT_AUXV, auxv, auxv_len);
6154b725ae77Skettenis xfree (auxv);
6155b725ae77Skettenis }
6156b725ae77Skettenis
6157b725ae77Skettenis make_cleanup (xfree, note_data);
6158b725ae77Skettenis return note_data;
6159b725ae77Skettenis }
6160b725ae77Skettenis #else /* !(Solaris or Unixware) */
6161b725ae77Skettenis static char *
procfs_make_note_section(bfd * obfd,int * note_size)6162b725ae77Skettenis procfs_make_note_section (bfd *obfd, int *note_size)
6163b725ae77Skettenis {
6164b725ae77Skettenis error ("gcore not implemented for this host.");
6165b725ae77Skettenis return NULL; /* lint */
6166b725ae77Skettenis }
6167b725ae77Skettenis #endif /* Solaris or Unixware */
6168b725ae77Skettenis /* =================== END GCORE .NOTE "MODULE" =================== */
6169