xref: /openbsd-src/gnu/usr.bin/binutils/gdb/infttrace.c (revision 11efff7f3ac2b3cfeff0c0cddc14294d9b3aca4f)
1b725ae77Skettenis /* Low level Unix child interface to ttrace, for GDB when running under HP-UX.
2*11efff7fSkettenis 
3*11efff7fSkettenis    Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
4*11efff7fSkettenis    1998, 1999, 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
5b725ae77Skettenis 
6b725ae77Skettenis    This file is part of GDB.
7b725ae77Skettenis 
8b725ae77Skettenis    This program is free software; you can redistribute it and/or modify
9b725ae77Skettenis    it under the terms of the GNU General Public License as published by
10b725ae77Skettenis    the Free Software Foundation; either version 2 of the License, or
11b725ae77Skettenis    (at your option) any later version.
12b725ae77Skettenis 
13b725ae77Skettenis    This program is distributed in the hope that it will be useful,
14b725ae77Skettenis    but WITHOUT ANY WARRANTY; without even the implied warranty of
15b725ae77Skettenis    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16b725ae77Skettenis    GNU General Public License for more details.
17b725ae77Skettenis 
18b725ae77Skettenis    You should have received a copy of the GNU General Public License
19b725ae77Skettenis    along with this program; if not, write to the Free Software
20b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
21b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
22b725ae77Skettenis 
23b725ae77Skettenis #include "defs.h"
24b725ae77Skettenis #include "frame.h"
25b725ae77Skettenis #include "inferior.h"
26b725ae77Skettenis #include "target.h"
27b725ae77Skettenis #include "gdb_string.h"
28b725ae77Skettenis #include "gdb_wait.h"
29b725ae77Skettenis #include "command.h"
30b725ae77Skettenis #include "gdbthread.h"
31*11efff7fSkettenis #include "infttrace.h"
32b725ae77Skettenis 
33b725ae77Skettenis /* We need pstat functionality so that we can get the exec file
34b725ae77Skettenis    for a process we attach to.
35b725ae77Skettenis 
36b725ae77Skettenis    According to HP, we should use the 64bit interfaces, so we
37b725ae77Skettenis    define _PSTAT64 to achieve this.  */
38b725ae77Skettenis #define _PSTAT64
39b725ae77Skettenis #include <sys/pstat.h>
40b725ae77Skettenis 
41b725ae77Skettenis /* Some hackery to work around a use of the #define name NO_FLAGS
42b725ae77Skettenis  * in both gdb and HPUX (bfd.h and /usr/include/machine/vmparam.h).
43b725ae77Skettenis  */
44b725ae77Skettenis #ifdef  NO_FLAGS
45b725ae77Skettenis #define INFTTRACE_TEMP_HACK NO_FLAGS
46b725ae77Skettenis #undef  NO_FLAGS
47b725ae77Skettenis #endif
48b725ae77Skettenis 
49b725ae77Skettenis #include <sys/param.h>
50b725ae77Skettenis #include <sys/dir.h>
51b725ae77Skettenis #include <signal.h>
52b725ae77Skettenis #include <sys/ioctl.h>
53b725ae77Skettenis 
54b725ae77Skettenis #include <sys/ttrace.h>
55b725ae77Skettenis #include <sys/mman.h>
56b725ae77Skettenis 
57b725ae77Skettenis #ifndef NO_PTRACE_H
58b725ae77Skettenis #ifdef PTRACE_IN_WRONG_PLACE
59b725ae77Skettenis #include <ptrace.h>
60b725ae77Skettenis #else
61b725ae77Skettenis #include <sys/ptrace.h>
62b725ae77Skettenis #endif
63b725ae77Skettenis #endif /* NO_PTRACE_H */
64b725ae77Skettenis 
65b725ae77Skettenis /* Second half of the hackery above.  Non-ANSI C, so
66b725ae77Skettenis  * we can't use "#error", alas.
67b725ae77Skettenis  */
68b725ae77Skettenis #ifdef NO_FLAGS
69b725ae77Skettenis #if (NO_FLAGS != INFTTRACE_TEMP_HACK )
70b725ae77Skettenis   /* #error "Hackery to remove warning didn't work right" */
71b725ae77Skettenis #else
72b725ae77Skettenis   /* Ok, new def'n of NO_FLAGS is same as old one; no action needed. */
73b725ae77Skettenis #endif
74b725ae77Skettenis #else
75b725ae77Skettenis   /* #error "Didn't get expected re-definition of NO_FLAGS" */
76b725ae77Skettenis #define NO_FLAGS INFTTRACE_TEMP_HACK
77b725ae77Skettenis #endif
78b725ae77Skettenis 
79b725ae77Skettenis #if !defined (PT_SETTRC)
80b725ae77Skettenis #define PT_SETTRC	0	/* Make process traceable by parent */
81b725ae77Skettenis #endif
82b725ae77Skettenis #if !defined (PT_READ_I)
83b725ae77Skettenis #define PT_READ_I	1	/* Read word from text space */
84b725ae77Skettenis #endif
85b725ae77Skettenis #if !defined (PT_READ_D)
86b725ae77Skettenis #define	PT_READ_D	2	/* Read word from data space */
87b725ae77Skettenis #endif
88b725ae77Skettenis #if !defined (PT_READ_U)
89b725ae77Skettenis #define PT_READ_U	3	/* Read word from kernel user struct */
90b725ae77Skettenis #endif
91b725ae77Skettenis #if !defined (PT_WRITE_I)
92b725ae77Skettenis #define PT_WRITE_I	4	/* Write word to text space */
93b725ae77Skettenis #endif
94b725ae77Skettenis #if !defined (PT_WRITE_D)
95b725ae77Skettenis #define PT_WRITE_D	5	/* Write word to data space */
96b725ae77Skettenis #endif
97b725ae77Skettenis #if !defined (PT_WRITE_U)
98b725ae77Skettenis #define PT_WRITE_U	6	/* Write word to kernel user struct */
99b725ae77Skettenis #endif
100b725ae77Skettenis #if !defined (PT_CONTINUE)
101b725ae77Skettenis #define PT_CONTINUE	7	/* Continue after signal */
102b725ae77Skettenis #endif
103b725ae77Skettenis #if !defined (PT_STEP)
104b725ae77Skettenis #define PT_STEP		9	/* Set flag for single stepping */
105b725ae77Skettenis #endif
106b725ae77Skettenis #if !defined (PT_KILL)
107b725ae77Skettenis #define PT_KILL		8	/* Send child a SIGKILL signal */
108b725ae77Skettenis #endif
109b725ae77Skettenis 
110b725ae77Skettenis #ifndef PT_ATTACH
111b725ae77Skettenis #define PT_ATTACH PTRACE_ATTACH
112b725ae77Skettenis #endif
113b725ae77Skettenis #ifndef PT_DETACH
114b725ae77Skettenis #define PT_DETACH PTRACE_DETACH
115b725ae77Skettenis #endif
116b725ae77Skettenis 
117b725ae77Skettenis #include "gdbcore.h"
118*11efff7fSkettenis #ifdef	HAVE_SYS_FILE_H
119b725ae77Skettenis #include <sys/file.h>
120b725ae77Skettenis #endif
121b725ae77Skettenis 
122b725ae77Skettenis /* This semaphore is used to coordinate the child and parent processes
123b725ae77Skettenis    after a fork(), and before an exec() by the child.  See parent_attach_all
124b725ae77Skettenis    for details.
125b725ae77Skettenis  */
126b725ae77Skettenis typedef struct
127b725ae77Skettenis   {
128b725ae77Skettenis     int parent_channel[2];	/* Parent "talks" to [1], child "listens" to [0] */
129b725ae77Skettenis     int child_channel[2];	/* Child "talks" to [1], parent "listens" to [0] */
130b725ae77Skettenis   }
131b725ae77Skettenis startup_semaphore_t;
132b725ae77Skettenis 
133b725ae77Skettenis #define SEM_TALK (1)
134b725ae77Skettenis #define SEM_LISTEN (0)
135b725ae77Skettenis 
136b725ae77Skettenis static startup_semaphore_t startup_semaphore;
137b725ae77Skettenis 
138b725ae77Skettenis /* See can_touch_threads_of_process for details. */
139b725ae77Skettenis static int vforking_child_pid = 0;
140b725ae77Skettenis static int vfork_in_flight = 0;
141b725ae77Skettenis 
142b725ae77Skettenis /* 1 if ok as results of a ttrace or ttrace_wait call, 0 otherwise.
143b725ae77Skettenis  */
144b725ae77Skettenis #define TT_OK( _status, _errno ) \
145b725ae77Skettenis     (((_status) == 1) && ((_errno) == 0))
146b725ae77Skettenis 
147b725ae77Skettenis #define TTRACE_ARG_TYPE uint64_t
148b725ae77Skettenis 
149b725ae77Skettenis /* When supplied as the "addr" operand, ttrace interprets this
150b725ae77Skettenis    to mean, "from the current address".
151b725ae77Skettenis  */
152b725ae77Skettenis #define TT_USE_CURRENT_PC ((TTRACE_ARG_TYPE) TT_NOPC)
153b725ae77Skettenis 
154b725ae77Skettenis /* When supplied as the "addr", "data" or "addr2" operand for most
155b725ae77Skettenis    requests, ttrace interprets this to mean, "pay no heed to this
156b725ae77Skettenis    argument".
157b725ae77Skettenis  */
158b725ae77Skettenis #define TT_NIL ((TTRACE_ARG_TYPE) TT_NULLARG)
159b725ae77Skettenis 
160b725ae77Skettenis /* This is capable of holding the value of a 32-bit register.  The
161b725ae77Skettenis    value is always left-aligned in the buffer; i.e., [0] contains
162b725ae77Skettenis    the most-significant byte of the register's value, and [sizeof(reg)]
163b725ae77Skettenis    contains the least-significant value.
164b725ae77Skettenis 
165b725ae77Skettenis    ??rehrauer: Yes, this assumes that an int is 32-bits on HP-UX, and
166b725ae77Skettenis    that registers are 32-bits on HP-UX.  The latter assumption changes
167b725ae77Skettenis    with PA2.0.
168b725ae77Skettenis  */
169b725ae77Skettenis typedef int register_value_t;
170b725ae77Skettenis 
171b725ae77Skettenis /********************************************************************
172b725ae77Skettenis 
173b725ae77Skettenis                  How this works:
174b725ae77Skettenis 
175b725ae77Skettenis    1.  Thread numbers
176b725ae77Skettenis 
177b725ae77Skettenis    The rest of GDB sees threads as being things with different
178b725ae77Skettenis    "pid" (process id) values.  See "thread.c" for details.  The
179b725ae77Skettenis    separate threads will be seen and reacted to if infttrace passes
180b725ae77Skettenis    back different pid values (for _events_).  See wait_for_inferior
181b725ae77Skettenis    in inftarg.c.
182b725ae77Skettenis 
183b725ae77Skettenis    So infttrace is going to use thread ids externally, pretending
184b725ae77Skettenis    they are process ids, and keep track internally so that it can
185b725ae77Skettenis    use the real process id (and thread id) when calling ttrace.
186b725ae77Skettenis 
187b725ae77Skettenis    The data structure that supports this is a linked list of the
188b725ae77Skettenis    current threads.  Since at some date infttrace will have to
189b725ae77Skettenis    deal with multiple processes, each list element records its
190b725ae77Skettenis    corresponding pid, rather than having a single global.
191b725ae77Skettenis 
192b725ae77Skettenis    Note that the list is only approximately current; that's ok, as
193b725ae77Skettenis    it's up to date when we need it (we hope!).  Also, it can contain
194b725ae77Skettenis    dead threads, as there's no harm if it does.
195b725ae77Skettenis 
196b725ae77Skettenis    The approach taken here is to bury the translation from external
197b725ae77Skettenis    to internal inside "call_ttrace" and a few other places.
198b725ae77Skettenis 
199b725ae77Skettenis    There are some wrinkles:
200b725ae77Skettenis 
201b725ae77Skettenis    o  When GDB forks itself to create the debug target process,
202b725ae77Skettenis       there's only a pid of 0 around in the child, so the
203b725ae77Skettenis       TT_PROC_SETTRC operation uses a more direct call to ttrace;
204b725ae77Skettenis       Similiarly, the initial setting of the event mask happens
205b725ae77Skettenis       early as  well, and so is also special-cased, and an attach
206b725ae77Skettenis       uses a real pid;
207b725ae77Skettenis 
208b725ae77Skettenis    o  We define an unthreaded application as having a "pseudo"
209b725ae77Skettenis       thread;
210b725ae77Skettenis 
211b725ae77Skettenis    o  To keep from confusing the rest of GDB, we don't switch
212b725ae77Skettenis       the PID for the pseudo thread to a TID.  A table will help:
213b725ae77Skettenis 
214b725ae77Skettenis       Rest of GDB sees these PIDs:     pid   tid1  tid2  tid3 ...
215b725ae77Skettenis 
216b725ae77Skettenis       Our thread list stores:          pid   pid   pid   pid  ...
217b725ae77Skettenis                                        tid0  tid1  tid2  tid3
218b725ae77Skettenis 
219b725ae77Skettenis       Ttrace sees these TIDS:          tid0  tid1  tid2  tid3 ...
220b725ae77Skettenis 
221b725ae77Skettenis       Both pid and tid0 will map to tid0, as there are infttrace.c-internal
222b725ae77Skettenis       calls to ttrace using tid0.
223b725ae77Skettenis 
224b725ae77Skettenis    2. Step and Continue
225b725ae77Skettenis 
226b725ae77Skettenis    Since we're implementing the "stop the world" model, sub-model
227b725ae77Skettenis    "other threads run during step", we have some stuff to do:
228b725ae77Skettenis 
229b725ae77Skettenis    o  User steps require continuing all threads other than the
230b725ae77Skettenis       one the user is stepping;
231b725ae77Skettenis 
232b725ae77Skettenis    o  Internal debugger steps (such as over a breakpoint or watchpoint,
233b725ae77Skettenis       but not out of a library load thunk) require stepping only
234b725ae77Skettenis       the selected thread; this means that we have to report the
235b725ae77Skettenis       step finish on that thread, which can lead to complications;
236b725ae77Skettenis 
237b725ae77Skettenis    o  When a thread is created, it is created running, rather
238b725ae77Skettenis       than stopped--so we have to stop it.
239b725ae77Skettenis 
240b725ae77Skettenis    The OS doesn't guarantee the stopped thread list will be stable,
241b725ae77Skettenis    no does it guarantee where on the stopped thread list a thread
242b725ae77Skettenis    that is single-stepped will wind up: it's possible that it will
243b725ae77Skettenis    be off the list for a while, it's possible the step will complete
244b725ae77Skettenis    and it will be re-posted to the end...
245b725ae77Skettenis 
246b725ae77Skettenis    This means we have to scan the stopped thread list, build up
247b725ae77Skettenis    a work-list, and then run down the work list; we can't do the
248b725ae77Skettenis    step/continue during the scan.
249b725ae77Skettenis 
250b725ae77Skettenis    3. Buffering events
251b725ae77Skettenis 
252b725ae77Skettenis    Then there's the issue of waiting for an event.  We do this by
253b725ae77Skettenis    noticing how many events are reported at the end of each wait.
254b725ae77Skettenis    From then on, we "fake" all resumes and steps, returning instantly,
255b725ae77Skettenis    and don't do another wait.  Once all pending events are reported,
256b725ae77Skettenis    we can really resume again.
257b725ae77Skettenis 
258b725ae77Skettenis    To keep this hidden, all the routines which know about tids and
259b725ae77Skettenis    pids or real events and simulated ones are static (file-local).
260b725ae77Skettenis 
261b725ae77Skettenis    This code can make lots of calls to ttrace, in particular it
262b725ae77Skettenis    can spin down the list of thread states more than once.  If this
263b725ae77Skettenis    becomes a performance hit, the spin could be done once and the
264b725ae77Skettenis    various "tsp" blocks saved, keeping all later spins in this
265b725ae77Skettenis    process.
266b725ae77Skettenis 
267b725ae77Skettenis    The O/S doesn't promise to keep the list straight, and so we must
268b725ae77Skettenis    re-scan a lot.  By observation, it looks like a single-step/wait
269b725ae77Skettenis    puts the stepped thread at the end of the list but doesn't change
270b725ae77Skettenis    it otherwise.
271b725ae77Skettenis 
272b725ae77Skettenis ****************************************************************
273b725ae77Skettenis */
274b725ae77Skettenis 
275b725ae77Skettenis /* Uncomment these to turn on various debugging output */
276b725ae77Skettenis /* #define THREAD_DEBUG */
277b725ae77Skettenis /* #define WAIT_BUFFER_DEBUG */
278b725ae77Skettenis /* #define PARANOIA */
279b725ae77Skettenis 
280b725ae77Skettenis 
281b725ae77Skettenis #define INFTTRACE_ALL_THREADS (-1)
282b725ae77Skettenis #define INFTTRACE_STEP        (1)
283b725ae77Skettenis #define INFTTRACE_CONTINUE    (0)
284b725ae77Skettenis 
285b725ae77Skettenis /* FIX: this is used in inftarg.c/child_wait, in a hack.
286b725ae77Skettenis  */
287b725ae77Skettenis extern int not_same_real_pid;
288b725ae77Skettenis 
289b725ae77Skettenis /* This is used to count buffered events.
290b725ae77Skettenis  */
291b725ae77Skettenis static unsigned int more_events_left = 0;
292b725ae77Skettenis 
293b725ae77Skettenis /* Process state.
294b725ae77Skettenis  */
295b725ae77Skettenis typedef enum process_state_enum
296b725ae77Skettenis   {
297b725ae77Skettenis     STOPPED,
298b725ae77Skettenis     FAKE_STEPPING,
299b725ae77Skettenis     FAKE_CONTINUE,		/* For later use */
300b725ae77Skettenis     RUNNING,
301b725ae77Skettenis     FORKING,
302b725ae77Skettenis     VFORKING
303b725ae77Skettenis   }
304b725ae77Skettenis process_state_t;
305b725ae77Skettenis 
306b725ae77Skettenis static process_state_t process_state = STOPPED;
307b725ae77Skettenis 
308b725ae77Skettenis /* User-specified stepping modality.
309b725ae77Skettenis  */
310b725ae77Skettenis typedef enum stepping_mode_enum
311b725ae77Skettenis   {
312b725ae77Skettenis     DO_DEFAULT,			/* ...which is a continue! */
313b725ae77Skettenis     DO_STEP,
314b725ae77Skettenis     DO_CONTINUE
315b725ae77Skettenis   }
316b725ae77Skettenis stepping_mode_t;
317b725ae77Skettenis 
318b725ae77Skettenis /* Action to take on an attach, depends on
319b725ae77Skettenis  * what kind (user command, fork, vfork).
320b725ae77Skettenis  *
321b725ae77Skettenis  * At the moment, this is either:
322b725ae77Skettenis  *
323b725ae77Skettenis  * o  continue with a SIGTRAP signal, or
324b725ae77Skettenis  *
325b725ae77Skettenis  * o  leave stopped.
326b725ae77Skettenis  */
327b725ae77Skettenis typedef enum attach_continue_enum
328b725ae77Skettenis   {
329b725ae77Skettenis     DO_ATTACH_CONTINUE,
330b725ae77Skettenis     DONT_ATTACH_CONTINUE
331b725ae77Skettenis   }
332b725ae77Skettenis attach_continue_t;
333b725ae77Skettenis 
334b725ae77Skettenis /* This flag is true if we are doing a step-over-bpt
335b725ae77Skettenis  * with buffered events.  We will have to be sure to
336b725ae77Skettenis  * report the right thread, as otherwise the spaghetti
337b725ae77Skettenis  * code in "infrun.c/wait_for_inferior" will get
338b725ae77Skettenis  * confused.
339b725ae77Skettenis  */
340b725ae77Skettenis static int doing_fake_step = 0;
341b725ae77Skettenis static lwpid_t fake_step_tid = 0;
342b725ae77Skettenis 
343b725ae77Skettenis 
344b725ae77Skettenis /****************************************************
345b725ae77Skettenis  * Thread information structure routines and types. *
346b725ae77Skettenis  ****************************************************
347b725ae77Skettenis  */
348b725ae77Skettenis typedef
349b725ae77Skettenis struct thread_info_struct
350b725ae77Skettenis   {
351b725ae77Skettenis     int am_pseudo;		/* This is a pseudo-thread for the process. */
352b725ae77Skettenis     int pid;			/* Process ID */
353b725ae77Skettenis     lwpid_t tid;		/* Thread  ID */
354b725ae77Skettenis     int handled;		/* 1 if a buffered event was handled. */
355b725ae77Skettenis     int seen;			/* 1 if this thread was seen on a traverse. */
356b725ae77Skettenis     int terminated;		/* 1 if thread has terminated. */
357b725ae77Skettenis     int have_signal;		/* 1 if signal to be sent */
358b725ae77Skettenis     enum target_signal signal_value;	/* Signal to send */
359b725ae77Skettenis     int have_start;		/* 1 if alternate starting address */
360b725ae77Skettenis     stepping_mode_t stepping_mode;	/* Whether to step or continue */
361b725ae77Skettenis     CORE_ADDR start;		/* Where to start */
362b725ae77Skettenis     int have_state;		/* 1 if the event state has been set */
363b725ae77Skettenis     ttstate_t last_stop_state;	/* The most recently-waited event for this thread. */
364b725ae77Skettenis     struct thread_info_struct
365b725ae77Skettenis      *next;			/* All threads are linked via this field. */
366b725ae77Skettenis     struct thread_info_struct
367b725ae77Skettenis      *next_pseudo;		/* All pseudo-threads are linked via this field. */
368b725ae77Skettenis   }
369b725ae77Skettenis thread_info;
370b725ae77Skettenis 
371b725ae77Skettenis typedef
372b725ae77Skettenis struct thread_info_header_struct
373b725ae77Skettenis   {
374b725ae77Skettenis     int count;
375b725ae77Skettenis     thread_info *head;
376b725ae77Skettenis     thread_info *head_pseudo;
377b725ae77Skettenis 
378b725ae77Skettenis   }
379b725ae77Skettenis thread_info_header;
380b725ae77Skettenis 
381b725ae77Skettenis static thread_info_header thread_head =
382b725ae77Skettenis {0, NULL, NULL};
383b725ae77Skettenis static thread_info_header deleted_threads =
384b725ae77Skettenis {0, NULL, NULL};
385b725ae77Skettenis 
386b725ae77Skettenis static ptid_t saved_real_ptid;
387b725ae77Skettenis 
388b725ae77Skettenis 
389b725ae77Skettenis /*************************************************
390b725ae77Skettenis  *          Debugging support functions          *
391b725ae77Skettenis  *************************************************
392b725ae77Skettenis  */
393b725ae77Skettenis CORE_ADDR
get_raw_pc(lwpid_t ttid)394b725ae77Skettenis get_raw_pc (lwpid_t ttid)
395b725ae77Skettenis {
396b725ae77Skettenis   unsigned long pc_val;
397b725ae77Skettenis   int offset;
398b725ae77Skettenis   int res;
399b725ae77Skettenis 
400b725ae77Skettenis   offset = register_addr (PC_REGNUM, U_REGS_OFFSET);
401b725ae77Skettenis   res = read_from_register_save_state (
402b725ae77Skettenis 					ttid,
403b725ae77Skettenis 					(TTRACE_ARG_TYPE) offset,
404b725ae77Skettenis 					(char *) &pc_val,
405b725ae77Skettenis 					sizeof (pc_val));
406b725ae77Skettenis   if (res <= 0)
407b725ae77Skettenis     {
408b725ae77Skettenis       return (CORE_ADDR) pc_val;
409b725ae77Skettenis     }
410b725ae77Skettenis   else
411b725ae77Skettenis     {
412b725ae77Skettenis       return (CORE_ADDR) 0;
413b725ae77Skettenis     }
414b725ae77Skettenis }
415b725ae77Skettenis 
416b725ae77Skettenis static char *
get_printable_name_of_stepping_mode(stepping_mode_t mode)417b725ae77Skettenis get_printable_name_of_stepping_mode (stepping_mode_t mode)
418b725ae77Skettenis {
419b725ae77Skettenis   switch (mode)
420b725ae77Skettenis     {
421b725ae77Skettenis     case DO_DEFAULT:
422b725ae77Skettenis       return "DO_DEFAULT";
423b725ae77Skettenis     case DO_STEP:
424b725ae77Skettenis       return "DO_STEP";
425b725ae77Skettenis     case DO_CONTINUE:
426b725ae77Skettenis       return "DO_CONTINUE";
427b725ae77Skettenis     default:
428b725ae77Skettenis       return "?unknown mode?";
429b725ae77Skettenis     }
430b725ae77Skettenis }
431b725ae77Skettenis 
432b725ae77Skettenis /* This function returns a pointer to a string describing the
433b725ae77Skettenis  * ttrace event being reported.
434b725ae77Skettenis  */
435b725ae77Skettenis char *
get_printable_name_of_ttrace_event(ttevents_t event)436b725ae77Skettenis get_printable_name_of_ttrace_event (ttevents_t event)
437b725ae77Skettenis {
438b725ae77Skettenis   /* This enumeration is "gappy", so don't use a table. */
439b725ae77Skettenis   switch (event)
440b725ae77Skettenis     {
441b725ae77Skettenis 
442b725ae77Skettenis     case TTEVT_NONE:
443b725ae77Skettenis       return "TTEVT_NONE";
444b725ae77Skettenis     case TTEVT_SIGNAL:
445b725ae77Skettenis       return "TTEVT_SIGNAL";
446b725ae77Skettenis     case TTEVT_FORK:
447b725ae77Skettenis       return "TTEVT_FORK";
448b725ae77Skettenis     case TTEVT_EXEC:
449b725ae77Skettenis       return "TTEVT_EXEC";
450b725ae77Skettenis     case TTEVT_EXIT:
451b725ae77Skettenis       return "TTEVT_EXIT";
452b725ae77Skettenis     case TTEVT_VFORK:
453b725ae77Skettenis       return "TTEVT_VFORK";
454b725ae77Skettenis     case TTEVT_SYSCALL_RETURN:
455b725ae77Skettenis       return "TTEVT_SYSCALL_RETURN";
456b725ae77Skettenis     case TTEVT_LWP_CREATE:
457b725ae77Skettenis       return "TTEVT_LWP_CREATE";
458b725ae77Skettenis     case TTEVT_LWP_TERMINATE:
459b725ae77Skettenis       return "TTEVT_LWP_TERMINATE";
460b725ae77Skettenis     case TTEVT_LWP_EXIT:
461b725ae77Skettenis       return "TTEVT_LWP_EXIT";
462b725ae77Skettenis     case TTEVT_LWP_ABORT_SYSCALL:
463b725ae77Skettenis       return "TTEVT_LWP_ABORT_SYSCALL";
464b725ae77Skettenis     case TTEVT_SYSCALL_ENTRY:
465b725ae77Skettenis       return "TTEVT_SYSCALL_ENTRY";
466b725ae77Skettenis     case TTEVT_SYSCALL_RESTART:
467b725ae77Skettenis       return "TTEVT_SYSCALL_RESTART";
468b725ae77Skettenis     default:
469b725ae77Skettenis       return "?new event?";
470b725ae77Skettenis     }
471b725ae77Skettenis }
472b725ae77Skettenis 
473b725ae77Skettenis 
474b725ae77Skettenis /* This function translates the ttrace request enumeration into
475b725ae77Skettenis  * a character string that is its printable (aka "human readable")
476b725ae77Skettenis  * name.
477b725ae77Skettenis  */
478b725ae77Skettenis char *
get_printable_name_of_ttrace_request(ttreq_t request)479b725ae77Skettenis get_printable_name_of_ttrace_request (ttreq_t request)
480b725ae77Skettenis {
481b725ae77Skettenis   if (!IS_TTRACE_REQ (request))
482b725ae77Skettenis     return "?bad req?";
483b725ae77Skettenis 
484b725ae77Skettenis   /* This enumeration is "gappy", so don't use a table. */
485b725ae77Skettenis   switch (request)
486b725ae77Skettenis     {
487b725ae77Skettenis     case TT_PROC_SETTRC:
488b725ae77Skettenis       return "TT_PROC_SETTRC";
489b725ae77Skettenis     case TT_PROC_ATTACH:
490b725ae77Skettenis       return "TT_PROC_ATTACH";
491b725ae77Skettenis     case TT_PROC_DETACH:
492b725ae77Skettenis       return "TT_PROC_DETACH";
493b725ae77Skettenis     case TT_PROC_RDTEXT:
494b725ae77Skettenis       return "TT_PROC_RDTEXT";
495b725ae77Skettenis     case TT_PROC_WRTEXT:
496b725ae77Skettenis       return "TT_PROC_WRTEXT";
497b725ae77Skettenis     case TT_PROC_RDDATA:
498b725ae77Skettenis       return "TT_PROC_RDDATA";
499b725ae77Skettenis     case TT_PROC_WRDATA:
500b725ae77Skettenis       return "TT_PROC_WRDATA";
501b725ae77Skettenis     case TT_PROC_STOP:
502b725ae77Skettenis       return "TT_PROC_STOP";
503b725ae77Skettenis     case TT_PROC_CONTINUE:
504b725ae77Skettenis       return "TT_PROC_CONTINUE";
505b725ae77Skettenis     case TT_PROC_GET_PATHNAME:
506b725ae77Skettenis       return "TT_PROC_GET_PATHNAME";
507b725ae77Skettenis     case TT_PROC_GET_EVENT_MASK:
508b725ae77Skettenis       return "TT_PROC_GET_EVENT_MASK";
509b725ae77Skettenis     case TT_PROC_SET_EVENT_MASK:
510b725ae77Skettenis       return "TT_PROC_SET_EVENT_MASK";
511b725ae77Skettenis     case TT_PROC_GET_FIRST_LWP_STATE:
512b725ae77Skettenis       return "TT_PROC_GET_FIRST_LWP_STATE";
513b725ae77Skettenis     case TT_PROC_GET_NEXT_LWP_STATE:
514b725ae77Skettenis       return "TT_PROC_GET_NEXT_LWP_STATE";
515b725ae77Skettenis     case TT_PROC_EXIT:
516b725ae77Skettenis       return "TT_PROC_EXIT";
517b725ae77Skettenis     case TT_PROC_GET_MPROTECT:
518b725ae77Skettenis       return "TT_PROC_GET_MPROTECT";
519b725ae77Skettenis     case TT_PROC_SET_MPROTECT:
520b725ae77Skettenis       return "TT_PROC_SET_MPROTECT";
521b725ae77Skettenis     case TT_PROC_SET_SCBM:
522b725ae77Skettenis       return "TT_PROC_SET_SCBM";
523b725ae77Skettenis     case TT_LWP_STOP:
524b725ae77Skettenis       return "TT_LWP_STOP";
525b725ae77Skettenis     case TT_LWP_CONTINUE:
526b725ae77Skettenis       return "TT_LWP_CONTINUE";
527b725ae77Skettenis     case TT_LWP_SINGLE:
528b725ae77Skettenis       return "TT_LWP_SINGLE";
529b725ae77Skettenis     case TT_LWP_RUREGS:
530b725ae77Skettenis       return "TT_LWP_RUREGS";
531b725ae77Skettenis     case TT_LWP_WUREGS:
532b725ae77Skettenis       return "TT_LWP_WUREGS";
533b725ae77Skettenis     case TT_LWP_GET_EVENT_MASK:
534b725ae77Skettenis       return "TT_LWP_GET_EVENT_MASK";
535b725ae77Skettenis     case TT_LWP_SET_EVENT_MASK:
536b725ae77Skettenis       return "TT_LWP_SET_EVENT_MASK";
537b725ae77Skettenis     case TT_LWP_GET_STATE:
538b725ae77Skettenis       return "TT_LWP_GET_STATE";
539b725ae77Skettenis     default:
540b725ae77Skettenis       return "?new req?";
541b725ae77Skettenis     }
542b725ae77Skettenis }
543b725ae77Skettenis 
544b725ae77Skettenis 
545b725ae77Skettenis /* This function translates the process state enumeration into
546b725ae77Skettenis  * a character string that is its printable (aka "human readable")
547b725ae77Skettenis  * name.
548b725ae77Skettenis  */
549b725ae77Skettenis static char *
get_printable_name_of_process_state(process_state_t process_state)550b725ae77Skettenis get_printable_name_of_process_state (process_state_t process_state)
551b725ae77Skettenis {
552b725ae77Skettenis   switch (process_state)
553b725ae77Skettenis     {
554b725ae77Skettenis     case STOPPED:
555b725ae77Skettenis       return "STOPPED";
556b725ae77Skettenis     case FAKE_STEPPING:
557b725ae77Skettenis       return "FAKE_STEPPING";
558b725ae77Skettenis     case RUNNING:
559b725ae77Skettenis       return "RUNNING";
560b725ae77Skettenis     case FORKING:
561b725ae77Skettenis       return "FORKING";
562b725ae77Skettenis     case VFORKING:
563b725ae77Skettenis       return "VFORKING";
564b725ae77Skettenis     default:
565b725ae77Skettenis       return "?some unknown state?";
566b725ae77Skettenis     }
567b725ae77Skettenis }
568b725ae77Skettenis 
569b725ae77Skettenis /* Set a ttrace thread state to a safe, initial state.
570b725ae77Skettenis  */
571b725ae77Skettenis static void
clear_ttstate_t(ttstate_t * tts)572b725ae77Skettenis clear_ttstate_t (ttstate_t *tts)
573b725ae77Skettenis {
574b725ae77Skettenis   tts->tts_pid = 0;
575b725ae77Skettenis   tts->tts_lwpid = 0;
576b725ae77Skettenis   tts->tts_user_tid = 0;
577b725ae77Skettenis   tts->tts_event = TTEVT_NONE;
578b725ae77Skettenis }
579b725ae77Skettenis 
580b725ae77Skettenis /* Copy ttrace thread state TTS_FROM into TTS_TO.
581b725ae77Skettenis  */
582b725ae77Skettenis static void
copy_ttstate_t(ttstate_t * tts_to,ttstate_t * tts_from)583b725ae77Skettenis copy_ttstate_t (ttstate_t *tts_to, ttstate_t *tts_from)
584b725ae77Skettenis {
585b725ae77Skettenis   memcpy ((char *) tts_to, (char *) tts_from, sizeof (*tts_to));
586b725ae77Skettenis }
587b725ae77Skettenis 
588b725ae77Skettenis /* Are there any live threads we know about?
589b725ae77Skettenis  */
590b725ae77Skettenis static int
any_thread_records(void)591b725ae77Skettenis any_thread_records (void)
592b725ae77Skettenis {
593b725ae77Skettenis   return (thread_head.count > 0);
594b725ae77Skettenis }
595b725ae77Skettenis 
596b725ae77Skettenis /* Create, fill in and link in a thread descriptor.
597b725ae77Skettenis  */
598b725ae77Skettenis static thread_info *
create_thread_info(int pid,lwpid_t tid)599b725ae77Skettenis create_thread_info (int pid, lwpid_t tid)
600b725ae77Skettenis {
601b725ae77Skettenis   thread_info *new_p;
602b725ae77Skettenis   thread_info *p;
603b725ae77Skettenis   int thread_count_of_pid;
604b725ae77Skettenis 
605b725ae77Skettenis   new_p = xmalloc (sizeof (thread_info));
606b725ae77Skettenis   new_p->pid = pid;
607b725ae77Skettenis   new_p->tid = tid;
608b725ae77Skettenis   new_p->have_signal = 0;
609b725ae77Skettenis   new_p->have_start = 0;
610b725ae77Skettenis   new_p->have_state = 0;
611b725ae77Skettenis   clear_ttstate_t (&new_p->last_stop_state);
612b725ae77Skettenis   new_p->am_pseudo = 0;
613b725ae77Skettenis   new_p->handled = 0;
614b725ae77Skettenis   new_p->seen = 0;
615b725ae77Skettenis   new_p->terminated = 0;
616b725ae77Skettenis   new_p->next = NULL;
617b725ae77Skettenis   new_p->next_pseudo = NULL;
618b725ae77Skettenis   new_p->stepping_mode = DO_DEFAULT;
619b725ae77Skettenis 
620b725ae77Skettenis   if (0 == thread_head.count)
621b725ae77Skettenis     {
622b725ae77Skettenis #ifdef THREAD_DEBUG
623b725ae77Skettenis       if (debug_on)
624b725ae77Skettenis 	printf ("First thread, pid %d tid %d!\n", pid, tid);
625b725ae77Skettenis #endif
626b725ae77Skettenis       saved_real_ptid = inferior_ptid;
627b725ae77Skettenis     }
628b725ae77Skettenis   else
629b725ae77Skettenis     {
630b725ae77Skettenis #ifdef THREAD_DEBUG
631b725ae77Skettenis       if (debug_on)
632b725ae77Skettenis 	printf ("Subsequent thread, pid %d tid %d\n", pid, tid);
633b725ae77Skettenis #endif
634b725ae77Skettenis     }
635b725ae77Skettenis 
636b725ae77Skettenis   /* Another day, another thread...
637b725ae77Skettenis    */
638b725ae77Skettenis   thread_head.count++;
639b725ae77Skettenis 
640b725ae77Skettenis   /* The new thread always goes at the head of the list.
641b725ae77Skettenis    */
642b725ae77Skettenis   new_p->next = thread_head.head;
643b725ae77Skettenis   thread_head.head = new_p;
644b725ae77Skettenis 
645b725ae77Skettenis   /* Is this the "pseudo" thread of a process?  It is if there's
646b725ae77Skettenis    * no other thread for this process on the list.  (Note that this
647b725ae77Skettenis    * accomodates multiple processes, such as we see even for simple
648b725ae77Skettenis    * cases like forking "non-threaded" programs.)
649b725ae77Skettenis    */
650b725ae77Skettenis   p = thread_head.head;
651b725ae77Skettenis   thread_count_of_pid = 0;
652b725ae77Skettenis   while (p)
653b725ae77Skettenis     {
654b725ae77Skettenis       if (p->pid == new_p->pid)
655b725ae77Skettenis 	thread_count_of_pid++;
656b725ae77Skettenis       p = p->next;
657b725ae77Skettenis     }
658b725ae77Skettenis 
659b725ae77Skettenis   /* Did we see any other threads for this pid?  (Recall that we just
660b725ae77Skettenis    * added this thread to the list...)
661b725ae77Skettenis    */
662b725ae77Skettenis   if (thread_count_of_pid == 1)
663b725ae77Skettenis     {
664b725ae77Skettenis       new_p->am_pseudo = 1;
665b725ae77Skettenis       new_p->next_pseudo = thread_head.head_pseudo;
666b725ae77Skettenis       thread_head.head_pseudo = new_p;
667b725ae77Skettenis     }
668b725ae77Skettenis 
669b725ae77Skettenis   return new_p;
670b725ae77Skettenis }
671b725ae77Skettenis 
672b725ae77Skettenis /* Get rid of our thread info.
673b725ae77Skettenis  */
674b725ae77Skettenis static void
clear_thread_info(void)675b725ae77Skettenis clear_thread_info (void)
676b725ae77Skettenis {
677b725ae77Skettenis   thread_info *p;
678b725ae77Skettenis   thread_info *q;
679b725ae77Skettenis 
680b725ae77Skettenis #ifdef THREAD_DEBUG
681b725ae77Skettenis   if (debug_on)
682b725ae77Skettenis     printf ("Clearing all thread info\n");
683b725ae77Skettenis #endif
684b725ae77Skettenis 
685b725ae77Skettenis   p = thread_head.head;
686b725ae77Skettenis   while (p)
687b725ae77Skettenis     {
688b725ae77Skettenis       q = p;
689b725ae77Skettenis       p = p->next;
690b725ae77Skettenis       xfree (q);
691b725ae77Skettenis     }
692b725ae77Skettenis 
693b725ae77Skettenis   thread_head.head = NULL;
694b725ae77Skettenis   thread_head.head_pseudo = NULL;
695b725ae77Skettenis   thread_head.count = 0;
696b725ae77Skettenis 
697b725ae77Skettenis   p = deleted_threads.head;
698b725ae77Skettenis   while (p)
699b725ae77Skettenis     {
700b725ae77Skettenis       q = p;
701b725ae77Skettenis       p = p->next;
702b725ae77Skettenis       xfree (q);
703b725ae77Skettenis     }
704b725ae77Skettenis 
705b725ae77Skettenis   deleted_threads.head = NULL;
706b725ae77Skettenis   deleted_threads.head_pseudo = NULL;
707b725ae77Skettenis   deleted_threads.count = 0;
708b725ae77Skettenis 
709b725ae77Skettenis   /* No threads, so can't have pending events.
710b725ae77Skettenis    */
711b725ae77Skettenis   more_events_left = 0;
712b725ae77Skettenis }
713b725ae77Skettenis 
714b725ae77Skettenis /* Given a tid, find the thread block for it.
715b725ae77Skettenis  */
716b725ae77Skettenis static thread_info *
find_thread_info(lwpid_t tid)717b725ae77Skettenis find_thread_info (lwpid_t tid)
718b725ae77Skettenis {
719b725ae77Skettenis   thread_info *p;
720b725ae77Skettenis 
721b725ae77Skettenis   for (p = thread_head.head; p; p = p->next)
722b725ae77Skettenis     {
723b725ae77Skettenis       if (p->tid == tid)
724b725ae77Skettenis 	{
725b725ae77Skettenis 	  return p;
726b725ae77Skettenis 	}
727b725ae77Skettenis     }
728b725ae77Skettenis 
729b725ae77Skettenis   for (p = deleted_threads.head; p; p = p->next)
730b725ae77Skettenis     {
731b725ae77Skettenis       if (p->tid == tid)
732b725ae77Skettenis 	{
733b725ae77Skettenis 	  return p;
734b725ae77Skettenis 	}
735b725ae77Skettenis     }
736b725ae77Skettenis 
737b725ae77Skettenis   return NULL;
738b725ae77Skettenis }
739b725ae77Skettenis 
740b725ae77Skettenis /* For any but the pseudo thread, this maps to the
741b725ae77Skettenis  * thread ID.  For the pseudo thread, if you pass either
742b725ae77Skettenis  * the thread id or the PID, you get the pseudo thread ID.
743b725ae77Skettenis  *
744b725ae77Skettenis  * We have to be prepared for core gdb to ask about
745b725ae77Skettenis  * deleted threads.  We do the map, but we don't like it.
746b725ae77Skettenis  */
747b725ae77Skettenis static lwpid_t
map_from_gdb_tid(lwpid_t gdb_tid)748b725ae77Skettenis map_from_gdb_tid (lwpid_t gdb_tid)
749b725ae77Skettenis {
750b725ae77Skettenis   thread_info *p;
751b725ae77Skettenis 
752b725ae77Skettenis   /* First assume gdb_tid really is a tid, and try to find a
753b725ae77Skettenis    * matching entry on the threads list.
754b725ae77Skettenis    */
755b725ae77Skettenis   for (p = thread_head.head; p; p = p->next)
756b725ae77Skettenis     {
757b725ae77Skettenis       if (p->tid == gdb_tid)
758b725ae77Skettenis 	return gdb_tid;
759b725ae77Skettenis     }
760b725ae77Skettenis 
761b725ae77Skettenis   /* It doesn't appear to be a tid; perhaps it's really a pid?
762b725ae77Skettenis    * Try to find a "pseudo" thread entry on the threads list.
763b725ae77Skettenis    */
764b725ae77Skettenis   for (p = thread_head.head_pseudo; p != NULL; p = p->next_pseudo)
765b725ae77Skettenis     {
766b725ae77Skettenis       if (p->pid == gdb_tid)
767b725ae77Skettenis 	return p->tid;
768b725ae77Skettenis     }
769b725ae77Skettenis 
770b725ae77Skettenis   /* Perhaps it's the tid of a deleted thread we may still
771b725ae77Skettenis    * have some knowledge of?
772b725ae77Skettenis    */
773b725ae77Skettenis   for (p = deleted_threads.head; p; p = p->next)
774b725ae77Skettenis     {
775b725ae77Skettenis       if (p->tid == gdb_tid)
776b725ae77Skettenis 	return gdb_tid;
777b725ae77Skettenis     }
778b725ae77Skettenis 
779b725ae77Skettenis   /* Or perhaps it's the pid of a deleted process we may still
780b725ae77Skettenis    * have knowledge of?
781b725ae77Skettenis    */
782b725ae77Skettenis   for (p = deleted_threads.head_pseudo; p != NULL; p = p->next_pseudo)
783b725ae77Skettenis     {
784b725ae77Skettenis       if (p->pid == gdb_tid)
785b725ae77Skettenis 	return p->tid;
786b725ae77Skettenis     }
787b725ae77Skettenis 
788b725ae77Skettenis   return 0;			/* Error? */
789b725ae77Skettenis }
790b725ae77Skettenis 
791b725ae77Skettenis /* Map the other way: from a real tid to the
792b725ae77Skettenis  * "pid" known by core gdb.  This tid may be
793b725ae77Skettenis  * for a thread that just got deleted, so we
794b725ae77Skettenis  * also need to consider deleted threads.
795b725ae77Skettenis  */
796b725ae77Skettenis static lwpid_t
map_to_gdb_tid(lwpid_t real_tid)797b725ae77Skettenis map_to_gdb_tid (lwpid_t real_tid)
798b725ae77Skettenis {
799b725ae77Skettenis   thread_info *p;
800b725ae77Skettenis 
801b725ae77Skettenis   for (p = thread_head.head; p; p = p->next)
802b725ae77Skettenis     {
803b725ae77Skettenis       if (p->tid == real_tid)
804b725ae77Skettenis 	{
805b725ae77Skettenis 	  if (p->am_pseudo)
806b725ae77Skettenis 	    return p->pid;
807b725ae77Skettenis 	  else
808b725ae77Skettenis 	    return real_tid;
809b725ae77Skettenis 	}
810b725ae77Skettenis     }
811b725ae77Skettenis 
812b725ae77Skettenis   for (p = deleted_threads.head; p; p = p->next)
813b725ae77Skettenis     {
814b725ae77Skettenis       if (p->tid == real_tid)
815b725ae77Skettenis 	if (p->am_pseudo)
816b725ae77Skettenis 	  return p->pid;	/* Error? */
817b725ae77Skettenis 	else
818b725ae77Skettenis 	  return real_tid;
819b725ae77Skettenis     }
820b725ae77Skettenis 
821b725ae77Skettenis   return 0;			/* Error?  Never heard of this thread! */
822b725ae77Skettenis }
823b725ae77Skettenis 
824b725ae77Skettenis /* Do any threads have saved signals?
825b725ae77Skettenis  */
826b725ae77Skettenis static int
saved_signals_exist(void)827b725ae77Skettenis saved_signals_exist (void)
828b725ae77Skettenis {
829b725ae77Skettenis   thread_info *p;
830b725ae77Skettenis 
831b725ae77Skettenis   for (p = thread_head.head; p; p = p->next)
832b725ae77Skettenis     {
833b725ae77Skettenis       if (p->have_signal)
834b725ae77Skettenis 	{
835b725ae77Skettenis 	  return 1;
836b725ae77Skettenis 	}
837b725ae77Skettenis     }
838b725ae77Skettenis 
839b725ae77Skettenis   return 0;
840b725ae77Skettenis }
841b725ae77Skettenis 
842b725ae77Skettenis /* Is this the tid for the zero-th thread?
843b725ae77Skettenis  */
844b725ae77Skettenis static int
is_pseudo_thread(lwpid_t tid)845b725ae77Skettenis is_pseudo_thread (lwpid_t tid)
846b725ae77Skettenis {
847b725ae77Skettenis   thread_info *p = find_thread_info (tid);
848b725ae77Skettenis   if (NULL == p || p->terminated)
849b725ae77Skettenis     return 0;
850b725ae77Skettenis   else
851b725ae77Skettenis     return p->am_pseudo;
852b725ae77Skettenis }
853b725ae77Skettenis 
854b725ae77Skettenis /* Is this thread terminated?
855b725ae77Skettenis  */
856b725ae77Skettenis static int
is_terminated(lwpid_t tid)857b725ae77Skettenis is_terminated (lwpid_t tid)
858b725ae77Skettenis {
859b725ae77Skettenis   thread_info *p = find_thread_info (tid);
860b725ae77Skettenis 
861b725ae77Skettenis   if (NULL != p)
862b725ae77Skettenis     return p->terminated;
863b725ae77Skettenis 
864b725ae77Skettenis   return 0;
865b725ae77Skettenis }
866b725ae77Skettenis 
867b725ae77Skettenis /* Is this pid a real PID or a TID?
868b725ae77Skettenis  */
869b725ae77Skettenis static int
is_process_id(int pid)870b725ae77Skettenis is_process_id (int pid)
871b725ae77Skettenis {
872b725ae77Skettenis   lwpid_t tid;
873b725ae77Skettenis   thread_info *tinfo;
874b725ae77Skettenis   pid_t this_pid;
875b725ae77Skettenis   int this_pid_count;
876b725ae77Skettenis 
877b725ae77Skettenis   /* What does PID really represent?
878b725ae77Skettenis    */
879b725ae77Skettenis   tid = map_from_gdb_tid (pid);
880b725ae77Skettenis   if (tid <= 0)
881b725ae77Skettenis     return 0;			/* Actually, is probably an error... */
882b725ae77Skettenis 
883b725ae77Skettenis   tinfo = find_thread_info (tid);
884b725ae77Skettenis 
885b725ae77Skettenis   /* Does it appear to be a true thread?
886b725ae77Skettenis    */
887b725ae77Skettenis   if (!tinfo->am_pseudo)
888b725ae77Skettenis     return 0;
889b725ae77Skettenis 
890b725ae77Skettenis   /* Else, it looks like it may be a process.  See if there's any other
891b725ae77Skettenis    * threads with the same process ID, though.  If there are, then TID
892b725ae77Skettenis    * just happens to be the first thread of several for this process.
893b725ae77Skettenis    */
894b725ae77Skettenis   this_pid = tinfo->pid;
895b725ae77Skettenis   this_pid_count = 0;
896b725ae77Skettenis   for (tinfo = thread_head.head; tinfo; tinfo = tinfo->next)
897b725ae77Skettenis     {
898b725ae77Skettenis       if (tinfo->pid == this_pid)
899b725ae77Skettenis 	this_pid_count++;
900b725ae77Skettenis     }
901b725ae77Skettenis 
902b725ae77Skettenis   return (this_pid_count == 1);
903b725ae77Skettenis }
904b725ae77Skettenis 
905b725ae77Skettenis 
906b725ae77Skettenis /* Add a thread to our info.  Prevent duplicate entries.
907b725ae77Skettenis  */
908b725ae77Skettenis static thread_info *
add_tthread(int pid,lwpid_t tid)909b725ae77Skettenis add_tthread (int pid, lwpid_t tid)
910b725ae77Skettenis {
911b725ae77Skettenis   thread_info *p;
912b725ae77Skettenis 
913b725ae77Skettenis   p = find_thread_info (tid);
914b725ae77Skettenis   if (NULL == p)
915b725ae77Skettenis     p = create_thread_info (pid, tid);
916b725ae77Skettenis 
917b725ae77Skettenis   return p;
918b725ae77Skettenis }
919b725ae77Skettenis 
920b725ae77Skettenis /* Notice that a thread was deleted.
921b725ae77Skettenis  */
922b725ae77Skettenis static void
del_tthread(lwpid_t tid)923b725ae77Skettenis del_tthread (lwpid_t tid)
924b725ae77Skettenis {
925b725ae77Skettenis   thread_info *p;
926b725ae77Skettenis   thread_info *chase;
927b725ae77Skettenis 
928b725ae77Skettenis   if (thread_head.count <= 0)
929b725ae77Skettenis     {
930b725ae77Skettenis       error ("Internal error in thread database.");
931b725ae77Skettenis       return;
932b725ae77Skettenis     }
933b725ae77Skettenis 
934b725ae77Skettenis   chase = NULL;
935b725ae77Skettenis   for (p = thread_head.head; p; p = p->next)
936b725ae77Skettenis     {
937b725ae77Skettenis       if (p->tid == tid)
938b725ae77Skettenis 	{
939b725ae77Skettenis 
940b725ae77Skettenis #ifdef THREAD_DEBUG
941b725ae77Skettenis 	  if (debug_on)
942b725ae77Skettenis 	    printf ("Delete here: %d \n", tid);
943b725ae77Skettenis #endif
944b725ae77Skettenis 
945b725ae77Skettenis 	  if (p->am_pseudo)
946b725ae77Skettenis 	    {
947b725ae77Skettenis 	      /*
948b725ae77Skettenis 	       * Deleting a main thread is ok if we're doing
949b725ae77Skettenis 	       * a parent-follow on a child; this is odd but
950b725ae77Skettenis 	       * not wrong.  It apparently _doesn't_ happen
951b725ae77Skettenis 	       * on the child-follow, as we don't just delete
952b725ae77Skettenis 	       * the pseudo while keeping the rest of the
953b725ae77Skettenis 	       * threads around--instead, we clear out the whole
954b725ae77Skettenis 	       * thread list at once.
955b725ae77Skettenis 	       */
956b725ae77Skettenis 	      thread_info *q;
957b725ae77Skettenis 	      thread_info *q_chase;
958b725ae77Skettenis 
959b725ae77Skettenis 	      q_chase = NULL;
960b725ae77Skettenis 	      for (q = thread_head.head_pseudo; q; q = q->next)
961b725ae77Skettenis 		{
962b725ae77Skettenis 		  if (q == p)
963b725ae77Skettenis 		    {
964b725ae77Skettenis 		      /* Remove from pseudo list.
965b725ae77Skettenis 		       */
966b725ae77Skettenis 		      if (q_chase == NULL)
967b725ae77Skettenis 			thread_head.head_pseudo = p->next_pseudo;
968b725ae77Skettenis 		      else
969b725ae77Skettenis 			q_chase->next = p->next_pseudo;
970b725ae77Skettenis 		    }
971b725ae77Skettenis 		  else
972b725ae77Skettenis 		    q_chase = q;
973b725ae77Skettenis 		}
974b725ae77Skettenis 	    }
975b725ae77Skettenis 
976b725ae77Skettenis 	  /* Remove from live list.
977b725ae77Skettenis 	   */
978b725ae77Skettenis 	  thread_head.count--;
979b725ae77Skettenis 
980b725ae77Skettenis 	  if (NULL == chase)
981b725ae77Skettenis 	    thread_head.head = p->next;
982b725ae77Skettenis 	  else
983b725ae77Skettenis 	    chase->next = p->next;
984b725ae77Skettenis 
985b725ae77Skettenis 	  /* Add to deleted thread list.
986b725ae77Skettenis 	   */
987b725ae77Skettenis 	  p->next = deleted_threads.head;
988b725ae77Skettenis 	  deleted_threads.head = p;
989b725ae77Skettenis 	  deleted_threads.count++;
990b725ae77Skettenis 	  if (p->am_pseudo)
991b725ae77Skettenis 	    {
992b725ae77Skettenis 	      p->next_pseudo = deleted_threads.head_pseudo;
993b725ae77Skettenis 	      deleted_threads.head_pseudo = p;
994b725ae77Skettenis 	    }
995b725ae77Skettenis 	  p->terminated = 1;
996b725ae77Skettenis 
997b725ae77Skettenis 	  return;
998b725ae77Skettenis 	}
999b725ae77Skettenis 
1000b725ae77Skettenis       else
1001b725ae77Skettenis 	chase = p;
1002b725ae77Skettenis     }
1003b725ae77Skettenis }
1004b725ae77Skettenis 
1005b725ae77Skettenis /* Get the pid for this tid. (Has to be a real TID!).
1006b725ae77Skettenis  */
1007b725ae77Skettenis static int
get_pid_for(lwpid_t tid)1008b725ae77Skettenis get_pid_for (lwpid_t tid)
1009b725ae77Skettenis {
1010b725ae77Skettenis   thread_info *p;
1011b725ae77Skettenis 
1012b725ae77Skettenis   for (p = thread_head.head; p; p = p->next)
1013b725ae77Skettenis     {
1014b725ae77Skettenis       if (p->tid == tid)
1015b725ae77Skettenis 	{
1016b725ae77Skettenis 	  return p->pid;
1017b725ae77Skettenis 	}
1018b725ae77Skettenis     }
1019b725ae77Skettenis 
1020b725ae77Skettenis   for (p = deleted_threads.head; p; p = p->next)
1021b725ae77Skettenis     {
1022b725ae77Skettenis       if (p->tid == tid)
1023b725ae77Skettenis 	{
1024b725ae77Skettenis 	  return p->pid;
1025b725ae77Skettenis 	}
1026b725ae77Skettenis     }
1027b725ae77Skettenis 
1028b725ae77Skettenis   return 0;
1029b725ae77Skettenis }
1030b725ae77Skettenis 
1031b725ae77Skettenis /* Note that this thread's current event has been handled.
1032b725ae77Skettenis  */
1033b725ae77Skettenis static void
set_handled(int pid,lwpid_t tid)1034b725ae77Skettenis set_handled (int pid, lwpid_t tid)
1035b725ae77Skettenis {
1036b725ae77Skettenis   thread_info *p;
1037b725ae77Skettenis 
1038b725ae77Skettenis   p = find_thread_info (tid);
1039b725ae77Skettenis   if (NULL == p)
1040b725ae77Skettenis     p = add_tthread (pid, tid);
1041b725ae77Skettenis 
1042b725ae77Skettenis   p->handled = 1;
1043b725ae77Skettenis }
1044b725ae77Skettenis 
1045b725ae77Skettenis /* Was this thread's current event handled?
1046b725ae77Skettenis  */
1047b725ae77Skettenis static int
was_handled(lwpid_t tid)1048b725ae77Skettenis was_handled (lwpid_t tid)
1049b725ae77Skettenis {
1050b725ae77Skettenis   thread_info *p;
1051b725ae77Skettenis 
1052b725ae77Skettenis   p = find_thread_info (tid);
1053b725ae77Skettenis   if (NULL != p)
1054b725ae77Skettenis     return p->handled;
1055b725ae77Skettenis 
1056b725ae77Skettenis   return 0;			/* New threads have not been handled */
1057b725ae77Skettenis }
1058b725ae77Skettenis 
1059b725ae77Skettenis /* Set this thread to unhandled.
1060b725ae77Skettenis  */
1061b725ae77Skettenis static void
clear_handled(lwpid_t tid)1062b725ae77Skettenis clear_handled (lwpid_t tid)
1063b725ae77Skettenis {
1064b725ae77Skettenis   thread_info *p;
1065b725ae77Skettenis 
1066b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
1067b725ae77Skettenis   if (debug_on)
1068b725ae77Skettenis     printf ("clear_handled %d\n", (int) tid);
1069b725ae77Skettenis #endif
1070b725ae77Skettenis 
1071b725ae77Skettenis   p = find_thread_info (tid);
1072b725ae77Skettenis   if (p == NULL)
1073b725ae77Skettenis     error ("Internal error: No thread state to clear?");
1074b725ae77Skettenis 
1075b725ae77Skettenis   p->handled = 0;
1076b725ae77Skettenis }
1077b725ae77Skettenis 
1078b725ae77Skettenis /* Set all threads to unhandled.
1079b725ae77Skettenis  */
1080b725ae77Skettenis static void
clear_all_handled(void)1081b725ae77Skettenis clear_all_handled (void)
1082b725ae77Skettenis {
1083b725ae77Skettenis   thread_info *p;
1084b725ae77Skettenis 
1085b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
1086b725ae77Skettenis   if (debug_on)
1087b725ae77Skettenis     printf ("clear_all_handled\n");
1088b725ae77Skettenis #endif
1089b725ae77Skettenis 
1090b725ae77Skettenis   for (p = thread_head.head; p; p = p->next)
1091b725ae77Skettenis     {
1092b725ae77Skettenis       p->handled = 0;
1093b725ae77Skettenis     }
1094b725ae77Skettenis 
1095b725ae77Skettenis   for (p = deleted_threads.head; p; p = p->next)
1096b725ae77Skettenis     {
1097b725ae77Skettenis       p->handled = 0;
1098b725ae77Skettenis     }
1099b725ae77Skettenis }
1100b725ae77Skettenis 
1101b725ae77Skettenis /* Set this thread to default stepping mode.
1102b725ae77Skettenis  */
1103b725ae77Skettenis static void
clear_stepping_mode(lwpid_t tid)1104b725ae77Skettenis clear_stepping_mode (lwpid_t tid)
1105b725ae77Skettenis {
1106b725ae77Skettenis   thread_info *p;
1107b725ae77Skettenis 
1108b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
1109b725ae77Skettenis   if (debug_on)
1110b725ae77Skettenis     printf ("clear_stepping_mode %d\n", (int) tid);
1111b725ae77Skettenis #endif
1112b725ae77Skettenis 
1113b725ae77Skettenis   p = find_thread_info (tid);
1114b725ae77Skettenis   if (p == NULL)
1115b725ae77Skettenis     error ("Internal error: No thread state to clear?");
1116b725ae77Skettenis 
1117b725ae77Skettenis   p->stepping_mode = DO_DEFAULT;
1118b725ae77Skettenis }
1119b725ae77Skettenis 
1120b725ae77Skettenis /* Set all threads to do default continue on resume.
1121b725ae77Skettenis  */
1122b725ae77Skettenis static void
clear_all_stepping_mode(void)1123b725ae77Skettenis clear_all_stepping_mode (void)
1124b725ae77Skettenis {
1125b725ae77Skettenis   thread_info *p;
1126b725ae77Skettenis 
1127b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
1128b725ae77Skettenis   if (debug_on)
1129b725ae77Skettenis     printf ("clear_all_stepping_mode\n");
1130b725ae77Skettenis #endif
1131b725ae77Skettenis 
1132b725ae77Skettenis   for (p = thread_head.head; p; p = p->next)
1133b725ae77Skettenis     {
1134b725ae77Skettenis       p->stepping_mode = DO_DEFAULT;
1135b725ae77Skettenis     }
1136b725ae77Skettenis 
1137b725ae77Skettenis   for (p = deleted_threads.head; p; p = p->next)
1138b725ae77Skettenis     {
1139b725ae77Skettenis       p->stepping_mode = DO_DEFAULT;
1140b725ae77Skettenis     }
1141b725ae77Skettenis }
1142b725ae77Skettenis 
1143b725ae77Skettenis /* Set all threads to unseen on this pass.
1144b725ae77Skettenis  */
1145b725ae77Skettenis static void
set_all_unseen(void)1146b725ae77Skettenis set_all_unseen (void)
1147b725ae77Skettenis {
1148b725ae77Skettenis   thread_info *p;
1149b725ae77Skettenis 
1150b725ae77Skettenis   for (p = thread_head.head; p; p = p->next)
1151b725ae77Skettenis     {
1152b725ae77Skettenis       p->seen = 0;
1153b725ae77Skettenis     }
1154b725ae77Skettenis }
1155b725ae77Skettenis 
1156b725ae77Skettenis #if (defined( THREAD_DEBUG ) || defined( PARANOIA ))
1157b725ae77Skettenis /* debugging routine.
1158b725ae77Skettenis  */
1159b725ae77Skettenis static void
print_tthread(thread_info * p)1160b725ae77Skettenis print_tthread (thread_info *p)
1161b725ae77Skettenis {
1162b725ae77Skettenis   printf (" Thread pid %d, tid %d", p->pid, p->tid);
1163b725ae77Skettenis   if (p->have_state)
1164b725ae77Skettenis     printf (", event is %s",
1165b725ae77Skettenis 	 get_printable_name_of_ttrace_event (p->last_stop_state.tts_event));
1166b725ae77Skettenis 
1167b725ae77Skettenis   if (p->am_pseudo)
1168b725ae77Skettenis     printf (", pseudo thread");
1169b725ae77Skettenis 
1170b725ae77Skettenis   if (p->have_signal)
1171b725ae77Skettenis     printf (", have signal 0x%x", p->signal_value);
1172b725ae77Skettenis 
1173b725ae77Skettenis   if (p->have_start)
1174b725ae77Skettenis     printf (", have start at 0x%x", p->start);
1175b725ae77Skettenis 
1176b725ae77Skettenis   printf (", step is %s", get_printable_name_of_stepping_mode (p->stepping_mode));
1177b725ae77Skettenis 
1178b725ae77Skettenis   if (p->handled)
1179b725ae77Skettenis     printf (", handled");
1180b725ae77Skettenis   else
1181b725ae77Skettenis     printf (", not handled");
1182b725ae77Skettenis 
1183b725ae77Skettenis   if (p->seen)
1184b725ae77Skettenis     printf (", seen");
1185b725ae77Skettenis   else
1186b725ae77Skettenis     printf (", not seen");
1187b725ae77Skettenis 
1188b725ae77Skettenis   printf ("\n");
1189b725ae77Skettenis }
1190b725ae77Skettenis 
1191b725ae77Skettenis static void
print_tthreads(void)1192b725ae77Skettenis print_tthreads (void)
1193b725ae77Skettenis {
1194b725ae77Skettenis   thread_info *p;
1195b725ae77Skettenis 
1196b725ae77Skettenis   if (thread_head.count == 0)
1197b725ae77Skettenis     printf ("Thread list is empty\n");
1198b725ae77Skettenis   else
1199b725ae77Skettenis     {
1200b725ae77Skettenis       printf ("Thread list has ");
1201b725ae77Skettenis       if (thread_head.count == 1)
1202b725ae77Skettenis 	printf ("1 entry:\n");
1203b725ae77Skettenis       else
1204b725ae77Skettenis 	printf ("%d entries:\n", thread_head.count);
1205b725ae77Skettenis       for (p = thread_head.head; p; p = p->next)
1206b725ae77Skettenis 	{
1207b725ae77Skettenis 	  print_tthread (p);
1208b725ae77Skettenis 	}
1209b725ae77Skettenis     }
1210b725ae77Skettenis 
1211b725ae77Skettenis   if (deleted_threads.count == 0)
1212b725ae77Skettenis     printf ("Deleted thread list is empty\n");
1213b725ae77Skettenis   else
1214b725ae77Skettenis     {
1215b725ae77Skettenis       printf ("Deleted thread list has ");
1216b725ae77Skettenis       if (deleted_threads.count == 1)
1217b725ae77Skettenis 	printf ("1 entry:\n");
1218b725ae77Skettenis       else
1219b725ae77Skettenis 	printf ("%d entries:\n", deleted_threads.count);
1220b725ae77Skettenis 
1221b725ae77Skettenis       for (p = deleted_threads.head; p; p = p->next)
1222b725ae77Skettenis 	{
1223b725ae77Skettenis 	  print_tthread (p);
1224b725ae77Skettenis 	}
1225b725ae77Skettenis     }
1226b725ae77Skettenis }
1227b725ae77Skettenis #endif
1228b725ae77Skettenis 
1229b725ae77Skettenis /* Update the thread list based on the "seen" bits.
1230b725ae77Skettenis  */
1231b725ae77Skettenis static void
update_thread_list(void)1232b725ae77Skettenis update_thread_list (void)
1233b725ae77Skettenis {
1234b725ae77Skettenis   thread_info *p;
1235b725ae77Skettenis   thread_info *chase;
1236b725ae77Skettenis 
1237b725ae77Skettenis   chase = NULL;
1238b725ae77Skettenis   for (p = thread_head.head; p; p = p->next)
1239b725ae77Skettenis     {
1240b725ae77Skettenis       /* Is this an "unseen" thread which really happens to be a process?
1241b725ae77Skettenis          If so, is it inferior_ptid and is a vfork in flight?  If yes to
1242b725ae77Skettenis          all, then DON'T REMOVE IT!  We're in the midst of moving a vfork
1243b725ae77Skettenis          operation, which is a multiple step thing, to the point where we
1244b725ae77Skettenis          can touch the parent again.  We've most likely stopped to examine
1245b725ae77Skettenis          the child at a late stage in the vfork, and if we're not following
1246b725ae77Skettenis          the child, we'd best not treat the parent as a dead "thread"...
1247b725ae77Skettenis        */
1248b725ae77Skettenis       if ((!p->seen) && p->am_pseudo && vfork_in_flight
1249b725ae77Skettenis 	  && (p->pid != vforking_child_pid))
1250b725ae77Skettenis 	p->seen = 1;
1251b725ae77Skettenis 
1252b725ae77Skettenis       if (!p->seen)
1253b725ae77Skettenis 	{
1254b725ae77Skettenis 	  /* Remove this one
1255b725ae77Skettenis 	   */
1256b725ae77Skettenis 
1257b725ae77Skettenis #ifdef THREAD_DEBUG
1258b725ae77Skettenis 	  if (debug_on)
1259b725ae77Skettenis 	    printf ("Delete unseen thread: %d \n", p->tid);
1260b725ae77Skettenis #endif
1261b725ae77Skettenis 	  del_tthread (p->tid);
1262b725ae77Skettenis 	}
1263b725ae77Skettenis     }
1264b725ae77Skettenis }
1265b725ae77Skettenis 
1266b725ae77Skettenis 
1267b725ae77Skettenis 
1268b725ae77Skettenis /************************************************
1269b725ae77Skettenis  *            O/S call wrappers                 *
1270b725ae77Skettenis  ************************************************
1271b725ae77Skettenis  */
1272b725ae77Skettenis 
1273b725ae77Skettenis /* This function simply calls ttrace with the given arguments.
1274b725ae77Skettenis  * It exists so that all calls to ttrace are isolated.  All
1275b725ae77Skettenis  * parameters should be as specified by "man 2 ttrace".
1276b725ae77Skettenis  *
1277b725ae77Skettenis  * No other "raw" calls to ttrace should exist in this module.
1278b725ae77Skettenis  */
1279b725ae77Skettenis static int
call_real_ttrace(ttreq_t request,pid_t pid,lwpid_t tid,TTRACE_ARG_TYPE addr,TTRACE_ARG_TYPE data,TTRACE_ARG_TYPE addr2)1280b725ae77Skettenis call_real_ttrace (ttreq_t request, pid_t pid, lwpid_t tid, TTRACE_ARG_TYPE addr,
1281b725ae77Skettenis 		  TTRACE_ARG_TYPE data, TTRACE_ARG_TYPE addr2)
1282b725ae77Skettenis {
1283b725ae77Skettenis   int tt_status;
1284b725ae77Skettenis 
1285b725ae77Skettenis   errno = 0;
1286b725ae77Skettenis   tt_status = ttrace (request, pid, tid, addr, data, addr2);
1287b725ae77Skettenis 
1288b725ae77Skettenis #ifdef THREAD_DEBUG
1289b725ae77Skettenis   if (errno)
1290b725ae77Skettenis     {
1291b725ae77Skettenis       /* Don't bother for a known benign error: if you ask for the
1292b725ae77Skettenis        * first thread state, but there is only one thread and it's
1293b725ae77Skettenis        * not stopped, ttrace complains.
1294b725ae77Skettenis        *
1295b725ae77Skettenis        * We have this inside the #ifdef because our caller will do
1296b725ae77Skettenis        * this check for real.
1297b725ae77Skettenis        */
1298b725ae77Skettenis       if (request != TT_PROC_GET_FIRST_LWP_STATE
1299b725ae77Skettenis 	  || errno != EPROTO)
1300b725ae77Skettenis 	{
1301b725ae77Skettenis 	  if (debug_on)
1302b725ae77Skettenis 	    printf ("TT fail for %s, with pid %d, tid %d, status %d \n",
1303b725ae77Skettenis 		    get_printable_name_of_ttrace_request (request),
1304b725ae77Skettenis 		    pid, tid, tt_status);
1305b725ae77Skettenis 	}
1306b725ae77Skettenis     }
1307b725ae77Skettenis #endif
1308b725ae77Skettenis 
1309b725ae77Skettenis #if 0
1310b725ae77Skettenis   /* ??rehrauer: It would probably be most robust to catch and report
1311b725ae77Skettenis    * failed requests here.  However, some clients of this interface
1312b725ae77Skettenis    * seem to expect to catch & deal with them, so we'd best not.
1313b725ae77Skettenis    */
1314b725ae77Skettenis   if (errno)
1315b725ae77Skettenis     {
1316b725ae77Skettenis       strcpy (reason_for_failure, "ttrace (");
1317b725ae77Skettenis       strcat (reason_for_failure, get_printable_name_of_ttrace_request (request));
1318b725ae77Skettenis       strcat (reason_for_failure, ")");
1319b725ae77Skettenis       printf ("ttrace error, errno = %d\n", errno);
1320b725ae77Skettenis       perror_with_name (reason_for_failure);
1321b725ae77Skettenis     }
1322b725ae77Skettenis #endif
1323b725ae77Skettenis 
1324b725ae77Skettenis   return tt_status;
1325b725ae77Skettenis }
1326b725ae77Skettenis 
1327b725ae77Skettenis 
1328b725ae77Skettenis /* This function simply calls ttrace_wait with the given arguments.
1329b725ae77Skettenis  * It exists so that all calls to ttrace_wait are isolated.
1330b725ae77Skettenis  *
1331b725ae77Skettenis  * No "raw" calls to ttrace_wait should exist elsewhere.
1332b725ae77Skettenis  */
1333b725ae77Skettenis static int
call_real_ttrace_wait(int pid,lwpid_t tid,ttwopt_t option,ttstate_t * tsp,size_t tsp_size)1334b725ae77Skettenis call_real_ttrace_wait (int pid, lwpid_t tid, ttwopt_t option, ttstate_t *tsp,
1335b725ae77Skettenis 		       size_t tsp_size)
1336b725ae77Skettenis {
1337b725ae77Skettenis   int ttw_status;
1338b725ae77Skettenis   thread_info *tinfo = NULL;
1339b725ae77Skettenis 
1340b725ae77Skettenis   errno = 0;
1341b725ae77Skettenis   ttw_status = ttrace_wait (pid, tid, option, tsp, tsp_size);
1342b725ae77Skettenis 
1343b725ae77Skettenis   if (errno)
1344b725ae77Skettenis     {
1345b725ae77Skettenis #ifdef THREAD_DEBUG
1346b725ae77Skettenis       if (debug_on)
1347b725ae77Skettenis 	printf ("TW fail with pid %d, tid %d \n", pid, tid);
1348b725ae77Skettenis #endif
1349b725ae77Skettenis 
1350b725ae77Skettenis       perror_with_name ("ttrace wait");
1351b725ae77Skettenis     }
1352b725ae77Skettenis 
1353b725ae77Skettenis   return ttw_status;
1354b725ae77Skettenis }
1355b725ae77Skettenis 
1356b725ae77Skettenis 
1357b725ae77Skettenis /* A process may have one or more kernel threads, of which all or
1358b725ae77Skettenis    none may be stopped.  This function returns the ID of the first
1359b725ae77Skettenis    kernel thread in a stopped state, or 0 if none are stopped.
1360b725ae77Skettenis 
1361b725ae77Skettenis    This function can be used with get_process_next_stopped_thread_id
1362b725ae77Skettenis    to iterate over the IDs of all stopped threads of this process.
1363b725ae77Skettenis  */
1364b725ae77Skettenis static lwpid_t
get_process_first_stopped_thread_id(int pid,ttstate_t * thread_state)1365b725ae77Skettenis get_process_first_stopped_thread_id (int pid, ttstate_t *thread_state)
1366b725ae77Skettenis {
1367b725ae77Skettenis   int tt_status;
1368b725ae77Skettenis 
1369b725ae77Skettenis   tt_status = call_real_ttrace (TT_PROC_GET_FIRST_LWP_STATE,
1370b725ae77Skettenis 				(pid_t) pid,
1371b725ae77Skettenis 				(lwpid_t) TT_NIL,
1372b725ae77Skettenis 				(TTRACE_ARG_TYPE) thread_state,
1373b725ae77Skettenis 				(TTRACE_ARG_TYPE) sizeof (*thread_state),
1374b725ae77Skettenis 				TT_NIL);
1375b725ae77Skettenis 
1376b725ae77Skettenis   if (errno)
1377b725ae77Skettenis     {
1378b725ae77Skettenis       if (errno == EPROTO)
1379b725ae77Skettenis 	{
1380b725ae77Skettenis 	  /* This is an error we can handle: there isn't any stopped
1381b725ae77Skettenis 	   * thread.  This happens when we're re-starting the application
1382b725ae77Skettenis 	   * and it has only one thread.  GET_NEXT handles the case of
1383b725ae77Skettenis 	   * no more stopped threads well; GET_FIRST doesn't.  (A ttrace
1384b725ae77Skettenis 	   * "feature".)
1385b725ae77Skettenis 	   */
1386b725ae77Skettenis 	  tt_status = 1;
1387b725ae77Skettenis 	  errno = 0;
1388b725ae77Skettenis 	  return 0;
1389b725ae77Skettenis 	}
1390b725ae77Skettenis       else
1391b725ae77Skettenis 	perror_with_name ("ttrace");
1392b725ae77Skettenis     }
1393b725ae77Skettenis 
1394b725ae77Skettenis   if (tt_status < 0)
1395b725ae77Skettenis     /* Failed somehow.
1396b725ae77Skettenis      */
1397b725ae77Skettenis     return 0;
1398b725ae77Skettenis 
1399b725ae77Skettenis   return thread_state->tts_lwpid;
1400b725ae77Skettenis }
1401b725ae77Skettenis 
1402b725ae77Skettenis 
1403b725ae77Skettenis /* This function returns the ID of the "next" kernel thread in a
1404b725ae77Skettenis    stopped state, or 0 if there are none.  "Next" refers to the
1405b725ae77Skettenis    thread following that of the last successful call to this
1406b725ae77Skettenis    function or to get_process_first_stopped_thread_id, using
1407b725ae77Skettenis    the value of thread_state returned by that call.
1408b725ae77Skettenis 
1409b725ae77Skettenis    This function can be used with get_process_first_stopped_thread_id
1410b725ae77Skettenis    to iterate over the IDs of all stopped threads of this process.
1411b725ae77Skettenis  */
1412b725ae77Skettenis static lwpid_t
get_process_next_stopped_thread_id(int pid,ttstate_t * thread_state)1413b725ae77Skettenis get_process_next_stopped_thread_id (int pid, ttstate_t *thread_state)
1414b725ae77Skettenis {
1415b725ae77Skettenis   int tt_status;
1416b725ae77Skettenis 
1417b725ae77Skettenis   tt_status = call_real_ttrace (
1418b725ae77Skettenis 				 TT_PROC_GET_NEXT_LWP_STATE,
1419b725ae77Skettenis 				 (pid_t) pid,
1420b725ae77Skettenis 				 (lwpid_t) TT_NIL,
1421b725ae77Skettenis 				 (TTRACE_ARG_TYPE) thread_state,
1422b725ae77Skettenis 				 (TTRACE_ARG_TYPE) sizeof (*thread_state),
1423b725ae77Skettenis 				 TT_NIL);
1424b725ae77Skettenis   if (errno)
1425b725ae77Skettenis     perror_with_name ("ttrace");
1426b725ae77Skettenis 
1427b725ae77Skettenis   if (tt_status < 0)
1428b725ae77Skettenis     /* Failed
1429b725ae77Skettenis      */
1430b725ae77Skettenis     return 0;
1431b725ae77Skettenis 
1432b725ae77Skettenis   else if (tt_status == 0)
1433b725ae77Skettenis     {
1434b725ae77Skettenis       /* End of list, no next state.  Don't return the
1435b725ae77Skettenis        * tts_lwpid, as it's a meaningless "240".
1436b725ae77Skettenis        *
1437b725ae77Skettenis        * This is an HPUX "feature".
1438b725ae77Skettenis        */
1439b725ae77Skettenis       return 0;
1440b725ae77Skettenis     }
1441b725ae77Skettenis 
1442b725ae77Skettenis   return thread_state->tts_lwpid;
1443b725ae77Skettenis }
1444b725ae77Skettenis 
1445b725ae77Skettenis /* ??rehrauer: Eventually this function perhaps should be calling
1446b725ae77Skettenis    pid_to_thread_id.  However, that function currently does nothing
1447b725ae77Skettenis    for HP-UX.  Even then, I'm not clear whether that function
1448b725ae77Skettenis    will return a "kernel" thread ID, or a "user" thread ID.  If
1449b725ae77Skettenis    the former, we can just call it here.  If the latter, we must
1450b725ae77Skettenis    map from the "user" tid to a "kernel" tid.
1451b725ae77Skettenis 
1452b725ae77Skettenis    NOTE: currently not called.
1453b725ae77Skettenis  */
1454b725ae77Skettenis static lwpid_t
get_active_tid_of_pid(int pid)1455b725ae77Skettenis get_active_tid_of_pid (int pid)
1456b725ae77Skettenis {
1457b725ae77Skettenis   ttstate_t thread_state;
1458b725ae77Skettenis 
1459b725ae77Skettenis   return get_process_first_stopped_thread_id (pid, &thread_state);
1460b725ae77Skettenis }
1461b725ae77Skettenis 
1462b725ae77Skettenis /* This function returns 1 if tt_request is a ttrace request that
1463b725ae77Skettenis  * operates upon all threads of a (i.e., the entire) process.
1464b725ae77Skettenis  */
1465b725ae77Skettenis int
is_process_ttrace_request(ttreq_t tt_request)1466b725ae77Skettenis is_process_ttrace_request (ttreq_t tt_request)
1467b725ae77Skettenis {
1468b725ae77Skettenis   return IS_TTRACE_PROCREQ (tt_request);
1469b725ae77Skettenis }
1470b725ae77Skettenis 
1471b725ae77Skettenis 
1472b725ae77Skettenis /* This function translates a thread ttrace request into
1473b725ae77Skettenis  * the equivalent process request for a one-thread process.
1474b725ae77Skettenis  */
1475b725ae77Skettenis static ttreq_t
make_process_version(ttreq_t request)1476b725ae77Skettenis make_process_version (ttreq_t request)
1477b725ae77Skettenis {
1478b725ae77Skettenis   if (!IS_TTRACE_REQ (request))
1479b725ae77Skettenis     {
1480b725ae77Skettenis       error ("Internal error, bad ttrace request made\n");
1481b725ae77Skettenis       return -1;
1482b725ae77Skettenis     }
1483b725ae77Skettenis 
1484b725ae77Skettenis   switch (request)
1485b725ae77Skettenis     {
1486b725ae77Skettenis     case TT_LWP_STOP:
1487b725ae77Skettenis       return TT_PROC_STOP;
1488b725ae77Skettenis 
1489b725ae77Skettenis     case TT_LWP_CONTINUE:
1490b725ae77Skettenis       return TT_PROC_CONTINUE;
1491b725ae77Skettenis 
1492b725ae77Skettenis     case TT_LWP_GET_EVENT_MASK:
1493b725ae77Skettenis       return TT_PROC_GET_EVENT_MASK;
1494b725ae77Skettenis 
1495b725ae77Skettenis     case TT_LWP_SET_EVENT_MASK:
1496b725ae77Skettenis       return TT_PROC_SET_EVENT_MASK;
1497b725ae77Skettenis 
1498b725ae77Skettenis     case TT_LWP_SINGLE:
1499b725ae77Skettenis     case TT_LWP_RUREGS:
1500b725ae77Skettenis     case TT_LWP_WUREGS:
1501b725ae77Skettenis     case TT_LWP_GET_STATE:
1502b725ae77Skettenis       return -1;		/* No equivalent */
1503b725ae77Skettenis 
1504b725ae77Skettenis     default:
1505b725ae77Skettenis       return request;
1506b725ae77Skettenis     }
1507b725ae77Skettenis }
1508b725ae77Skettenis 
1509b725ae77Skettenis 
1510b725ae77Skettenis /* This function translates the "pid" used by the rest of
1511b725ae77Skettenis  * gdb to a real pid and a tid.  It then calls "call_real_ttrace"
1512b725ae77Skettenis  * with the given arguments.
1513b725ae77Skettenis  *
1514b725ae77Skettenis  * In general, other parts of this module should call this
1515b725ae77Skettenis  * function when they are dealing with external users, who only
1516b725ae77Skettenis  * have tids to pass (but they call it "pid" for historical
1517b725ae77Skettenis  * reasons).
1518b725ae77Skettenis  */
1519b725ae77Skettenis static int
call_ttrace(ttreq_t request,int gdb_tid,TTRACE_ARG_TYPE addr,TTRACE_ARG_TYPE data,TTRACE_ARG_TYPE addr2)1520b725ae77Skettenis call_ttrace (ttreq_t request, int gdb_tid, TTRACE_ARG_TYPE addr,
1521b725ae77Skettenis 	     TTRACE_ARG_TYPE data, TTRACE_ARG_TYPE addr2)
1522b725ae77Skettenis {
1523b725ae77Skettenis   lwpid_t real_tid;
1524b725ae77Skettenis   int real_pid;
1525b725ae77Skettenis   ttreq_t new_request;
1526b725ae77Skettenis   int tt_status;
1527b725ae77Skettenis   char reason_for_failure[100];	/* Arbitrary size, should be big enough. */
1528b725ae77Skettenis 
1529b725ae77Skettenis #ifdef THREAD_DEBUG
1530b725ae77Skettenis   int is_interesting = 0;
1531b725ae77Skettenis 
1532b725ae77Skettenis   if (TT_LWP_RUREGS == request)
1533b725ae77Skettenis     {
1534b725ae77Skettenis       is_interesting = 1;	/* Adjust code here as desired */
1535b725ae77Skettenis     }
1536b725ae77Skettenis 
1537b725ae77Skettenis   if (is_interesting && 0 && debug_on)
1538b725ae77Skettenis     {
1539b725ae77Skettenis       if (!is_process_ttrace_request (request))
1540b725ae77Skettenis 	{
1541b725ae77Skettenis 	  printf ("TT: Thread request, tid is %d", gdb_tid);
1542b725ae77Skettenis 	  printf ("== SINGLE at %x", addr);
1543b725ae77Skettenis 	}
1544b725ae77Skettenis       else
1545b725ae77Skettenis 	{
1546b725ae77Skettenis 	  printf ("TT: Process request, tid is %d\n", gdb_tid);
1547b725ae77Skettenis 	  printf ("==! SINGLE at %x", addr);
1548b725ae77Skettenis 	}
1549b725ae77Skettenis     }
1550b725ae77Skettenis #endif
1551b725ae77Skettenis 
1552b725ae77Skettenis   /* The initial SETTRC and SET_EVENT_MASK calls (and all others
1553b725ae77Skettenis    * which happen before any threads get set up) should go
1554b725ae77Skettenis    * directly to "call_real_ttrace", so they don't happen here.
1555b725ae77Skettenis    *
1556b725ae77Skettenis    * But hardware watchpoints do a SET_EVENT_MASK, so we can't
1557b725ae77Skettenis    * rule them out....
1558b725ae77Skettenis    */
1559b725ae77Skettenis #ifdef THREAD_DEBUG
1560b725ae77Skettenis   if (request == TT_PROC_SETTRC && debug_on)
1561b725ae77Skettenis     printf ("Unexpected call for TT_PROC_SETTRC\n");
1562b725ae77Skettenis #endif
1563b725ae77Skettenis 
1564b725ae77Skettenis   /* Sometimes we get called with a bogus tid (e.g., if a
1565b725ae77Skettenis    * thread has terminated, we return 0; inftarg later asks
1566b725ae77Skettenis    * whether the thread has exited/forked/vforked).
1567b725ae77Skettenis    */
1568b725ae77Skettenis   if (gdb_tid == 0)
1569b725ae77Skettenis     {
1570b725ae77Skettenis       errno = ESRCH;		/* ttrace's response would probably be "No such process". */
1571b725ae77Skettenis       return -1;
1572b725ae77Skettenis     }
1573b725ae77Skettenis 
1574b725ae77Skettenis   /* All other cases should be able to expect that there are
1575b725ae77Skettenis    * thread records.
1576b725ae77Skettenis    */
1577b725ae77Skettenis   if (!any_thread_records ())
1578b725ae77Skettenis     {
1579b725ae77Skettenis #ifdef THREAD_DEBUG
1580b725ae77Skettenis       if (debug_on)
1581b725ae77Skettenis 	warning ("No thread records for ttrace call");
1582b725ae77Skettenis #endif
1583b725ae77Skettenis       errno = ESRCH;		/* ttrace's response would be "No such process". */
1584b725ae77Skettenis       return -1;
1585b725ae77Skettenis     }
1586b725ae77Skettenis 
1587b725ae77Skettenis   /* OK, now the task is to translate the incoming tid into
1588b725ae77Skettenis    * a pid/tid pair.
1589b725ae77Skettenis    */
1590b725ae77Skettenis   real_tid = map_from_gdb_tid (gdb_tid);
1591b725ae77Skettenis   real_pid = get_pid_for (real_tid);
1592b725ae77Skettenis 
1593b725ae77Skettenis   /* Now check the result.  "Real_pid" is NULL if our list
1594b725ae77Skettenis    * didn't find it.  We have some tricks we can play to fix
1595b725ae77Skettenis    * this, however.
1596b725ae77Skettenis    */
1597b725ae77Skettenis   if (0 == real_pid)
1598b725ae77Skettenis     {
1599b725ae77Skettenis       ttstate_t thread_state;
1600b725ae77Skettenis 
1601b725ae77Skettenis #ifdef THREAD_DEBUG
1602b725ae77Skettenis       if (debug_on)
1603b725ae77Skettenis 	printf ("No saved pid for tid %d\n", gdb_tid);
1604b725ae77Skettenis #endif
1605b725ae77Skettenis 
1606b725ae77Skettenis       if (is_process_ttrace_request (request))
1607b725ae77Skettenis 	{
1608b725ae77Skettenis 
1609b725ae77Skettenis 	  /* Ok, we couldn't get a tid.  Try to translate to
1610b725ae77Skettenis 	   * the equivalent process operation.  We expect this
1611b725ae77Skettenis 	   * NOT to happen, so this is a desparation-type
1612b725ae77Skettenis 	   * move.  It can happen if there is an internal
1613b725ae77Skettenis 	   * error and so no "wait()" call is ever done.
1614b725ae77Skettenis 	   */
1615b725ae77Skettenis 	  new_request = make_process_version (request);
1616b725ae77Skettenis 	  if (new_request == -1)
1617b725ae77Skettenis 	    {
1618b725ae77Skettenis 
1619b725ae77Skettenis #ifdef THREAD_DEBUG
1620b725ae77Skettenis 	      if (debug_on)
1621b725ae77Skettenis 		printf ("...and couldn't make process version of thread operation\n");
1622b725ae77Skettenis #endif
1623b725ae77Skettenis 
1624b725ae77Skettenis 	      /* Use hacky saved pid, which won't always be correct
1625b725ae77Skettenis 	       * in the multi-process future.  Use tid as thread,
1626b725ae77Skettenis 	       * probably dooming this to failure.  FIX!
1627b725ae77Skettenis 	       */
1628b725ae77Skettenis 	      if (! ptid_equal (saved_real_ptid, null_ptid))
1629b725ae77Skettenis 		{
1630b725ae77Skettenis #ifdef THREAD_DEBUG
1631b725ae77Skettenis 		  if (debug_on)
1632b725ae77Skettenis 		    printf ("...using saved pid %d\n",
1633b725ae77Skettenis 		            PIDGET (saved_real_ptid));
1634b725ae77Skettenis #endif
1635b725ae77Skettenis 
1636b725ae77Skettenis 		  real_pid = PIDGET (saved_real_ptid);
1637b725ae77Skettenis 		  real_tid = gdb_tid;
1638b725ae77Skettenis 		}
1639b725ae77Skettenis 
1640b725ae77Skettenis 	      else
1641b725ae77Skettenis 		error ("Unable to perform thread operation");
1642b725ae77Skettenis 	    }
1643b725ae77Skettenis 
1644b725ae77Skettenis 	  else
1645b725ae77Skettenis 	    {
1646b725ae77Skettenis 	      /* Sucessfully translated this to a process request,
1647b725ae77Skettenis 	       * which needs no thread value.
1648b725ae77Skettenis 	       */
1649b725ae77Skettenis 	      real_pid = gdb_tid;
1650b725ae77Skettenis 	      real_tid = 0;
1651b725ae77Skettenis 	      request = new_request;
1652b725ae77Skettenis 
1653b725ae77Skettenis #ifdef THREAD_DEBUG
1654b725ae77Skettenis 	      if (debug_on)
1655b725ae77Skettenis 		{
1656b725ae77Skettenis 		  printf ("Translated thread request to process request\n");
1657b725ae77Skettenis 		  if (ptid_equal (saved_real_ptid, null_ptid))
1658b725ae77Skettenis 		    printf ("...but there's no saved pid\n");
1659b725ae77Skettenis 
1660b725ae77Skettenis 		  else
1661b725ae77Skettenis 		    {
1662b725ae77Skettenis 		      if (gdb_tid != PIDGET (saved_real_ptid))
1663b725ae77Skettenis 			printf ("...but have the wrong pid (%d rather than %d)\n",
1664b725ae77Skettenis 				gdb_tid, PIDGET (saved_real_ptid));
1665b725ae77Skettenis 		    }
1666b725ae77Skettenis 		}
1667b725ae77Skettenis #endif
1668b725ae77Skettenis 	    }			/* Translated to a process request */
1669b725ae77Skettenis 	}			/* Is a process request */
1670b725ae77Skettenis 
1671b725ae77Skettenis       else
1672b725ae77Skettenis 	{
1673b725ae77Skettenis 	  /* We have to have a thread.  Ooops.
1674b725ae77Skettenis 	   */
1675b725ae77Skettenis 	  error ("Thread request with no threads (%s)",
1676b725ae77Skettenis 		 get_printable_name_of_ttrace_request (request));
1677b725ae77Skettenis 	}
1678b725ae77Skettenis     }
1679b725ae77Skettenis 
1680b725ae77Skettenis   /* Ttrace doesn't like to see tid values on process requests,
1681b725ae77Skettenis    * even if we have the right one.
1682b725ae77Skettenis    */
1683b725ae77Skettenis   if (is_process_ttrace_request (request))
1684b725ae77Skettenis     {
1685b725ae77Skettenis       real_tid = 0;
1686b725ae77Skettenis     }
1687b725ae77Skettenis 
1688b725ae77Skettenis #ifdef THREAD_DEBUG
1689b725ae77Skettenis   if (is_interesting && 0 && debug_on)
1690b725ae77Skettenis     {
1691b725ae77Skettenis       printf ("    now tid %d, pid %d\n", real_tid, real_pid);
1692b725ae77Skettenis       printf ("    request is %s\n", get_printable_name_of_ttrace_request (request));
1693b725ae77Skettenis     }
1694b725ae77Skettenis #endif
1695b725ae77Skettenis 
1696b725ae77Skettenis   /* Finally, the (almost) real call.
1697b725ae77Skettenis    */
1698b725ae77Skettenis   tt_status = call_real_ttrace (request, real_pid, real_tid, addr, data, addr2);
1699b725ae77Skettenis 
1700b725ae77Skettenis #ifdef THREAD_DEBUG
1701b725ae77Skettenis   if (is_interesting && debug_on)
1702b725ae77Skettenis     {
1703b725ae77Skettenis       if (!TT_OK (tt_status, errno)
1704b725ae77Skettenis 	  && !(tt_status == 0 & errno == 0))
1705b725ae77Skettenis 	printf (" got error (errno==%d, status==%d)\n", errno, tt_status);
1706b725ae77Skettenis     }
1707b725ae77Skettenis #endif
1708b725ae77Skettenis 
1709b725ae77Skettenis   return tt_status;
1710b725ae77Skettenis }
1711b725ae77Skettenis 
1712b725ae77Skettenis 
1713b725ae77Skettenis /* Stop all the threads of a process.
1714b725ae77Skettenis 
1715b725ae77Skettenis  * NOTE: use of TT_PROC_STOP can cause a thread with a real event
1716b725ae77Skettenis  *       to get a TTEVT_NONE event, discarding the old event.  Be
1717b725ae77Skettenis  *       very careful, and only call TT_PROC_STOP when you mean it!
1718b725ae77Skettenis  */
1719b725ae77Skettenis static void
stop_all_threads_of_process(pid_t real_pid)1720b725ae77Skettenis stop_all_threads_of_process (pid_t real_pid)
1721b725ae77Skettenis {
1722b725ae77Skettenis   int ttw_status;
1723b725ae77Skettenis 
1724b725ae77Skettenis   ttw_status = call_real_ttrace (TT_PROC_STOP,
1725b725ae77Skettenis 				 (pid_t) real_pid,
1726b725ae77Skettenis 				 (lwpid_t) TT_NIL,
1727b725ae77Skettenis 				 (TTRACE_ARG_TYPE) TT_NIL,
1728b725ae77Skettenis 				 (TTRACE_ARG_TYPE) TT_NIL,
1729b725ae77Skettenis 				 TT_NIL);
1730b725ae77Skettenis   if (errno)
1731b725ae77Skettenis     perror_with_name ("ttrace stop of other threads");
1732b725ae77Skettenis }
1733b725ae77Skettenis 
1734b725ae77Skettenis 
1735b725ae77Skettenis /* Under some circumstances, it's unsafe to attempt to stop, or even
1736b725ae77Skettenis    query the state of, a process' threads.
1737b725ae77Skettenis 
1738b725ae77Skettenis    In ttrace-based HP-UX, an example is a vforking child process.  The
1739b725ae77Skettenis    vforking parent and child are somewhat fragile, w/r/t what we can do
1740b725ae77Skettenis    what we can do to them with ttrace, until after the child exits or
1741b725ae77Skettenis    execs, or until the parent's vfork event is delivered.  Until that
1742b725ae77Skettenis    time, we must not try to stop the process' threads, or inquire how
1743b725ae77Skettenis    many there are, or even alter its data segments, or it typically dies
1744b725ae77Skettenis    with a SIGILL.  Sigh.
1745b725ae77Skettenis 
1746b725ae77Skettenis    This function returns 1 if this stopped process, and the event that
1747b725ae77Skettenis    we're told was responsible for its current stopped state, cannot safely
1748b725ae77Skettenis    have its threads examined.
1749b725ae77Skettenis  */
1750b725ae77Skettenis #define CHILD_VFORKED(evt,pid) \
1751b725ae77Skettenis   (((evt) == TTEVT_VFORK) && ((pid) != PIDGET (inferior_ptid)))
1752b725ae77Skettenis #define CHILD_URPED(evt,pid) \
1753b725ae77Skettenis   ((((evt) == TTEVT_EXEC) || ((evt) == TTEVT_EXIT)) && ((pid) != vforking_child_pid))
1754b725ae77Skettenis #define PARENT_VFORKED(evt,pid) \
1755b725ae77Skettenis   (((evt) == TTEVT_VFORK) && ((pid) == PIDGET (inferior_ptid)))
1756b725ae77Skettenis 
1757b725ae77Skettenis static int
can_touch_threads_of_process(int pid,ttevents_t stopping_event)1758b725ae77Skettenis can_touch_threads_of_process (int pid, ttevents_t stopping_event)
1759b725ae77Skettenis {
1760b725ae77Skettenis   if (CHILD_VFORKED (stopping_event, pid))
1761b725ae77Skettenis     {
1762b725ae77Skettenis       vforking_child_pid = pid;
1763b725ae77Skettenis       vfork_in_flight = 1;
1764b725ae77Skettenis     }
1765b725ae77Skettenis 
1766b725ae77Skettenis   else if (vfork_in_flight &&
1767b725ae77Skettenis 	   (PARENT_VFORKED (stopping_event, pid) ||
1768b725ae77Skettenis 	    CHILD_URPED (stopping_event, pid)))
1769b725ae77Skettenis     {
1770b725ae77Skettenis       vfork_in_flight = 0;
1771b725ae77Skettenis       vforking_child_pid = 0;
1772b725ae77Skettenis     }
1773b725ae77Skettenis 
1774b725ae77Skettenis   return !vfork_in_flight;
1775b725ae77Skettenis }
1776b725ae77Skettenis 
1777b725ae77Skettenis 
1778b725ae77Skettenis /* If we can find an as-yet-unhandled thread state of a
1779b725ae77Skettenis  * stopped thread of this process return 1 and set "tsp".
1780b725ae77Skettenis  * Return 0 if we can't.
1781b725ae77Skettenis  *
1782b725ae77Skettenis  * If this function is used when the threads of PIS haven't
1783b725ae77Skettenis  * been stopped, undefined behaviour is guaranteed!
1784b725ae77Skettenis  */
1785b725ae77Skettenis static int
select_stopped_thread_of_process(int pid,ttstate_t * tsp)1786b725ae77Skettenis select_stopped_thread_of_process (int pid, ttstate_t *tsp)
1787b725ae77Skettenis {
1788b725ae77Skettenis   lwpid_t candidate_tid, tid;
1789b725ae77Skettenis   ttstate_t candidate_tstate, tstate;
1790b725ae77Skettenis 
1791b725ae77Skettenis   /* If we're not allowed to touch the process now, then just
1792b725ae77Skettenis    * return the current value of *TSP.
1793b725ae77Skettenis    *
1794b725ae77Skettenis    * This supports "vfork".  It's ok, really, to double the
1795b725ae77Skettenis    * current event (the child EXEC, we hope!).
1796b725ae77Skettenis    */
1797b725ae77Skettenis   if (!can_touch_threads_of_process (pid, tsp->tts_event))
1798b725ae77Skettenis     return 1;
1799b725ae77Skettenis 
1800b725ae77Skettenis   /* Decide which of (possibly more than one) events to
1801b725ae77Skettenis    * return as the first one.  We scan them all so that
1802b725ae77Skettenis    * we always return the result of a fake-step first.
1803b725ae77Skettenis    */
1804b725ae77Skettenis   candidate_tid = 0;
1805b725ae77Skettenis   for (tid = get_process_first_stopped_thread_id (pid, &tstate);
1806b725ae77Skettenis        tid != 0;
1807b725ae77Skettenis        tid = get_process_next_stopped_thread_id (pid, &tstate))
1808b725ae77Skettenis     {
1809b725ae77Skettenis       /* TTEVT_NONE events are uninteresting to our clients.  They're
1810b725ae77Skettenis        * an artifact of our "stop the world" model--the thread is
1811b725ae77Skettenis        * stopped because we stopped it.
1812b725ae77Skettenis        */
1813b725ae77Skettenis       if (tstate.tts_event == TTEVT_NONE)
1814b725ae77Skettenis 	{
1815b725ae77Skettenis 	  set_handled (pid, tstate.tts_lwpid);
1816b725ae77Skettenis 	}
1817b725ae77Skettenis 
1818b725ae77Skettenis       /* Did we just single-step a single thread, without letting any
1819b725ae77Skettenis        * of the others run?  Is this an event for that thread?
1820b725ae77Skettenis        *
1821b725ae77Skettenis        * If so, we believe our client would prefer to see this event
1822b725ae77Skettenis        * over any others.  (Typically the client wants to just push
1823b725ae77Skettenis        * one thread a little farther forward, and then go around
1824b725ae77Skettenis        * checking for what all threads are doing.)
1825b725ae77Skettenis        */
1826b725ae77Skettenis       else if (doing_fake_step && (tstate.tts_lwpid == fake_step_tid))
1827b725ae77Skettenis 	{
1828b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
1829b725ae77Skettenis 	  /* It's possible here to see either a SIGTRAP (due to
1830b725ae77Skettenis 	   * successful completion of a step) or a SYSCALL_ENTRY
1831b725ae77Skettenis 	   * (due to a step completion with active hardware
1832b725ae77Skettenis 	   * watchpoints).
1833b725ae77Skettenis 	   */
1834b725ae77Skettenis 	  if (debug_on)
1835b725ae77Skettenis 	    printf ("Ending fake step with tid %d, state %s\n",
1836b725ae77Skettenis 		    tstate.tts_lwpid,
1837b725ae77Skettenis 		    get_printable_name_of_ttrace_event (tstate.tts_event));
1838b725ae77Skettenis #endif
1839b725ae77Skettenis 
1840b725ae77Skettenis 	  /* Remember this one, and throw away any previous
1841b725ae77Skettenis 	   * candidate.
1842b725ae77Skettenis 	   */
1843b725ae77Skettenis 	  candidate_tid = tstate.tts_lwpid;
1844b725ae77Skettenis 	  candidate_tstate = tstate;
1845b725ae77Skettenis 	}
1846b725ae77Skettenis 
1847b725ae77Skettenis #ifdef FORGET_DELETED_BPTS
1848b725ae77Skettenis 
1849b725ae77Skettenis       /* We can't just do this, as if we do, and then wind
1850b725ae77Skettenis        * up the loop with no unhandled events, we need to
1851b725ae77Skettenis        * handle that case--the appropriate reaction is to
1852b725ae77Skettenis        * just continue, but there's no easy way to do that.
1853b725ae77Skettenis        *
1854b725ae77Skettenis        * Better to put this in the ttrace_wait call--if, when
1855b725ae77Skettenis        * we fake a wait, we update our events based on the
1856b725ae77Skettenis        * breakpoint_here_pc call and find there are no more events,
1857b725ae77Skettenis        * then we better continue and so on.
1858b725ae77Skettenis        *
1859b725ae77Skettenis        * Or we could put it in the next/continue fake.
1860b725ae77Skettenis        * But it has to go in the buffering code, not in the
1861b725ae77Skettenis        * real go/wait code.
1862b725ae77Skettenis        */
1863b725ae77Skettenis       else if ((TTEVT_SIGNAL == tstate.tts_event)
1864b725ae77Skettenis 	       && (5 == tstate.tts_u.tts_signal.tts_signo)
1865b725ae77Skettenis 	       && (0 != get_raw_pc (tstate.tts_lwpid))
1866b725ae77Skettenis 	       && !breakpoint_here_p (get_raw_pc (tstate.tts_lwpid)))
1867b725ae77Skettenis 	{
1868b725ae77Skettenis 	  /*
1869b725ae77Skettenis 	   * If the user deleted a breakpoint while this
1870b725ae77Skettenis 	   * breakpoint-hit event was buffered, we can forget
1871b725ae77Skettenis 	   * it now.
1872b725ae77Skettenis 	   */
1873b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
1874b725ae77Skettenis 	  if (debug_on)
1875b725ae77Skettenis 	    printf ("Forgetting deleted bp hit for thread %d\n",
1876b725ae77Skettenis 		    tstate.tts_lwpid);
1877b725ae77Skettenis #endif
1878b725ae77Skettenis 
1879b725ae77Skettenis 	  set_handled (pid, tstate.tts_lwpid);
1880b725ae77Skettenis 	}
1881b725ae77Skettenis #endif
1882b725ae77Skettenis 
1883b725ae77Skettenis       /* Else, is this the first "unhandled" event?  If so,
1884b725ae77Skettenis        * we believe our client wants to see it (if we don't
1885b725ae77Skettenis        * see a fake-step later on in the scan).
1886b725ae77Skettenis        */
1887b725ae77Skettenis       else if (!was_handled (tstate.tts_lwpid) && candidate_tid == 0)
1888b725ae77Skettenis 	{
1889b725ae77Skettenis 	  candidate_tid = tstate.tts_lwpid;
1890b725ae77Skettenis 	  candidate_tstate = tstate;
1891b725ae77Skettenis 	}
1892b725ae77Skettenis 
1893b725ae77Skettenis       /* This is either an event that has already been "handled",
1894b725ae77Skettenis        * and thus we believe is uninteresting to our client, or we
1895b725ae77Skettenis        * already have a candidate event.  Ignore it...
1896b725ae77Skettenis        */
1897b725ae77Skettenis     }
1898b725ae77Skettenis 
1899b725ae77Skettenis   /* What do we report?
1900b725ae77Skettenis    */
1901b725ae77Skettenis   if (doing_fake_step)
1902b725ae77Skettenis     {
1903b725ae77Skettenis       if (candidate_tid == fake_step_tid)
1904b725ae77Skettenis 	{
1905b725ae77Skettenis 	  /* Fake step.
1906b725ae77Skettenis 	   */
1907b725ae77Skettenis 	  tstate = candidate_tstate;
1908b725ae77Skettenis 	}
1909b725ae77Skettenis       else
1910b725ae77Skettenis 	{
1911b725ae77Skettenis 	  warning ("Internal error: fake-step failed to complete.");
1912b725ae77Skettenis 	  return 0;
1913b725ae77Skettenis 	}
1914b725ae77Skettenis     }
1915b725ae77Skettenis   else if (candidate_tid != 0)
1916b725ae77Skettenis     {
1917b725ae77Skettenis       /* Found a candidate unhandled event.
1918b725ae77Skettenis        */
1919b725ae77Skettenis       tstate = candidate_tstate;
1920b725ae77Skettenis     }
1921b725ae77Skettenis   else if (tid != 0)
1922b725ae77Skettenis     {
1923b725ae77Skettenis       warning ("Internal error in call of ttrace_wait.");
1924b725ae77Skettenis       return 0;
1925b725ae77Skettenis     }
1926b725ae77Skettenis   else
1927b725ae77Skettenis     {
1928b725ae77Skettenis       warning ("Internal error: no unhandled thread event to select");
1929b725ae77Skettenis       return 0;
1930b725ae77Skettenis     }
1931b725ae77Skettenis 
1932b725ae77Skettenis   copy_ttstate_t (tsp, &tstate);
1933b725ae77Skettenis   return 1;
1934b725ae77Skettenis }				/* End of select_stopped_thread_of_process */
1935b725ae77Skettenis 
1936b725ae77Skettenis #ifdef PARANOIA
1937b725ae77Skettenis /* Check our internal thread data against the real thing.
1938b725ae77Skettenis  */
1939b725ae77Skettenis static void
check_thread_consistency(pid_t real_pid)1940b725ae77Skettenis check_thread_consistency (pid_t real_pid)
1941b725ae77Skettenis {
1942b725ae77Skettenis   int tid;			/* really lwpid_t */
1943b725ae77Skettenis   ttstate_t tstate;
1944b725ae77Skettenis   thread_info *p;
1945b725ae77Skettenis 
1946b725ae77Skettenis   /* Spin down the O/S list of threads, checking that they
1947b725ae77Skettenis    * match what we've got.
1948b725ae77Skettenis    */
1949b725ae77Skettenis   for (tid = get_process_first_stopped_thread_id (real_pid, &tstate);
1950b725ae77Skettenis        tid != 0;
1951b725ae77Skettenis        tid = get_process_next_stopped_thread_id (real_pid, &tstate))
1952b725ae77Skettenis     {
1953b725ae77Skettenis 
1954b725ae77Skettenis       p = find_thread_info (tid);
1955b725ae77Skettenis 
1956b725ae77Skettenis       if (NULL == p)
1957b725ae77Skettenis 	{
1958b725ae77Skettenis 	  warning ("No internal thread data for thread %d.", tid);
1959b725ae77Skettenis 	  continue;
1960b725ae77Skettenis 	}
1961b725ae77Skettenis 
1962b725ae77Skettenis       if (!p->seen)
1963b725ae77Skettenis 	{
1964b725ae77Skettenis 	  warning ("Inconsistent internal thread data for thread %d.", tid);
1965b725ae77Skettenis 	}
1966b725ae77Skettenis 
1967b725ae77Skettenis       if (p->terminated)
1968b725ae77Skettenis 	{
1969b725ae77Skettenis 	  warning ("Thread %d is not terminated, internal error.", tid);
1970b725ae77Skettenis 	  continue;
1971b725ae77Skettenis 	}
1972b725ae77Skettenis 
1973b725ae77Skettenis 
1974b725ae77Skettenis #define TT_COMPARE( fld ) \
1975b725ae77Skettenis             tstate.fld != p->last_stop_state.fld
1976b725ae77Skettenis 
1977b725ae77Skettenis       if (p->have_state)
1978b725ae77Skettenis 	{
1979b725ae77Skettenis 	  if (TT_COMPARE (tts_pid)
1980b725ae77Skettenis 	      || TT_COMPARE (tts_lwpid)
1981b725ae77Skettenis 	      || TT_COMPARE (tts_user_tid)
1982b725ae77Skettenis 	      || TT_COMPARE (tts_event)
1983b725ae77Skettenis 	      || TT_COMPARE (tts_flags)
1984b725ae77Skettenis 	      || TT_COMPARE (tts_scno)
1985b725ae77Skettenis 	      || TT_COMPARE (tts_scnargs))
1986b725ae77Skettenis 	    {
1987b725ae77Skettenis 	      warning ("Internal thread data for thread %d is wrong.", tid);
1988b725ae77Skettenis 	      continue;
1989b725ae77Skettenis 	    }
1990b725ae77Skettenis 	}
1991b725ae77Skettenis     }
1992b725ae77Skettenis }
1993b725ae77Skettenis #endif /* PARANOIA */
1994b725ae77Skettenis 
1995b725ae77Skettenis 
1996b725ae77Skettenis /* This function wraps calls to "call_real_ttrace_wait" so
1997b725ae77Skettenis  * that a actual wait is only done when all pending events
1998b725ae77Skettenis  * have been reported.
1999b725ae77Skettenis  *
2000b725ae77Skettenis  * Note that typically it is called with a pid of "0", i.e.
2001b725ae77Skettenis  * the "don't care" value.
2002b725ae77Skettenis  *
2003b725ae77Skettenis  * Return value is the status of the pseudo wait.
2004b725ae77Skettenis  */
2005b725ae77Skettenis static int
call_ttrace_wait(int pid,ttwopt_t option,ttstate_t * tsp,size_t tsp_size)2006b725ae77Skettenis call_ttrace_wait (int pid, ttwopt_t option, ttstate_t *tsp, size_t tsp_size)
2007b725ae77Skettenis {
2008b725ae77Skettenis   /* This holds the actual, for-real, true process ID.
2009b725ae77Skettenis    */
2010b725ae77Skettenis   static int real_pid;
2011b725ae77Skettenis 
2012b725ae77Skettenis   /* As an argument to ttrace_wait, zero pid
2013b725ae77Skettenis    * means "Any process", and zero tid means
2014b725ae77Skettenis    * "Any thread of the specified process".
2015b725ae77Skettenis    */
2016b725ae77Skettenis   int wait_pid = 0;
2017b725ae77Skettenis   lwpid_t wait_tid = 0;
2018b725ae77Skettenis   lwpid_t real_tid;
2019b725ae77Skettenis 
2020b725ae77Skettenis   int ttw_status = 0;		/* To be returned */
2021b725ae77Skettenis 
2022b725ae77Skettenis   thread_info *tinfo = NULL;
2023b725ae77Skettenis 
2024b725ae77Skettenis   if (pid != 0)
2025b725ae77Skettenis     {
2026b725ae77Skettenis       /* Unexpected case.
2027b725ae77Skettenis        */
2028b725ae77Skettenis #ifdef THREAD_DEBUG
2029b725ae77Skettenis       if (debug_on)
2030b725ae77Skettenis 	printf ("TW: Pid to wait on is %d\n", pid);
2031b725ae77Skettenis #endif
2032b725ae77Skettenis 
2033b725ae77Skettenis       if (!any_thread_records ())
2034b725ae77Skettenis 	error ("No thread records for ttrace call w. specific pid");
2035b725ae77Skettenis 
2036b725ae77Skettenis       /* OK, now the task is to translate the incoming tid into
2037b725ae77Skettenis        * a pid/tid pair.
2038b725ae77Skettenis        */
2039b725ae77Skettenis       real_tid = map_from_gdb_tid (pid);
2040b725ae77Skettenis       real_pid = get_pid_for (real_tid);
2041b725ae77Skettenis #ifdef THREAD_DEBUG
2042b725ae77Skettenis       if (debug_on)
2043b725ae77Skettenis 	printf ("==TW: real pid %d, real tid %d\n", real_pid, real_tid);
2044b725ae77Skettenis #endif
2045b725ae77Skettenis     }
2046b725ae77Skettenis 
2047b725ae77Skettenis 
2048b725ae77Skettenis   /* Sanity checks and set-up.
2049b725ae77Skettenis    *                             Process State
2050b725ae77Skettenis    *
2051b725ae77Skettenis    *                        Stopped   Running    Fake-step  (v)Fork
2052b725ae77Skettenis    *                      \________________________________________
2053b725ae77Skettenis    *                      |
2054b725ae77Skettenis    *  No buffered events  |  error     wait       wait      wait
2055b725ae77Skettenis    *                      |
2056b725ae77Skettenis    *  Buffered events     |  debuffer  error      wait      debuffer (?)
2057b725ae77Skettenis    *
2058b725ae77Skettenis    */
2059b725ae77Skettenis   if (more_events_left == 0)
2060b725ae77Skettenis     {
2061b725ae77Skettenis 
2062b725ae77Skettenis       if (process_state == RUNNING)
2063b725ae77Skettenis 	{
2064b725ae77Skettenis 	  /* OK--normal call of ttrace_wait with no buffered events.
2065b725ae77Skettenis 	   */
2066b725ae77Skettenis 	  ;
2067b725ae77Skettenis 	}
2068b725ae77Skettenis       else if (process_state == FAKE_STEPPING)
2069b725ae77Skettenis 	{
2070b725ae77Skettenis 	  /* Ok--call of ttrace_wait to support
2071b725ae77Skettenis 	   * fake stepping with no buffered events.
2072b725ae77Skettenis 	   *
2073b725ae77Skettenis 	   * But we better be fake-stepping!
2074b725ae77Skettenis 	   */
2075b725ae77Skettenis 	  if (!doing_fake_step)
2076b725ae77Skettenis 	    {
2077b725ae77Skettenis 	      warning ("Inconsistent thread state.");
2078b725ae77Skettenis 	    }
2079b725ae77Skettenis 	}
2080b725ae77Skettenis       else if ((process_state == FORKING)
2081b725ae77Skettenis 	       || (process_state == VFORKING))
2082b725ae77Skettenis 	{
2083b725ae77Skettenis 	  /* Ok--there are two processes, so waiting
2084b725ae77Skettenis 	   * for the second while the first is stopped
2085b725ae77Skettenis 	   * is ok.  Handled bits stay as they were.
2086b725ae77Skettenis 	   */
2087b725ae77Skettenis 	  ;
2088b725ae77Skettenis 	}
2089b725ae77Skettenis       else if (process_state == STOPPED)
2090b725ae77Skettenis 	{
2091b725ae77Skettenis 	  warning ("Process not running at wait call.");
2092b725ae77Skettenis 	}
2093b725ae77Skettenis       else
2094b725ae77Skettenis 	/* No known state.
2095b725ae77Skettenis 	 */
2096b725ae77Skettenis 	warning ("Inconsistent process state.");
2097b725ae77Skettenis     }
2098b725ae77Skettenis 
2099b725ae77Skettenis   else
2100b725ae77Skettenis     {
2101b725ae77Skettenis       /* More events left
2102b725ae77Skettenis        */
2103b725ae77Skettenis       if (process_state == STOPPED)
2104b725ae77Skettenis 	{
2105b725ae77Skettenis 	  /* OK--buffered events being unbuffered.
2106b725ae77Skettenis 	   */
2107b725ae77Skettenis 	  ;
2108b725ae77Skettenis 	}
2109b725ae77Skettenis       else if (process_state == RUNNING)
2110b725ae77Skettenis 	{
2111b725ae77Skettenis 	  /* An error--shouldn't have buffered events
2112b725ae77Skettenis 	   * when running.
2113b725ae77Skettenis 	   */
2114b725ae77Skettenis 	  warning ("Trying to continue with buffered events:");
2115b725ae77Skettenis 	}
2116b725ae77Skettenis       else if (process_state == FAKE_STEPPING)
2117b725ae77Skettenis 	{
2118b725ae77Skettenis 	  /*
2119b725ae77Skettenis 	   * Better be fake-stepping!
2120b725ae77Skettenis 	   */
2121b725ae77Skettenis 	  if (!doing_fake_step)
2122b725ae77Skettenis 	    {
2123b725ae77Skettenis 	      warning ("Losing buffered thread events!\n");
2124b725ae77Skettenis 	    }
2125b725ae77Skettenis 	}
2126b725ae77Skettenis       else if ((process_state == FORKING)
2127b725ae77Skettenis 	       || (process_state == VFORKING))
2128b725ae77Skettenis 	{
2129b725ae77Skettenis 	  /* Ok--there are two processes, so waiting
2130b725ae77Skettenis 	   * for the second while the first is stopped
2131b725ae77Skettenis 	   * is ok.  Handled bits stay as they were.
2132b725ae77Skettenis 	   */
2133b725ae77Skettenis 	  ;
2134b725ae77Skettenis 	}
2135b725ae77Skettenis       else
2136b725ae77Skettenis 	warning ("Process in unknown state with buffered events.");
2137b725ae77Skettenis     }
2138b725ae77Skettenis 
2139b725ae77Skettenis   /* Sometimes we have to wait for a particular thread
2140b725ae77Skettenis    * (if we're stepping over a bpt).  In that case, we
2141b725ae77Skettenis    * _know_ it's going to complete the single-step we
2142b725ae77Skettenis    * asked for (because we're only doing the step under
2143b725ae77Skettenis    * certain very well-understood circumstances), so it
2144b725ae77Skettenis    * can't block.
2145b725ae77Skettenis    */
2146b725ae77Skettenis   if (doing_fake_step)
2147b725ae77Skettenis     {
2148b725ae77Skettenis       wait_tid = fake_step_tid;
2149b725ae77Skettenis       wait_pid = get_pid_for (fake_step_tid);
2150b725ae77Skettenis 
2151b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
2152b725ae77Skettenis       if (debug_on)
2153b725ae77Skettenis 	printf ("Doing a wait after a fake-step for %d, pid %d\n",
2154b725ae77Skettenis 		wait_tid, wait_pid);
2155b725ae77Skettenis #endif
2156b725ae77Skettenis     }
2157b725ae77Skettenis 
2158b725ae77Skettenis   if (more_events_left == 0	/* No buffered events, need real ones. */
2159b725ae77Skettenis       || process_state != STOPPED)
2160b725ae77Skettenis     {
2161b725ae77Skettenis       /* If there are no buffered events, and so we need
2162b725ae77Skettenis        * real ones, or if we are FORKING, VFORKING,
2163b725ae77Skettenis        * FAKE_STEPPING or RUNNING, and thus have to do
2164b725ae77Skettenis        * a real wait, then do a real wait.
2165b725ae77Skettenis        */
2166b725ae77Skettenis 
2167b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
2168b725ae77Skettenis       /* Normal case... */
2169b725ae77Skettenis       if (debug_on)
2170b725ae77Skettenis 	printf ("TW: do it for real; pid %d, tid %d\n", wait_pid, wait_tid);
2171b725ae77Skettenis #endif
2172b725ae77Skettenis 
2173b725ae77Skettenis       /* The actual wait call.
2174b725ae77Skettenis        */
2175b725ae77Skettenis       ttw_status = call_real_ttrace_wait (wait_pid, wait_tid, option, tsp, tsp_size);
2176b725ae77Skettenis 
2177b725ae77Skettenis       /* Note that the routines we'll call will be using "call_real_ttrace",
2178b725ae77Skettenis        * not "call_ttrace", and thus need the real pid rather than the pseudo-tid
2179b725ae77Skettenis        * the rest of the world uses (which is actually the tid).
2180b725ae77Skettenis        */
2181b725ae77Skettenis       real_pid = tsp->tts_pid;
2182b725ae77Skettenis 
2183b725ae77Skettenis       /* For most events: Stop the world!
2184b725ae77Skettenis 
2185b725ae77Skettenis        * It's sometimes not safe to stop all threads of a process.
2186b725ae77Skettenis        * Sometimes it's not even safe to ask for the thread state
2187b725ae77Skettenis        * of a process!
2188b725ae77Skettenis        */
2189b725ae77Skettenis       if (can_touch_threads_of_process (real_pid, tsp->tts_event))
2190b725ae77Skettenis 	{
2191b725ae77Skettenis 	  /* If we're really only stepping a single thread, then don't
2192b725ae77Skettenis 	   * try to stop all the others -- we only do this single-stepping
2193b725ae77Skettenis 	   * business when all others were already stopped...and the stop
2194b725ae77Skettenis 	   * would mess up other threads' events.
2195b725ae77Skettenis 	   *
2196b725ae77Skettenis 	   * Similiarly, if there are other threads with events,
2197b725ae77Skettenis 	   * don't do the stop.
2198b725ae77Skettenis 	   */
2199b725ae77Skettenis 	  if (!doing_fake_step)
2200b725ae77Skettenis 	    {
2201b725ae77Skettenis 	      if (more_events_left > 0)
2202b725ae77Skettenis 		warning ("Internal error in stopping process");
2203b725ae77Skettenis 
2204b725ae77Skettenis 	      stop_all_threads_of_process (real_pid);
2205b725ae77Skettenis 
2206b725ae77Skettenis 	      /* At this point, we could scan and update_thread_list(),
2207b725ae77Skettenis 	       * and only use the local list for the rest of the
2208b725ae77Skettenis 	       * module! We'd get rid of the scans in the various
2209b725ae77Skettenis 	       * continue routines (adding one in attach).  It'd
2210b725ae77Skettenis 	       * be great--UPGRADE ME!
2211b725ae77Skettenis 	       */
2212b725ae77Skettenis 	    }
2213b725ae77Skettenis 	}
2214b725ae77Skettenis 
2215b725ae77Skettenis #ifdef PARANOIA
2216b725ae77Skettenis       else if (debug_on)
2217b725ae77Skettenis 	{
2218b725ae77Skettenis 	  if (more_events_left > 0)
2219b725ae77Skettenis 	    printf ("== Can't stop process; more events!\n");
2220b725ae77Skettenis 	  else
2221b725ae77Skettenis 	    printf ("== Can't stop process!\n");
2222b725ae77Skettenis 	}
2223b725ae77Skettenis #endif
2224b725ae77Skettenis 
2225b725ae77Skettenis       process_state = STOPPED;
2226b725ae77Skettenis 
2227b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
2228b725ae77Skettenis       if (debug_on)
2229b725ae77Skettenis 	printf ("Process set to STOPPED\n");
2230b725ae77Skettenis #endif
2231b725ae77Skettenis     }
2232b725ae77Skettenis 
2233b725ae77Skettenis   else
2234b725ae77Skettenis     {
2235b725ae77Skettenis       /* Fake a call to ttrace_wait.  The process must be
2236b725ae77Skettenis        * STOPPED, as we aren't going to do any wait.
2237b725ae77Skettenis        */
2238b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
2239b725ae77Skettenis       if (debug_on)
2240b725ae77Skettenis 	printf ("TW: fake it\n");
2241b725ae77Skettenis #endif
2242b725ae77Skettenis 
2243b725ae77Skettenis       if (process_state != STOPPED)
2244b725ae77Skettenis 	{
2245b725ae77Skettenis 	  warning ("Process not stopped at wait call, in state '%s'.\n",
2246b725ae77Skettenis 		   get_printable_name_of_process_state (process_state));
2247b725ae77Skettenis 	}
2248b725ae77Skettenis 
2249b725ae77Skettenis       if (doing_fake_step)
2250b725ae77Skettenis 	error ("Internal error in stepping over breakpoint");
2251b725ae77Skettenis 
2252b725ae77Skettenis       ttw_status = 0;		/* Faking it is always successful! */
2253b725ae77Skettenis     }				/* End of fake or not? if */
2254b725ae77Skettenis 
2255b725ae77Skettenis   /* Pick an event to pass to our caller.  Be paranoid.
2256b725ae77Skettenis    */
2257b725ae77Skettenis   if (!select_stopped_thread_of_process (real_pid, tsp))
2258b725ae77Skettenis     warning ("Can't find event, using previous event.");
2259b725ae77Skettenis 
2260b725ae77Skettenis   else if (tsp->tts_event == TTEVT_NONE)
2261b725ae77Skettenis     warning ("Internal error: no thread has a real event.");
2262b725ae77Skettenis 
2263b725ae77Skettenis   else if (doing_fake_step)
2264b725ae77Skettenis     {
2265b725ae77Skettenis       if (fake_step_tid != tsp->tts_lwpid)
2266b725ae77Skettenis 	warning ("Internal error in stepping over breakpoint.");
2267b725ae77Skettenis 
2268b725ae77Skettenis       /* This wait clears the (current) fake-step if there was one.
2269b725ae77Skettenis        */
2270b725ae77Skettenis       doing_fake_step = 0;
2271b725ae77Skettenis       fake_step_tid = 0;
2272b725ae77Skettenis     }
2273b725ae77Skettenis 
2274b725ae77Skettenis   /* We now have a correct tsp and ttw_status for the thread
2275b725ae77Skettenis    * which we want to report.  So it's "handled"!  This call
2276b725ae77Skettenis    * will add it to our list if it's not there already.
2277b725ae77Skettenis    */
2278b725ae77Skettenis   set_handled (real_pid, tsp->tts_lwpid);
2279b725ae77Skettenis 
2280b725ae77Skettenis   /* Save a copy of the ttrace state of this thread, in our local
2281b725ae77Skettenis      thread descriptor.
2282b725ae77Skettenis 
2283b725ae77Skettenis      This caches the state.  The implementation of queries like
2284b725ae77Skettenis      hpux_has_execd can then use this cached state, rather than
2285b725ae77Skettenis      be forced to make an explicit ttrace call to get it.
2286b725ae77Skettenis 
2287b725ae77Skettenis      (Guard against the condition that this is the first time we've
2288b725ae77Skettenis      waited on, i.e., seen this thread, and so haven't yet entered
2289b725ae77Skettenis      it into our list of threads.)
2290b725ae77Skettenis    */
2291b725ae77Skettenis   tinfo = find_thread_info (tsp->tts_lwpid);
2292b725ae77Skettenis   if (tinfo != NULL)
2293b725ae77Skettenis     {
2294b725ae77Skettenis       copy_ttstate_t (&tinfo->last_stop_state, tsp);
2295b725ae77Skettenis       tinfo->have_state = 1;
2296b725ae77Skettenis     }
2297b725ae77Skettenis 
2298b725ae77Skettenis   return ttw_status;
2299b725ae77Skettenis }				/* call_ttrace_wait */
2300b725ae77Skettenis 
2301b725ae77Skettenis #if defined(CHILD_REPORTED_EXEC_EVENTS_PER_EXEC_CALL)
2302b725ae77Skettenis int
child_reported_exec_events_per_exec_call(void)2303b725ae77Skettenis child_reported_exec_events_per_exec_call (void)
2304b725ae77Skettenis {
2305b725ae77Skettenis   return 1;			/* ttrace reports the event once per call. */
2306b725ae77Skettenis }
2307b725ae77Skettenis #endif
2308b725ae77Skettenis 
2309b725ae77Skettenis 
2310b725ae77Skettenis 
2311b725ae77Skettenis /* Our implementation of hardware watchpoints involves making memory
2312b725ae77Skettenis    pages write-protected.  We must remember a page's original permissions,
2313b725ae77Skettenis    and we must also know when it is appropriate to restore a page's
2314b725ae77Skettenis    permissions to its original state.
2315b725ae77Skettenis 
2316b725ae77Skettenis    We use a "dictionary" of hardware-watched pages to do this.  Each
2317b725ae77Skettenis    hardware-watched page is recorded in the dictionary.  Each page's
2318b725ae77Skettenis    dictionary entry contains the original permissions and a reference
2319b725ae77Skettenis    count.  Pages are hashed into the dictionary by their start address.
2320b725ae77Skettenis 
2321b725ae77Skettenis    When hardware watchpoint is set on page X for the first time, page X
2322b725ae77Skettenis    is added to the dictionary with a reference count of 1.  If other
2323b725ae77Skettenis    hardware watchpoints are subsequently set on page X, its reference
2324b725ae77Skettenis    count is incremented.  When hardware watchpoints are removed from
2325b725ae77Skettenis    page X, its reference count is decremented.  If a page's reference
2326b725ae77Skettenis    count drops to 0, it's permissions are restored and the page's entry
2327b725ae77Skettenis    is thrown out of the dictionary.
2328b725ae77Skettenis  */
2329b725ae77Skettenis typedef struct memory_page
2330b725ae77Skettenis {
2331b725ae77Skettenis   CORE_ADDR page_start;
2332b725ae77Skettenis   int reference_count;
2333b725ae77Skettenis   int original_permissions;
2334b725ae77Skettenis   struct memory_page *next;
2335b725ae77Skettenis   struct memory_page *previous;
2336b725ae77Skettenis }
2337b725ae77Skettenis memory_page_t;
2338b725ae77Skettenis 
2339b725ae77Skettenis #define MEMORY_PAGE_DICTIONARY_BUCKET_COUNT  128
2340b725ae77Skettenis 
2341b725ae77Skettenis static struct
2342b725ae77Skettenis   {
2343b725ae77Skettenis     LONGEST page_count;
2344b725ae77Skettenis     int page_size;
2345b725ae77Skettenis     int page_protections_allowed;
2346b725ae77Skettenis     /* These are just the heads of chains of actual page descriptors. */
2347b725ae77Skettenis     memory_page_t buckets[MEMORY_PAGE_DICTIONARY_BUCKET_COUNT];
2348b725ae77Skettenis   }
2349b725ae77Skettenis memory_page_dictionary;
2350b725ae77Skettenis 
2351b725ae77Skettenis 
2352b725ae77Skettenis static void
require_memory_page_dictionary(void)2353b725ae77Skettenis require_memory_page_dictionary (void)
2354b725ae77Skettenis {
2355b725ae77Skettenis   int i;
2356b725ae77Skettenis 
2357b725ae77Skettenis   /* Is the memory page dictionary ready for use?  If so, we're done. */
2358b725ae77Skettenis   if (memory_page_dictionary.page_count >= (LONGEST) 0)
2359b725ae77Skettenis     return;
2360b725ae77Skettenis 
2361b725ae77Skettenis   /* Else, initialize it. */
2362b725ae77Skettenis   memory_page_dictionary.page_count = (LONGEST) 0;
2363b725ae77Skettenis 
2364b725ae77Skettenis   for (i = 0; i < MEMORY_PAGE_DICTIONARY_BUCKET_COUNT; i++)
2365b725ae77Skettenis     {
2366b725ae77Skettenis       memory_page_dictionary.buckets[i].page_start = (CORE_ADDR) 0;
2367b725ae77Skettenis       memory_page_dictionary.buckets[i].reference_count = 0;
2368b725ae77Skettenis       memory_page_dictionary.buckets[i].next = NULL;
2369b725ae77Skettenis       memory_page_dictionary.buckets[i].previous = NULL;
2370b725ae77Skettenis     }
2371b725ae77Skettenis }
2372b725ae77Skettenis 
2373b725ae77Skettenis 
2374b725ae77Skettenis static void
retire_memory_page_dictionary(void)2375b725ae77Skettenis retire_memory_page_dictionary (void)
2376b725ae77Skettenis {
2377b725ae77Skettenis   memory_page_dictionary.page_count = (LONGEST) - 1;
2378b725ae77Skettenis }
2379b725ae77Skettenis 
2380b725ae77Skettenis 
2381b725ae77Skettenis /* Write-protect the memory page that starts at this address.
2382b725ae77Skettenis 
2383b725ae77Skettenis    Returns the original permissions of the page.
2384b725ae77Skettenis  */
2385b725ae77Skettenis static int
write_protect_page(int pid,CORE_ADDR page_start)2386b725ae77Skettenis write_protect_page (int pid, CORE_ADDR page_start)
2387b725ae77Skettenis {
2388b725ae77Skettenis   int tt_status;
2389b725ae77Skettenis   int original_permissions;
2390b725ae77Skettenis   int new_permissions;
2391b725ae77Skettenis 
2392b725ae77Skettenis   tt_status = call_ttrace (TT_PROC_GET_MPROTECT,
2393b725ae77Skettenis 			   pid,
2394b725ae77Skettenis 			   (TTRACE_ARG_TYPE) page_start,
2395b725ae77Skettenis 			   TT_NIL,
2396b725ae77Skettenis 			   (TTRACE_ARG_TYPE) & original_permissions);
2397b725ae77Skettenis   if (errno || (tt_status < 0))
2398b725ae77Skettenis     {
2399b725ae77Skettenis       return 0;			/* What else can we do? */
2400b725ae77Skettenis     }
2401b725ae77Skettenis 
2402b725ae77Skettenis   /* We'll also write-protect the page now, if that's allowed. */
2403b725ae77Skettenis   if (memory_page_dictionary.page_protections_allowed)
2404b725ae77Skettenis     {
2405b725ae77Skettenis       new_permissions = original_permissions & ~PROT_WRITE;
2406b725ae77Skettenis       tt_status = call_ttrace (TT_PROC_SET_MPROTECT,
2407b725ae77Skettenis 			       pid,
2408b725ae77Skettenis 			       (TTRACE_ARG_TYPE) page_start,
2409b725ae77Skettenis 			 (TTRACE_ARG_TYPE) memory_page_dictionary.page_size,
2410b725ae77Skettenis 			       (TTRACE_ARG_TYPE) new_permissions);
2411b725ae77Skettenis       if (errno || (tt_status < 0))
2412b725ae77Skettenis 	{
2413b725ae77Skettenis 	  return 0;		/* What else can we do? */
2414b725ae77Skettenis 	}
2415b725ae77Skettenis     }
2416b725ae77Skettenis 
2417b725ae77Skettenis   return original_permissions;
2418b725ae77Skettenis }
2419b725ae77Skettenis 
2420b725ae77Skettenis 
2421b725ae77Skettenis /* Unwrite-protect the memory page that starts at this address, restoring
2422b725ae77Skettenis    (what we must assume are) its original permissions.
2423b725ae77Skettenis  */
2424b725ae77Skettenis static void
unwrite_protect_page(int pid,CORE_ADDR page_start,int original_permissions)2425b725ae77Skettenis unwrite_protect_page (int pid, CORE_ADDR page_start, int original_permissions)
2426b725ae77Skettenis {
2427b725ae77Skettenis   int tt_status;
2428b725ae77Skettenis 
2429b725ae77Skettenis   tt_status = call_ttrace (TT_PROC_SET_MPROTECT,
2430b725ae77Skettenis 			   pid,
2431b725ae77Skettenis 			   (TTRACE_ARG_TYPE) page_start,
2432b725ae77Skettenis 			 (TTRACE_ARG_TYPE) memory_page_dictionary.page_size,
2433b725ae77Skettenis 			   (TTRACE_ARG_TYPE) original_permissions);
2434b725ae77Skettenis   if (errno || (tt_status < 0))
2435b725ae77Skettenis     {
2436b725ae77Skettenis       return;			/* What else can we do? */
2437b725ae77Skettenis     }
2438b725ae77Skettenis }
2439b725ae77Skettenis 
2440b725ae77Skettenis 
2441b725ae77Skettenis /* Memory page-protections are used to implement "hardware" watchpoints
2442b725ae77Skettenis    on HP-UX.
2443b725ae77Skettenis 
2444b725ae77Skettenis    For every memory page that is currently being watched (i.e., that
2445b725ae77Skettenis    presently should be write-protected), write-protect it.
2446b725ae77Skettenis  */
2447b725ae77Skettenis void
hppa_enable_page_protection_events(int pid)2448b725ae77Skettenis hppa_enable_page_protection_events (int pid)
2449b725ae77Skettenis {
2450b725ae77Skettenis   int bucket;
2451b725ae77Skettenis 
2452b725ae77Skettenis   memory_page_dictionary.page_protections_allowed = 1;
2453b725ae77Skettenis 
2454b725ae77Skettenis   for (bucket = 0; bucket < MEMORY_PAGE_DICTIONARY_BUCKET_COUNT; bucket++)
2455b725ae77Skettenis     {
2456b725ae77Skettenis       memory_page_t *page;
2457b725ae77Skettenis 
2458b725ae77Skettenis       page = memory_page_dictionary.buckets[bucket].next;
2459b725ae77Skettenis       while (page != NULL)
2460b725ae77Skettenis 	{
2461b725ae77Skettenis 	  page->original_permissions = write_protect_page (pid, page->page_start);
2462b725ae77Skettenis 	  page = page->next;
2463b725ae77Skettenis 	}
2464b725ae77Skettenis     }
2465b725ae77Skettenis }
2466b725ae77Skettenis 
2467b725ae77Skettenis 
2468b725ae77Skettenis /* Memory page-protections are used to implement "hardware" watchpoints
2469b725ae77Skettenis    on HP-UX.
2470b725ae77Skettenis 
2471b725ae77Skettenis    For every memory page that is currently being watched (i.e., that
2472b725ae77Skettenis    presently is or should be write-protected), un-write-protect it.
2473b725ae77Skettenis  */
2474b725ae77Skettenis void
hppa_disable_page_protection_events(int pid)2475b725ae77Skettenis hppa_disable_page_protection_events (int pid)
2476b725ae77Skettenis {
2477b725ae77Skettenis   int bucket;
2478b725ae77Skettenis 
2479b725ae77Skettenis   for (bucket = 0; bucket < MEMORY_PAGE_DICTIONARY_BUCKET_COUNT; bucket++)
2480b725ae77Skettenis     {
2481b725ae77Skettenis       memory_page_t *page;
2482b725ae77Skettenis 
2483b725ae77Skettenis       page = memory_page_dictionary.buckets[bucket].next;
2484b725ae77Skettenis       while (page != NULL)
2485b725ae77Skettenis 	{
2486b725ae77Skettenis 	  unwrite_protect_page (pid, page->page_start, page->original_permissions);
2487b725ae77Skettenis 	  page = page->next;
2488b725ae77Skettenis 	}
2489b725ae77Skettenis     }
2490b725ae77Skettenis 
2491b725ae77Skettenis   memory_page_dictionary.page_protections_allowed = 0;
2492b725ae77Skettenis }
2493b725ae77Skettenis 
2494b725ae77Skettenis /* Count the number of outstanding events.  At this
2495b725ae77Skettenis  * point, we have selected one thread and its event
2496b725ae77Skettenis  * as the one to be "reported" upwards to core gdb.
2497b725ae77Skettenis  * That thread is already marked as "handled".
2498b725ae77Skettenis  *
2499b725ae77Skettenis  * Note: we could just scan our own thread list.  FIXME!
2500b725ae77Skettenis  */
2501b725ae77Skettenis static int
count_unhandled_events(int real_pid,lwpid_t real_tid)2502b725ae77Skettenis count_unhandled_events (int real_pid, lwpid_t real_tid)
2503b725ae77Skettenis {
2504b725ae77Skettenis   ttstate_t tstate;
2505b725ae77Skettenis   lwpid_t ttid;
2506b725ae77Skettenis   int events_left;
2507b725ae77Skettenis 
2508b725ae77Skettenis   /* Ok, find out how many threads have real events to report.
2509b725ae77Skettenis    */
2510b725ae77Skettenis   events_left = 0;
2511b725ae77Skettenis   ttid = get_process_first_stopped_thread_id (real_pid, &tstate);
2512b725ae77Skettenis 
2513b725ae77Skettenis #ifdef THREAD_DEBUG
2514b725ae77Skettenis   if (debug_on)
2515b725ae77Skettenis     {
2516b725ae77Skettenis       if (ttid == 0)
2517b725ae77Skettenis 	printf ("Process %d has no threads\n", real_pid);
2518b725ae77Skettenis       else
2519b725ae77Skettenis 	printf ("Process %d has these threads:\n", real_pid);
2520b725ae77Skettenis     }
2521b725ae77Skettenis #endif
2522b725ae77Skettenis 
2523b725ae77Skettenis   while (ttid > 0)
2524b725ae77Skettenis     {
2525b725ae77Skettenis       if (tstate.tts_event != TTEVT_NONE
2526b725ae77Skettenis 	  && !was_handled (ttid))
2527b725ae77Skettenis 	{
2528b725ae77Skettenis 	  /* TTEVT_NONE implies we just stopped it ourselves
2529b725ae77Skettenis 	   * because we're the stop-the-world guys, so it's
2530b725ae77Skettenis 	   * not an event from our point of view.
2531b725ae77Skettenis 	   *
2532b725ae77Skettenis 	   * If "was_handled" is true, this is an event we
2533b725ae77Skettenis 	   * already handled, so don't count it.
2534b725ae77Skettenis 	   *
2535b725ae77Skettenis 	   * Note that we don't count the thread with the
2536b725ae77Skettenis 	   * currently-reported event, as it's already marked
2537b725ae77Skettenis 	   * as handled.
2538b725ae77Skettenis 	   */
2539b725ae77Skettenis 	  events_left++;
2540b725ae77Skettenis 	}
2541b725ae77Skettenis 
2542b725ae77Skettenis #if defined( THREAD_DEBUG ) || defined( WAIT_BUFFER_DEBUG )
2543b725ae77Skettenis       if (debug_on)
2544b725ae77Skettenis 	{
2545b725ae77Skettenis 	  if (ttid == real_tid)
2546b725ae77Skettenis 	    printf ("*");	/* Thread we're reporting */
2547b725ae77Skettenis 	  else
2548b725ae77Skettenis 	    printf (" ");
2549b725ae77Skettenis 
2550b725ae77Skettenis 	  if (tstate.tts_event != TTEVT_NONE)
2551b725ae77Skettenis 	    printf ("+");	/* Thread with a real event */
2552b725ae77Skettenis 	  else
2553b725ae77Skettenis 	    printf (" ");
2554b725ae77Skettenis 
2555b725ae77Skettenis 	  if (was_handled (ttid))
2556b725ae77Skettenis 	    printf ("h");	/* Thread has been handled */
2557b725ae77Skettenis 	  else
2558b725ae77Skettenis 	    printf (" ");
2559b725ae77Skettenis 
2560b725ae77Skettenis 	  printf (" %d, with event %s", ttid,
2561b725ae77Skettenis 		  get_printable_name_of_ttrace_event (tstate.tts_event));
2562b725ae77Skettenis 
2563b725ae77Skettenis 	  if (tstate.tts_event == TTEVT_SIGNAL
2564b725ae77Skettenis 	      && 5 == tstate.tts_u.tts_signal.tts_signo)
2565b725ae77Skettenis 	    {
2566b725ae77Skettenis 	      CORE_ADDR pc_val;
2567b725ae77Skettenis 
2568b725ae77Skettenis 	      pc_val = get_raw_pc (ttid);
2569b725ae77Skettenis 
2570b725ae77Skettenis 	      if (pc_val > 0)
2571b725ae77Skettenis 		printf (" breakpoint at 0x%x\n", pc_val);
2572b725ae77Skettenis 	      else
2573b725ae77Skettenis 		printf (" bpt, can't fetch pc.\n");
2574b725ae77Skettenis 	    }
2575b725ae77Skettenis 	  else
2576b725ae77Skettenis 	    printf ("\n");
2577b725ae77Skettenis 	}
2578b725ae77Skettenis #endif
2579b725ae77Skettenis 
2580b725ae77Skettenis       ttid = get_process_next_stopped_thread_id (real_pid, &tstate);
2581b725ae77Skettenis     }
2582b725ae77Skettenis 
2583b725ae77Skettenis #if defined( THREAD_DEBUG ) || defined( WAIT_BUFFER_DEBUG )
2584b725ae77Skettenis   if (debug_on)
2585b725ae77Skettenis     if (events_left > 0)
2586b725ae77Skettenis       printf ("There are thus %d pending events\n", events_left);
2587b725ae77Skettenis #endif
2588b725ae77Skettenis 
2589b725ae77Skettenis   return events_left;
2590b725ae77Skettenis }
2591b725ae77Skettenis 
2592b725ae77Skettenis /* This function is provided as a sop to clients that are calling
2593b725ae77Skettenis  * ptrace_wait to wait for a process to stop.  (see the
2594b725ae77Skettenis  * implementation of child_wait.)  Return value is the pid for
2595b725ae77Skettenis  * the event that ended the wait.
2596b725ae77Skettenis  *
2597b725ae77Skettenis  * Note: used by core gdb and so uses the pseudo-pid (really tid).
2598b725ae77Skettenis  */
2599b725ae77Skettenis int
ptrace_wait(ptid_t ptid,int * status)2600b725ae77Skettenis ptrace_wait (ptid_t ptid, int *status)
2601b725ae77Skettenis {
2602b725ae77Skettenis   ttstate_t tsp;
2603b725ae77Skettenis   int ttwait_return;
2604b725ae77Skettenis   int real_pid;
2605b725ae77Skettenis   ttstate_t state;
2606b725ae77Skettenis   lwpid_t real_tid;
2607b725ae77Skettenis   int return_pid;
2608b725ae77Skettenis 
2609b725ae77Skettenis   /* The ptrace implementation of this also ignores pid.
2610b725ae77Skettenis    */
2611b725ae77Skettenis   *status = 0;
2612b725ae77Skettenis 
2613b725ae77Skettenis   ttwait_return = call_ttrace_wait (0, TTRACE_WAITOK, &tsp, sizeof (tsp));
2614b725ae77Skettenis   if (ttwait_return < 0)
2615b725ae77Skettenis     {
2616b725ae77Skettenis       /* ??rehrauer: It appears that if our inferior exits and we
2617b725ae77Skettenis          haven't asked for exit events, that we're not getting any
2618b725ae77Skettenis          indication save a negative return from ttrace_wait and an
2619b725ae77Skettenis          errno set to ESRCH?
2620b725ae77Skettenis        */
2621b725ae77Skettenis       if (errno == ESRCH)
2622b725ae77Skettenis 	{
2623b725ae77Skettenis 	  *status = 0;		/* WIFEXITED */
2624b725ae77Skettenis 	  return PIDGET (inferior_ptid);
2625b725ae77Skettenis 	}
2626b725ae77Skettenis 
2627b725ae77Skettenis       warning ("Call of ttrace_wait returned with errno %d.",
2628b725ae77Skettenis 	       errno);
2629b725ae77Skettenis       *status = ttwait_return;
2630b725ae77Skettenis       return PIDGET (inferior_ptid);
2631b725ae77Skettenis     }
2632b725ae77Skettenis 
2633b725ae77Skettenis   real_pid = tsp.tts_pid;
2634b725ae77Skettenis   real_tid = tsp.tts_lwpid;
2635b725ae77Skettenis 
2636b725ae77Skettenis   /* One complication is that the "tts_event" structure has
2637b725ae77Skettenis    * a set of flags, and more than one can be set.  So we
2638b725ae77Skettenis    * either have to force an order (as we do here), or handle
2639b725ae77Skettenis    * more than one flag at a time.
2640b725ae77Skettenis    */
2641b725ae77Skettenis   if (tsp.tts_event & TTEVT_LWP_CREATE)
2642b725ae77Skettenis     {
2643b725ae77Skettenis 
2644b725ae77Skettenis       /* Unlike what you might expect, this event is reported in
2645b725ae77Skettenis        * the _creating_ thread, and the _created_ thread (whose tid
2646b725ae77Skettenis        * we have) is still running.  So we have to stop it.  This
2647b725ae77Skettenis        * has already been done in "call_ttrace_wait", but should we
2648b725ae77Skettenis        * ever abandon the "stop-the-world" model, here's the command
2649b725ae77Skettenis        * to use:
2650b725ae77Skettenis        *
2651b725ae77Skettenis        *    call_ttrace( TT_LWP_STOP, real_tid, TT_NIL, TT_NIL, TT_NIL );
2652b725ae77Skettenis        *
2653b725ae77Skettenis        * Note that this would depend on being called _after_ "add_tthread"
2654b725ae77Skettenis        * below for the tid-to-pid translation to be done in "call_ttrace".
2655b725ae77Skettenis        */
2656b725ae77Skettenis 
2657b725ae77Skettenis #ifdef THREAD_DEBUG
2658b725ae77Skettenis       if (debug_on)
2659b725ae77Skettenis 	printf ("New thread: pid %d, tid %d, creator tid %d\n",
2660b725ae77Skettenis 		real_pid, tsp.tts_u.tts_thread.tts_target_lwpid,
2661b725ae77Skettenis 		real_tid);
2662b725ae77Skettenis #endif
2663b725ae77Skettenis 
2664b725ae77Skettenis       /* Now we have to return the tid of the created thread, not
2665b725ae77Skettenis        * the creating thread, or "wait_for_inferior" won't know we
2666b725ae77Skettenis        * have a new "process" (thread).  Plus we should record it
2667b725ae77Skettenis        * right, too.
2668b725ae77Skettenis        */
2669b725ae77Skettenis       real_tid = tsp.tts_u.tts_thread.tts_target_lwpid;
2670b725ae77Skettenis 
2671b725ae77Skettenis       add_tthread (real_pid, real_tid);
2672b725ae77Skettenis     }
2673b725ae77Skettenis 
2674b725ae77Skettenis   else if ((tsp.tts_event & TTEVT_LWP_TERMINATE)
2675b725ae77Skettenis 	   || (tsp.tts_event & TTEVT_LWP_EXIT))
2676b725ae77Skettenis     {
2677b725ae77Skettenis 
2678b725ae77Skettenis #ifdef THREAD_DEBUG
2679b725ae77Skettenis       if (debug_on)
2680b725ae77Skettenis 	printf ("Thread dies: %d\n", real_tid);
2681b725ae77Skettenis #endif
2682b725ae77Skettenis 
2683b725ae77Skettenis       del_tthread (real_tid);
2684b725ae77Skettenis     }
2685b725ae77Skettenis 
2686b725ae77Skettenis   else if (tsp.tts_event & TTEVT_EXEC)
2687b725ae77Skettenis     {
2688b725ae77Skettenis 
2689b725ae77Skettenis #ifdef THREAD_DEBUG
2690b725ae77Skettenis       if (debug_on)
2691b725ae77Skettenis 	printf ("Pid %d has zero'th thread %d; inferior pid is %d\n",
2692b725ae77Skettenis 		real_pid, real_tid, PIDGET (inferior_ptid));
2693b725ae77Skettenis #endif
2694b725ae77Skettenis 
2695b725ae77Skettenis       add_tthread (real_pid, real_tid);
2696b725ae77Skettenis     }
2697b725ae77Skettenis 
2698b725ae77Skettenis #ifdef THREAD_DEBUG
2699b725ae77Skettenis   else if (debug_on)
2700b725ae77Skettenis     {
2701b725ae77Skettenis       printf ("Process-level event %s, using tid %d\n",
2702b725ae77Skettenis 	      get_printable_name_of_ttrace_event (tsp.tts_event),
2703b725ae77Skettenis 	      real_tid);
2704b725ae77Skettenis 
2705b725ae77Skettenis       /* OK to do this, as "add_tthread" won't add
2706b725ae77Skettenis        * duplicate entries.  Also OK not to do it,
2707b725ae77Skettenis        * as this event isn't one which can change the
2708b725ae77Skettenis        * thread state.
2709b725ae77Skettenis        */
2710b725ae77Skettenis       add_tthread (real_pid, real_tid);
2711b725ae77Skettenis     }
2712b725ae77Skettenis #endif
2713b725ae77Skettenis 
2714b725ae77Skettenis 
2715b725ae77Skettenis   /* How many events are left to report later?
2716b725ae77Skettenis    * In a non-stop-the-world model, this isn't needed.
2717b725ae77Skettenis    *
2718b725ae77Skettenis    * Note that it's not always safe to query the thread state of a process,
2719b725ae77Skettenis    * which is what count_unhandled_events does.  (If unsafe, we're left with
2720b725ae77Skettenis    * no other resort than to assume that no more events remain...)
2721b725ae77Skettenis    */
2722b725ae77Skettenis   if (can_touch_threads_of_process (real_pid, tsp.tts_event))
2723b725ae77Skettenis     more_events_left = count_unhandled_events (real_pid, real_tid);
2724b725ae77Skettenis 
2725b725ae77Skettenis   else
2726b725ae77Skettenis     {
2727b725ae77Skettenis       if (more_events_left > 0)
2728b725ae77Skettenis 	warning ("Vfork or fork causing loss of %d buffered events.",
2729b725ae77Skettenis 		 more_events_left);
2730b725ae77Skettenis 
2731b725ae77Skettenis       more_events_left = 0;
2732b725ae77Skettenis     }
2733b725ae77Skettenis 
2734b725ae77Skettenis   /* Attempt to translate the ttrace_wait-returned status into the
2735b725ae77Skettenis      ptrace equivalent.
2736b725ae77Skettenis 
2737b725ae77Skettenis      ??rehrauer: This is somewhat fragile.  We really ought to rewrite
2738b725ae77Skettenis      clients that expect to pick apart a ptrace wait status, to use
2739b725ae77Skettenis      something a little more abstract.
2740b725ae77Skettenis    */
2741b725ae77Skettenis   if ((tsp.tts_event & TTEVT_EXEC)
2742b725ae77Skettenis       || (tsp.tts_event & TTEVT_FORK)
2743b725ae77Skettenis       || (tsp.tts_event & TTEVT_VFORK))
2744b725ae77Skettenis     {
2745b725ae77Skettenis       /* Forks come in pairs (parent and child), so core gdb
2746b725ae77Skettenis        * will do two waits.  Be ready to notice this.
2747b725ae77Skettenis        */
2748b725ae77Skettenis       if (tsp.tts_event & TTEVT_FORK)
2749b725ae77Skettenis 	{
2750b725ae77Skettenis 	  process_state = FORKING;
2751b725ae77Skettenis 
2752b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
2753b725ae77Skettenis 	  if (debug_on)
2754b725ae77Skettenis 	    printf ("Process set to FORKING\n");
2755b725ae77Skettenis #endif
2756b725ae77Skettenis 	}
2757b725ae77Skettenis       else if (tsp.tts_event & TTEVT_VFORK)
2758b725ae77Skettenis 	{
2759b725ae77Skettenis 	  process_state = VFORKING;
2760b725ae77Skettenis 
2761b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
2762b725ae77Skettenis 	  if (debug_on)
2763b725ae77Skettenis 	    printf ("Process set to VFORKING\n");
2764b725ae77Skettenis #endif
2765b725ae77Skettenis 	}
2766b725ae77Skettenis 
2767b725ae77Skettenis       /* Make an exec or fork look like a breakpoint.  Definitely a hack,
2768b725ae77Skettenis          but I don't think non HP-UX-specific clients really carefully
2769b725ae77Skettenis          inspect the first events they get after inferior startup, so
2770b725ae77Skettenis          it probably almost doesn't matter what we claim this is.
2771b725ae77Skettenis        */
2772b725ae77Skettenis 
2773b725ae77Skettenis #ifdef THREAD_DEBUG
2774b725ae77Skettenis       if (debug_on)
2775b725ae77Skettenis 	printf ("..a process 'event'\n");
2776b725ae77Skettenis #endif
2777b725ae77Skettenis 
2778b725ae77Skettenis       /* Also make fork and exec events look like bpts, so they can be caught.
2779b725ae77Skettenis        */
2780b725ae77Skettenis       *status = 0177 | (_SIGTRAP << 8);
2781b725ae77Skettenis     }
2782b725ae77Skettenis 
2783b725ae77Skettenis   /* Special-cases: We ask for syscall entry and exit events to implement
2784b725ae77Skettenis      "fast" (aka "hardware") watchpoints.
2785b725ae77Skettenis 
2786b725ae77Skettenis      When we get a syscall entry, we want to disable page-protections,
2787b725ae77Skettenis      and resume the inferior; this isn't an event we wish for
2788b725ae77Skettenis      wait_for_inferior to see.  Note that we must resume ONLY the
2789b725ae77Skettenis      thread that reported the syscall entry; we don't want to allow
2790b725ae77Skettenis      other threads to run with the page protections off, as they might
2791b725ae77Skettenis      then be able to write to watch memory without it being caught.
2792b725ae77Skettenis 
2793b725ae77Skettenis      When we get a syscall exit, we want to reenable page-protections,
2794b725ae77Skettenis      but we don't want to resume the inferior; this is an event we wish
2795b725ae77Skettenis      wait_for_inferior to see.  Make it look like the signal we normally
2796b725ae77Skettenis      get for a single-step completion.  This should cause wait_for_inferior
2797b725ae77Skettenis      to evaluate whether any watchpoint triggered.
2798b725ae77Skettenis 
2799b725ae77Skettenis      Or rather, that's what we'd LIKE to do for syscall exit; we can't,
2800b725ae77Skettenis      due to some HP-UX "features".  Some syscalls have problems with
2801b725ae77Skettenis      write-protections on some pages, and some syscalls seem to have
2802b725ae77Skettenis      pending writes to those pages at the time we're getting the return
2803b725ae77Skettenis      event.  So, we'll single-step the inferior to get out of the syscall,
2804b725ae77Skettenis      and then reenable protections.
2805b725ae77Skettenis 
2806b725ae77Skettenis      Note that we're intentionally allowing the syscall exit case to
2807b725ae77Skettenis      fall through into the succeeding cases, as sometimes we single-
2808b725ae77Skettenis      step out of one syscall only to immediately enter another...
2809b725ae77Skettenis    */
2810b725ae77Skettenis   else if ((tsp.tts_event & TTEVT_SYSCALL_ENTRY)
2811b725ae77Skettenis 	   || (tsp.tts_event & TTEVT_SYSCALL_RETURN))
2812b725ae77Skettenis     {
2813b725ae77Skettenis       /* Make a syscall event look like a breakpoint.  Same comments
2814b725ae77Skettenis          as for exec & fork events.
2815b725ae77Skettenis        */
2816b725ae77Skettenis #ifdef THREAD_DEBUG
2817b725ae77Skettenis       if (debug_on)
2818b725ae77Skettenis 	printf ("..a syscall 'event'\n");
2819b725ae77Skettenis #endif
2820b725ae77Skettenis 
2821b725ae77Skettenis       /* Also make syscall events look like bpts, so they can be caught.
2822b725ae77Skettenis        */
2823b725ae77Skettenis       *status = 0177 | (_SIGTRAP << 8);
2824b725ae77Skettenis     }
2825b725ae77Skettenis 
2826b725ae77Skettenis   else if ((tsp.tts_event & TTEVT_LWP_CREATE)
2827b725ae77Skettenis 	   || (tsp.tts_event & TTEVT_LWP_TERMINATE)
2828b725ae77Skettenis 	   || (tsp.tts_event & TTEVT_LWP_EXIT))
2829b725ae77Skettenis     {
2830b725ae77Skettenis       /* Make a thread event look like a breakpoint.  Same comments
2831b725ae77Skettenis        * as for exec & fork events.
2832b725ae77Skettenis        */
2833b725ae77Skettenis #ifdef THREAD_DEBUG
2834b725ae77Skettenis       if (debug_on)
2835b725ae77Skettenis 	printf ("..a thread 'event'\n");
2836b725ae77Skettenis #endif
2837b725ae77Skettenis 
2838b725ae77Skettenis       /* Also make thread events look like bpts, so they can be caught.
2839b725ae77Skettenis        */
2840b725ae77Skettenis       *status = 0177 | (_SIGTRAP << 8);
2841b725ae77Skettenis     }
2842b725ae77Skettenis 
2843b725ae77Skettenis   else if ((tsp.tts_event & TTEVT_EXIT))
2844b725ae77Skettenis     {				/* WIFEXITED */
2845b725ae77Skettenis 
2846b725ae77Skettenis #ifdef THREAD_DEBUG
2847b725ae77Skettenis       if (debug_on)
2848b725ae77Skettenis 	printf ("..an exit\n");
2849b725ae77Skettenis #endif
2850b725ae77Skettenis 
2851b725ae77Skettenis       /* Prevent rest of gdb from thinking this is
2852b725ae77Skettenis        * a new thread if for some reason it's never
2853b725ae77Skettenis        * seen the main thread before.
2854b725ae77Skettenis        */
2855b725ae77Skettenis       inferior_ptid = pid_to_ptid (map_to_gdb_tid (real_tid));	/* HACK, FIX */
2856b725ae77Skettenis 
2857b725ae77Skettenis       *status = 0 | (tsp.tts_u.tts_exit.tts_exitcode);
2858b725ae77Skettenis     }
2859b725ae77Skettenis 
2860b725ae77Skettenis   else if (tsp.tts_event & TTEVT_SIGNAL)
2861b725ae77Skettenis     {				/* WIFSTOPPED */
2862b725ae77Skettenis #ifdef THREAD_DEBUG
2863b725ae77Skettenis       if (debug_on)
2864b725ae77Skettenis 	printf ("..a signal, %d\n", tsp.tts_u.tts_signal.tts_signo);
2865b725ae77Skettenis #endif
2866b725ae77Skettenis 
2867b725ae77Skettenis       *status = 0177 | (tsp.tts_u.tts_signal.tts_signo << 8);
2868b725ae77Skettenis     }
2869b725ae77Skettenis 
2870b725ae77Skettenis   else
2871b725ae77Skettenis     {				/* !WIFSTOPPED */
2872b725ae77Skettenis 
2873b725ae77Skettenis       /* This means the process or thread terminated.  But we should've
2874b725ae77Skettenis          caught an explicit exit/termination above.  So warn (this is
2875b725ae77Skettenis          really an internal error) and claim the process or thread
2876b725ae77Skettenis          terminated with a SIGTRAP.
2877b725ae77Skettenis        */
2878b725ae77Skettenis 
2879b725ae77Skettenis       warning ("process_wait: unknown process state");
2880b725ae77Skettenis 
2881b725ae77Skettenis #ifdef THREAD_DEBUG
2882b725ae77Skettenis       if (debug_on)
2883b725ae77Skettenis 	printf ("Process-level event %s, using tid %d\n",
2884b725ae77Skettenis 		get_printable_name_of_ttrace_event (tsp.tts_event),
2885b725ae77Skettenis 		real_tid);
2886b725ae77Skettenis #endif
2887b725ae77Skettenis 
2888b725ae77Skettenis       *status = _SIGTRAP;
2889b725ae77Skettenis     }
2890b725ae77Skettenis 
2891b725ae77Skettenis #ifdef THREAD_DEBUG
2892b725ae77Skettenis   if (debug_on)
2893b725ae77Skettenis     printf ("Done waiting, pid is %d, tid %d\n", real_pid, real_tid);
2894b725ae77Skettenis #endif
2895b725ae77Skettenis 
2896b725ae77Skettenis   /* All code external to this module uses the tid, but calls
2897b725ae77Skettenis    * it "pid".  There's some tweaking so that the outside sees
2898b725ae77Skettenis    * the first thread as having the same number as the starting
2899b725ae77Skettenis    * pid.
2900b725ae77Skettenis    */
2901b725ae77Skettenis   return_pid = map_to_gdb_tid (real_tid);
2902b725ae77Skettenis 
2903b725ae77Skettenis   if (real_tid == 0 || return_pid == 0)
2904b725ae77Skettenis     {
2905b725ae77Skettenis       warning ("Internal error: process-wait failed.");
2906b725ae77Skettenis     }
2907b725ae77Skettenis 
2908b725ae77Skettenis   return return_pid;
2909b725ae77Skettenis }
2910b725ae77Skettenis 
2911b725ae77Skettenis 
2912b725ae77Skettenis /* This function causes the caller's process to be traced by its
2913b725ae77Skettenis    parent.  This is intended to be called after GDB forks itself,
2914b725ae77Skettenis    and before the child execs the target.  Despite the name, it
2915b725ae77Skettenis    is called by the child.
2916b725ae77Skettenis 
2917b725ae77Skettenis    Note that HP-UX ttrace is rather funky in how this is done.
2918b725ae77Skettenis    If the parent wants to get the initial exec event of a child,
2919b725ae77Skettenis    it must set the ttrace event mask of the child to include execs.
2920b725ae77Skettenis    (The child cannot do this itself.)  This must be done after the
2921b725ae77Skettenis    child is forked, but before it execs.
2922b725ae77Skettenis 
2923b725ae77Skettenis    To coordinate the parent and child, we implement a semaphore using
2924b725ae77Skettenis    pipes.  After SETTRC'ing itself, the child tells the parent that
2925b725ae77Skettenis    it is now traceable by the parent, and waits for the parent's
2926b725ae77Skettenis    acknowledgement.  The parent can then set the child's event mask,
2927b725ae77Skettenis    and notify the child that it can now exec.
2928b725ae77Skettenis 
2929b725ae77Skettenis    (The acknowledgement by parent happens as a result of a call to
2930b725ae77Skettenis    child_acknowledge_created_inferior.)
2931b725ae77Skettenis  */
2932b725ae77Skettenis int
parent_attach_all(int p1,PTRACE_ARG3_TYPE p2,int p3)2933b725ae77Skettenis parent_attach_all (int p1, PTRACE_ARG3_TYPE p2, int p3)
2934b725ae77Skettenis {
2935b725ae77Skettenis   int tt_status;
2936b725ae77Skettenis 
2937b725ae77Skettenis   /* We need a memory home for a constant, to pass it to ttrace.
2938b725ae77Skettenis      The value of the constant is arbitrary, so long as both
2939b725ae77Skettenis      parent and child use the same value.  Might as well use the
2940b725ae77Skettenis      "magic" constant provided by ttrace...
2941b725ae77Skettenis    */
2942b725ae77Skettenis   uint64_t tc_magic_child = TT_VERSION;
2943b725ae77Skettenis   uint64_t tc_magic_parent = 0;
2944b725ae77Skettenis 
2945b725ae77Skettenis   tt_status = call_real_ttrace (
2946b725ae77Skettenis 				 TT_PROC_SETTRC,
2947b725ae77Skettenis 				 (int) TT_NIL,
2948b725ae77Skettenis 				 (lwpid_t) TT_NIL,
2949b725ae77Skettenis 				 TT_NIL,
2950b725ae77Skettenis 				 (TTRACE_ARG_TYPE) TT_VERSION,
2951b725ae77Skettenis 				 TT_NIL);
2952b725ae77Skettenis 
2953b725ae77Skettenis   if (tt_status < 0)
2954b725ae77Skettenis     return tt_status;
2955b725ae77Skettenis 
2956b725ae77Skettenis   /* Notify the parent that we're potentially ready to exec(). */
2957b725ae77Skettenis   write (startup_semaphore.child_channel[SEM_TALK],
2958b725ae77Skettenis 	 &tc_magic_child,
2959b725ae77Skettenis 	 sizeof (tc_magic_child));
2960b725ae77Skettenis 
2961b725ae77Skettenis   /* Wait for acknowledgement from the parent. */
2962b725ae77Skettenis   read (startup_semaphore.parent_channel[SEM_LISTEN],
2963b725ae77Skettenis 	&tc_magic_parent,
2964b725ae77Skettenis 	sizeof (tc_magic_parent));
2965b725ae77Skettenis 
2966b725ae77Skettenis   if (tc_magic_child != tc_magic_parent)
2967b725ae77Skettenis     warning ("mismatched semaphore magic");
2968b725ae77Skettenis 
2969b725ae77Skettenis   /* Discard our copy of the semaphore. */
2970b725ae77Skettenis   (void) close (startup_semaphore.parent_channel[SEM_LISTEN]);
2971b725ae77Skettenis   (void) close (startup_semaphore.parent_channel[SEM_TALK]);
2972b725ae77Skettenis   (void) close (startup_semaphore.child_channel[SEM_LISTEN]);
2973b725ae77Skettenis   (void) close (startup_semaphore.child_channel[SEM_TALK]);
2974b725ae77Skettenis 
2975b725ae77Skettenis   return tt_status;
2976b725ae77Skettenis }
2977b725ae77Skettenis 
2978b725ae77Skettenis /* Despite being file-local, this routine is dealing with
2979b725ae77Skettenis  * actual process IDs, not thread ids.  That's because it's
2980b725ae77Skettenis  * called before the first "wait" call, and there's no map
2981b725ae77Skettenis  * yet from tids to pids.
2982b725ae77Skettenis  *
2983b725ae77Skettenis  * When it is called, a forked child is running, but waiting on
2984b725ae77Skettenis  * the semaphore.  If you stop the child and re-start it,
2985b725ae77Skettenis  * things get confused, so don't do that!  An attached child is
2986b725ae77Skettenis  * stopped.
2987b725ae77Skettenis  *
2988b725ae77Skettenis  * Since this is called after either attach or run, we
2989b725ae77Skettenis  * have to be the common part of both.
2990b725ae77Skettenis  */
2991b725ae77Skettenis static void
require_notification_of_events(int real_pid)2992b725ae77Skettenis require_notification_of_events (int real_pid)
2993b725ae77Skettenis {
2994b725ae77Skettenis   int tt_status;
2995b725ae77Skettenis   ttevent_t notifiable_events;
2996b725ae77Skettenis 
2997b725ae77Skettenis   lwpid_t tid;
2998b725ae77Skettenis   ttstate_t thread_state;
2999b725ae77Skettenis 
3000b725ae77Skettenis #ifdef THREAD_DEBUG
3001b725ae77Skettenis   if (debug_on)
3002b725ae77Skettenis     printf ("Require notif, pid is %d\n", real_pid);
3003b725ae77Skettenis #endif
3004b725ae77Skettenis 
3005b725ae77Skettenis   /* Temporary HACK: tell inftarg.c/child_wait to not
3006b725ae77Skettenis    * loop until pids are the same.
3007b725ae77Skettenis    */
3008b725ae77Skettenis   not_same_real_pid = 0;
3009b725ae77Skettenis 
3010b725ae77Skettenis   sigemptyset (&notifiable_events.tte_signals);
3011b725ae77Skettenis   notifiable_events.tte_opts = TTEO_NONE;
3012b725ae77Skettenis 
3013b725ae77Skettenis   /* This ensures that forked children inherit their parent's
3014b725ae77Skettenis    * event mask, which we're setting here.
3015b725ae77Skettenis    *
3016b725ae77Skettenis    * NOTE: if you debug gdb with itself, then the ultimate
3017b725ae77Skettenis    *       debuggee gets flags set by the outermost gdb, as
3018b725ae77Skettenis    *       a child of a child will still inherit.
3019b725ae77Skettenis    */
3020b725ae77Skettenis   notifiable_events.tte_opts |= TTEO_PROC_INHERIT;
3021b725ae77Skettenis 
3022b725ae77Skettenis   notifiable_events.tte_events = TTEVT_DEFAULT;
3023b725ae77Skettenis   notifiable_events.tte_events |= TTEVT_SIGNAL;
3024b725ae77Skettenis   notifiable_events.tte_events |= TTEVT_EXEC;
3025b725ae77Skettenis   notifiable_events.tte_events |= TTEVT_EXIT;
3026b725ae77Skettenis   notifiable_events.tte_events |= TTEVT_FORK;
3027b725ae77Skettenis   notifiable_events.tte_events |= TTEVT_VFORK;
3028b725ae77Skettenis   notifiable_events.tte_events |= TTEVT_LWP_CREATE;
3029b725ae77Skettenis   notifiable_events.tte_events |= TTEVT_LWP_EXIT;
3030b725ae77Skettenis   notifiable_events.tte_events |= TTEVT_LWP_TERMINATE;
3031b725ae77Skettenis 
3032b725ae77Skettenis   tt_status = call_real_ttrace (
3033b725ae77Skettenis 				 TT_PROC_SET_EVENT_MASK,
3034b725ae77Skettenis 				 real_pid,
3035b725ae77Skettenis 				 (lwpid_t) TT_NIL,
3036b725ae77Skettenis 				 (TTRACE_ARG_TYPE) & notifiable_events,
3037b725ae77Skettenis 			       (TTRACE_ARG_TYPE) sizeof (notifiable_events),
3038b725ae77Skettenis 				 TT_NIL);
3039b725ae77Skettenis }
3040b725ae77Skettenis 
3041b725ae77Skettenis static void
require_notification_of_exec_events(int real_pid)3042b725ae77Skettenis require_notification_of_exec_events (int real_pid)
3043b725ae77Skettenis {
3044b725ae77Skettenis   int tt_status;
3045b725ae77Skettenis   ttevent_t notifiable_events;
3046b725ae77Skettenis 
3047b725ae77Skettenis   lwpid_t tid;
3048b725ae77Skettenis   ttstate_t thread_state;
3049b725ae77Skettenis 
3050b725ae77Skettenis #ifdef THREAD_DEBUG
3051b725ae77Skettenis   if (debug_on)
3052b725ae77Skettenis     printf ("Require notif, pid is %d\n", real_pid);
3053b725ae77Skettenis #endif
3054b725ae77Skettenis 
3055b725ae77Skettenis   /* Temporary HACK: tell inftarg.c/child_wait to not
3056b725ae77Skettenis    * loop until pids are the same.
3057b725ae77Skettenis    */
3058b725ae77Skettenis   not_same_real_pid = 0;
3059b725ae77Skettenis 
3060b725ae77Skettenis   sigemptyset (&notifiable_events.tte_signals);
3061b725ae77Skettenis   notifiable_events.tte_opts = TTEO_NOSTRCCHLD;
3062b725ae77Skettenis 
3063b725ae77Skettenis   /* This ensures that forked children don't inherit their parent's
3064b725ae77Skettenis    * event mask, which we're setting here.
3065b725ae77Skettenis    */
3066b725ae77Skettenis   notifiable_events.tte_opts &= ~TTEO_PROC_INHERIT;
3067b725ae77Skettenis 
3068b725ae77Skettenis   notifiable_events.tte_events = TTEVT_DEFAULT;
3069b725ae77Skettenis   notifiable_events.tte_events |= TTEVT_EXEC;
3070b725ae77Skettenis   notifiable_events.tte_events |= TTEVT_EXIT;
3071b725ae77Skettenis 
3072b725ae77Skettenis   tt_status = call_real_ttrace (
3073b725ae77Skettenis 				 TT_PROC_SET_EVENT_MASK,
3074b725ae77Skettenis 				 real_pid,
3075b725ae77Skettenis 				 (lwpid_t) TT_NIL,
3076b725ae77Skettenis 				 (TTRACE_ARG_TYPE) & notifiable_events,
3077b725ae77Skettenis 			       (TTRACE_ARG_TYPE) sizeof (notifiable_events),
3078b725ae77Skettenis 				 TT_NIL);
3079b725ae77Skettenis }
3080b725ae77Skettenis 
3081b725ae77Skettenis 
3082b725ae77Skettenis /* This function is called by the parent process, with pid being the
3083b725ae77Skettenis  * ID of the child process, after the debugger has forked.
3084b725ae77Skettenis  */
3085b725ae77Skettenis void
child_acknowledge_created_inferior(int pid)3086b725ae77Skettenis child_acknowledge_created_inferior (int pid)
3087b725ae77Skettenis {
3088b725ae77Skettenis   /* We need a memory home for a constant, to pass it to ttrace.
3089b725ae77Skettenis      The value of the constant is arbitrary, so long as both
3090b725ae77Skettenis      parent and child use the same value.  Might as well use the
3091b725ae77Skettenis      "magic" constant provided by ttrace...
3092b725ae77Skettenis    */
3093b725ae77Skettenis   uint64_t tc_magic_parent = TT_VERSION;
3094b725ae77Skettenis   uint64_t tc_magic_child = 0;
3095b725ae77Skettenis 
3096b725ae77Skettenis   /* Wait for the child to tell us that it has forked. */
3097b725ae77Skettenis   read (startup_semaphore.child_channel[SEM_LISTEN],
3098b725ae77Skettenis 	&tc_magic_child,
3099b725ae77Skettenis 	sizeof (tc_magic_child));
3100b725ae77Skettenis 
3101b725ae77Skettenis   /* Clear thread info now.  We'd like to do this in
3102b725ae77Skettenis    * "require...", but that messes up attach.
3103b725ae77Skettenis    */
3104b725ae77Skettenis   clear_thread_info ();
3105b725ae77Skettenis 
3106b725ae77Skettenis   /* Tell the "rest of gdb" that the initial thread exists.
3107b725ae77Skettenis    * This isn't really a hack.  Other thread-based versions
3108b725ae77Skettenis    * of gdb (e.g. gnu-nat.c) seem to do the same thing.
3109b725ae77Skettenis    *
3110b725ae77Skettenis    * Q: Why don't we also add this thread to the local
3111b725ae77Skettenis    *    list via "add_tthread"?
3112b725ae77Skettenis    *
3113b725ae77Skettenis    * A: Because we don't know the tid, and can't stop the
3114b725ae77Skettenis    *    the process safely to ask what it is.  Anyway, we'll
3115b725ae77Skettenis    *    add it when it gets the EXEC event.
3116b725ae77Skettenis    */
3117b725ae77Skettenis   add_thread (pid_to_ptid (pid));		/* in thread.c */
3118b725ae77Skettenis 
3119b725ae77Skettenis   /* We can now set the child's ttrace event mask.
3120b725ae77Skettenis    */
3121b725ae77Skettenis   require_notification_of_exec_events (pid);
3122b725ae77Skettenis 
3123b725ae77Skettenis   /* Tell ourselves that the process is running.
3124b725ae77Skettenis    */
3125b725ae77Skettenis   process_state = RUNNING;
3126b725ae77Skettenis 
3127b725ae77Skettenis   /* Notify the child that it can exec. */
3128b725ae77Skettenis   write (startup_semaphore.parent_channel[SEM_TALK],
3129b725ae77Skettenis 	 &tc_magic_parent,
3130b725ae77Skettenis 	 sizeof (tc_magic_parent));
3131b725ae77Skettenis 
3132b725ae77Skettenis   /* Discard our copy of the semaphore. */
3133b725ae77Skettenis   (void) close (startup_semaphore.parent_channel[SEM_LISTEN]);
3134b725ae77Skettenis   (void) close (startup_semaphore.parent_channel[SEM_TALK]);
3135b725ae77Skettenis   (void) close (startup_semaphore.child_channel[SEM_LISTEN]);
3136b725ae77Skettenis   (void) close (startup_semaphore.child_channel[SEM_TALK]);
3137b725ae77Skettenis }
3138b725ae77Skettenis 
3139b725ae77Skettenis 
3140b725ae77Skettenis /*
3141b725ae77Skettenis  * arrange for notification of all events by
3142b725ae77Skettenis  * calling require_notification_of_events.
3143b725ae77Skettenis  */
3144b725ae77Skettenis void
child_post_startup_inferior(ptid_t ptid)3145b725ae77Skettenis child_post_startup_inferior (ptid_t ptid)
3146b725ae77Skettenis {
3147b725ae77Skettenis   require_notification_of_events (PIDGET (ptid));
3148b725ae77Skettenis }
3149b725ae77Skettenis 
3150b725ae77Skettenis /* From here on, we should expect tids rather than pids.
3151b725ae77Skettenis  */
3152b725ae77Skettenis static void
hppa_enable_catch_fork(int tid)3153b725ae77Skettenis hppa_enable_catch_fork (int tid)
3154b725ae77Skettenis {
3155b725ae77Skettenis   int tt_status;
3156b725ae77Skettenis   ttevent_t ttrace_events;
3157b725ae77Skettenis 
3158b725ae77Skettenis   /* Get the set of events that are currently enabled.
3159b725ae77Skettenis    */
3160b725ae77Skettenis   tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
3161b725ae77Skettenis 			   tid,
3162b725ae77Skettenis 			   (TTRACE_ARG_TYPE) & ttrace_events,
3163b725ae77Skettenis 			   (TTRACE_ARG_TYPE) sizeof (ttrace_events),
3164b725ae77Skettenis 			   TT_NIL);
3165b725ae77Skettenis   if (errno)
3166b725ae77Skettenis     perror_with_name ("ttrace");
3167b725ae77Skettenis 
3168b725ae77Skettenis   /* Add forks to that set. */
3169b725ae77Skettenis   ttrace_events.tte_events |= TTEVT_FORK;
3170b725ae77Skettenis 
3171b725ae77Skettenis #ifdef THREAD_DEBUG
3172b725ae77Skettenis   if (debug_on)
3173b725ae77Skettenis     printf ("enable fork, tid is %d\n", tid);
3174b725ae77Skettenis #endif
3175b725ae77Skettenis 
3176b725ae77Skettenis   tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
3177b725ae77Skettenis 			   tid,
3178b725ae77Skettenis 			   (TTRACE_ARG_TYPE) & ttrace_events,
3179b725ae77Skettenis 			   (TTRACE_ARG_TYPE) sizeof (ttrace_events),
3180b725ae77Skettenis 			   TT_NIL);
3181b725ae77Skettenis   if (errno)
3182b725ae77Skettenis     perror_with_name ("ttrace");
3183b725ae77Skettenis }
3184b725ae77Skettenis 
3185b725ae77Skettenis 
3186b725ae77Skettenis static void
hppa_disable_catch_fork(int tid)3187b725ae77Skettenis hppa_disable_catch_fork (int tid)
3188b725ae77Skettenis {
3189b725ae77Skettenis   int tt_status;
3190b725ae77Skettenis   ttevent_t ttrace_events;
3191b725ae77Skettenis 
3192b725ae77Skettenis   /* Get the set of events that are currently enabled.
3193b725ae77Skettenis    */
3194b725ae77Skettenis   tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
3195b725ae77Skettenis 			   tid,
3196b725ae77Skettenis 			   (TTRACE_ARG_TYPE) & ttrace_events,
3197b725ae77Skettenis 			   (TTRACE_ARG_TYPE) sizeof (ttrace_events),
3198b725ae77Skettenis 			   TT_NIL);
3199b725ae77Skettenis 
3200b725ae77Skettenis   if (errno)
3201b725ae77Skettenis     perror_with_name ("ttrace");
3202b725ae77Skettenis 
3203b725ae77Skettenis   /* Remove forks from that set. */
3204b725ae77Skettenis   ttrace_events.tte_events &= ~TTEVT_FORK;
3205b725ae77Skettenis 
3206b725ae77Skettenis #ifdef THREAD_DEBUG
3207b725ae77Skettenis   if (debug_on)
3208b725ae77Skettenis     printf ("disable fork, tid is %d\n", tid);
3209b725ae77Skettenis #endif
3210b725ae77Skettenis 
3211b725ae77Skettenis   tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
3212b725ae77Skettenis 			   tid,
3213b725ae77Skettenis 			   (TTRACE_ARG_TYPE) & ttrace_events,
3214b725ae77Skettenis 			   (TTRACE_ARG_TYPE) sizeof (ttrace_events),
3215b725ae77Skettenis 			   TT_NIL);
3216b725ae77Skettenis 
3217b725ae77Skettenis   if (errno)
3218b725ae77Skettenis     perror_with_name ("ttrace");
3219b725ae77Skettenis }
3220b725ae77Skettenis 
3221b725ae77Skettenis 
3222b725ae77Skettenis #if defined(CHILD_INSERT_FORK_CATCHPOINT)
3223b725ae77Skettenis int
child_insert_fork_catchpoint(int tid)3224b725ae77Skettenis child_insert_fork_catchpoint (int tid)
3225b725ae77Skettenis {
3226b725ae77Skettenis   /* Enable reporting of fork events from the kernel. */
3227b725ae77Skettenis   /* ??rehrauer: For the moment, we're always enabling these events,
3228b725ae77Skettenis      and just ignoring them if there's no catchpoint to catch them.
3229b725ae77Skettenis    */
3230b725ae77Skettenis   return 0;
3231b725ae77Skettenis }
3232b725ae77Skettenis #endif
3233b725ae77Skettenis 
3234b725ae77Skettenis 
3235b725ae77Skettenis #if defined(CHILD_REMOVE_FORK_CATCHPOINT)
3236b725ae77Skettenis int
child_remove_fork_catchpoint(int tid)3237b725ae77Skettenis child_remove_fork_catchpoint (int tid)
3238b725ae77Skettenis {
3239b725ae77Skettenis   /* Disable reporting of fork events from the kernel. */
3240b725ae77Skettenis   /* ??rehrauer: For the moment, we're always enabling these events,
3241b725ae77Skettenis      and just ignoring them if there's no catchpoint to catch them.
3242b725ae77Skettenis    */
3243b725ae77Skettenis   return 0;
3244b725ae77Skettenis }
3245b725ae77Skettenis #endif
3246b725ae77Skettenis 
3247b725ae77Skettenis 
3248b725ae77Skettenis static void
hppa_enable_catch_vfork(int tid)3249b725ae77Skettenis hppa_enable_catch_vfork (int tid)
3250b725ae77Skettenis {
3251b725ae77Skettenis   int tt_status;
3252b725ae77Skettenis   ttevent_t ttrace_events;
3253b725ae77Skettenis 
3254b725ae77Skettenis   /* Get the set of events that are currently enabled.
3255b725ae77Skettenis    */
3256b725ae77Skettenis   tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
3257b725ae77Skettenis 			   tid,
3258b725ae77Skettenis 			   (TTRACE_ARG_TYPE) & ttrace_events,
3259b725ae77Skettenis 			   (TTRACE_ARG_TYPE) sizeof (ttrace_events),
3260b725ae77Skettenis 			   TT_NIL);
3261b725ae77Skettenis 
3262b725ae77Skettenis   if (errno)
3263b725ae77Skettenis     perror_with_name ("ttrace");
3264b725ae77Skettenis 
3265b725ae77Skettenis   /* Add vforks to that set. */
3266b725ae77Skettenis   ttrace_events.tte_events |= TTEVT_VFORK;
3267b725ae77Skettenis 
3268b725ae77Skettenis #ifdef THREAD_DEBUG
3269b725ae77Skettenis   if (debug_on)
3270b725ae77Skettenis     printf ("enable vfork, tid is %d\n", tid);
3271b725ae77Skettenis #endif
3272b725ae77Skettenis 
3273b725ae77Skettenis   tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
3274b725ae77Skettenis 			   tid,
3275b725ae77Skettenis 			   (TTRACE_ARG_TYPE) & ttrace_events,
3276b725ae77Skettenis 			   (TTRACE_ARG_TYPE) sizeof (ttrace_events),
3277b725ae77Skettenis 			   TT_NIL);
3278b725ae77Skettenis 
3279b725ae77Skettenis   if (errno)
3280b725ae77Skettenis     perror_with_name ("ttrace");
3281b725ae77Skettenis }
3282b725ae77Skettenis 
3283b725ae77Skettenis 
3284b725ae77Skettenis static void
hppa_disable_catch_vfork(int tid)3285b725ae77Skettenis hppa_disable_catch_vfork (int tid)
3286b725ae77Skettenis {
3287b725ae77Skettenis   int tt_status;
3288b725ae77Skettenis   ttevent_t ttrace_events;
3289b725ae77Skettenis 
3290b725ae77Skettenis   /* Get the set of events that are currently enabled. */
3291b725ae77Skettenis   tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
3292b725ae77Skettenis 			   tid,
3293b725ae77Skettenis 			   (TTRACE_ARG_TYPE) & ttrace_events,
3294b725ae77Skettenis 			   (TTRACE_ARG_TYPE) sizeof (ttrace_events),
3295b725ae77Skettenis 			   TT_NIL);
3296b725ae77Skettenis 
3297b725ae77Skettenis   if (errno)
3298b725ae77Skettenis     perror_with_name ("ttrace");
3299b725ae77Skettenis 
3300b725ae77Skettenis   /* Remove vforks from that set. */
3301b725ae77Skettenis   ttrace_events.tte_events &= ~TTEVT_VFORK;
3302b725ae77Skettenis 
3303b725ae77Skettenis #ifdef THREAD_DEBUG
3304b725ae77Skettenis   if (debug_on)
3305b725ae77Skettenis     printf ("disable vfork, tid is %d\n", tid);
3306b725ae77Skettenis #endif
3307b725ae77Skettenis   tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
3308b725ae77Skettenis 			   tid,
3309b725ae77Skettenis 			   (TTRACE_ARG_TYPE) & ttrace_events,
3310b725ae77Skettenis 			   (TTRACE_ARG_TYPE) sizeof (ttrace_events),
3311b725ae77Skettenis 			   TT_NIL);
3312b725ae77Skettenis 
3313b725ae77Skettenis   if (errno)
3314b725ae77Skettenis     perror_with_name ("ttrace");
3315b725ae77Skettenis }
3316b725ae77Skettenis 
3317b725ae77Skettenis 
3318b725ae77Skettenis #if defined(CHILD_INSERT_VFORK_CATCHPOINT)
3319b725ae77Skettenis int
child_insert_vfork_catchpoint(int tid)3320b725ae77Skettenis child_insert_vfork_catchpoint (int tid)
3321b725ae77Skettenis {
3322b725ae77Skettenis   /* Enable reporting of vfork events from the kernel. */
3323b725ae77Skettenis   /* ??rehrauer: For the moment, we're always enabling these events,
3324b725ae77Skettenis      and just ignoring them if there's no catchpoint to catch them.
3325b725ae77Skettenis    */
3326b725ae77Skettenis   return 0;
3327b725ae77Skettenis }
3328b725ae77Skettenis #endif
3329b725ae77Skettenis 
3330b725ae77Skettenis 
3331b725ae77Skettenis #if defined(CHILD_REMOVE_VFORK_CATCHPOINT)
3332b725ae77Skettenis int
child_remove_vfork_catchpoint(int tid)3333b725ae77Skettenis child_remove_vfork_catchpoint (int tid)
3334b725ae77Skettenis {
3335b725ae77Skettenis   /* Disable reporting of vfork events from the kernel. */
3336b725ae77Skettenis   /* ??rehrauer: For the moment, we're always enabling these events,
3337b725ae77Skettenis      and just ignoring them if there's no catchpoint to catch them.
3338b725ae77Skettenis    */
3339b725ae77Skettenis   return 0;
3340b725ae77Skettenis }
3341b725ae77Skettenis #endif
3342b725ae77Skettenis 
3343b725ae77Skettenis /* Q: Do we need to map the returned process ID to a thread ID?
3344b725ae77Skettenis 
3345b725ae77Skettenis  * A: I don't think so--here we want a _real_ pid.  Any later
3346b725ae77Skettenis  *    operations will call "require_notification_of_events" and
3347b725ae77Skettenis  *    start the mapping.
3348b725ae77Skettenis  */
3349b725ae77Skettenis int
hpux_has_forked(int tid,int * childpid)3350b725ae77Skettenis hpux_has_forked (int tid, int *childpid)
3351b725ae77Skettenis {
3352b725ae77Skettenis   int tt_status;
3353b725ae77Skettenis   ttstate_t ttrace_state;
3354b725ae77Skettenis   thread_info *tinfo;
3355b725ae77Skettenis 
3356b725ae77Skettenis   /* Do we have cached thread state that we can consult?  If so, use it. */
3357b725ae77Skettenis   tinfo = find_thread_info (map_from_gdb_tid (tid));
3358b725ae77Skettenis   if (tinfo != NULL)
3359b725ae77Skettenis     {
3360b725ae77Skettenis       copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state);
3361b725ae77Skettenis     }
3362b725ae77Skettenis 
3363b725ae77Skettenis   /* Nope, must read the thread's current state */
3364b725ae77Skettenis   else
3365b725ae77Skettenis     {
3366b725ae77Skettenis       tt_status = call_ttrace (TT_LWP_GET_STATE,
3367b725ae77Skettenis 			       tid,
3368b725ae77Skettenis 			       (TTRACE_ARG_TYPE) & ttrace_state,
3369b725ae77Skettenis 			       (TTRACE_ARG_TYPE) sizeof (ttrace_state),
3370b725ae77Skettenis 			       TT_NIL);
3371b725ae77Skettenis 
3372b725ae77Skettenis       if (errno)
3373b725ae77Skettenis 	perror_with_name ("ttrace");
3374b725ae77Skettenis 
3375b725ae77Skettenis       if (tt_status < 0)
3376b725ae77Skettenis 	return 0;
3377b725ae77Skettenis     }
3378b725ae77Skettenis 
3379b725ae77Skettenis   if (ttrace_state.tts_event & TTEVT_FORK)
3380b725ae77Skettenis     {
3381b725ae77Skettenis       *childpid = ttrace_state.tts_u.tts_fork.tts_fpid;
3382b725ae77Skettenis       return 1;
3383b725ae77Skettenis     }
3384b725ae77Skettenis 
3385b725ae77Skettenis   return 0;
3386b725ae77Skettenis }
3387b725ae77Skettenis 
3388b725ae77Skettenis /* See hpux_has_forked for pid discussion.
3389b725ae77Skettenis  */
3390b725ae77Skettenis int
hpux_has_vforked(int tid,int * childpid)3391b725ae77Skettenis hpux_has_vforked (int tid, int *childpid)
3392b725ae77Skettenis {
3393b725ae77Skettenis   int tt_status;
3394b725ae77Skettenis   ttstate_t ttrace_state;
3395b725ae77Skettenis   thread_info *tinfo;
3396b725ae77Skettenis 
3397b725ae77Skettenis   /* Do we have cached thread state that we can consult?  If so, use it. */
3398b725ae77Skettenis   tinfo = find_thread_info (map_from_gdb_tid (tid));
3399b725ae77Skettenis   if (tinfo != NULL)
3400b725ae77Skettenis     copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state);
3401b725ae77Skettenis 
3402b725ae77Skettenis   /* Nope, must read the thread's current state */
3403b725ae77Skettenis   else
3404b725ae77Skettenis     {
3405b725ae77Skettenis       tt_status = call_ttrace (TT_LWP_GET_STATE,
3406b725ae77Skettenis 			       tid,
3407b725ae77Skettenis 			       (TTRACE_ARG_TYPE) & ttrace_state,
3408b725ae77Skettenis 			       (TTRACE_ARG_TYPE) sizeof (ttrace_state),
3409b725ae77Skettenis 			       TT_NIL);
3410b725ae77Skettenis 
3411b725ae77Skettenis       if (errno)
3412b725ae77Skettenis 	perror_with_name ("ttrace");
3413b725ae77Skettenis 
3414b725ae77Skettenis       if (tt_status < 0)
3415b725ae77Skettenis 	return 0;
3416b725ae77Skettenis     }
3417b725ae77Skettenis 
3418b725ae77Skettenis   if (ttrace_state.tts_event & TTEVT_VFORK)
3419b725ae77Skettenis     {
3420b725ae77Skettenis       *childpid = ttrace_state.tts_u.tts_fork.tts_fpid;
3421b725ae77Skettenis       return 1;
3422b725ae77Skettenis     }
3423b725ae77Skettenis 
3424b725ae77Skettenis   return 0;
3425b725ae77Skettenis }
3426b725ae77Skettenis 
3427b725ae77Skettenis 
3428b725ae77Skettenis #if defined(CHILD_INSERT_EXEC_CATCHPOINT)
3429b725ae77Skettenis int
child_insert_exec_catchpoint(int tid)3430b725ae77Skettenis child_insert_exec_catchpoint (int tid)
3431b725ae77Skettenis {
3432b725ae77Skettenis   /* Enable reporting of exec events from the kernel. */
3433b725ae77Skettenis   /* ??rehrauer: For the moment, we're always enabling these events,
3434b725ae77Skettenis      and just ignoring them if there's no catchpoint to catch them.
3435b725ae77Skettenis    */
3436b725ae77Skettenis   return 0;
3437b725ae77Skettenis }
3438b725ae77Skettenis #endif
3439b725ae77Skettenis 
3440b725ae77Skettenis 
3441b725ae77Skettenis #if defined(CHILD_REMOVE_EXEC_CATCHPOINT)
3442b725ae77Skettenis int
child_remove_exec_catchpoint(int tid)3443b725ae77Skettenis child_remove_exec_catchpoint (int tid)
3444b725ae77Skettenis {
3445b725ae77Skettenis   /* Disable reporting of execevents from the kernel. */
3446b725ae77Skettenis   /* ??rehrauer: For the moment, we're always enabling these events,
3447b725ae77Skettenis      and just ignoring them if there's no catchpoint to catch them.
3448b725ae77Skettenis    */
3449b725ae77Skettenis   return 0;
3450b725ae77Skettenis }
3451b725ae77Skettenis #endif
3452b725ae77Skettenis 
3453b725ae77Skettenis 
3454b725ae77Skettenis int
hpux_has_execd(int tid,char ** execd_pathname)3455b725ae77Skettenis hpux_has_execd (int tid, char **execd_pathname)
3456b725ae77Skettenis {
3457b725ae77Skettenis   int tt_status;
3458b725ae77Skettenis   ttstate_t ttrace_state;
3459b725ae77Skettenis   thread_info *tinfo;
3460b725ae77Skettenis 
3461b725ae77Skettenis   /* Do we have cached thread state that we can consult?  If so, use it. */
3462b725ae77Skettenis   tinfo = find_thread_info (map_from_gdb_tid (tid));
3463b725ae77Skettenis   if (tinfo != NULL)
3464b725ae77Skettenis     copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state);
3465b725ae77Skettenis 
3466b725ae77Skettenis   /* Nope, must read the thread's current state */
3467b725ae77Skettenis   else
3468b725ae77Skettenis     {
3469b725ae77Skettenis       tt_status = call_ttrace (TT_LWP_GET_STATE,
3470b725ae77Skettenis 			       tid,
3471b725ae77Skettenis 			       (TTRACE_ARG_TYPE) & ttrace_state,
3472b725ae77Skettenis 			       (TTRACE_ARG_TYPE) sizeof (ttrace_state),
3473b725ae77Skettenis 			       TT_NIL);
3474b725ae77Skettenis 
3475b725ae77Skettenis       if (errno)
3476b725ae77Skettenis 	perror_with_name ("ttrace");
3477b725ae77Skettenis 
3478b725ae77Skettenis       if (tt_status < 0)
3479b725ae77Skettenis 	return 0;
3480b725ae77Skettenis     }
3481b725ae77Skettenis 
3482b725ae77Skettenis   if (ttrace_state.tts_event & TTEVT_EXEC)
3483b725ae77Skettenis     {
3484b725ae77Skettenis       /* See child_pid_to_exec_file in this file: this is a macro.
3485b725ae77Skettenis        */
3486b725ae77Skettenis       char *exec_file = target_pid_to_exec_file (tid);
3487b725ae77Skettenis 
3488b725ae77Skettenis       *execd_pathname = savestring (exec_file, strlen (exec_file));
3489b725ae77Skettenis       return 1;
3490b725ae77Skettenis     }
3491b725ae77Skettenis 
3492b725ae77Skettenis   return 0;
3493b725ae77Skettenis }
3494b725ae77Skettenis 
3495b725ae77Skettenis 
3496b725ae77Skettenis int
hpux_has_syscall_event(int pid,enum target_waitkind * kind,int * syscall_id)3497b725ae77Skettenis hpux_has_syscall_event (int pid, enum target_waitkind *kind, int *syscall_id)
3498b725ae77Skettenis {
3499b725ae77Skettenis   int tt_status;
3500b725ae77Skettenis   ttstate_t ttrace_state;
3501b725ae77Skettenis   thread_info *tinfo;
3502b725ae77Skettenis 
3503b725ae77Skettenis   /* Do we have cached thread state that we can consult?  If so, use it. */
3504b725ae77Skettenis   tinfo = find_thread_info (map_from_gdb_tid (pid));
3505b725ae77Skettenis   if (tinfo != NULL)
3506b725ae77Skettenis     copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state);
3507b725ae77Skettenis 
3508b725ae77Skettenis   /* Nope, must read the thread's current state */
3509b725ae77Skettenis   else
3510b725ae77Skettenis     {
3511b725ae77Skettenis       tt_status = call_ttrace (TT_LWP_GET_STATE,
3512b725ae77Skettenis 			       pid,
3513b725ae77Skettenis 			       (TTRACE_ARG_TYPE) & ttrace_state,
3514b725ae77Skettenis 			       (TTRACE_ARG_TYPE) sizeof (ttrace_state),
3515b725ae77Skettenis 			       TT_NIL);
3516b725ae77Skettenis 
3517b725ae77Skettenis       if (errno)
3518b725ae77Skettenis 	perror_with_name ("ttrace");
3519b725ae77Skettenis 
3520b725ae77Skettenis       if (tt_status < 0)
3521b725ae77Skettenis 	return 0;
3522b725ae77Skettenis     }
3523b725ae77Skettenis 
3524b725ae77Skettenis   *kind = TARGET_WAITKIND_SPURIOUS;	/* Until proven otherwise... */
3525b725ae77Skettenis   *syscall_id = -1;
3526b725ae77Skettenis 
3527b725ae77Skettenis   if (ttrace_state.tts_event & TTEVT_SYSCALL_ENTRY)
3528b725ae77Skettenis     *kind = TARGET_WAITKIND_SYSCALL_ENTRY;
3529b725ae77Skettenis   else if (ttrace_state.tts_event & TTEVT_SYSCALL_RETURN)
3530b725ae77Skettenis     *kind = TARGET_WAITKIND_SYSCALL_RETURN;
3531b725ae77Skettenis   else
3532b725ae77Skettenis     return 0;
3533b725ae77Skettenis 
3534b725ae77Skettenis   *syscall_id = ttrace_state.tts_scno;
3535b725ae77Skettenis   return 1;
3536b725ae77Skettenis }
3537b725ae77Skettenis 
3538b725ae77Skettenis 
3539b725ae77Skettenis 
3540b725ae77Skettenis #if defined(CHILD_THREAD_ALIVE)
3541b725ae77Skettenis 
3542b725ae77Skettenis /* Check to see if the given thread is alive.
3543b725ae77Skettenis 
3544b725ae77Skettenis  * We'll trust the thread list, as the more correct
3545b725ae77Skettenis  * approach of stopping the process and spinning down
3546b725ae77Skettenis  * the OS's thread list is _very_ expensive.
3547b725ae77Skettenis  *
3548b725ae77Skettenis  * May need a FIXME for that reason.
3549b725ae77Skettenis  */
3550b725ae77Skettenis int
child_thread_alive(ptid_t ptid)3551b725ae77Skettenis child_thread_alive (ptid_t ptid)
3552b725ae77Skettenis {
3553b725ae77Skettenis   lwpid_t gdb_tid = PIDGET (ptid);
3554b725ae77Skettenis   lwpid_t tid;
3555b725ae77Skettenis 
3556b725ae77Skettenis   /* This spins down the lists twice.
3557b725ae77Skettenis    * Possible peformance improvement here!
3558b725ae77Skettenis    */
3559b725ae77Skettenis   tid = map_from_gdb_tid (gdb_tid);
3560b725ae77Skettenis   return !is_terminated (tid);
3561b725ae77Skettenis }
3562b725ae77Skettenis 
3563b725ae77Skettenis #endif
3564b725ae77Skettenis 
3565b725ae77Skettenis 
3566b725ae77Skettenis 
3567b725ae77Skettenis /* This function attempts to read the specified number of bytes from the
3568b725ae77Skettenis    save_state_t that is our view into the hardware registers, starting at
3569b725ae77Skettenis    ss_offset, and ending at ss_offset + sizeof_buf - 1
3570b725ae77Skettenis 
3571b725ae77Skettenis    If this function succeeds, it deposits the fetched bytes into buf,
3572b725ae77Skettenis    and returns 0.
3573b725ae77Skettenis 
3574b725ae77Skettenis    If it fails, it returns a negative result.  The contents of buf are
3575b725ae77Skettenis    undefined it this function fails.
3576b725ae77Skettenis  */
3577b725ae77Skettenis int
read_from_register_save_state(int tid,TTRACE_ARG_TYPE ss_offset,char * buf,int sizeof_buf)3578b725ae77Skettenis read_from_register_save_state (int tid, TTRACE_ARG_TYPE ss_offset, char *buf,
3579b725ae77Skettenis 			       int sizeof_buf)
3580b725ae77Skettenis {
3581b725ae77Skettenis   int tt_status;
3582b725ae77Skettenis   register_value_t register_value = 0;
3583b725ae77Skettenis 
3584b725ae77Skettenis   tt_status = call_ttrace (TT_LWP_RUREGS,
3585b725ae77Skettenis 			   tid,
3586b725ae77Skettenis 			   ss_offset,
3587b725ae77Skettenis 			   (TTRACE_ARG_TYPE) sizeof_buf,
3588b725ae77Skettenis 			   (TTRACE_ARG_TYPE) buf);
3589b725ae77Skettenis 
3590b725ae77Skettenis   if (tt_status == 1)
3591b725ae77Skettenis     /* Map ttrace's version of success to our version.
3592b725ae77Skettenis      * Sometime ttrace returns 0, but that's ok here.
3593b725ae77Skettenis      */
3594b725ae77Skettenis     return 0;
3595b725ae77Skettenis 
3596b725ae77Skettenis   return tt_status;
3597b725ae77Skettenis }
3598b725ae77Skettenis 
3599b725ae77Skettenis 
3600b725ae77Skettenis /* This function attempts to write the specified number of bytes to the
3601b725ae77Skettenis    save_state_t that is our view into the hardware registers, starting at
3602b725ae77Skettenis    ss_offset, and ending at ss_offset + sizeof_buf - 1
3603b725ae77Skettenis 
3604b725ae77Skettenis    If this function succeeds, it deposits the bytes in buf, and returns 0.
3605b725ae77Skettenis 
3606b725ae77Skettenis    If it fails, it returns a negative result.  The contents of the save_state_t
3607b725ae77Skettenis    are undefined it this function fails.
3608b725ae77Skettenis  */
3609b725ae77Skettenis int
write_to_register_save_state(int tid,TTRACE_ARG_TYPE ss_offset,char * buf,int sizeof_buf)3610b725ae77Skettenis write_to_register_save_state (int tid, TTRACE_ARG_TYPE ss_offset, char *buf,
3611b725ae77Skettenis 			      int sizeof_buf)
3612b725ae77Skettenis {
3613b725ae77Skettenis   int tt_status;
3614b725ae77Skettenis   register_value_t register_value = 0;
3615b725ae77Skettenis 
3616b725ae77Skettenis   tt_status = call_ttrace (TT_LWP_WUREGS,
3617b725ae77Skettenis 			   tid,
3618b725ae77Skettenis 			   ss_offset,
3619b725ae77Skettenis 			   (TTRACE_ARG_TYPE) sizeof_buf,
3620b725ae77Skettenis 			   (TTRACE_ARG_TYPE) buf);
3621b725ae77Skettenis   return tt_status;
3622b725ae77Skettenis }
3623b725ae77Skettenis 
3624b725ae77Skettenis 
3625b725ae77Skettenis /* This function is a sop to the largeish number of direct calls
3626b725ae77Skettenis    to call_ptrace that exist in other files.  Rather than create
3627b725ae77Skettenis    functions whose name abstracts away from ptrace, and change all
3628b725ae77Skettenis    the present callers of call_ptrace, we'll do the expedient (and
3629b725ae77Skettenis    perhaps only practical) thing.
3630b725ae77Skettenis 
3631b725ae77Skettenis    Note HP-UX explicitly disallows a mix of ptrace & ttrace on a traced
3632b725ae77Skettenis    process.  Thus, we must translate all ptrace requests into their
3633b725ae77Skettenis    process-specific, ttrace equivalents.
3634b725ae77Skettenis  */
3635b725ae77Skettenis int
call_ptrace(int pt_request,int gdb_tid,PTRACE_ARG3_TYPE addr,int data)3636b725ae77Skettenis call_ptrace (int pt_request, int gdb_tid, PTRACE_ARG3_TYPE addr, int data)
3637b725ae77Skettenis {
3638b725ae77Skettenis   ttreq_t tt_request;
3639b725ae77Skettenis   TTRACE_ARG_TYPE tt_addr = (TTRACE_ARG_TYPE) addr;
3640b725ae77Skettenis   TTRACE_ARG_TYPE tt_data = (TTRACE_ARG_TYPE) data;
3641b725ae77Skettenis   TTRACE_ARG_TYPE tt_addr2 = TT_NIL;
3642b725ae77Skettenis   int tt_status;
3643b725ae77Skettenis   register_value_t register_value;
3644b725ae77Skettenis   int read_buf;
3645b725ae77Skettenis 
3646b725ae77Skettenis   /* Perform the necessary argument translation.  Note that some
3647b725ae77Skettenis      cases are funky enough in the ttrace realm that we handle them
3648b725ae77Skettenis      very specially.
3649b725ae77Skettenis    */
3650b725ae77Skettenis   switch (pt_request)
3651b725ae77Skettenis     {
3652b725ae77Skettenis       /* The following cases cannot conveniently be handled conveniently
3653b725ae77Skettenis          by merely adjusting the ptrace arguments and feeding into the
3654b725ae77Skettenis          generic call to ttrace at the bottom of this function.
3655b725ae77Skettenis 
3656b725ae77Skettenis          Note that because all branches of this switch end in "return",
3657b725ae77Skettenis          there's no need for any "break" statements.
3658b725ae77Skettenis        */
3659b725ae77Skettenis     case PT_SETTRC:
3660b725ae77Skettenis       return parent_attach_all (0, 0, 0);
3661b725ae77Skettenis 
3662b725ae77Skettenis     case PT_RUREGS:
3663b725ae77Skettenis       tt_status = read_from_register_save_state (gdb_tid,
3664b725ae77Skettenis 						 tt_addr,
3665b725ae77Skettenis 						 &register_value,
3666b725ae77Skettenis 						 sizeof (register_value));
3667b725ae77Skettenis       if (tt_status < 0)
3668b725ae77Skettenis 	return tt_status;
3669b725ae77Skettenis       return register_value;
3670b725ae77Skettenis 
3671b725ae77Skettenis     case PT_WUREGS:
3672b725ae77Skettenis       register_value = (int) tt_data;
3673b725ae77Skettenis       tt_status = write_to_register_save_state (gdb_tid,
3674b725ae77Skettenis 						tt_addr,
3675b725ae77Skettenis 						&register_value,
3676b725ae77Skettenis 						sizeof (register_value));
3677b725ae77Skettenis       return tt_status;
3678b725ae77Skettenis       break;
3679b725ae77Skettenis 
3680b725ae77Skettenis     case PT_READ_I:
3681b725ae77Skettenis       tt_status = call_ttrace (TT_PROC_RDTEXT,	/* Implicit 4-byte xfer becomes block-xfer. */
3682b725ae77Skettenis 			       gdb_tid,
3683b725ae77Skettenis 			       tt_addr,
3684b725ae77Skettenis 			       (TTRACE_ARG_TYPE) 4,
3685b725ae77Skettenis 			       (TTRACE_ARG_TYPE) & read_buf);
3686b725ae77Skettenis       if (tt_status < 0)
3687b725ae77Skettenis 	return tt_status;
3688b725ae77Skettenis       return read_buf;
3689b725ae77Skettenis 
3690b725ae77Skettenis     case PT_READ_D:
3691b725ae77Skettenis       tt_status = call_ttrace (TT_PROC_RDDATA,	/* Implicit 4-byte xfer becomes block-xfer. */
3692b725ae77Skettenis 			       gdb_tid,
3693b725ae77Skettenis 			       tt_addr,
3694b725ae77Skettenis 			       (TTRACE_ARG_TYPE) 4,
3695b725ae77Skettenis 			       (TTRACE_ARG_TYPE) & read_buf);
3696b725ae77Skettenis       if (tt_status < 0)
3697b725ae77Skettenis 	return tt_status;
3698b725ae77Skettenis       return read_buf;
3699b725ae77Skettenis 
3700b725ae77Skettenis     case PT_ATTACH:
3701b725ae77Skettenis       tt_status = call_real_ttrace (TT_PROC_ATTACH,
3702b725ae77Skettenis 				    map_from_gdb_tid (gdb_tid),
3703b725ae77Skettenis 				    (lwpid_t) TT_NIL,
3704b725ae77Skettenis 				    tt_addr,
3705b725ae77Skettenis 				    (TTRACE_ARG_TYPE) TT_VERSION,
3706b725ae77Skettenis 				    tt_addr2);
3707b725ae77Skettenis       if (tt_status < 0)
3708b725ae77Skettenis 	return tt_status;
3709b725ae77Skettenis       return tt_status;
3710b725ae77Skettenis 
3711b725ae77Skettenis       /* The following cases are handled by merely adjusting the ptrace
3712b725ae77Skettenis          arguments and feeding into the generic call to ttrace.
3713b725ae77Skettenis        */
3714b725ae77Skettenis     case PT_DETACH:
3715b725ae77Skettenis       tt_request = TT_PROC_DETACH;
3716b725ae77Skettenis       break;
3717b725ae77Skettenis 
3718b725ae77Skettenis     case PT_WRITE_I:
3719b725ae77Skettenis       tt_request = TT_PROC_WRTEXT;	/* Translates 4-byte xfer to block-xfer. */
3720b725ae77Skettenis       tt_data = 4;		/* This many bytes. */
3721b725ae77Skettenis       tt_addr2 = (TTRACE_ARG_TYPE) & data;	/* Address of xfer source. */
3722b725ae77Skettenis       break;
3723b725ae77Skettenis 
3724b725ae77Skettenis     case PT_WRITE_D:
3725b725ae77Skettenis       tt_request = TT_PROC_WRDATA;	/* Translates 4-byte xfer to block-xfer. */
3726b725ae77Skettenis       tt_data = 4;		/* This many bytes. */
3727b725ae77Skettenis       tt_addr2 = (TTRACE_ARG_TYPE) & data;	/* Address of xfer source. */
3728b725ae77Skettenis       break;
3729b725ae77Skettenis 
3730b725ae77Skettenis     case PT_RDTEXT:
3731b725ae77Skettenis       tt_request = TT_PROC_RDTEXT;
3732b725ae77Skettenis       break;
3733b725ae77Skettenis 
3734b725ae77Skettenis     case PT_RDDATA:
3735b725ae77Skettenis       tt_request = TT_PROC_RDDATA;
3736b725ae77Skettenis       break;
3737b725ae77Skettenis 
3738b725ae77Skettenis     case PT_WRTEXT:
3739b725ae77Skettenis       tt_request = TT_PROC_WRTEXT;
3740b725ae77Skettenis       break;
3741b725ae77Skettenis 
3742b725ae77Skettenis     case PT_WRDATA:
3743b725ae77Skettenis       tt_request = TT_PROC_WRDATA;
3744b725ae77Skettenis       break;
3745b725ae77Skettenis 
3746b725ae77Skettenis     case PT_CONTINUE:
3747b725ae77Skettenis       tt_request = TT_PROC_CONTINUE;
3748b725ae77Skettenis       break;
3749b725ae77Skettenis 
3750b725ae77Skettenis     case PT_STEP:
3751b725ae77Skettenis       tt_request = TT_LWP_SINGLE;	/* Should not be making this request? */
3752b725ae77Skettenis       break;
3753b725ae77Skettenis 
3754b725ae77Skettenis     case PT_KILL:
3755b725ae77Skettenis       tt_request = TT_PROC_EXIT;
3756b725ae77Skettenis       break;
3757b725ae77Skettenis 
3758b725ae77Skettenis     case PT_GET_PROCESS_PATHNAME:
3759b725ae77Skettenis       tt_request = TT_PROC_GET_PATHNAME;
3760b725ae77Skettenis       break;
3761b725ae77Skettenis 
3762b725ae77Skettenis     default:
3763b725ae77Skettenis       tt_request = pt_request;	/* Let ttrace be the one to complain. */
3764b725ae77Skettenis       break;
3765b725ae77Skettenis     }
3766b725ae77Skettenis 
3767b725ae77Skettenis   return call_ttrace (tt_request,
3768b725ae77Skettenis 		      gdb_tid,
3769b725ae77Skettenis 		      tt_addr,
3770b725ae77Skettenis 		      tt_data,
3771b725ae77Skettenis 		      tt_addr2);
3772b725ae77Skettenis }
3773b725ae77Skettenis 
3774b725ae77Skettenis /* Kill that pesky process!
3775b725ae77Skettenis  */
3776b725ae77Skettenis void
kill_inferior(void)3777b725ae77Skettenis kill_inferior (void)
3778b725ae77Skettenis {
3779b725ae77Skettenis   int tid;
3780b725ae77Skettenis   int wait_status;
3781b725ae77Skettenis   thread_info *t;
3782b725ae77Skettenis   thread_info **paranoia;
3783b725ae77Skettenis   int para_count, i;
3784b725ae77Skettenis 
3785b725ae77Skettenis   if (PIDGET (inferior_ptid) == 0)
3786b725ae77Skettenis     return;
3787b725ae77Skettenis 
3788b725ae77Skettenis   /* Walk the list of "threads", some of which are "pseudo threads",
3789b725ae77Skettenis      aka "processes".  For each that is NOT inferior_ptid, stop it,
3790b725ae77Skettenis      and detach it.
3791b725ae77Skettenis 
3792b725ae77Skettenis      You see, we may not have just a single process to kill.  If we're
3793b725ae77Skettenis      restarting or quitting or detaching just after the inferior has
3794b725ae77Skettenis      forked, then we've actually two processes to clean up.
3795b725ae77Skettenis 
3796b725ae77Skettenis      But we can't just call target_mourn_inferior() for each, since that
3797b725ae77Skettenis      zaps the target vector.
3798b725ae77Skettenis    */
3799b725ae77Skettenis 
3800b725ae77Skettenis   paranoia = (thread_info **) xmalloc (thread_head.count *
3801b725ae77Skettenis 				       sizeof (thread_info *));
3802b725ae77Skettenis   para_count = 0;
3803b725ae77Skettenis 
3804b725ae77Skettenis   t = thread_head.head;
3805b725ae77Skettenis   while (t)
3806b725ae77Skettenis     {
3807b725ae77Skettenis 
3808b725ae77Skettenis       paranoia[para_count] = t;
3809b725ae77Skettenis       for (i = 0; i < para_count; i++)
3810b725ae77Skettenis 	{
3811b725ae77Skettenis 	  if (t->next == paranoia[i])
3812b725ae77Skettenis 	    {
3813b725ae77Skettenis 	      warning ("Bad data in gdb's thread data; repairing.");
3814b725ae77Skettenis 	      t->next = 0;
3815b725ae77Skettenis 	    }
3816b725ae77Skettenis 	}
3817b725ae77Skettenis       para_count++;
3818b725ae77Skettenis 
3819b725ae77Skettenis       if (t->am_pseudo && (t->pid != PIDGET (inferior_ptid)))
3820b725ae77Skettenis 	{
3821b725ae77Skettenis 	  call_ttrace (TT_PROC_EXIT,
3822b725ae77Skettenis 		       t->pid,
3823b725ae77Skettenis 		       TT_NIL,
3824b725ae77Skettenis 		       TT_NIL,
3825b725ae77Skettenis 		       TT_NIL);
3826b725ae77Skettenis 	}
3827b725ae77Skettenis       t = t->next;
3828b725ae77Skettenis     }
3829b725ae77Skettenis 
3830b725ae77Skettenis   xfree (paranoia);
3831b725ae77Skettenis 
3832b725ae77Skettenis   call_ttrace (TT_PROC_EXIT,
3833b725ae77Skettenis 	       PIDGET (inferior_ptid),
3834b725ae77Skettenis 	       TT_NIL,
3835b725ae77Skettenis 	       TT_NIL,
3836b725ae77Skettenis 	       TT_NIL);
3837b725ae77Skettenis   target_mourn_inferior ();
3838b725ae77Skettenis   clear_thread_info ();
3839b725ae77Skettenis }
3840b725ae77Skettenis 
3841b725ae77Skettenis 
3842*11efff7fSkettenis #ifndef DEPRECATED_CHILD_RESUME
3843b725ae77Skettenis 
3844b725ae77Skettenis /* Sanity check a thread about to be continued.
3845b725ae77Skettenis  */
3846b725ae77Skettenis static void
thread_dropping_event_check(thread_info * p)3847b725ae77Skettenis thread_dropping_event_check (thread_info *p)
3848b725ae77Skettenis {
3849b725ae77Skettenis   if (!p->handled)
3850b725ae77Skettenis     {
3851b725ae77Skettenis       /*
3852b725ae77Skettenis        * This seems to happen when we "next" over a
3853b725ae77Skettenis        * "fork()" while following the parent.  If it's
3854b725ae77Skettenis        * the FORK event, that's ok.  If it's a SIGNAL
3855b725ae77Skettenis        * in the unfollowed child, that's ok to--but
3856b725ae77Skettenis        * how can we know that's what's going on?
3857b725ae77Skettenis        *
3858b725ae77Skettenis        * FIXME!
3859b725ae77Skettenis        */
3860b725ae77Skettenis       if (p->have_state)
3861b725ae77Skettenis 	{
3862b725ae77Skettenis 	  if (p->last_stop_state.tts_event == TTEVT_FORK)
3863b725ae77Skettenis 	    {
3864b725ae77Skettenis 	      /* Ok */
3865b725ae77Skettenis 	      ;
3866b725ae77Skettenis 	    }
3867b725ae77Skettenis 	  else if (p->last_stop_state.tts_event == TTEVT_SIGNAL)
3868b725ae77Skettenis 	    {
3869b725ae77Skettenis 	      /* Ok, close eyes and let it happen.
3870b725ae77Skettenis 	       */
3871b725ae77Skettenis 	      ;
3872b725ae77Skettenis 	    }
3873b725ae77Skettenis 	  else
3874b725ae77Skettenis 	    {
3875b725ae77Skettenis 	      /* This shouldn't happen--we're dropping a
3876b725ae77Skettenis 	       * real event.
3877b725ae77Skettenis 	       */
3878b725ae77Skettenis 	      warning ("About to continue process %d, thread %d with unhandled event %s.",
3879b725ae77Skettenis 		       p->pid, p->tid,
3880b725ae77Skettenis 		       get_printable_name_of_ttrace_event (
3881b725ae77Skettenis 					     p->last_stop_state.tts_event));
3882b725ae77Skettenis 
3883b725ae77Skettenis #ifdef PARANOIA
3884b725ae77Skettenis 	      if (debug_on)
3885b725ae77Skettenis 		print_tthread (p);
3886b725ae77Skettenis #endif
3887b725ae77Skettenis 	    }
3888b725ae77Skettenis 	}
3889b725ae77Skettenis       else
3890b725ae77Skettenis 	{
3891b725ae77Skettenis 	  /* No saved state, have to assume it failed.
3892b725ae77Skettenis 	   */
3893b725ae77Skettenis 	  warning ("About to continue process %d, thread %d with unhandled event.",
3894b725ae77Skettenis 		   p->pid, p->tid);
3895b725ae77Skettenis #ifdef PARANOIA
3896b725ae77Skettenis 	  if (debug_on)
3897b725ae77Skettenis 	    print_tthread (p);
3898b725ae77Skettenis #endif
3899b725ae77Skettenis 	}
3900b725ae77Skettenis     }
3901b725ae77Skettenis 
3902b725ae77Skettenis }				/* thread_dropping_event_check */
3903b725ae77Skettenis 
3904b725ae77Skettenis /* Use a loop over the threads to continue all the threads but
3905b725ae77Skettenis  * the one specified, which is to be stepped.
3906b725ae77Skettenis  */
3907b725ae77Skettenis static void
threads_continue_all_but_one(lwpid_t gdb_tid,int signal)3908b725ae77Skettenis threads_continue_all_but_one (lwpid_t gdb_tid, int signal)
3909b725ae77Skettenis {
3910b725ae77Skettenis   thread_info *p;
3911b725ae77Skettenis   int thread_signal;
3912b725ae77Skettenis   lwpid_t real_tid;
3913b725ae77Skettenis   lwpid_t scan_tid;
3914b725ae77Skettenis   ttstate_t state;
3915b725ae77Skettenis   int real_pid;
3916b725ae77Skettenis 
3917b725ae77Skettenis #ifdef THREAD_DEBUG
3918b725ae77Skettenis   if (debug_on)
3919b725ae77Skettenis     printf ("Using loop over threads to step/resume with signals\n");
3920b725ae77Skettenis #endif
3921b725ae77Skettenis 
3922b725ae77Skettenis   /* First update the thread list.
3923b725ae77Skettenis    */
3924b725ae77Skettenis   set_all_unseen ();
3925b725ae77Skettenis   real_tid = map_from_gdb_tid (gdb_tid);
3926b725ae77Skettenis   real_pid = get_pid_for (real_tid);
3927b725ae77Skettenis 
3928b725ae77Skettenis   scan_tid = get_process_first_stopped_thread_id (real_pid, &state);
3929b725ae77Skettenis   while (0 != scan_tid)
3930b725ae77Skettenis     {
3931b725ae77Skettenis 
3932b725ae77Skettenis #ifdef THREAD_DEBUG
3933b725ae77Skettenis       /* FIX: later should check state is stopped;
3934b725ae77Skettenis        * state.tts_flags & TTS_STATEMASK == TTS_WASSUSPENDED
3935b725ae77Skettenis        */
3936b725ae77Skettenis       if (debug_on)
3937b725ae77Skettenis  	if ((state.tts_flags & TTS_STATEMASK) != TTS_WASSUSPENDED)
3938b725ae77Skettenis 	  printf ("About to continue non-stopped thread %d\n", scan_tid);
3939b725ae77Skettenis #endif
3940b725ae77Skettenis 
3941b725ae77Skettenis       p = find_thread_info (scan_tid);
3942b725ae77Skettenis       if (NULL == p)
3943b725ae77Skettenis 	{
3944b725ae77Skettenis 	  add_tthread (real_pid, scan_tid);
3945b725ae77Skettenis 	  p = find_thread_info (scan_tid);
3946b725ae77Skettenis 
3947b725ae77Skettenis 	  /* This is either a newly-created thread or the
3948b725ae77Skettenis 	   * result of a fork; in either case there's no
3949b725ae77Skettenis 	   * actual event to worry about.
3950b725ae77Skettenis 	   */
3951b725ae77Skettenis 	  p->handled = 1;
3952b725ae77Skettenis 
3953b725ae77Skettenis 	  if (state.tts_event != TTEVT_NONE)
3954b725ae77Skettenis 	    {
3955b725ae77Skettenis 	      /* Oops, do need to worry!
3956b725ae77Skettenis 	       */
3957b725ae77Skettenis 	      warning ("Unexpected thread with \"%s\" event.",
3958b725ae77Skettenis 		       get_printable_name_of_ttrace_event (state.tts_event));
3959b725ae77Skettenis 	    }
3960b725ae77Skettenis 	}
3961b725ae77Skettenis       else if (scan_tid != p->tid)
3962b725ae77Skettenis 	error ("Bad data in thread database.");
3963b725ae77Skettenis 
3964b725ae77Skettenis #ifdef THREAD_DEBUG
3965b725ae77Skettenis       if (debug_on)
3966b725ae77Skettenis 	if (p->terminated)
3967b725ae77Skettenis 	  printf ("Why are we continuing a dead thread?\n");
3968b725ae77Skettenis #endif
3969b725ae77Skettenis 
3970b725ae77Skettenis       p->seen = 1;
3971b725ae77Skettenis 
3972b725ae77Skettenis       scan_tid = get_process_next_stopped_thread_id (real_pid, &state);
3973b725ae77Skettenis     }
3974b725ae77Skettenis 
3975b725ae77Skettenis   /* Remove unseen threads.
3976b725ae77Skettenis    */
3977b725ae77Skettenis   update_thread_list ();
3978b725ae77Skettenis 
3979b725ae77Skettenis   /* Now run down the thread list and continue or step.
3980b725ae77Skettenis    */
3981b725ae77Skettenis   for (p = thread_head.head; p; p = p->next)
3982b725ae77Skettenis     {
3983b725ae77Skettenis 
3984b725ae77Skettenis       /* Sanity check.
3985b725ae77Skettenis        */
3986b725ae77Skettenis       thread_dropping_event_check (p);
3987b725ae77Skettenis 
3988b725ae77Skettenis       /* Pass the correct signals along.
3989b725ae77Skettenis        */
3990b725ae77Skettenis       if (p->have_signal)
3991b725ae77Skettenis 	{
3992b725ae77Skettenis 	  thread_signal = p->signal_value;
3993b725ae77Skettenis 	  p->have_signal = 0;
3994b725ae77Skettenis 	}
3995b725ae77Skettenis       else
3996b725ae77Skettenis 	thread_signal = 0;
3997b725ae77Skettenis 
3998b725ae77Skettenis       if (p->tid != real_tid)
3999b725ae77Skettenis 	{
4000b725ae77Skettenis 	  /*
4001b725ae77Skettenis 	   * Not the thread of interest, so continue it
4002b725ae77Skettenis 	   * as the user expects.
4003b725ae77Skettenis 	   */
4004b725ae77Skettenis 	  if (p->stepping_mode == DO_STEP)
4005b725ae77Skettenis 	    {
4006b725ae77Skettenis 	      /* Just step this thread.
4007b725ae77Skettenis 	       */
4008b725ae77Skettenis 	      call_ttrace (
4009b725ae77Skettenis 			    TT_LWP_SINGLE,
4010b725ae77Skettenis 			    p->tid,
4011b725ae77Skettenis 			    TT_USE_CURRENT_PC,
4012b725ae77Skettenis 			    (TTRACE_ARG_TYPE) target_signal_to_host (signal),
4013b725ae77Skettenis 			    TT_NIL);
4014b725ae77Skettenis 	    }
4015b725ae77Skettenis 	  else
4016b725ae77Skettenis 	    {
4017b725ae77Skettenis 	      /* Regular continue (default case).
4018b725ae77Skettenis 	       */
4019b725ae77Skettenis 	      call_ttrace (
4020b725ae77Skettenis 			    TT_LWP_CONTINUE,
4021b725ae77Skettenis 			    p->tid,
4022b725ae77Skettenis 			    TT_USE_CURRENT_PC,
4023b725ae77Skettenis 		    (TTRACE_ARG_TYPE) target_signal_to_host (thread_signal),
4024b725ae77Skettenis 			    TT_NIL);
4025b725ae77Skettenis 	    }
4026b725ae77Skettenis 	}
4027b725ae77Skettenis       else
4028b725ae77Skettenis 	{
4029b725ae77Skettenis 	  /* Step the thread of interest.
4030b725ae77Skettenis 	   */
4031b725ae77Skettenis 	  call_ttrace (
4032b725ae77Skettenis 			TT_LWP_SINGLE,
4033b725ae77Skettenis 			real_tid,
4034b725ae77Skettenis 			TT_USE_CURRENT_PC,
4035b725ae77Skettenis 			(TTRACE_ARG_TYPE) target_signal_to_host (signal),
4036b725ae77Skettenis 			TT_NIL);
4037b725ae77Skettenis 	}
4038b725ae77Skettenis     }				/* Loop over threads */
4039b725ae77Skettenis }				/* End threads_continue_all_but_one */
4040b725ae77Skettenis 
4041b725ae77Skettenis /* Use a loop over the threads to continue all the threads.
4042b725ae77Skettenis  * This is done when a signal must be sent to any of the threads.
4043b725ae77Skettenis  */
4044b725ae77Skettenis static void
threads_continue_all_with_signals(lwpid_t gdb_tid,int signal)4045b725ae77Skettenis threads_continue_all_with_signals (lwpid_t gdb_tid, int signal)
4046b725ae77Skettenis {
4047b725ae77Skettenis   thread_info *p;
4048b725ae77Skettenis   int thread_signal;
4049b725ae77Skettenis   lwpid_t real_tid;
4050b725ae77Skettenis   lwpid_t scan_tid;
4051b725ae77Skettenis   ttstate_t state;
4052b725ae77Skettenis   int real_pid;
4053b725ae77Skettenis 
4054b725ae77Skettenis #ifdef THREAD_DEBUG
4055b725ae77Skettenis   if (debug_on)
4056b725ae77Skettenis     printf ("Using loop over threads to resume with signals\n");
4057b725ae77Skettenis #endif
4058b725ae77Skettenis 
4059b725ae77Skettenis   /* Scan and update thread list.
4060b725ae77Skettenis    */
4061b725ae77Skettenis   set_all_unseen ();
4062b725ae77Skettenis   real_tid = map_from_gdb_tid (gdb_tid);
4063b725ae77Skettenis   real_pid = get_pid_for (real_tid);
4064b725ae77Skettenis 
4065b725ae77Skettenis   scan_tid = get_process_first_stopped_thread_id (real_pid, &state);
4066b725ae77Skettenis   while (0 != scan_tid)
4067b725ae77Skettenis     {
4068b725ae77Skettenis 
4069b725ae77Skettenis #ifdef THREAD_DEBUG
4070b725ae77Skettenis       if (debug_on)
4071b725ae77Skettenis 	if ((state.tts_flags & TTS_STATEMASK) != TTS_WASSUSPENDED)
4072b725ae77Skettenis 	  warning ("About to continue non-stopped thread %d\n", scan_tid);
4073b725ae77Skettenis #endif
4074b725ae77Skettenis 
4075b725ae77Skettenis       p = find_thread_info (scan_tid);
4076b725ae77Skettenis       if (NULL == p)
4077b725ae77Skettenis 	{
4078b725ae77Skettenis 	  add_tthread (real_pid, scan_tid);
4079b725ae77Skettenis 	  p = find_thread_info (scan_tid);
4080b725ae77Skettenis 
4081b725ae77Skettenis 	  /* This is either a newly-created thread or the
4082b725ae77Skettenis 	   * result of a fork; in either case there's no
4083b725ae77Skettenis 	   * actual event to worry about.
4084b725ae77Skettenis 	   */
4085b725ae77Skettenis 	  p->handled = 1;
4086b725ae77Skettenis 
4087b725ae77Skettenis 	  if (state.tts_event != TTEVT_NONE)
4088b725ae77Skettenis 	    {
4089b725ae77Skettenis 	      /* Oops, do need to worry!
4090b725ae77Skettenis 	       */
4091b725ae77Skettenis 	      warning ("Unexpected thread with \"%s\" event.",
4092b725ae77Skettenis 		       get_printable_name_of_ttrace_event (state.tts_event));
4093b725ae77Skettenis 	    }
4094b725ae77Skettenis 	}
4095b725ae77Skettenis 
4096b725ae77Skettenis #ifdef THREAD_DEBUG
4097b725ae77Skettenis       if (debug_on)
4098b725ae77Skettenis 	if (p->terminated)
4099b725ae77Skettenis 	  printf ("Why are we continuing a dead thread? (1)\n");
4100b725ae77Skettenis #endif
4101b725ae77Skettenis 
4102b725ae77Skettenis       p->seen = 1;
4103b725ae77Skettenis 
4104b725ae77Skettenis       scan_tid = get_process_next_stopped_thread_id (real_pid, &state);
4105b725ae77Skettenis     }
4106b725ae77Skettenis 
4107b725ae77Skettenis   /* Remove unseen threads from our list.
4108b725ae77Skettenis    */
4109b725ae77Skettenis   update_thread_list ();
4110b725ae77Skettenis 
4111b725ae77Skettenis   /* Continue the threads.
4112b725ae77Skettenis    */
4113b725ae77Skettenis   for (p = thread_head.head; p; p = p->next)
4114b725ae77Skettenis     {
4115b725ae77Skettenis 
4116b725ae77Skettenis       /* Sanity check.
4117b725ae77Skettenis        */
4118b725ae77Skettenis       thread_dropping_event_check (p);
4119b725ae77Skettenis 
4120b725ae77Skettenis       /* Pass the correct signals along.
4121b725ae77Skettenis        */
4122b725ae77Skettenis       if (p->tid == real_tid)
4123b725ae77Skettenis 	{
4124b725ae77Skettenis 	  thread_signal = signal;
4125b725ae77Skettenis 	  p->have_signal = 0;
4126b725ae77Skettenis 	}
4127b725ae77Skettenis       else if (p->have_signal)
4128b725ae77Skettenis 	{
4129b725ae77Skettenis 	  thread_signal = p->signal_value;
4130b725ae77Skettenis 	  p->have_signal = 0;
4131b725ae77Skettenis 	}
4132b725ae77Skettenis       else
4133b725ae77Skettenis 	thread_signal = 0;
4134b725ae77Skettenis 
4135b725ae77Skettenis       if (p->stepping_mode == DO_STEP)
4136b725ae77Skettenis 	{
4137b725ae77Skettenis 	  call_ttrace (
4138b725ae77Skettenis 			TT_LWP_SINGLE,
4139b725ae77Skettenis 			p->tid,
4140b725ae77Skettenis 			TT_USE_CURRENT_PC,
4141b725ae77Skettenis 			(TTRACE_ARG_TYPE) target_signal_to_host (signal),
4142b725ae77Skettenis 			TT_NIL);
4143b725ae77Skettenis 	}
4144b725ae77Skettenis       else
4145b725ae77Skettenis 	{
4146b725ae77Skettenis 	  /* Continue this thread (default case).
4147b725ae77Skettenis 	   */
4148b725ae77Skettenis 	  call_ttrace (
4149b725ae77Skettenis 			TT_LWP_CONTINUE,
4150b725ae77Skettenis 			p->tid,
4151b725ae77Skettenis 			TT_USE_CURRENT_PC,
4152b725ae77Skettenis 		    (TTRACE_ARG_TYPE) target_signal_to_host (thread_signal),
4153b725ae77Skettenis 			TT_NIL);
4154b725ae77Skettenis 	}
4155b725ae77Skettenis     }
4156b725ae77Skettenis }				/* End threads_continue_all_with_signals */
4157b725ae77Skettenis 
4158b725ae77Skettenis /* Step one thread only.
4159b725ae77Skettenis  */
4160b725ae77Skettenis static void
thread_fake_step(lwpid_t tid,enum target_signal signal)4161b725ae77Skettenis thread_fake_step (lwpid_t tid, enum target_signal signal)
4162b725ae77Skettenis {
4163b725ae77Skettenis   thread_info *p;
4164b725ae77Skettenis 
4165b725ae77Skettenis #ifdef THREAD_DEBUG
4166b725ae77Skettenis   if (debug_on)
4167b725ae77Skettenis     {
4168b725ae77Skettenis       printf ("Doing a fake-step over a bpt, etc. for %d\n", tid);
4169b725ae77Skettenis 
4170b725ae77Skettenis       if (is_terminated (tid))
4171b725ae77Skettenis 	printf ("Why are we continuing a dead thread? (4)\n");
4172b725ae77Skettenis     }
4173b725ae77Skettenis #endif
4174b725ae77Skettenis 
4175b725ae77Skettenis   if (doing_fake_step)
4176b725ae77Skettenis     warning ("Step while step already in progress.");
4177b725ae77Skettenis 
4178b725ae77Skettenis   /* See if there's a saved signal value for this
4179b725ae77Skettenis    * thread to be passed on, but no current signal.
4180b725ae77Skettenis    */
4181b725ae77Skettenis   p = find_thread_info (tid);
4182b725ae77Skettenis   if (p != NULL)
4183b725ae77Skettenis     {
4184b725ae77Skettenis       if (p->have_signal && signal == TARGET_SIGNAL_0)
4185b725ae77Skettenis 	{
4186b725ae77Skettenis 	  /* Pass on a saved signal.
4187b725ae77Skettenis 	   */
4188b725ae77Skettenis 	  signal = p->signal_value;
4189b725ae77Skettenis 	}
4190b725ae77Skettenis 
4191b725ae77Skettenis       p->have_signal = 0;
4192b725ae77Skettenis     }
4193b725ae77Skettenis 
4194b725ae77Skettenis   if (!p->handled)
4195b725ae77Skettenis     warning ("Internal error: continuing unhandled thread.");
4196b725ae77Skettenis 
4197b725ae77Skettenis   call_ttrace (TT_LWP_SINGLE,
4198b725ae77Skettenis 	       tid,
4199b725ae77Skettenis 	       TT_USE_CURRENT_PC,
4200b725ae77Skettenis 	       (TTRACE_ARG_TYPE) target_signal_to_host (signal),
4201b725ae77Skettenis 	       TT_NIL);
4202b725ae77Skettenis 
4203b725ae77Skettenis   /* Do bookkeeping so "call_ttrace_wait" knows it has to wait
4204b725ae77Skettenis    * for this thread only, and clear any saved signal info.
4205b725ae77Skettenis    */
4206b725ae77Skettenis   doing_fake_step = 1;
4207b725ae77Skettenis   fake_step_tid = tid;
4208b725ae77Skettenis 
4209b725ae77Skettenis }				/* End thread_fake_step */
4210b725ae77Skettenis 
4211b725ae77Skettenis /* Continue one thread when a signal must be sent to it.
4212b725ae77Skettenis  */
4213b725ae77Skettenis static void
threads_continue_one_with_signal(lwpid_t gdb_tid,int signal)4214b725ae77Skettenis threads_continue_one_with_signal (lwpid_t gdb_tid, int signal)
4215b725ae77Skettenis {
4216b725ae77Skettenis   thread_info *p;
4217b725ae77Skettenis   lwpid_t real_tid;
4218b725ae77Skettenis   int real_pid;
4219b725ae77Skettenis 
4220b725ae77Skettenis #ifdef THREAD_DEBUG
4221b725ae77Skettenis   if (debug_on)
4222b725ae77Skettenis     printf ("Continuing one thread with a signal\n");
4223b725ae77Skettenis #endif
4224b725ae77Skettenis 
4225b725ae77Skettenis   real_tid = map_from_gdb_tid (gdb_tid);
4226b725ae77Skettenis   real_pid = get_pid_for (real_tid);
4227b725ae77Skettenis 
4228b725ae77Skettenis   p = find_thread_info (real_tid);
4229b725ae77Skettenis   if (NULL == p)
4230b725ae77Skettenis     {
4231b725ae77Skettenis       add_tthread (real_pid, real_tid);
4232b725ae77Skettenis     }
4233b725ae77Skettenis 
4234b725ae77Skettenis #ifdef THREAD_DEBUG
4235b725ae77Skettenis   if (debug_on)
4236b725ae77Skettenis     if (p->terminated)
4237b725ae77Skettenis       printf ("Why are we continuing a dead thread? (2)\n");
4238b725ae77Skettenis #endif
4239b725ae77Skettenis 
4240b725ae77Skettenis   if (!p->handled)
4241b725ae77Skettenis     warning ("Internal error: continuing unhandled thread.");
4242b725ae77Skettenis 
4243b725ae77Skettenis   p->have_signal = 0;
4244b725ae77Skettenis 
4245b725ae77Skettenis   call_ttrace (TT_LWP_CONTINUE,
4246b725ae77Skettenis 	       gdb_tid,
4247b725ae77Skettenis 	       TT_USE_CURRENT_PC,
4248b725ae77Skettenis 	       (TTRACE_ARG_TYPE) target_signal_to_host (signal),
4249b725ae77Skettenis 	       TT_NIL);
4250b725ae77Skettenis }
4251b725ae77Skettenis #endif
4252b725ae77Skettenis 
4253*11efff7fSkettenis #ifndef DEPRECATED_CHILD_RESUME
4254b725ae77Skettenis 
4255b725ae77Skettenis /* Resume execution of the inferior process.
4256b725ae77Skettenis 
4257b725ae77Skettenis  * This routine is in charge of setting the "handled" bits.
4258b725ae77Skettenis  *
4259b725ae77Skettenis  *   If STEP is zero,      continue it.
4260b725ae77Skettenis  *   If STEP is nonzero,   single-step it.
4261b725ae77Skettenis  *
4262b725ae77Skettenis  *   If SIGNAL is nonzero, give it that signal.
4263b725ae77Skettenis  *
4264b725ae77Skettenis  *   If TID is -1,         apply to all threads.
4265b725ae77Skettenis  *   If TID is not -1,     apply to specified thread.
4266b725ae77Skettenis  *
4267b725ae77Skettenis  *           STEP
4268b725ae77Skettenis  *      \      !0                        0
4269b725ae77Skettenis  *  TID  \________________________________________________
4270b725ae77Skettenis  *       |
4271b725ae77Skettenis  *   -1  |   Step current            Continue all threads
4272b725ae77Skettenis  *       |   thread and              (but which gets any
4273b725ae77Skettenis  *       |   continue others         signal?--We look at
4274b725ae77Skettenis  *       |                           "inferior_ptid")
4275b725ae77Skettenis  *       |
4276b725ae77Skettenis  *    N  |   Step _this_ thread      Continue _this_ thread
4277b725ae77Skettenis  *       |   and leave others        and leave others
4278b725ae77Skettenis  *       |   stopped; internally     stopped; used only for
4279b725ae77Skettenis  *       |   used by gdb, never      hardware watchpoints
4280b725ae77Skettenis  *       |   a user command.         and attach, never a
4281b725ae77Skettenis  *       |                           user command.
4282b725ae77Skettenis  */
4283b725ae77Skettenis void
child_resume(ptid_t ptid,int step,enum target_signal signal)4284b725ae77Skettenis child_resume (ptid_t ptid, int step, enum target_signal signal)
4285b725ae77Skettenis {
4286b725ae77Skettenis   int resume_all_threads;
4287b725ae77Skettenis   lwpid_t tid;
4288b725ae77Skettenis   process_state_t new_process_state;
4289b725ae77Skettenis   lwpid_t gdb_tid = PIDGET (ptid);
4290b725ae77Skettenis 
4291b725ae77Skettenis   resume_all_threads =
4292b725ae77Skettenis     (gdb_tid == INFTTRACE_ALL_THREADS) ||
4293b725ae77Skettenis     (vfork_in_flight);
4294b725ae77Skettenis 
4295b725ae77Skettenis   if (resume_all_threads)
4296b725ae77Skettenis     {
4297b725ae77Skettenis       /* Resume all threads, but first pick a tid value
4298b725ae77Skettenis        * so we can get the pid when in call_ttrace doing
4299b725ae77Skettenis        * the map.
4300b725ae77Skettenis        */
4301b725ae77Skettenis       if (vfork_in_flight)
4302b725ae77Skettenis 	tid = vforking_child_pid;
4303b725ae77Skettenis       else
4304b725ae77Skettenis 	tid = map_from_gdb_tid (PIDGET (inferior_ptid));
4305b725ae77Skettenis     }
4306b725ae77Skettenis   else
4307b725ae77Skettenis     tid = map_from_gdb_tid (gdb_tid);
4308b725ae77Skettenis 
4309b725ae77Skettenis #ifdef THREAD_DEBUG
4310b725ae77Skettenis   if (debug_on)
4311b725ae77Skettenis     {
4312b725ae77Skettenis       if (more_events_left)
4313b725ae77Skettenis 	printf ("More events; ");
4314b725ae77Skettenis 
4315b725ae77Skettenis       if (signal != 0)
4316b725ae77Skettenis 	printf ("Sending signal %d; ", signal);
4317b725ae77Skettenis 
4318b725ae77Skettenis       if (resume_all_threads)
4319b725ae77Skettenis 	{
4320b725ae77Skettenis 	  if (step == 0)
4321b725ae77Skettenis 	    printf ("Continue process %d\n", tid);
4322b725ae77Skettenis 	  else
4323b725ae77Skettenis 	    printf ("Step/continue thread %d\n", tid);
4324b725ae77Skettenis 	}
4325b725ae77Skettenis       else
4326b725ae77Skettenis 	{
4327b725ae77Skettenis 	  if (step == 0)
4328b725ae77Skettenis 	    printf ("Continue thread %d\n", tid);
4329b725ae77Skettenis 	  else
4330b725ae77Skettenis 	    printf ("Step just thread %d\n", tid);
4331b725ae77Skettenis 	}
4332b725ae77Skettenis 
4333b725ae77Skettenis       if (vfork_in_flight)
4334b725ae77Skettenis 	printf ("Vfork in flight\n");
4335b725ae77Skettenis     }
4336b725ae77Skettenis #endif
4337b725ae77Skettenis 
4338b725ae77Skettenis   if (process_state == RUNNING)
4339b725ae77Skettenis     warning ("Internal error in resume logic; doing resume or step anyway.");
4340b725ae77Skettenis 
4341b725ae77Skettenis   if (!step			/* Asked to continue...       */
4342b725ae77Skettenis       && resume_all_threads	/* whole process..            */
4343b725ae77Skettenis       && signal != 0		/* with a signal...           */
4344b725ae77Skettenis       && more_events_left > 0)
4345b725ae77Skettenis     {				/* but we can't yet--save it! */
4346b725ae77Skettenis 
4347b725ae77Skettenis       /* Continue with signal means we have to set the pending
4348b725ae77Skettenis        * signal value for this thread.
4349b725ae77Skettenis        */
4350b725ae77Skettenis       thread_info *k;
4351b725ae77Skettenis 
4352b725ae77Skettenis #ifdef THREAD_DEBUG
4353b725ae77Skettenis       if (debug_on)
4354b725ae77Skettenis 	printf ("Saving signal %d for thread %d\n", signal, tid);
4355b725ae77Skettenis #endif
4356b725ae77Skettenis 
4357b725ae77Skettenis       k = find_thread_info (tid);
4358b725ae77Skettenis       if (k != NULL)
4359b725ae77Skettenis 	{
4360b725ae77Skettenis 	  k->have_signal = 1;
4361b725ae77Skettenis 	  k->signal_value = signal;
4362b725ae77Skettenis 
4363b725ae77Skettenis #ifdef THREAD_DEBUG
4364b725ae77Skettenis 	  if (debug_on)
4365b725ae77Skettenis 	    if (k->terminated)
4366b725ae77Skettenis 	      printf ("Why are we continuing a dead thread? (3)\n");
4367b725ae77Skettenis #endif
4368b725ae77Skettenis 
4369b725ae77Skettenis 	}
4370b725ae77Skettenis 
4371b725ae77Skettenis #ifdef THREAD_DEBUG
4372b725ae77Skettenis       else if (debug_on)
4373b725ae77Skettenis 	{
4374b725ae77Skettenis 	  printf ("No thread info for tid %d\n", tid);
4375b725ae77Skettenis 	}
4376b725ae77Skettenis #endif
4377b725ae77Skettenis     }
4378b725ae77Skettenis 
4379b725ae77Skettenis   /* Are we faking this "continue" or "step"?
4380b725ae77Skettenis 
4381b725ae77Skettenis    * We used to do steps by continuing all the threads for
4382b725ae77Skettenis    * which the events had been handled already.  While
4383b725ae77Skettenis    * conceptually nicer (hides it all in a lower level), this
4384b725ae77Skettenis    * can lead to starvation and a hang (e.g. all but one thread
4385b725ae77Skettenis    * are unhandled at a breakpoint just before a "join" operation,
4386b725ae77Skettenis    * and one thread is in the join, and the user wants to step that
4387b725ae77Skettenis    * thread).
4388b725ae77Skettenis    */
4389b725ae77Skettenis   if (resume_all_threads	/* Whole process, therefore user command */
4390b725ae77Skettenis       && more_events_left > 0)
4391b725ae77Skettenis     {				/* But we can't do this yet--fake it! */
4392b725ae77Skettenis       thread_info *p;
4393b725ae77Skettenis 
4394b725ae77Skettenis       if (!step)
4395b725ae77Skettenis 	{
4396b725ae77Skettenis 	  /* No need to do any notes on a per-thread
4397b725ae77Skettenis 	   * basis--we're done!
4398b725ae77Skettenis 	   */
4399b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
4400b725ae77Skettenis 	  if (debug_on)
4401b725ae77Skettenis 	    printf ("Faking a process resume.\n");
4402b725ae77Skettenis #endif
4403b725ae77Skettenis 
4404b725ae77Skettenis 	  return;
4405b725ae77Skettenis 	}
4406b725ae77Skettenis       else
4407b725ae77Skettenis 	{
4408b725ae77Skettenis 
4409b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
4410b725ae77Skettenis 	  if (debug_on)
4411b725ae77Skettenis 	    printf ("Faking a process step.\n");
4412b725ae77Skettenis #endif
4413b725ae77Skettenis 
4414b725ae77Skettenis 	}
4415b725ae77Skettenis 
4416b725ae77Skettenis       p = find_thread_info (tid);
4417b725ae77Skettenis       if (p == NULL)
4418b725ae77Skettenis 	{
4419b725ae77Skettenis 	  warning ("No thread information for tid %d, 'next' command ignored.\n", tid);
4420b725ae77Skettenis 	  return;
4421b725ae77Skettenis 	}
4422b725ae77Skettenis       else
4423b725ae77Skettenis 	{
4424b725ae77Skettenis 
4425b725ae77Skettenis #ifdef THREAD_DEBUG
4426b725ae77Skettenis 	  if (debug_on)
4427b725ae77Skettenis 	    if (p->terminated)
4428b725ae77Skettenis 	      printf ("Why are we continuing a dead thread? (3.5)\n");
4429b725ae77Skettenis #endif
4430b725ae77Skettenis 
4431b725ae77Skettenis 	  if (p->stepping_mode != DO_DEFAULT)
4432b725ae77Skettenis 	    {
4433b725ae77Skettenis 	      warning ("Step or continue command applied to thread which is already stepping or continuing; command ignored.");
4434b725ae77Skettenis 
4435b725ae77Skettenis 	      return;
4436b725ae77Skettenis 	    }
4437b725ae77Skettenis 
4438b725ae77Skettenis 	  if (step)
4439b725ae77Skettenis 	    p->stepping_mode = DO_STEP;
4440b725ae77Skettenis 	  else
4441b725ae77Skettenis 	    p->stepping_mode = DO_CONTINUE;
4442b725ae77Skettenis 
4443b725ae77Skettenis 	  return;
4444b725ae77Skettenis 	}			/* Have thread info */
4445b725ae77Skettenis     }				/* Must fake step or go */
4446b725ae77Skettenis 
4447b725ae77Skettenis   /* Execept for fake-steps, from here on we know we are
4448b725ae77Skettenis    * going to wind up with a running process which will
4449b725ae77Skettenis    * need a real wait.
4450b725ae77Skettenis    */
4451b725ae77Skettenis   new_process_state = RUNNING;
4452b725ae77Skettenis 
4453b725ae77Skettenis   /* An address of TT_USE_CURRENT_PC tells ttrace to continue from where
4454b725ae77Skettenis    * it was.  (If GDB wanted it to start some other way, we have already
4455b725ae77Skettenis    * written a new PC value to the child.)
4456b725ae77Skettenis    *
4457b725ae77Skettenis    * If this system does not support PT_STEP, a higher level function will
4458b725ae77Skettenis    * have called single_step() to transmute the step request into a
4459b725ae77Skettenis    * continue request (by setting breakpoints on all possible successor
4460b725ae77Skettenis    * instructions), so we don't have to worry about that here.
4461b725ae77Skettenis    */
4462b725ae77Skettenis   if (step)
4463b725ae77Skettenis     {
4464b725ae77Skettenis       if (resume_all_threads)
4465b725ae77Skettenis 	{
4466b725ae77Skettenis 	  /*
4467b725ae77Skettenis 	   * Regular user step: other threads get a "continue".
4468b725ae77Skettenis 	   */
4469b725ae77Skettenis 	  threads_continue_all_but_one (tid, signal);
4470b725ae77Skettenis 	  clear_all_handled ();
4471b725ae77Skettenis 	  clear_all_stepping_mode ();
4472b725ae77Skettenis 	}
4473b725ae77Skettenis 
4474b725ae77Skettenis       else
4475b725ae77Skettenis 	{
4476b725ae77Skettenis 	  /* "Fake step": gdb is stepping one thread over a
4477b725ae77Skettenis 	   * breakpoint, watchpoint, or out of a library load
4478b725ae77Skettenis 	   * event, etc.  The rest just stay where they are.
4479b725ae77Skettenis 	   *
4480b725ae77Skettenis 	   * Also used when there are pending events: we really
4481b725ae77Skettenis 	   * step the current thread, but leave the rest stopped.
4482b725ae77Skettenis 	   * Users can't request this, but "wait_for_inferior"
4483b725ae77Skettenis 	   * does--a lot!
4484b725ae77Skettenis 	   */
4485b725ae77Skettenis 	  thread_fake_step (tid, signal);
4486b725ae77Skettenis 
4487b725ae77Skettenis 	  /* Clear the "handled" state of this thread, because
4488b725ae77Skettenis 	   * we'll soon get a new event for it.  Other events
4489b725ae77Skettenis 	   * stay as they were.
4490b725ae77Skettenis 	   */
4491b725ae77Skettenis 	  clear_handled (tid);
4492b725ae77Skettenis 	  clear_stepping_mode (tid);
4493b725ae77Skettenis 	  new_process_state = FAKE_STEPPING;
4494b725ae77Skettenis 	}
4495b725ae77Skettenis     }
4496b725ae77Skettenis 
4497b725ae77Skettenis   else
4498b725ae77Skettenis     {
4499b725ae77Skettenis       /* TT_LWP_CONTINUE can pass signals to threads, TT_PROC_CONTINUE can't.
4500b725ae77Skettenis 	 Therefore, we really can't use TT_PROC_CONTINUE here.
4501b725ae77Skettenis 
4502b725ae77Skettenis 	 Consider a process which stopped due to signal which gdb decides
4503b725ae77Skettenis 	 to handle and not pass on to the inferior.  In that case we must
4504b725ae77Skettenis 	 clear the pending signal by restarting the inferior using
4505b725ae77Skettenis 	 TT_LWP_CONTINUE and pass zero as the signal number.  Else the
4506b725ae77Skettenis 	 pending signal will be passed to the inferior.  interrupt.exp
4507b725ae77Skettenis 	 in the testsuite does this precise thing and fails due to the
4508b725ae77Skettenis 	 unwanted signal delivery to the inferior.  */
4509b725ae77Skettenis       /* drow/2002-12-05: However, note that we must use TT_PROC_CONTINUE
4510b725ae77Skettenis 	 if we are tracing a vfork.  */
4511b725ae77Skettenis       if (vfork_in_flight)
4512b725ae77Skettenis 	{
4513b725ae77Skettenis 	  call_ttrace (TT_PROC_CONTINUE, tid, TT_NIL, TT_NIL, TT_NIL);
4514b725ae77Skettenis 	  clear_all_handled ();
4515b725ae77Skettenis 	  clear_all_stepping_mode ();
4516b725ae77Skettenis 	}
4517b725ae77Skettenis       else if (resume_all_threads)
4518b725ae77Skettenis 	{
4519b725ae77Skettenis #ifdef THREAD_DEBUG
4520b725ae77Skettenis 	  if (debug_on)
4521b725ae77Skettenis 	    printf ("Doing a continue by loop of all threads\n");
4522b725ae77Skettenis #endif
4523b725ae77Skettenis 
4524b725ae77Skettenis 	  threads_continue_all_with_signals (tid, signal);
4525b725ae77Skettenis 
4526b725ae77Skettenis 	  clear_all_handled ();
4527b725ae77Skettenis 	  clear_all_stepping_mode ();
4528b725ae77Skettenis 	}
4529b725ae77Skettenis       else
4530b725ae77Skettenis 	{
4531b725ae77Skettenis #ifdef THREAD_DEBUG
4532b725ae77Skettenis 	  printf ("Doing a continue w/signal of just thread %d\n", tid);
4533b725ae77Skettenis #endif
4534b725ae77Skettenis 
4535b725ae77Skettenis 	  threads_continue_one_with_signal (tid, signal);
4536b725ae77Skettenis 
4537b725ae77Skettenis 	  /* Clear the "handled" state of this thread, because we
4538b725ae77Skettenis 	     will soon get a new event for it.  Other events can
4539b725ae77Skettenis 	     stay as they were.  */
4540b725ae77Skettenis 	  clear_handled (tid);
4541b725ae77Skettenis 	  clear_stepping_mode (tid);
4542b725ae77Skettenis 	}
4543b725ae77Skettenis     }
4544b725ae77Skettenis 
4545b725ae77Skettenis   process_state = new_process_state;
4546b725ae77Skettenis 
4547b725ae77Skettenis #ifdef WAIT_BUFFER_DEBUG
4548b725ae77Skettenis   if (debug_on)
4549b725ae77Skettenis     printf ("Process set to %s\n",
4550b725ae77Skettenis 	    get_printable_name_of_process_state (process_state));
4551b725ae77Skettenis #endif
4552b725ae77Skettenis 
4553b725ae77Skettenis }
4554*11efff7fSkettenis #endif /* DEPRECATED_CHILD_RESUME */
4555b725ae77Skettenis 
4556b725ae77Skettenis /*
4557b725ae77Skettenis  * Like it says.
4558b725ae77Skettenis  *
4559b725ae77Skettenis  * One worry is that we may not be attaching to "inferior_ptid"
4560b725ae77Skettenis  * and thus may not want to clear out our data.  FIXME?
4561b725ae77Skettenis  *
4562b725ae77Skettenis  */
4563b725ae77Skettenis static void
update_thread_state_after_attach(int pid,attach_continue_t kind_of_go)4564b725ae77Skettenis update_thread_state_after_attach (int pid, attach_continue_t kind_of_go)
4565b725ae77Skettenis {
4566b725ae77Skettenis   int tt_status;
4567b725ae77Skettenis   ttstate_t thread_state;
4568b725ae77Skettenis   lwpid_t a_thread;
4569b725ae77Skettenis   lwpid_t tid;
4570b725ae77Skettenis 
4571b725ae77Skettenis   /* The process better be stopped.
4572b725ae77Skettenis    */
4573b725ae77Skettenis   if (process_state != STOPPED
4574b725ae77Skettenis       && process_state != VFORKING)
4575b725ae77Skettenis     warning ("Internal error attaching.");
4576b725ae77Skettenis 
4577b725ae77Skettenis   /* Clear out old tthread info and start over.  This has the
4578b725ae77Skettenis    * side effect of ensuring that the TRAP is reported as being
4579b725ae77Skettenis    * in the right thread (re-mapped from tid to pid).
4580b725ae77Skettenis    *
4581b725ae77Skettenis    * It's because we need to add the tthread _now_ that we
4582b725ae77Skettenis    * need to call "clear_thread_info" _now_, and that's why
4583b725ae77Skettenis    * "require_notification_of_events" doesn't clear the thread
4584b725ae77Skettenis    * info (it's called later than this routine).
4585b725ae77Skettenis    */
4586b725ae77Skettenis   clear_thread_info ();
4587b725ae77Skettenis   a_thread = 0;
4588b725ae77Skettenis 
4589b725ae77Skettenis   for (tid = get_process_first_stopped_thread_id (pid, &thread_state);
4590b725ae77Skettenis        tid != 0;
4591b725ae77Skettenis        tid = get_process_next_stopped_thread_id (pid, &thread_state))
4592b725ae77Skettenis     {
4593b725ae77Skettenis       thread_info *p;
4594b725ae77Skettenis 
4595b725ae77Skettenis       if (a_thread == 0)
4596b725ae77Skettenis 	{
4597b725ae77Skettenis 	  a_thread = tid;
4598b725ae77Skettenis #ifdef THREAD_DEBUG
4599b725ae77Skettenis 	  if (debug_on)
4600b725ae77Skettenis 	    printf ("Attaching to process %d, thread %d\n",
4601b725ae77Skettenis 		    pid, a_thread);
4602b725ae77Skettenis #endif
4603b725ae77Skettenis 	}
4604b725ae77Skettenis 
4605b725ae77Skettenis       /* Tell ourselves and the "rest of gdb" that this thread
4606b725ae77Skettenis        * exists.
4607b725ae77Skettenis        *
4608b725ae77Skettenis        * This isn't really a hack.  Other thread-based versions
4609b725ae77Skettenis        * of gdb (e.g. gnu-nat.c) seem to do the same thing.
4610b725ae77Skettenis        *
4611b725ae77Skettenis        * We don't need to do mapping here, as we know this
4612b725ae77Skettenis        * is the first thread and thus gets the real pid
4613b725ae77Skettenis        * (and is "inferior_ptid").
4614b725ae77Skettenis        *
4615b725ae77Skettenis        * NOTE: it probably isn't the originating thread,
4616b725ae77Skettenis        *       but that doesn't matter (we hope!).
4617b725ae77Skettenis        */
4618b725ae77Skettenis       add_tthread (pid, tid);
4619b725ae77Skettenis       p = find_thread_info (tid);
4620b725ae77Skettenis       if (NULL == p)		/* ?We just added it! */
4621b725ae77Skettenis 	error ("Internal error adding a thread on attach.");
4622b725ae77Skettenis 
4623b725ae77Skettenis       copy_ttstate_t (&p->last_stop_state, &thread_state);
4624b725ae77Skettenis       p->have_state = 1;
4625b725ae77Skettenis 
4626b725ae77Skettenis       if (DO_ATTACH_CONTINUE == kind_of_go)
4627b725ae77Skettenis 	{
4628b725ae77Skettenis 	  /*
4629b725ae77Skettenis 	   * If we are going to CONTINUE afterwards,
4630b725ae77Skettenis 	   * raising a SIGTRAP, don't bother trying to
4631b725ae77Skettenis 	   * handle this event.  But check first!
4632b725ae77Skettenis 	   */
4633b725ae77Skettenis 	  switch (p->last_stop_state.tts_event)
4634b725ae77Skettenis 	    {
4635b725ae77Skettenis 
4636b725ae77Skettenis 	    case TTEVT_NONE:
4637b725ae77Skettenis 	      /* Ok to set this handled.
4638b725ae77Skettenis 	       */
4639b725ae77Skettenis 	      break;
4640b725ae77Skettenis 
4641b725ae77Skettenis 	    default:
4642b725ae77Skettenis 	      warning ("Internal error; skipping event %s on process %d, thread %d.",
4643b725ae77Skettenis 		       get_printable_name_of_ttrace_event (
4644b725ae77Skettenis 					      p->last_stop_state.tts_event),
4645b725ae77Skettenis 		       p->pid, p->tid);
4646b725ae77Skettenis 	    }
4647b725ae77Skettenis 
4648b725ae77Skettenis 	  set_handled (pid, tid);
4649b725ae77Skettenis 
4650b725ae77Skettenis 	}
4651b725ae77Skettenis       else
4652b725ae77Skettenis 	{
4653b725ae77Skettenis 	  /* There will be no "continue" opertion, so the
4654b725ae77Skettenis 	   * process remains stopped.  Don't set any events
4655b725ae77Skettenis 	   * handled except the "gimmies".
4656b725ae77Skettenis 	   */
4657b725ae77Skettenis 	  switch (p->last_stop_state.tts_event)
4658b725ae77Skettenis 	    {
4659b725ae77Skettenis 
4660b725ae77Skettenis 	    case TTEVT_NONE:
4661b725ae77Skettenis 	      /* Ok to ignore this.
4662b725ae77Skettenis 	       */
4663b725ae77Skettenis 	      set_handled (pid, tid);
4664b725ae77Skettenis 	      break;
4665b725ae77Skettenis 
4666b725ae77Skettenis 	    case TTEVT_EXEC:
4667b725ae77Skettenis 	    case TTEVT_FORK:
4668b725ae77Skettenis 	      /* Expected "other" FORK or EXEC event from a
4669b725ae77Skettenis 	       * fork or vfork.
4670b725ae77Skettenis 	       */
4671b725ae77Skettenis 	      break;
4672b725ae77Skettenis 
4673b725ae77Skettenis 	    default:
4674b725ae77Skettenis 	      printf ("Internal error: failed to handle event %s on process %d, thread %d.",
4675b725ae77Skettenis 		      get_printable_name_of_ttrace_event (
4676b725ae77Skettenis 					      p->last_stop_state.tts_event),
4677b725ae77Skettenis 		      p->pid, p->tid);
4678b725ae77Skettenis 	    }
4679b725ae77Skettenis 	}
4680b725ae77Skettenis 
4681b725ae77Skettenis       add_thread (pid_to_ptid (pid));		/* in thread.c */
4682b725ae77Skettenis     }
4683b725ae77Skettenis 
4684b725ae77Skettenis #ifdef PARANOIA
4685b725ae77Skettenis   if (debug_on)
4686b725ae77Skettenis     print_tthreads ();
4687b725ae77Skettenis #endif
4688b725ae77Skettenis 
4689b725ae77Skettenis   /* One mustn't call ttrace_wait() after attaching via ttrace,
4690b725ae77Skettenis      'cause the process is stopped already.
4691b725ae77Skettenis 
4692b725ae77Skettenis      However, the upper layers of gdb's execution control will
4693b725ae77Skettenis      want to wait after attaching (but not after forks, in
4694b725ae77Skettenis      which case they will be doing a "target_resume", anticipating
4695b725ae77Skettenis      a later TTEVT_EXEC or TTEVT_FORK event).
4696b725ae77Skettenis 
4697b725ae77Skettenis      To make this attach() implementation more compatible with
4698b725ae77Skettenis      others, we'll make the attached-to process raise a SIGTRAP.
4699b725ae77Skettenis 
4700b725ae77Skettenis      Issue: this continues only one thread.  That could be
4701b725ae77Skettenis      dangerous if the thread is blocked--the process won't run
4702b725ae77Skettenis      and no trap will be raised.  FIX! (check state.tts_flags?
4703b725ae77Skettenis      need one that's either TTS_WASRUNNING--but we've stopped
4704b725ae77Skettenis      it and made it TTS_WASSUSPENDED.  Hum...FIXME!)
4705b725ae77Skettenis    */
4706b725ae77Skettenis   if (DO_ATTACH_CONTINUE == kind_of_go)
4707b725ae77Skettenis     {
4708b725ae77Skettenis       tt_status = call_real_ttrace (
4709b725ae77Skettenis 				     TT_LWP_CONTINUE,
4710b725ae77Skettenis 				     pid,
4711b725ae77Skettenis 				     a_thread,
4712b725ae77Skettenis 				     TT_USE_CURRENT_PC,
4713b725ae77Skettenis 	       (TTRACE_ARG_TYPE) target_signal_to_host (TARGET_SIGNAL_TRAP),
4714b725ae77Skettenis 				     TT_NIL);
4715b725ae77Skettenis       if (errno)
4716b725ae77Skettenis 	perror_with_name ("ttrace");
4717b725ae77Skettenis 
4718b725ae77Skettenis       clear_handled (a_thread);	/* So TRAP will be reported. */
4719b725ae77Skettenis 
4720b725ae77Skettenis       /* Now running.
4721b725ae77Skettenis        */
4722b725ae77Skettenis       process_state = RUNNING;
4723b725ae77Skettenis     }
4724b725ae77Skettenis 
4725b725ae77Skettenis   attach_flag = 1;
4726b725ae77Skettenis }
4727b725ae77Skettenis 
4728b725ae77Skettenis 
4729b725ae77Skettenis /* Start debugging the process whose number is PID.
4730b725ae77Skettenis  * (A _real_ pid).
4731b725ae77Skettenis  */
4732b725ae77Skettenis int
attach(int pid)4733b725ae77Skettenis attach (int pid)
4734b725ae77Skettenis {
4735b725ae77Skettenis   int tt_status;
4736b725ae77Skettenis 
4737b725ae77Skettenis   tt_status = call_real_ttrace (
4738b725ae77Skettenis 				 TT_PROC_ATTACH,
4739b725ae77Skettenis 				 pid,
4740b725ae77Skettenis 				 (lwpid_t) TT_NIL,
4741b725ae77Skettenis 				 TT_NIL,
4742b725ae77Skettenis 				 (TTRACE_ARG_TYPE) TT_VERSION,
4743b725ae77Skettenis 				 TT_NIL);
4744b725ae77Skettenis   if (errno)
4745b725ae77Skettenis     perror_with_name ("ttrace attach");
4746b725ae77Skettenis 
4747b725ae77Skettenis   /* If successful, the process is now stopped.
4748b725ae77Skettenis    */
4749b725ae77Skettenis   process_state = STOPPED;
4750b725ae77Skettenis 
4751b725ae77Skettenis   /* Our caller ("attach_command" in "infcmd.c")
4752b725ae77Skettenis    * expects to do a "wait_for_inferior" after
4753b725ae77Skettenis    * the attach, so make sure the inferior is
4754b725ae77Skettenis    * running when we're done.
4755b725ae77Skettenis    */
4756b725ae77Skettenis   update_thread_state_after_attach (pid, DO_ATTACH_CONTINUE);
4757b725ae77Skettenis 
4758b725ae77Skettenis   return pid;
4759b725ae77Skettenis }
4760b725ae77Skettenis 
4761b725ae77Skettenis 
4762b725ae77Skettenis #if defined(CHILD_POST_ATTACH)
4763b725ae77Skettenis void
child_post_attach(int pid)4764b725ae77Skettenis child_post_attach (int pid)
4765b725ae77Skettenis {
4766b725ae77Skettenis #ifdef THREAD_DEBUG
4767b725ae77Skettenis   if (debug_on)
4768b725ae77Skettenis     printf ("child-post-attach call\n");
4769b725ae77Skettenis #endif
4770b725ae77Skettenis 
4771b725ae77Skettenis   require_notification_of_events (pid);
4772b725ae77Skettenis }
4773b725ae77Skettenis #endif
4774b725ae77Skettenis 
4775b725ae77Skettenis 
4776b725ae77Skettenis /* Stop debugging the process whose number is PID
4777b725ae77Skettenis    and continue it with signal number SIGNAL.
4778b725ae77Skettenis    SIGNAL = 0 means just continue it.
4779b725ae77Skettenis  */
4780b725ae77Skettenis void
detach(int signal)4781b725ae77Skettenis detach (int signal)
4782b725ae77Skettenis {
4783b725ae77Skettenis   errno = 0;
4784b725ae77Skettenis   call_ttrace (TT_PROC_DETACH,
4785b725ae77Skettenis 	       PIDGET (inferior_ptid),
4786b725ae77Skettenis 	       TT_NIL,
4787b725ae77Skettenis 	       (TTRACE_ARG_TYPE) signal,
4788b725ae77Skettenis 	       TT_NIL);
4789b725ae77Skettenis   attach_flag = 0;
4790b725ae77Skettenis 
4791b725ae77Skettenis   clear_thread_info ();
4792b725ae77Skettenis 
4793b725ae77Skettenis   /* Process-state? */
4794b725ae77Skettenis }
4795b725ae77Skettenis 
4796b725ae77Skettenis 
4797b725ae77Skettenis /* Default the type of the ttrace transfer to int.  */
4798b725ae77Skettenis #ifndef TTRACE_XFER_TYPE
4799b725ae77Skettenis #define TTRACE_XFER_TYPE int
4800b725ae77Skettenis #endif
4801b725ae77Skettenis 
4802b725ae77Skettenis void
_initialize_kernel_u_addr(void)4803b725ae77Skettenis _initialize_kernel_u_addr (void)
4804b725ae77Skettenis {
4805b725ae77Skettenis }
4806b725ae77Skettenis 
4807b725ae77Skettenis #if !defined (CHILD_XFER_MEMORY)
4808b725ae77Skettenis /* NOTE! I tried using TTRACE_READDATA, etc., to read and write memory
4809b725ae77Skettenis    in the NEW_SUN_TTRACE case.
4810b725ae77Skettenis    It ought to be straightforward.  But it appears that writing did
4811b725ae77Skettenis    not write the data that I specified.  I cannot understand where
4812b725ae77Skettenis    it got the data that it actually did write.  */
4813b725ae77Skettenis 
4814b725ae77Skettenis /* Copy LEN bytes to or from inferior's memory starting at MEMADDR
4815b725ae77Skettenis    to debugger memory starting at MYADDR.   Copy to inferior if
4816b725ae77Skettenis    WRITE is nonzero.  TARGET is ignored.
4817b725ae77Skettenis 
4818*11efff7fSkettenis    Returns the length copied, which is either the LEN argument or
4819*11efff7fSkettenis    zero.  This xfer function does not do partial moves, since
4820*11efff7fSkettenis    deprecated_child_ops doesn't allow memory operations to cross below
4821*11efff7fSkettenis    us in the target stack anyway.  */
4822b725ae77Skettenis 
4823b725ae77Skettenis int
child_xfer_memory(CORE_ADDR memaddr,char * myaddr,int len,int write,struct mem_attrib * attrib,struct target_ops * target)4824b725ae77Skettenis child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
4825b725ae77Skettenis 		   struct mem_attrib *attrib,
4826b725ae77Skettenis 		   struct target_ops *target)
4827b725ae77Skettenis {
4828b725ae77Skettenis   int i;
4829b725ae77Skettenis   /* Round starting address down to longword boundary.  */
4830b725ae77Skettenis   CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (TTRACE_XFER_TYPE);
4831b725ae77Skettenis   /* Round ending address up; get number of longwords that makes.  */
4832b725ae77Skettenis   int count
4833b725ae77Skettenis   = (((memaddr + len) - addr) + sizeof (TTRACE_XFER_TYPE) - 1)
4834b725ae77Skettenis   / sizeof (TTRACE_XFER_TYPE);
4835b725ae77Skettenis   /* Allocate buffer of that many longwords.  */
4836b725ae77Skettenis   /* FIXME (alloca): This code, cloned from infptrace.c, is unsafe
4837b725ae77Skettenis      because it uses alloca to allocate a buffer of arbitrary size.
4838b725ae77Skettenis      For very large xfers, this could crash GDB's stack.  */
4839b725ae77Skettenis   TTRACE_XFER_TYPE *buffer
4840b725ae77Skettenis     = (TTRACE_XFER_TYPE *) alloca (count * sizeof (TTRACE_XFER_TYPE));
4841b725ae77Skettenis 
4842b725ae77Skettenis   if (write)
4843b725ae77Skettenis     {
4844b725ae77Skettenis       /* Fill start and end extra bytes of buffer with existing memory data.  */
4845b725ae77Skettenis 
4846b725ae77Skettenis       if (addr != memaddr || len < (int) sizeof (TTRACE_XFER_TYPE))
4847b725ae77Skettenis 	{
4848b725ae77Skettenis 	  /* Need part of initial word -- fetch it.  */
4849b725ae77Skettenis 	  buffer[0] = call_ttrace (TT_LWP_RDTEXT,
4850b725ae77Skettenis 				   PIDGET (inferior_ptid),
4851b725ae77Skettenis 				   (TTRACE_ARG_TYPE) addr,
4852b725ae77Skettenis 				   TT_NIL,
4853b725ae77Skettenis 				   TT_NIL);
4854b725ae77Skettenis 	}
4855b725ae77Skettenis 
4856b725ae77Skettenis       if (count > 1)		/* FIXME, avoid if even boundary */
4857b725ae77Skettenis 	{
4858b725ae77Skettenis 	  buffer[count - 1] = call_ttrace (TT_LWP_RDTEXT,
4859b725ae77Skettenis 					   PIDGET (inferior_ptid),
4860b725ae77Skettenis 					   ((TTRACE_ARG_TYPE)
4861b725ae77Skettenis 			  (addr + (count - 1) * sizeof (TTRACE_XFER_TYPE))),
4862b725ae77Skettenis 					   TT_NIL,
4863b725ae77Skettenis 					   TT_NIL);
4864b725ae77Skettenis 	}
4865b725ae77Skettenis 
4866b725ae77Skettenis       /* Copy data to be written over corresponding part of buffer */
4867b725ae77Skettenis 
4868b725ae77Skettenis       memcpy ((char *) buffer + (memaddr & (sizeof (TTRACE_XFER_TYPE) - 1)),
4869b725ae77Skettenis 	      myaddr,
4870b725ae77Skettenis 	      len);
4871b725ae77Skettenis 
4872b725ae77Skettenis       /* Write the entire buffer.  */
4873b725ae77Skettenis 
4874b725ae77Skettenis       for (i = 0; i < count; i++, addr += sizeof (TTRACE_XFER_TYPE))
4875b725ae77Skettenis 	{
4876b725ae77Skettenis 	  errno = 0;
4877b725ae77Skettenis 	  call_ttrace (TT_LWP_WRDATA,
4878b725ae77Skettenis 		       PIDGET (inferior_ptid),
4879b725ae77Skettenis 		       (TTRACE_ARG_TYPE) addr,
4880b725ae77Skettenis 		       (TTRACE_ARG_TYPE) buffer[i],
4881b725ae77Skettenis 		       TT_NIL);
4882b725ae77Skettenis 	  if (errno)
4883b725ae77Skettenis 	    {
4884b725ae77Skettenis 	      /* Using the appropriate one (I or D) is necessary for
4885b725ae77Skettenis 	         Gould NP1, at least.  */
4886b725ae77Skettenis 	      errno = 0;
4887b725ae77Skettenis 	      call_ttrace (TT_LWP_WRTEXT,
4888b725ae77Skettenis 			   PIDGET (inferior_ptid),
4889b725ae77Skettenis 			   (TTRACE_ARG_TYPE) addr,
4890b725ae77Skettenis 			   (TTRACE_ARG_TYPE) buffer[i],
4891b725ae77Skettenis 			   TT_NIL);
4892b725ae77Skettenis 	    }
4893b725ae77Skettenis 	  if (errno)
4894b725ae77Skettenis 	    return 0;
4895b725ae77Skettenis 	}
4896b725ae77Skettenis     }
4897b725ae77Skettenis   else
4898b725ae77Skettenis     {
4899b725ae77Skettenis       /* Read all the longwords */
4900b725ae77Skettenis       for (i = 0; i < count; i++, addr += sizeof (TTRACE_XFER_TYPE))
4901b725ae77Skettenis 	{
4902b725ae77Skettenis 	  errno = 0;
4903b725ae77Skettenis 	  buffer[i] = call_ttrace (TT_LWP_RDTEXT,
4904b725ae77Skettenis 				   PIDGET (inferior_ptid),
4905b725ae77Skettenis 				   (TTRACE_ARG_TYPE) addr,
4906b725ae77Skettenis 				   TT_NIL,
4907b725ae77Skettenis 				   TT_NIL);
4908b725ae77Skettenis 	  if (errno)
4909b725ae77Skettenis 	    return 0;
4910b725ae77Skettenis 	  QUIT;
4911b725ae77Skettenis 	}
4912b725ae77Skettenis 
4913b725ae77Skettenis       /* Copy appropriate bytes out of the buffer.  */
4914b725ae77Skettenis       memcpy (myaddr,
4915b725ae77Skettenis 	      (char *) buffer + (memaddr & (sizeof (TTRACE_XFER_TYPE) - 1)),
4916b725ae77Skettenis 	      len);
4917b725ae77Skettenis     }
4918b725ae77Skettenis   return len;
4919b725ae77Skettenis }
4920b725ae77Skettenis 
4921b725ae77Skettenis 
4922b725ae77Skettenis static void
udot_info(void)4923b725ae77Skettenis udot_info (void)
4924b725ae77Skettenis {
4925b725ae77Skettenis   int udot_off;			/* Offset into user struct */
4926b725ae77Skettenis   int udot_val;			/* Value from user struct at udot_off */
4927b725ae77Skettenis   char mess[128];		/* For messages */
4928b725ae77Skettenis 
4929b725ae77Skettenis   if (!target_has_execution)
4930b725ae77Skettenis     {
4931b725ae77Skettenis       error ("The program is not being run.");
4932b725ae77Skettenis     }
4933b725ae77Skettenis 
4934b725ae77Skettenis #if !defined (KERNEL_U_SIZE)
4935b725ae77Skettenis 
4936b725ae77Skettenis   /* Adding support for this command is easy.  Typically you just add a
4937b725ae77Skettenis      routine, called "kernel_u_size" that returns the size of the user
4938b725ae77Skettenis      struct, to the appropriate *-nat.c file and then add to the native
4939b725ae77Skettenis      config file "#define KERNEL_U_SIZE kernel_u_size()" */
4940b725ae77Skettenis   error ("Don't know how large ``struct user'' is in this version of gdb.");
4941b725ae77Skettenis 
4942b725ae77Skettenis #else
4943b725ae77Skettenis 
4944b725ae77Skettenis   for (udot_off = 0; udot_off < KERNEL_U_SIZE; udot_off += sizeof (udot_val))
4945b725ae77Skettenis     {
4946b725ae77Skettenis       if ((udot_off % 24) == 0)
4947b725ae77Skettenis 	{
4948b725ae77Skettenis 	  if (udot_off > 0)
4949b725ae77Skettenis 	    {
4950b725ae77Skettenis 	      printf_filtered ("\n");
4951b725ae77Skettenis 	    }
4952b725ae77Skettenis 	  printf_filtered ("%04x:", udot_off);
4953b725ae77Skettenis 	}
4954b725ae77Skettenis       udot_val = call_ttrace (TT_LWP_RUREGS,
4955b725ae77Skettenis 			      PIDGET (inferior_ptid),
4956b725ae77Skettenis 			      (TTRACE_ARG_TYPE) udot_off,
4957b725ae77Skettenis 			      TT_NIL,
4958b725ae77Skettenis 			      TT_NIL);
4959b725ae77Skettenis       if (errno != 0)
4960b725ae77Skettenis 	{
4961b725ae77Skettenis 	  sprintf (mess, "\nreading user struct at offset 0x%x", udot_off);
4962b725ae77Skettenis 	  perror_with_name (mess);
4963b725ae77Skettenis 	}
4964b725ae77Skettenis       /* Avoid using nonportable (?) "*" in print specs */
4965b725ae77Skettenis       printf_filtered (sizeof (int) == 4 ? " 0x%08x" : " 0x%16x", udot_val);
4966b725ae77Skettenis     }
4967b725ae77Skettenis   printf_filtered ("\n");
4968b725ae77Skettenis 
4969b725ae77Skettenis #endif
4970b725ae77Skettenis }
4971b725ae77Skettenis #endif /* !defined (CHILD_XFER_MEMORY).  */
4972b725ae77Skettenis 
4973b725ae77Skettenis 
4974b725ae77Skettenis /* TTrace version of "target_pid_to_exec_file"
4975b725ae77Skettenis  */
4976b725ae77Skettenis char *
child_pid_to_exec_file(int tid)4977b725ae77Skettenis child_pid_to_exec_file (int tid)
4978b725ae77Skettenis {
4979b725ae77Skettenis   int tt_status;
4980b725ae77Skettenis   static char exec_file_buffer[1024];
4981b725ae77Skettenis   pid_t pid;
4982b725ae77Skettenis   static struct pst_status buf;
4983b725ae77Skettenis 
4984b725ae77Skettenis   /* On various versions of hpux11, this may fail due to a supposed
4985b725ae77Skettenis      kernel bug.  We have alternate methods to get this information
4986b725ae77Skettenis      (ie pstat).  */
4987b725ae77Skettenis   tt_status = call_ttrace (TT_PROC_GET_PATHNAME,
4988b725ae77Skettenis 			   tid,
4989b725ae77Skettenis 			   (uint64_t) exec_file_buffer,
4990b725ae77Skettenis 			   sizeof (exec_file_buffer) - 1,
4991b725ae77Skettenis 			   0);
4992b725ae77Skettenis   if (tt_status >= 0)
4993b725ae77Skettenis     return exec_file_buffer;
4994b725ae77Skettenis 
4995b725ae77Skettenis   /* Try to get process information via pstat and extract the filename
4996b725ae77Skettenis      from the pst_cmd field within the pst_status structure.  */
4997b725ae77Skettenis   if (pstat_getproc (&buf, sizeof (struct pst_status), 0, tid) != -1)
4998b725ae77Skettenis     {
4999b725ae77Skettenis       char *p = buf.pst_cmd;
5000b725ae77Skettenis 
5001b725ae77Skettenis       while (*p && *p != ' ')
5002b725ae77Skettenis 	p++;
5003b725ae77Skettenis       *p = 0;
5004b725ae77Skettenis 
5005b725ae77Skettenis       return (buf.pst_cmd);
5006b725ae77Skettenis     }
5007b725ae77Skettenis 
5008b725ae77Skettenis   return (NULL);
5009b725ae77Skettenis }
5010b725ae77Skettenis 
5011b725ae77Skettenis void
pre_fork_inferior(void)5012b725ae77Skettenis pre_fork_inferior (void)
5013b725ae77Skettenis {
5014b725ae77Skettenis   int status;
5015b725ae77Skettenis 
5016b725ae77Skettenis   status = pipe (startup_semaphore.parent_channel);
5017b725ae77Skettenis   if (status < 0)
5018b725ae77Skettenis     {
5019b725ae77Skettenis       warning ("error getting parent pipe for startup semaphore");
5020b725ae77Skettenis       return;
5021b725ae77Skettenis     }
5022b725ae77Skettenis 
5023b725ae77Skettenis   status = pipe (startup_semaphore.child_channel);
5024b725ae77Skettenis   if (status < 0)
5025b725ae77Skettenis     {
5026b725ae77Skettenis       warning ("error getting child pipe for startup semaphore");
5027b725ae77Skettenis       return;
5028b725ae77Skettenis     }
5029b725ae77Skettenis }
5030b725ae77Skettenis 
5031b725ae77Skettenis /* Called from child_follow_fork in hppah-nat.c.
5032b725ae77Skettenis  *
5033b725ae77Skettenis  * This seems to be intended to attach after a fork or
5034b725ae77Skettenis  * vfork, while "attach" is used to attach to a pid
5035b725ae77Skettenis  * given by the user.  The check for an existing attach
5036b725ae77Skettenis  * seems odd--it always fails in our test system.
5037b725ae77Skettenis  */
5038b725ae77Skettenis int
hppa_require_attach(int pid)5039b725ae77Skettenis hppa_require_attach (int pid)
5040b725ae77Skettenis {
5041b725ae77Skettenis   int tt_status;
5042b725ae77Skettenis   CORE_ADDR pc;
5043b725ae77Skettenis   CORE_ADDR pc_addr;
5044b725ae77Skettenis   unsigned int regs_offset;
5045b725ae77Skettenis   process_state_t old_process_state = process_state;
5046b725ae77Skettenis 
5047b725ae77Skettenis   /* Are we already attached?  There appears to be no explicit
5048b725ae77Skettenis    * way to answer this via ttrace, so we try something which
5049b725ae77Skettenis    * should be innocuous if we are attached.  If that fails,
5050b725ae77Skettenis    * then we assume we're not attached, and so attempt to make
5051b725ae77Skettenis    * it so.
5052b725ae77Skettenis    */
5053b725ae77Skettenis   errno = 0;
5054b725ae77Skettenis   tt_status = call_real_ttrace (TT_PROC_STOP,
5055b725ae77Skettenis 				pid,
5056b725ae77Skettenis 				(lwpid_t) TT_NIL,
5057b725ae77Skettenis 				(TTRACE_ARG_TYPE) TT_NIL,
5058b725ae77Skettenis 				(TTRACE_ARG_TYPE) TT_NIL,
5059b725ae77Skettenis 				TT_NIL);
5060b725ae77Skettenis 
5061b725ae77Skettenis   if (errno)
5062b725ae77Skettenis     {
5063b725ae77Skettenis       /* No change to process-state!
5064b725ae77Skettenis        */
5065b725ae77Skettenis       errno = 0;
5066b725ae77Skettenis       pid = attach (pid);
5067b725ae77Skettenis     }
5068b725ae77Skettenis   else
5069b725ae77Skettenis     {
5070b725ae77Skettenis       /* If successful, the process is now stopped.  But if
5071b725ae77Skettenis        * we're VFORKING, the parent is still running, so don't
5072b725ae77Skettenis        * change the process state.
5073b725ae77Skettenis        */
5074b725ae77Skettenis       if (process_state != VFORKING)
5075b725ae77Skettenis 	process_state = STOPPED;
5076b725ae77Skettenis 
5077b725ae77Skettenis       /* If we were already attached, you'd think that we
5078b725ae77Skettenis        * would need to start going again--but you'd be wrong,
5079b725ae77Skettenis        * as the fork-following code is actually in the middle
5080b725ae77Skettenis        * of the "resume" routine in in "infrun.c" and so
5081b725ae77Skettenis        * will (almost) immediately do a resume.
5082b725ae77Skettenis        *
5083b725ae77Skettenis        * On the other hand, if we are VFORKING, which means
5084b725ae77Skettenis        * that the child and the parent share a process for a
5085b725ae77Skettenis        * while, we know that "resume" won't be resuming
5086b725ae77Skettenis        * until the child EXEC event is seen.  But we still
5087b725ae77Skettenis        * don't want to continue, as the event is already
5088b725ae77Skettenis        * there waiting.
5089b725ae77Skettenis        */
5090b725ae77Skettenis       update_thread_state_after_attach (pid, DONT_ATTACH_CONTINUE);
5091b725ae77Skettenis     }				/* STOP succeeded */
5092b725ae77Skettenis 
5093b725ae77Skettenis   return pid;
5094b725ae77Skettenis }
5095b725ae77Skettenis 
5096b725ae77Skettenis int
hppa_require_detach(int pid,int signal)5097b725ae77Skettenis hppa_require_detach (int pid, int signal)
5098b725ae77Skettenis {
5099b725ae77Skettenis   int tt_status;
5100b725ae77Skettenis 
5101b725ae77Skettenis   /* If signal is non-zero, we must pass the signal on to the active
5102b725ae77Skettenis      thread prior to detaching.  We do this by continuing the threads
5103b725ae77Skettenis      with the signal.
5104b725ae77Skettenis    */
5105b725ae77Skettenis   if (signal != 0)
5106b725ae77Skettenis     {
5107b725ae77Skettenis       errno = 0;
5108b725ae77Skettenis       threads_continue_all_with_signals (pid, signal);
5109b725ae77Skettenis     }
5110b725ae77Skettenis 
5111b725ae77Skettenis   errno = 0;
5112b725ae77Skettenis   tt_status = call_ttrace (TT_PROC_DETACH,
5113b725ae77Skettenis 			   pid,
5114b725ae77Skettenis 			   TT_NIL,
5115b725ae77Skettenis 			   TT_NIL,
5116b725ae77Skettenis 			   TT_NIL);
5117b725ae77Skettenis 
5118b725ae77Skettenis   errno = 0;			/* Ignore any errors. */
5119b725ae77Skettenis 
5120b725ae77Skettenis   /* process_state? */
5121b725ae77Skettenis 
5122b725ae77Skettenis   return pid;
5123b725ae77Skettenis }
5124b725ae77Skettenis 
5125b725ae77Skettenis /* Given the starting address of a memory page, hash it to a bucket in
5126b725ae77Skettenis    the memory page dictionary.
5127b725ae77Skettenis  */
5128b725ae77Skettenis static int
get_dictionary_bucket_of_page(CORE_ADDR page_start)5129b725ae77Skettenis get_dictionary_bucket_of_page (CORE_ADDR page_start)
5130b725ae77Skettenis {
5131b725ae77Skettenis   int hash;
5132b725ae77Skettenis 
5133b725ae77Skettenis   hash = (page_start / memory_page_dictionary.page_size);
5134b725ae77Skettenis   hash = hash % MEMORY_PAGE_DICTIONARY_BUCKET_COUNT;
5135b725ae77Skettenis 
5136b725ae77Skettenis   return hash;
5137b725ae77Skettenis }
5138b725ae77Skettenis 
5139b725ae77Skettenis 
5140b725ae77Skettenis /* Given a memory page's starting address, get (i.e., find an existing
5141b725ae77Skettenis    or create a new) dictionary entry for the page.  The page will be
5142b725ae77Skettenis    write-protected when this function returns, but may have a reference
5143b725ae77Skettenis    count of 0 (if the page was newly-added to the dictionary).
5144b725ae77Skettenis  */
5145b725ae77Skettenis static memory_page_t *
get_dictionary_entry_of_page(int pid,CORE_ADDR page_start)5146b725ae77Skettenis get_dictionary_entry_of_page (int pid, CORE_ADDR page_start)
5147b725ae77Skettenis {
5148b725ae77Skettenis   int bucket;
5149b725ae77Skettenis   memory_page_t *page = NULL;
5150b725ae77Skettenis   memory_page_t *previous_page = NULL;
5151b725ae77Skettenis 
5152b725ae77Skettenis   /* We're going to be using the dictionary now, than-kew. */
5153b725ae77Skettenis   require_memory_page_dictionary ();
5154b725ae77Skettenis 
5155b725ae77Skettenis   /* Try to find an existing dictionary entry for this page.  Hash
5156b725ae77Skettenis      on the page's starting address.
5157b725ae77Skettenis    */
5158b725ae77Skettenis   bucket = get_dictionary_bucket_of_page (page_start);
5159b725ae77Skettenis   page = &memory_page_dictionary.buckets[bucket];
5160b725ae77Skettenis   while (page != NULL)
5161b725ae77Skettenis     {
5162b725ae77Skettenis       if (page->page_start == page_start)
5163b725ae77Skettenis 	break;
5164b725ae77Skettenis       previous_page = page;
5165b725ae77Skettenis       page = page->next;
5166b725ae77Skettenis     }
5167b725ae77Skettenis 
5168b725ae77Skettenis   /* Did we find a dictionary entry for this page?  If not, then
5169b725ae77Skettenis      add it to the dictionary now.
5170b725ae77Skettenis    */
5171b725ae77Skettenis   if (page == NULL)
5172b725ae77Skettenis     {
5173b725ae77Skettenis       /* Create a new entry. */
5174b725ae77Skettenis       page = (memory_page_t *) xmalloc (sizeof (memory_page_t));
5175b725ae77Skettenis       page->page_start = page_start;
5176b725ae77Skettenis       page->reference_count = 0;
5177b725ae77Skettenis       page->next = NULL;
5178b725ae77Skettenis       page->previous = NULL;
5179b725ae77Skettenis 
5180b725ae77Skettenis       /* We'll write-protect the page now, if that's allowed. */
5181b725ae77Skettenis       page->original_permissions = write_protect_page (pid, page_start);
5182b725ae77Skettenis 
5183b725ae77Skettenis       /* Add the new entry to the dictionary. */
5184b725ae77Skettenis       page->previous = previous_page;
5185b725ae77Skettenis       previous_page->next = page;
5186b725ae77Skettenis 
5187b725ae77Skettenis       memory_page_dictionary.page_count++;
5188b725ae77Skettenis     }
5189b725ae77Skettenis 
5190b725ae77Skettenis   return page;
5191b725ae77Skettenis }
5192b725ae77Skettenis 
5193b725ae77Skettenis 
5194b725ae77Skettenis static void
remove_dictionary_entry_of_page(int pid,memory_page_t * page)5195b725ae77Skettenis remove_dictionary_entry_of_page (int pid, memory_page_t *page)
5196b725ae77Skettenis {
5197b725ae77Skettenis   /* Restore the page's original permissions. */
5198b725ae77Skettenis   unwrite_protect_page (pid, page->page_start, page->original_permissions);
5199b725ae77Skettenis 
5200b725ae77Skettenis   /* Kick the page out of the dictionary. */
5201b725ae77Skettenis   if (page->previous != NULL)
5202b725ae77Skettenis     page->previous->next = page->next;
5203b725ae77Skettenis   if (page->next != NULL)
5204b725ae77Skettenis     page->next->previous = page->previous;
5205b725ae77Skettenis 
5206b725ae77Skettenis   /* Just in case someone retains a handle to this after it's freed. */
5207b725ae77Skettenis   page->page_start = (CORE_ADDR) 0;
5208b725ae77Skettenis 
5209b725ae77Skettenis   memory_page_dictionary.page_count--;
5210b725ae77Skettenis 
5211b725ae77Skettenis   xfree (page);
5212b725ae77Skettenis }
5213b725ae77Skettenis 
5214b725ae77Skettenis 
5215b725ae77Skettenis static void
hppa_enable_syscall_events(int pid)5216b725ae77Skettenis hppa_enable_syscall_events (int pid)
5217b725ae77Skettenis {
5218b725ae77Skettenis   int tt_status;
5219b725ae77Skettenis   ttevent_t ttrace_events;
5220b725ae77Skettenis 
5221b725ae77Skettenis   /* Get the set of events that are currently enabled. */
5222b725ae77Skettenis   tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
5223b725ae77Skettenis 			   pid,
5224b725ae77Skettenis 			   (TTRACE_ARG_TYPE) & ttrace_events,
5225b725ae77Skettenis 			   (TTRACE_ARG_TYPE) sizeof (ttrace_events),
5226b725ae77Skettenis 			   TT_NIL);
5227b725ae77Skettenis   if (errno)
5228b725ae77Skettenis     perror_with_name ("ttrace");
5229b725ae77Skettenis 
5230b725ae77Skettenis   /* Add syscall events to that set. */
5231b725ae77Skettenis   ttrace_events.tte_events |= TTEVT_SYSCALL_ENTRY;
5232b725ae77Skettenis   ttrace_events.tte_events |= TTEVT_SYSCALL_RETURN;
5233b725ae77Skettenis 
5234b725ae77Skettenis   tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
5235b725ae77Skettenis 			   pid,
5236b725ae77Skettenis 			   (TTRACE_ARG_TYPE) & ttrace_events,
5237b725ae77Skettenis 			   (TTRACE_ARG_TYPE) sizeof (ttrace_events),
5238b725ae77Skettenis 			   TT_NIL);
5239b725ae77Skettenis   if (errno)
5240b725ae77Skettenis     perror_with_name ("ttrace");
5241b725ae77Skettenis }
5242b725ae77Skettenis 
5243b725ae77Skettenis 
5244b725ae77Skettenis static void
hppa_disable_syscall_events(int pid)5245b725ae77Skettenis hppa_disable_syscall_events (int pid)
5246b725ae77Skettenis {
5247b725ae77Skettenis   int tt_status;
5248b725ae77Skettenis   ttevent_t ttrace_events;
5249b725ae77Skettenis 
5250b725ae77Skettenis   /* Get the set of events that are currently enabled. */
5251b725ae77Skettenis   tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
5252b725ae77Skettenis 			   pid,
5253b725ae77Skettenis 			   (TTRACE_ARG_TYPE) & ttrace_events,
5254b725ae77Skettenis 			   (TTRACE_ARG_TYPE) sizeof (ttrace_events),
5255b725ae77Skettenis 			   TT_NIL);
5256b725ae77Skettenis   if (errno)
5257b725ae77Skettenis     perror_with_name ("ttrace");
5258b725ae77Skettenis 
5259b725ae77Skettenis   /* Remove syscall events from that set. */
5260b725ae77Skettenis   ttrace_events.tte_events &= ~TTEVT_SYSCALL_ENTRY;
5261b725ae77Skettenis   ttrace_events.tte_events &= ~TTEVT_SYSCALL_RETURN;
5262b725ae77Skettenis 
5263b725ae77Skettenis   tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
5264b725ae77Skettenis 			   pid,
5265b725ae77Skettenis 			   (TTRACE_ARG_TYPE) & ttrace_events,
5266b725ae77Skettenis 			   (TTRACE_ARG_TYPE) sizeof (ttrace_events),
5267b725ae77Skettenis 			   TT_NIL);
5268b725ae77Skettenis   if (errno)
5269b725ae77Skettenis     perror_with_name ("ttrace");
5270b725ae77Skettenis }
5271b725ae77Skettenis 
5272b725ae77Skettenis 
5273b725ae77Skettenis /* The address range beginning with START and ending with START+LEN-1
5274b725ae77Skettenis    (inclusive) is to be watched via page-protection by a new watchpoint.
5275b725ae77Skettenis    Set protection for all pages that overlap that range.
5276b725ae77Skettenis 
5277b725ae77Skettenis    Note that our caller sets TYPE to:
5278b725ae77Skettenis    0 for a bp_hardware_watchpoint,
5279b725ae77Skettenis    1 for a bp_read_watchpoint,
5280b725ae77Skettenis    2 for a bp_access_watchpoint
5281b725ae77Skettenis 
5282b725ae77Skettenis    (Yes, this is intentionally (though lord only knows why) different
5283b725ae77Skettenis    from the TYPE that is passed to hppa_remove_hw_watchpoint.)
5284b725ae77Skettenis  */
5285b725ae77Skettenis int
hppa_insert_hw_watchpoint(int pid,CORE_ADDR start,LONGEST len,int type)5286b725ae77Skettenis hppa_insert_hw_watchpoint (int pid, CORE_ADDR start, LONGEST len, int type)
5287b725ae77Skettenis {
5288b725ae77Skettenis   CORE_ADDR page_start;
5289b725ae77Skettenis   int dictionary_was_empty;
5290b725ae77Skettenis   int page_size;
5291b725ae77Skettenis   int page_id;
5292b725ae77Skettenis   LONGEST range_size_in_pages;
5293b725ae77Skettenis 
5294b725ae77Skettenis   if (type != 0)
5295b725ae77Skettenis     error ("read or access hardware watchpoints not supported on HP-UX");
5296b725ae77Skettenis 
5297b725ae77Skettenis   /* Examine all pages in the address range. */
5298b725ae77Skettenis   require_memory_page_dictionary ();
5299b725ae77Skettenis 
5300b725ae77Skettenis   dictionary_was_empty = (memory_page_dictionary.page_count == (LONGEST) 0);
5301b725ae77Skettenis 
5302b725ae77Skettenis   page_size = memory_page_dictionary.page_size;
5303b725ae77Skettenis   page_start = (start / page_size) * page_size;
5304b725ae77Skettenis   range_size_in_pages = ((LONGEST) len + (LONGEST) page_size - 1) / (LONGEST) page_size;
5305b725ae77Skettenis 
5306b725ae77Skettenis   for (page_id = 0; page_id < range_size_in_pages; page_id++, page_start += page_size)
5307b725ae77Skettenis     {
5308b725ae77Skettenis       memory_page_t *page;
5309b725ae77Skettenis 
5310b725ae77Skettenis       /* This gets the page entered into the dictionary if it was
5311b725ae77Skettenis          not already entered.
5312b725ae77Skettenis        */
5313b725ae77Skettenis       page = get_dictionary_entry_of_page (pid, page_start);
5314b725ae77Skettenis       page->reference_count++;
5315b725ae77Skettenis     }
5316b725ae77Skettenis 
5317b725ae77Skettenis   /* Our implementation depends on seeing calls to kernel code, for the
5318b725ae77Skettenis      following reason.  Here we ask to be notified of syscalls.
5319b725ae77Skettenis 
5320b725ae77Skettenis      When a protected page is accessed by user code, HP-UX raises a SIGBUS.
5321b725ae77Skettenis      Fine.
5322b725ae77Skettenis 
5323b725ae77Skettenis      But when kernel code accesses the page, it doesn't give a SIGBUS.
5324b725ae77Skettenis      Rather, the system call that touched the page fails, with errno=EFAULT.
5325b725ae77Skettenis      Not good for us.
5326b725ae77Skettenis 
5327b725ae77Skettenis      We could accomodate this "feature" by asking to be notified of syscall
5328b725ae77Skettenis      entries & exits; upon getting an entry event, disabling page-protections;
5329b725ae77Skettenis      upon getting an exit event, reenabling page-protections and then checking
5330b725ae77Skettenis      if any watchpoints triggered.
5331b725ae77Skettenis 
5332b725ae77Skettenis      However, this turns out to be a real performance loser.  syscalls are
5333b725ae77Skettenis      usually a frequent occurrence.  Having to unprotect-reprotect all watched
5334b725ae77Skettenis      pages, and also to then read all watched memory locations and compare for
5335b725ae77Skettenis      triggers, can be quite expensive.
5336b725ae77Skettenis 
5337b725ae77Skettenis      Instead, we'll only ask to be notified of syscall exits.  When we get
5338b725ae77Skettenis      one, we'll check whether errno is set.  If not, or if it's not EFAULT,
5339b725ae77Skettenis      we can just continue the inferior.
5340b725ae77Skettenis 
5341b725ae77Skettenis      If errno is set upon syscall exit to EFAULT, we must perform some fairly
5342b725ae77Skettenis      hackish stuff to determine whether the failure really was due to a
5343b725ae77Skettenis      page-protect trap on a watched location.
5344b725ae77Skettenis    */
5345b725ae77Skettenis   if (dictionary_was_empty)
5346b725ae77Skettenis     hppa_enable_syscall_events (pid);
5347b725ae77Skettenis 
5348b725ae77Skettenis   return 1;
5349b725ae77Skettenis }
5350b725ae77Skettenis 
5351b725ae77Skettenis 
5352b725ae77Skettenis /* The address range beginning with START and ending with START+LEN-1
5353b725ae77Skettenis    (inclusive) was being watched via page-protection by a watchpoint
5354b725ae77Skettenis    which has been removed.  Remove protection for all pages that
5355b725ae77Skettenis    overlap that range, which are not also being watched by other
5356b725ae77Skettenis    watchpoints.
5357b725ae77Skettenis  */
5358b725ae77Skettenis int
hppa_remove_hw_watchpoint(int pid,CORE_ADDR start,LONGEST len,int type)5359b725ae77Skettenis hppa_remove_hw_watchpoint (int pid, CORE_ADDR start, LONGEST len, int type)
5360b725ae77Skettenis {
5361b725ae77Skettenis   CORE_ADDR page_start;
5362b725ae77Skettenis   int dictionary_is_empty;
5363b725ae77Skettenis   int page_size;
5364b725ae77Skettenis   int page_id;
5365b725ae77Skettenis   LONGEST range_size_in_pages;
5366b725ae77Skettenis 
5367b725ae77Skettenis   if (type != 0)
5368b725ae77Skettenis     error ("read or access hardware watchpoints not supported on HP-UX");
5369b725ae77Skettenis 
5370b725ae77Skettenis   /* Examine all pages in the address range. */
5371b725ae77Skettenis   require_memory_page_dictionary ();
5372b725ae77Skettenis 
5373b725ae77Skettenis   page_size = memory_page_dictionary.page_size;
5374b725ae77Skettenis   page_start = (start / page_size) * page_size;
5375b725ae77Skettenis   range_size_in_pages = ((LONGEST) len + (LONGEST) page_size - 1) / (LONGEST) page_size;
5376b725ae77Skettenis 
5377b725ae77Skettenis   for (page_id = 0; page_id < range_size_in_pages; page_id++, page_start += page_size)
5378b725ae77Skettenis     {
5379b725ae77Skettenis       memory_page_t *page;
5380b725ae77Skettenis 
5381b725ae77Skettenis       page = get_dictionary_entry_of_page (pid, page_start);
5382b725ae77Skettenis       page->reference_count--;
5383b725ae77Skettenis 
5384b725ae77Skettenis       /* Was this the last reference of this page?  If so, then we
5385b725ae77Skettenis          must scrub the entry from the dictionary, and also restore
5386b725ae77Skettenis          the page's original permissions.
5387b725ae77Skettenis        */
5388b725ae77Skettenis       if (page->reference_count == 0)
5389b725ae77Skettenis 	remove_dictionary_entry_of_page (pid, page);
5390b725ae77Skettenis     }
5391b725ae77Skettenis 
5392b725ae77Skettenis   dictionary_is_empty = (memory_page_dictionary.page_count == (LONGEST) 0);
5393b725ae77Skettenis 
5394b725ae77Skettenis   /* If write protections are currently disallowed, then that implies that
5395b725ae77Skettenis      wait_for_inferior believes that the inferior is within a system call.
5396b725ae77Skettenis      Since we want to see both syscall entry and return, it's clearly not
5397b725ae77Skettenis      good to disable syscall events in this state!
5398b725ae77Skettenis 
5399b725ae77Skettenis      ??rehrauer: Yeah, it'd be better if we had a specific flag that said,
5400b725ae77Skettenis      "inferior is between syscall events now".  Oh well.
5401b725ae77Skettenis    */
5402b725ae77Skettenis   if (dictionary_is_empty && memory_page_dictionary.page_protections_allowed)
5403b725ae77Skettenis     hppa_disable_syscall_events (pid);
5404b725ae77Skettenis 
5405b725ae77Skettenis   return 1;
5406b725ae77Skettenis }
5407b725ae77Skettenis 
5408b725ae77Skettenis 
5409b725ae77Skettenis /* Could we implement a watchpoint of this type via our available
5410b725ae77Skettenis    hardware support?
5411b725ae77Skettenis 
5412b725ae77Skettenis    This query does not consider whether a particular address range
5413b725ae77Skettenis    could be so watched, but just whether support is generally available
5414b725ae77Skettenis    for such things.  See hppa_range_profitable_for_hw_watchpoint for a
5415b725ae77Skettenis    query that answers whether a particular range should be watched via
5416b725ae77Skettenis    hardware support.
5417b725ae77Skettenis  */
5418b725ae77Skettenis int
hppa_can_use_hw_watchpoint(int type,int cnt,int ot)5419b725ae77Skettenis hppa_can_use_hw_watchpoint (int type, int cnt, int ot)
5420b725ae77Skettenis {
5421b725ae77Skettenis   return (type == bp_hardware_watchpoint);
5422b725ae77Skettenis }
5423b725ae77Skettenis 
5424b725ae77Skettenis 
5425b725ae77Skettenis /* Assuming we could set a hardware watchpoint on this address, do
5426b725ae77Skettenis    we think it would be profitable ("a good idea") to do so?  If not,
5427b725ae77Skettenis    we can always set a regular (aka single-step & test) watchpoint
5428b725ae77Skettenis    on the address...
5429b725ae77Skettenis  */
5430b725ae77Skettenis int
hppa_range_profitable_for_hw_watchpoint(int pid,CORE_ADDR start,LONGEST len)5431b725ae77Skettenis hppa_range_profitable_for_hw_watchpoint (int pid, CORE_ADDR start, LONGEST len)
5432b725ae77Skettenis {
5433b725ae77Skettenis   int range_is_stack_based;
5434b725ae77Skettenis   int range_is_accessible;
5435b725ae77Skettenis   CORE_ADDR page_start;
5436b725ae77Skettenis   int page_size;
5437b725ae77Skettenis   int page;
5438b725ae77Skettenis   LONGEST range_size_in_pages;
5439b725ae77Skettenis 
5440b725ae77Skettenis   /* ??rehrauer: For now, say that all addresses are potentially
5441b725ae77Skettenis      profitable.  Possibly later we'll want to test the address
5442b725ae77Skettenis      for "stackness"?
5443b725ae77Skettenis    */
5444b725ae77Skettenis   range_is_stack_based = 0;
5445b725ae77Skettenis 
5446b725ae77Skettenis   /* If any page in the range is inaccessible, then we cannot
5447b725ae77Skettenis      really use hardware watchpointing, even though our client
5448b725ae77Skettenis      thinks we can.  In that case, it's actually an error to
5449b725ae77Skettenis      attempt to use hw watchpoints, so we'll tell our client
5450b725ae77Skettenis      that the range is "unprofitable", and hope that they listen...
5451b725ae77Skettenis    */
5452b725ae77Skettenis   range_is_accessible = 1;	/* Until proven otherwise. */
5453b725ae77Skettenis 
5454b725ae77Skettenis   /* Examine all pages in the address range. */
5455b725ae77Skettenis   errno = 0;
5456b725ae77Skettenis   page_size = sysconf (_SC_PAGE_SIZE);
5457b725ae77Skettenis 
5458b725ae77Skettenis   /* If we can't determine page size, we're hosed.  Tell our
5459b725ae77Skettenis      client it's unprofitable to use hw watchpoints for this
5460b725ae77Skettenis      range.
5461b725ae77Skettenis    */
5462b725ae77Skettenis   if (errno || (page_size <= 0))
5463b725ae77Skettenis     {
5464b725ae77Skettenis       errno = 0;
5465b725ae77Skettenis       return 0;
5466b725ae77Skettenis     }
5467b725ae77Skettenis 
5468b725ae77Skettenis   page_start = (start / page_size) * page_size;
5469b725ae77Skettenis   range_size_in_pages = len / (LONGEST) page_size;
5470b725ae77Skettenis 
5471b725ae77Skettenis   for (page = 0; page < range_size_in_pages; page++, page_start += page_size)
5472b725ae77Skettenis     {
5473b725ae77Skettenis       int tt_status;
5474b725ae77Skettenis       int page_permissions;
5475b725ae77Skettenis 
5476b725ae77Skettenis       /* Is this page accessible? */
5477b725ae77Skettenis       errno = 0;
5478b725ae77Skettenis       tt_status = call_ttrace (TT_PROC_GET_MPROTECT,
5479b725ae77Skettenis 			       pid,
5480b725ae77Skettenis 			       (TTRACE_ARG_TYPE) page_start,
5481b725ae77Skettenis 			       TT_NIL,
5482b725ae77Skettenis 			       (TTRACE_ARG_TYPE) & page_permissions);
5483b725ae77Skettenis       if (errno || (tt_status < 0))
5484b725ae77Skettenis 	{
5485b725ae77Skettenis 	  errno = 0;
5486b725ae77Skettenis 	  range_is_accessible = 0;
5487b725ae77Skettenis 	  break;
5488b725ae77Skettenis 	}
5489b725ae77Skettenis 
5490b725ae77Skettenis       /* Yes, go for another... */
5491b725ae77Skettenis     }
5492b725ae77Skettenis 
5493b725ae77Skettenis   return (!range_is_stack_based && range_is_accessible);
5494b725ae77Skettenis }
5495b725ae77Skettenis 
5496b725ae77Skettenis 
5497b725ae77Skettenis char *
hppa_pid_or_tid_to_str(ptid_t ptid)5498b725ae77Skettenis hppa_pid_or_tid_to_str (ptid_t ptid)
5499b725ae77Skettenis {
5500b725ae77Skettenis   static char buf[100];		/* Static because address returned. */
5501b725ae77Skettenis   pid_t id = PIDGET (ptid);
5502b725ae77Skettenis 
5503b725ae77Skettenis   /* Does this appear to be a process?  If so, print it that way. */
5504b725ae77Skettenis   if (is_process_id (id))
5505b725ae77Skettenis     return child_pid_to_str (ptid);
5506b725ae77Skettenis 
5507b725ae77Skettenis   /* Else, print both the GDB thread number and the system thread id. */
5508b725ae77Skettenis   sprintf (buf, "thread %d (", pid_to_thread_id (ptid));
5509b725ae77Skettenis   strcat (buf, hppa_tid_to_str (ptid));
5510b725ae77Skettenis   strcat (buf, ")\0");
5511b725ae77Skettenis 
5512b725ae77Skettenis   return buf;
5513b725ae77Skettenis }
5514b725ae77Skettenis 
5515b725ae77Skettenis 
5516b725ae77Skettenis void
hppa_ensure_vforking_parent_remains_stopped(int pid)5517b725ae77Skettenis hppa_ensure_vforking_parent_remains_stopped (int pid)
5518b725ae77Skettenis {
5519b725ae77Skettenis   /* Nothing to do when using ttrace.  Only the ptrace-based implementation
5520b725ae77Skettenis      must do real work.
5521b725ae77Skettenis    */
5522b725ae77Skettenis }
5523b725ae77Skettenis 
5524b725ae77Skettenis 
5525b725ae77Skettenis int
hppa_resume_execd_vforking_child_to_get_parent_vfork(void)5526b725ae77Skettenis hppa_resume_execd_vforking_child_to_get_parent_vfork (void)
5527b725ae77Skettenis {
5528b725ae77Skettenis   return 0;			/* No, the parent vfork is available now. */
5529b725ae77Skettenis }
5530b725ae77Skettenis 
5531b725ae77Skettenis 
5532b725ae77Skettenis /* Write a register as a 64bit value.  This may be necessary if the
5533b725ae77Skettenis    native OS is too braindamaged to allow some (or all) registers to
5534b725ae77Skettenis    be written in 32bit hunks such as hpux11 and the PC queue registers.
5535b725ae77Skettenis 
5536b725ae77Skettenis    This is horribly gross and disgusting.  */
5537b725ae77Skettenis 
5538b725ae77Skettenis int
ttrace_write_reg_64(int gdb_tid,CORE_ADDR dest_addr,CORE_ADDR src_addr)5539b725ae77Skettenis ttrace_write_reg_64 (int gdb_tid, CORE_ADDR dest_addr, CORE_ADDR src_addr)
5540b725ae77Skettenis {
5541b725ae77Skettenis   pid_t 	pid;
5542b725ae77Skettenis   lwpid_t 	tid;
5543b725ae77Skettenis   int  		tt_status;
5544b725ae77Skettenis 
5545b725ae77Skettenis   tid = map_from_gdb_tid (gdb_tid);
5546b725ae77Skettenis   pid = get_pid_for (tid);
5547b725ae77Skettenis 
5548b725ae77Skettenis   errno = 0;
5549b725ae77Skettenis   tt_status = ttrace (TT_LWP_WUREGS,
5550b725ae77Skettenis 		      pid,
5551b725ae77Skettenis 		      tid,
5552b725ae77Skettenis 		      (TTRACE_ARG_TYPE) dest_addr,
5553b725ae77Skettenis 		      8,
5554b725ae77Skettenis 		      (TTRACE_ARG_TYPE) src_addr );
5555b725ae77Skettenis 
5556b725ae77Skettenis #ifdef THREAD_DEBUG
5557b725ae77Skettenis   if (errno)
5558b725ae77Skettenis     {
5559b725ae77Skettenis       /* Don't bother for a known benign error: if you ask for the
5560b725ae77Skettenis          first thread state, but there is only one thread and it's
5561b725ae77Skettenis          not stopped, ttrace complains.
5562b725ae77Skettenis 
5563b725ae77Skettenis          We have this inside the #ifdef because our caller will do
5564b725ae77Skettenis          this check for real.  */
5565b725ae77Skettenis       if( request != TT_PROC_GET_FIRST_LWP_STATE
5566b725ae77Skettenis           ||  errno   != EPROTO )
5567b725ae77Skettenis         {
5568b725ae77Skettenis           if( debug_on )
5569b725ae77Skettenis             printf( "TT fail for %s, with pid %d, tid %d, status %d \n",
5570b725ae77Skettenis                     get_printable_name_of_ttrace_request (TT_LWP_WUREGS),
5571b725ae77Skettenis                     pid, tid, tt_status );
5572b725ae77Skettenis         }
5573b725ae77Skettenis     }
5574b725ae77Skettenis #endif
5575b725ae77Skettenis 
5576b725ae77Skettenis   return tt_status;
5577b725ae77Skettenis }
5578b725ae77Skettenis 
5579b725ae77Skettenis void
_initialize_infttrace(void)5580b725ae77Skettenis _initialize_infttrace (void)
5581b725ae77Skettenis {
5582b725ae77Skettenis   /* Initialize the ttrace-based hardware watchpoint implementation. */
5583b725ae77Skettenis   memory_page_dictionary.page_count = (LONGEST) - 1;
5584b725ae77Skettenis   memory_page_dictionary.page_protections_allowed = 1;
5585b725ae77Skettenis 
5586b725ae77Skettenis   errno = 0;
5587b725ae77Skettenis   memory_page_dictionary.page_size = sysconf (_SC_PAGE_SIZE);
5588b725ae77Skettenis 
5589b725ae77Skettenis   /* We do a lot of casts from pointers to TTRACE_ARG_TYPE; make sure
5590b725ae77Skettenis      this is okay.  */
5591b725ae77Skettenis   if (sizeof (TTRACE_ARG_TYPE) < sizeof (void *))
5592b725ae77Skettenis     internal_error (__FILE__, __LINE__, "failed internal consistency check");
5593b725ae77Skettenis 
5594b725ae77Skettenis   if (errno || (memory_page_dictionary.page_size <= 0))
5595b725ae77Skettenis     perror_with_name ("sysconf");
5596b725ae77Skettenis }
5597