infttrace.c revision 46283
146283Sdfr/* Low level Unix child interface to ttrace, for GDB when running under HP-UX.
246283Sdfr   Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
346283Sdfr   Free Software Foundation, Inc.
446283Sdfr
546283SdfrThis file is part of GDB.
646283Sdfr
746283SdfrThis program is free software; you can redistribute it and/or modify
846283Sdfrit under the terms of the GNU General Public License as published by
946283Sdfrthe Free Software Foundation; either version 2 of the License, or
1046283Sdfr(at your option) any later version.
1146283Sdfr
1246283SdfrThis program is distributed in the hope that it will be useful,
1346283Sdfrbut WITHOUT ANY WARRANTY; without even the implied warranty of
1446283SdfrMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1546283SdfrGNU General Public License for more details.
1646283Sdfr
1746283SdfrYou should have received a copy of the GNU General Public License
1846283Sdfralong with this program; if not, write to the Free Software
1946283SdfrFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
2046283Sdfr
2146283Sdfr#include "defs.h"
2246283Sdfr#include "frame.h"
2346283Sdfr#include "inferior.h"
2446283Sdfr#include "target.h"
2546283Sdfr#include "gdb_string.h"
2646283Sdfr#include "wait.h"
2746283Sdfr#include "command.h"
2846283Sdfr
2946283Sdfr/* Some hackery to work around a use of the #define name NO_FLAGS
3046283Sdfr * in both gdb and HPUX (bfd.h and /usr/include/machine/vmparam.h).
3146283Sdfr */
3246283Sdfr#ifdef  NO_FLAGS
3346283Sdfr#define INFTTRACE_TEMP_HACK NO_FLAGS
3446283Sdfr#undef  NO_FLAGS
3546283Sdfr#endif
3646283Sdfr
3746283Sdfr#ifdef USG
3846283Sdfr#include <sys/types.h>
3946283Sdfr#endif
4046283Sdfr
4146283Sdfr#include <sys/param.h>
4246283Sdfr#include <sys/dir.h>
4346283Sdfr#include <signal.h>
4446283Sdfr#include <sys/ioctl.h>
4546283Sdfr
4646283Sdfr#include <sys/ttrace.h>
4746283Sdfr#ifdef HAVE_UNISTD_H
4846283Sdfr#include <unistd.h>
4946283Sdfr#endif
5046283Sdfr#include <sys/mman.h>
5146283Sdfr
5246283Sdfr#ifndef NO_PTRACE_H
5346283Sdfr#ifdef PTRACE_IN_WRONG_PLACE
5446283Sdfr#include <ptrace.h>
5546283Sdfr#else
5646283Sdfr#include <sys/ptrace.h>
5746283Sdfr#endif
5846283Sdfr#endif /* NO_PTRACE_H */
5946283Sdfr
6046283Sdfr/* Second half of the hackery above.  Non-ANSI C, so
6146283Sdfr * we can't use "#error", alas.
6246283Sdfr */
6346283Sdfr#ifdef NO_FLAGS
6446283Sdfr#if (NO_FLAGS != INFTTRACE_TEMP_HACK )
6546283Sdfr  /* #error "Hackery to remove warning didn't work right" */
6646283Sdfr#else
6746283Sdfr  /* Ok, new def'n of NO_FLAGS is same as old one; no action needed. */
6846283Sdfr#endif
6946283Sdfr#else
7046283Sdfr  /* #error "Didn't get expected re-definition of NO_FLAGS" */
7146283Sdfr#define NO_FLAGS INFTTRACE_TEMP_HACK
7246283Sdfr#endif
7346283Sdfr
7446283Sdfr#if !defined (PT_SETTRC)
7546283Sdfr#define PT_SETTRC	0	/* Make process traceable by parent */
7646283Sdfr#endif
7746283Sdfr#if !defined (PT_READ_I)
7846283Sdfr#define PT_READ_I	1	/* Read word from text space */
7946283Sdfr#endif
8046283Sdfr#if !defined (PT_READ_D)
8146283Sdfr#define	PT_READ_D	2	/* Read word from data space */
8246283Sdfr#endif
8346283Sdfr#if !defined (PT_READ_U)
8446283Sdfr#define PT_READ_U	3	/* Read word from kernel user struct */
8546283Sdfr#endif
8646283Sdfr#if !defined (PT_WRITE_I)
8746283Sdfr#define PT_WRITE_I	4	/* Write word to text space */
8846283Sdfr#endif
8946283Sdfr#if !defined (PT_WRITE_D)
9046283Sdfr#define PT_WRITE_D	5	/* Write word to data space */
9146283Sdfr#endif
9246283Sdfr#if !defined (PT_WRITE_U)
9346283Sdfr#define PT_WRITE_U	6	/* Write word to kernel user struct */
9446283Sdfr#endif
9546283Sdfr#if !defined (PT_CONTINUE)
9646283Sdfr#define PT_CONTINUE	7	/* Continue after signal */
9746283Sdfr#endif
9846283Sdfr#if !defined (PT_STEP)
9946283Sdfr#define PT_STEP		9	/* Set flag for single stepping */
10046283Sdfr#endif
10146283Sdfr#if !defined (PT_KILL)
10246283Sdfr#define PT_KILL		8	/* Send child a SIGKILL signal */
10346283Sdfr#endif
10446283Sdfr
10546283Sdfr#ifndef PT_ATTACH
10646283Sdfr#define PT_ATTACH PTRACE_ATTACH
10746283Sdfr#endif
10846283Sdfr#ifndef PT_DETACH
10946283Sdfr#define PT_DETACH PTRACE_DETACH
11046283Sdfr#endif
11146283Sdfr
11246283Sdfr#include "gdbcore.h"
11346283Sdfr#ifndef	NO_SYS_FILE
11446283Sdfr#include <sys/file.h>
11546283Sdfr#endif
11646283Sdfr
11746283Sdfr/* This semaphore is used to coordinate the child and parent processes
11846283Sdfr   after a fork(), and before an exec() by the child.  See parent_attach_all
11946283Sdfr   for details.
12046283Sdfr   */
12146283Sdfrtypedef struct {
12246283Sdfr    int  parent_channel[2];  /* Parent "talks" to [1], child "listens" to [0] */
12346283Sdfr    int  child_channel[2];   /* Child "talks" to [1], parent "listens" to [0] */
12446283Sdfr} startup_semaphore_t;
12546283Sdfr
12646283Sdfr#define SEM_TALK (1)
12746283Sdfr#define SEM_LISTEN (0)
12846283Sdfr
12946283Sdfrstatic startup_semaphore_t  startup_semaphore;
13046283Sdfr
13146283Sdfr/* See can_touch_threads_of_process for details. */
13246283Sdfrstatic int  vforking_child_pid = 0;
13346283Sdfrstatic int  vfork_in_flight = 0;
13446283Sdfr
13546283Sdfr/* To support PREPARE_TO_PROCEED (hppa_prepare_to_proceed).
13646283Sdfr */
13746283Sdfrstatic pid_t old_gdb_pid  = 0;
13846283Sdfrstatic pid_t reported_pid = 0;
13946283Sdfrstatic int reported_bpt = 0;
14046283Sdfr
14146283Sdfr/* 1 if ok as results of a ttrace or ttrace_wait call, 0 otherwise.
14246283Sdfr */
14346283Sdfr#define TT_OK( _status, _errno ) \
14446283Sdfr    (((_status) == 1) && ((_errno) == 0))
14546283Sdfr
14646283Sdfr#define TTRACE_ARG_TYPE uint64_t
14746283Sdfr
14846283Sdfr/* When supplied as the "addr" operand, ttrace interprets this
14946283Sdfr   to mean, "from the current address".
15046283Sdfr   */
15146283Sdfr#define TT_USE_CURRENT_PC ((TTRACE_ARG_TYPE) TT_NOPC)
15246283Sdfr
15346283Sdfr/* When supplied as the "addr", "data" or "addr2" operand for most
15446283Sdfr   requests, ttrace interprets this to mean, "pay no heed to this
15546283Sdfr   argument".
15646283Sdfr   */
15746283Sdfr#define TT_NIL ((TTRACE_ARG_TYPE) TT_NULLARG)
15846283Sdfr
15946283Sdfr/* This is capable of holding the value of a 32-bit register.  The
16046283Sdfr   value is always left-aligned in the buffer; i.e., [0] contains
16146283Sdfr   the most-significant byte of the register's value, and [sizeof(reg)]
16246283Sdfr   contains the least-significant value.
16346283Sdfr
16446283Sdfr   ??rehrauer: Yes, this assumes that an int is 32-bits on HP-UX, and
16546283Sdfr   that registers are 32-bits on HP-UX.  The latter assumption changes
16646283Sdfr   with PA2.0.
16746283Sdfr   */
16846283Sdfrtypedef int  register_value_t;
16946283Sdfr
17046283Sdfr/********************************************************************
17146283Sdfr
17246283Sdfr                 How this works:
17346283Sdfr
17446283Sdfr   1.  Thread numbers
17546283Sdfr
17646283Sdfr   The rest of GDB sees threads as being things with different
17746283Sdfr   "pid" (process id) values.  See "thread.c" for details.  The
17846283Sdfr   separate threads will be seen and reacted to if infttrace passes
17946283Sdfr   back different pid values (for _events_).  See wait_for_inferior
18046283Sdfr   in inftarg.c.
18146283Sdfr
18246283Sdfr   So infttrace is going to use thread ids externally, pretending
18346283Sdfr   they are process ids, and keep track internally so that it can
18446283Sdfr   use the real process id (and thread id) when calling ttrace.
18546283Sdfr
18646283Sdfr   The data structure that supports this is a linked list of the
18746283Sdfr   current threads.  Since at some date infttrace will have to
18846283Sdfr   deal with multiple processes, each list element records its
18946283Sdfr   corresponding pid, rather than having a single global.
19046283Sdfr
19146283Sdfr   Note that the list is only approximately current; that's ok, as
19246283Sdfr   it's up to date when we need it (we hope!).  Also, it can contain
19346283Sdfr   dead threads, as there's no harm if it does.
19446283Sdfr
19546283Sdfr   The approach taken here is to bury the translation from external
19646283Sdfr   to internal inside "call_ttrace" and a few other places.
19746283Sdfr
19846283Sdfr   There are some wrinkles:
19946283Sdfr
20046283Sdfr   o  When GDB forks itself to create the debug target process,
20146283Sdfr      there's only a pid of 0 around in the child, so the
20246283Sdfr      TT_PROC_SETTRC operation uses a more direct call to ttrace;
20346283Sdfr      Similiarly, the initial setting of the event mask happens
20446283Sdfr      early as  well, and so is also special-cased, and an attach
20546283Sdfr      uses a real pid;
20646283Sdfr
20746283Sdfr   o  We define an unthreaded application as having a "pseudo"
20846283Sdfr      thread;
20946283Sdfr
21046283Sdfr   o  To keep from confusing the rest of GDB, we don't switch
21146283Sdfr      the PID for the pseudo thread to a TID.  A table will help:
21246283Sdfr
21346283Sdfr      Rest of GDB sees these PIDs:     pid   tid1  tid2  tid3 ...
21446283Sdfr
21546283Sdfr      Our thread list stores:          pid   pid   pid   pid  ...
21646283Sdfr                                       tid0  tid1  tid2  tid3
21746283Sdfr
21846283Sdfr      Ttrace sees these TIDS:          tid0  tid1  tid2  tid3 ...
21946283Sdfr
22046283Sdfr      Both pid and tid0 will map to tid0, as there are infttrace.c-internal
22146283Sdfr      calls to ttrace using tid0.
22246283Sdfr
22346283Sdfr   2. Step and Continue
22446283Sdfr
22546283Sdfr   Since we're implementing the "stop the world" model, sub-model
22646283Sdfr   "other threads run during step", we have some stuff to do:
22746283Sdfr
22846283Sdfr   o  User steps require continuing all threads other than the
22946283Sdfr      one the user is stepping;
23046283Sdfr
23146283Sdfr   o  Internal debugger steps (such as over a breakpoint or watchpoint,
23246283Sdfr      but not out of a library load thunk) require stepping only
23346283Sdfr      the selected thread; this means that we have to report the
23446283Sdfr      step finish on that thread, which can lead to complications;
23546283Sdfr
23646283Sdfr   o  When a thread is created, it is created running, rather
23746283Sdfr      than stopped--so we have to stop it.
23846283Sdfr
23946283Sdfr   The OS doesn't guarantee the stopped thread list will be stable,
24046283Sdfr   no does it guarantee where on the stopped thread list a thread
24146283Sdfr   that is single-stepped will wind up: it's possible that it will
24246283Sdfr   be off the list for a while, it's possible the step will complete
24346283Sdfr   and it will be re-posted to the end...
24446283Sdfr
24546283Sdfr   This means we have to scan the stopped thread list, build up
24646283Sdfr   a work-list, and then run down the work list; we can't do the
24746283Sdfr   step/continue during the scan.
24846283Sdfr
24946283Sdfr   3. Buffering events
25046283Sdfr
25146283Sdfr   Then there's the issue of waiting for an event.  We do this by
25246283Sdfr   noticing how many events are reported at the end of each wait.
25346283Sdfr   From then on, we "fake" all resumes and steps, returning instantly,
25446283Sdfr   and don't do another wait.  Once all pending events are reported,
25546283Sdfr   we can really resume again.
25646283Sdfr
25746283Sdfr   To keep this hidden, all the routines which know about tids and
25846283Sdfr   pids or real events and simulated ones are static (file-local).
25946283Sdfr
26046283Sdfr   This code can make lots of calls to ttrace, in particular it
26146283Sdfr   can spin down the list of thread states more than once.  If this
26246283Sdfr   becomes a performance hit, the spin could be done once and the
26346283Sdfr   various "tsp" blocks saved, keeping all later spins in this
26446283Sdfr   process.
26546283Sdfr
26646283Sdfr   The O/S doesn't promise to keep the list straight, and so we must
26746283Sdfr   re-scan a lot.  By observation, it looks like a single-step/wait
26846283Sdfr   puts the stepped thread at the end of the list but doesn't change
26946283Sdfr   it otherwise.
27046283Sdfr
27146283Sdfr****************************************************************
27246283Sdfr*/
27346283Sdfr
27446283Sdfr/* Uncomment these to turn on various debugging output */
27546283Sdfr/* #define THREAD_DEBUG */
27646283Sdfr/* #define WAIT_BUFFER_DEBUG */
27746283Sdfr/* #define PARANOIA */
27846283Sdfr
27946283Sdfr
28046283Sdfr#define INFTTRACE_ALL_THREADS (-1)
28146283Sdfr#define INFTTRACE_STEP        (1)
28246283Sdfr#define INFTTRACE_CONTINUE    (0)
28346283Sdfr
28446283Sdfr/* FIX: this is used in inftarg.c/child_wait, in a hack.
28546283Sdfr */
28646283Sdfrextern int not_same_real_pid;
28746283Sdfr
28846283Sdfr/* This is used to count buffered events.
28946283Sdfr */
29046283Sdfrstatic unsigned int more_events_left = 0;
29146283Sdfr
29246283Sdfr/* Process state.
29346283Sdfr */
29446283Sdfrtypedef enum process_state_enum {
29546283Sdfr    STOPPED,
29646283Sdfr    FAKE_STEPPING,
29746283Sdfr    FAKE_CONTINUE,   /* For later use */
29846283Sdfr    RUNNING,
29946283Sdfr    FORKING,
30046283Sdfr    VFORKING
30146283Sdfr} process_state_t;
30246283Sdfr
30346283Sdfrstatic process_state_t process_state = STOPPED;
30446283Sdfr
30546283Sdfr/* User-specified stepping modality.
30646283Sdfr */
30746283Sdfrtypedef enum stepping_mode_enum {
30846283Sdfr    DO_DEFAULT,  /* ...which is a continue! */
30946283Sdfr    DO_STEP,
31046283Sdfr    DO_CONTINUE
31146283Sdfr} stepping_mode_t;
31246283Sdfr
31346283Sdfr/* Action to take on an attach, depends on
31446283Sdfr * what kind (user command, fork, vfork).
31546283Sdfr *
31646283Sdfr * At the moment, this is either:
31746283Sdfr *
31846283Sdfr * o  continue with a SIGTRAP signal, or
31946283Sdfr *
32046283Sdfr * o  leave stopped.
32146283Sdfr */
32246283Sdfrtypedef enum attach_continue_enum {
32346283Sdfr   DO_ATTACH_CONTINUE,
32446283Sdfr   DONT_ATTACH_CONTINUE
32546283Sdfr} attach_continue_t;
32646283Sdfr
32746283Sdfr/* This flag is true if we are doing a step-over-bpt
32846283Sdfr * with buffered events.  We will have to be sure to
32946283Sdfr * report the right thread, as otherwise the spaghetti
33046283Sdfr * code in "infrun.c/wait_for_inferior" will get
33146283Sdfr * confused.
33246283Sdfr */
33346283Sdfrstatic int doing_fake_step  = 0;
33446283Sdfrstatic lwpid_t  fake_step_tid    = 0;
33546283Sdfr
33646283Sdfr
33746283Sdfr/****************************************************
33846283Sdfr * Thread information structure routines and types. *
33946283Sdfr ****************************************************
34046283Sdfr */
34146283Sdfrtypedef
34246283Sdfrstruct thread_info_struct
34346283Sdfr{
34446283Sdfr    int			am_pseudo;      /* This is a pseudo-thread for the process. */
34546283Sdfr    int                 pid;            /* Process ID */
34646283Sdfr    lwpid_t             tid;            /* Thread  ID */
34746283Sdfr    int			handled;        /* 1 if a buffered event was handled. */
34846283Sdfr    int			seen;           /* 1 if this thread was seen on a traverse. */
34946283Sdfr    int			terminated;     /* 1 if thread has terminated. */
35046283Sdfr    int			have_signal;    /* 1 if signal to be sent */
35146283Sdfr    enum target_signal  signal_value;   /* Signal to send */
35246283Sdfr    int			have_start;     /* 1 if alternate starting address */
35346283Sdfr    stepping_mode_t     stepping_mode;  /* Whether to step or continue */
35446283Sdfr    CORE_ADDR           start;          /* Where to start */
35546283Sdfr    int			have_state;     /* 1 if the event state has been set */
35646283Sdfr    ttstate_t           last_stop_state;/* The most recently-waited event for this thread. */
35746283Sdfr    struct thread_info_struct
35846283Sdfr                       *next;           /* All threads are linked via this field. */
35946283Sdfr    struct thread_info_struct
36046283Sdfr                       *next_pseudo;    /* All pseudo-threads are linked via this field. */
36146283Sdfr} thread_info;
36246283Sdfr
36346283Sdfrtypedef
36446283Sdfrstruct thread_info_header_struct
36546283Sdfr{
36646283Sdfr    int          count;
36746283Sdfr    thread_info *head;
36846283Sdfr    thread_info *head_pseudo;
36946283Sdfr
37046283Sdfr} thread_info_header;
37146283Sdfr
37246283Sdfrstatic thread_info_header thread_head     = { 0, NULL, NULL };
37346283Sdfrstatic thread_info_header deleted_threads = { 0, NULL, NULL };
37446283Sdfr
37546283Sdfrstatic saved_real_pid = 0;
37646283Sdfr
37746283Sdfr
37846283Sdfr/*************************************************
37946283Sdfr *          Debugging support functions          *
38046283Sdfr *************************************************
38146283Sdfr */
38246283SdfrCORE_ADDR
38346283Sdfrget_raw_pc( ttid )
38446283Sdfr    lwpid_t ttid;
38546283Sdfr{
38646283Sdfr    unsigned long pc_val;
38746283Sdfr    int      offset;
38846283Sdfr    int      res;
38946283Sdfr
39046283Sdfr    offset = register_addr( PC_REGNUM, U_REGS_OFFSET );
39146283Sdfr    res    = read_from_register_save_state(
39246283Sdfr                       ttid,
39346283Sdfr                       (TTRACE_ARG_TYPE) offset,
39446283Sdfr                       (char *) &pc_val,
39546283Sdfr                       sizeof( pc_val ));
39646283Sdfr    if( res <= 0 ) {
39746283Sdfr        return (CORE_ADDR) pc_val;
39846283Sdfr    }
39946283Sdfr    else {
40046283Sdfr        return (CORE_ADDR) 0;
40146283Sdfr    }
40246283Sdfr}
40346283Sdfr
40446283Sdfrstatic char *
40546283Sdfrget_printable_name_of_stepping_mode( mode )
40646283Sdfr    stepping_mode_t mode;
40746283Sdfr{
40846283Sdfr  switch( mode ) {
40946283Sdfr    case DO_DEFAULT:  return "DO_DEFAULT";
41046283Sdfr    case DO_STEP:     return "DO_STEP";
41146283Sdfr    case DO_CONTINUE: return "DO_CONTINUE";
41246283Sdfr    default:          return "?unknown mode?";
41346283Sdfr  }
41446283Sdfr}
41546283Sdfr
41646283Sdfr/* This function returns a pointer to a string describing the
41746283Sdfr * ttrace event being reported.
41846283Sdfr */
41946283Sdfrchar *
42046283Sdfrget_printable_name_of_ttrace_event (event)
42146283Sdfr  ttevents_t event;
42246283Sdfr{
42346283Sdfr  /* This enumeration is "gappy", so don't use a table. */
42446283Sdfr  switch (event) {
42546283Sdfr
42646283Sdfr    case TTEVT_NONE:
42746283Sdfr       return "TTEVT_NONE";
42846283Sdfr    case TTEVT_SIGNAL:
42946283Sdfr       return "TTEVT_SIGNAL";
43046283Sdfr    case TTEVT_FORK:
43146283Sdfr       return "TTEVT_FORK";
43246283Sdfr    case TTEVT_EXEC:
43346283Sdfr       return "TTEVT_EXEC";
43446283Sdfr    case TTEVT_EXIT:
43546283Sdfr       return "TTEVT_EXIT";
43646283Sdfr    case TTEVT_VFORK:
43746283Sdfr       return "TTEVT_VFORK";
43846283Sdfr    case TTEVT_SYSCALL_RETURN:
43946283Sdfr       return "TTEVT_SYSCALL_RETURN";
44046283Sdfr    case TTEVT_LWP_CREATE:
44146283Sdfr       return "TTEVT_LWP_CREATE";
44246283Sdfr    case TTEVT_LWP_TERMINATE:
44346283Sdfr       return "TTEVT_LWP_TERMINATE";
44446283Sdfr    case TTEVT_LWP_EXIT:
44546283Sdfr       return "TTEVT_LWP_EXIT";
44646283Sdfr    case TTEVT_LWP_ABORT_SYSCALL:
44746283Sdfr       return "TTEVT_LWP_ABORT_SYSCALL";
44846283Sdfr    case TTEVT_SYSCALL_ENTRY:
44946283Sdfr       return "TTEVT_SYSCALL_ENTRY";
45046283Sdfr    case TTEVT_SYSCALL_RESTART:
45146283Sdfr       return "TTEVT_SYSCALL_RESTART";
45246283Sdfr    default :
45346283Sdfr      return "?new event?";
45446283Sdfr  }
45546283Sdfr}
45646283Sdfr
45746283Sdfr
45846283Sdfr/* This function translates the ttrace request enumeration into
45946283Sdfr * a character string that is its printable (aka "human readable")
46046283Sdfr * name.
46146283Sdfr */
46246283Sdfrchar *
46346283Sdfrget_printable_name_of_ttrace_request (request)
46446283Sdfr  ttreq_t  request;
46546283Sdfr{
46646283Sdfr  if (!IS_TTRACE_REQ (request))
46746283Sdfr    return "?bad req?";
46846283Sdfr
46946283Sdfr  /* This enumeration is "gappy", so don't use a table. */
47046283Sdfr  switch (request) {
47146283Sdfr    case TT_PROC_SETTRC :
47246283Sdfr      return "TT_PROC_SETTRC";
47346283Sdfr    case TT_PROC_ATTACH :
47446283Sdfr      return "TT_PROC_ATTACH";
47546283Sdfr    case TT_PROC_DETACH :
47646283Sdfr      return "TT_PROC_DETACH";
47746283Sdfr    case TT_PROC_RDTEXT :
47846283Sdfr      return "TT_PROC_RDTEXT";
47946283Sdfr    case TT_PROC_WRTEXT :
48046283Sdfr      return "TT_PROC_WRTEXT";
48146283Sdfr    case TT_PROC_RDDATA :
48246283Sdfr      return "TT_PROC_RDDATA";
48346283Sdfr    case TT_PROC_WRDATA :
48446283Sdfr      return "TT_PROC_WRDATA";
48546283Sdfr    case TT_PROC_STOP :
48646283Sdfr      return "TT_PROC_STOP";
48746283Sdfr    case TT_PROC_CONTINUE :
48846283Sdfr      return "TT_PROC_CONTINUE";
48946283Sdfr    case TT_PROC_GET_PATHNAME :
49046283Sdfr      return "TT_PROC_GET_PATHNAME";
49146283Sdfr    case TT_PROC_GET_EVENT_MASK :
49246283Sdfr      return "TT_PROC_GET_EVENT_MASK";
49346283Sdfr    case TT_PROC_SET_EVENT_MASK :
49446283Sdfr      return "TT_PROC_SET_EVENT_MASK";
49546283Sdfr    case TT_PROC_GET_FIRST_LWP_STATE :
49646283Sdfr      return "TT_PROC_GET_FIRST_LWP_STATE";
49746283Sdfr    case TT_PROC_GET_NEXT_LWP_STATE :
49846283Sdfr      return "TT_PROC_GET_NEXT_LWP_STATE";
49946283Sdfr    case TT_PROC_EXIT :
50046283Sdfr      return "TT_PROC_EXIT";
50146283Sdfr    case TT_PROC_GET_MPROTECT :
50246283Sdfr      return "TT_PROC_GET_MPROTECT";
50346283Sdfr    case TT_PROC_SET_MPROTECT :
50446283Sdfr      return "TT_PROC_SET_MPROTECT";
50546283Sdfr    case TT_PROC_SET_SCBM :
50646283Sdfr      return "TT_PROC_SET_SCBM";
50746283Sdfr    case TT_LWP_STOP :
50846283Sdfr      return "TT_LWP_STOP";
50946283Sdfr    case TT_LWP_CONTINUE :
51046283Sdfr      return "TT_LWP_CONTINUE";
51146283Sdfr    case TT_LWP_SINGLE :
51246283Sdfr      return "TT_LWP_SINGLE";
51346283Sdfr    case TT_LWP_RUREGS :
51446283Sdfr      return "TT_LWP_RUREGS";
51546283Sdfr    case TT_LWP_WUREGS :
51646283Sdfr      return "TT_LWP_WUREGS";
51746283Sdfr    case TT_LWP_GET_EVENT_MASK :
51846283Sdfr      return "TT_LWP_GET_EVENT_MASK";
51946283Sdfr    case TT_LWP_SET_EVENT_MASK :
52046283Sdfr      return "TT_LWP_SET_EVENT_MASK";
52146283Sdfr    case TT_LWP_GET_STATE	:
52246283Sdfr      return "TT_LWP_GET_STATE";
52346283Sdfr    default :
52446283Sdfr      return "?new req?";
52546283Sdfr  }
52646283Sdfr}
52746283Sdfr
52846283Sdfr
52946283Sdfr/* This function translates the process state enumeration into
53046283Sdfr * a character string that is its printable (aka "human readable")
53146283Sdfr * name.
53246283Sdfr */
53346283Sdfrstatic char *
53446283Sdfrget_printable_name_of_process_state (process_state)
53546283Sdfr  process_state_t  process_state;
53646283Sdfr{
53746283Sdfr  switch (process_state) {
53846283Sdfr    case STOPPED:
53946283Sdfr      return "STOPPED";
54046283Sdfr    case FAKE_STEPPING:
54146283Sdfr      return "FAKE_STEPPING";
54246283Sdfr    case RUNNING:
54346283Sdfr      return "RUNNING";
54446283Sdfr    case FORKING:
54546283Sdfr      return "FORKING";
54646283Sdfr    case VFORKING:
54746283Sdfr      return "VFORKING";
54846283Sdfr    default:
54946283Sdfr      return "?some unknown state?";
55046283Sdfr  }
55146283Sdfr}
55246283Sdfr
55346283Sdfr/* Set a ttrace thread state to a safe, initial state.
55446283Sdfr */
55546283Sdfrstatic void
55646283Sdfrclear_ttstate_t (tts)
55746283Sdfr    ttstate_t *  tts;
55846283Sdfr{
55946283Sdfr    tts->tts_pid = 0;
56046283Sdfr    tts->tts_lwpid = 0;
56146283Sdfr    tts->tts_user_tid = 0;
56246283Sdfr    tts->tts_event = TTEVT_NONE;
56346283Sdfr}
56446283Sdfr
56546283Sdfr/* Copy ttrace thread state TTS_FROM into TTS_TO.
56646283Sdfr */
56746283Sdfrstatic void
56846283Sdfrcopy_ttstate_t (tts_to, tts_from)
56946283Sdfr    ttstate_t *  tts_to;
57046283Sdfr    ttstate_t *  tts_from;
57146283Sdfr{
57246283Sdfr    memcpy ((char *) tts_to, (char *) tts_from, sizeof (*tts_to));
57346283Sdfr}
57446283Sdfr
57546283Sdfr/* Are there any live threads we know about?
57646283Sdfr */
57746283Sdfrstatic int
57846283Sdfrany_thread_records()
57946283Sdfr{
58046283Sdfr    return( thread_head.count > 0 );
58146283Sdfr}
58246283Sdfr
58346283Sdfr/* Create, fill in and link in a thread descriptor.
58446283Sdfr */
58546283Sdfrstatic thread_info *
58646283Sdfrcreate_thread_info (pid, tid)
58746283Sdfr    int     pid;
58846283Sdfr    lwpid_t tid;
58946283Sdfr{
59046283Sdfr    thread_info *  new_p;
59146283Sdfr    thread_info *  p;
59246283Sdfr    int  thread_count_of_pid;
59346283Sdfr
59446283Sdfr    new_p = malloc( sizeof( thread_info ));
59546283Sdfr    new_p->pid = pid;
59646283Sdfr    new_p->tid = tid;
59746283Sdfr    new_p->have_signal = 0;
59846283Sdfr    new_p->have_start  = 0;
59946283Sdfr    new_p->have_state  = 0;
60046283Sdfr    clear_ttstate_t( &new_p->last_stop_state );
60146283Sdfr    new_p->am_pseudo   = 0;
60246283Sdfr    new_p->handled     = 0;
60346283Sdfr    new_p->seen        = 0;
60446283Sdfr    new_p->terminated  = 0;
60546283Sdfr    new_p->next        = NULL;
60646283Sdfr    new_p->next_pseudo = NULL;
60746283Sdfr    new_p->stepping_mode = DO_DEFAULT;
60846283Sdfr
60946283Sdfr    if( 0 == thread_head.count ) {
61046283Sdfr#ifdef THREAD_DEBUG
61146283Sdfr        if( debug_on )
61246283Sdfr            printf( "First thread, pid %d tid %d!\n", pid, tid );
61346283Sdfr#endif
61446283Sdfr        saved_real_pid = inferior_pid;
61546283Sdfr    }
61646283Sdfr    else {
61746283Sdfr#ifdef THREAD_DEBUG
61846283Sdfr        if( debug_on )
61946283Sdfr            printf( "Subsequent thread, pid %d tid %d\n", pid, tid );
62046283Sdfr#endif
62146283Sdfr    }
62246283Sdfr
62346283Sdfr    /* Another day, another thread...
62446283Sdfr     */
62546283Sdfr    thread_head.count++;
62646283Sdfr
62746283Sdfr    /* The new thread always goes at the head of the list.
62846283Sdfr     */
62946283Sdfr    new_p->next       = thread_head.head;
63046283Sdfr    thread_head.head  = new_p;
63146283Sdfr
63246283Sdfr    /* Is this the "pseudo" thread of a process?  It is if there's
63346283Sdfr     * no other thread for this process on the list.  (Note that this
63446283Sdfr     * accomodates multiple processes, such as we see even for simple
63546283Sdfr     * cases like forking "non-threaded" programs.)
63646283Sdfr     */
63746283Sdfr    p = thread_head.head;
63846283Sdfr    thread_count_of_pid = 0;
63946283Sdfr    while (p)
64046283Sdfr      {
64146283Sdfr        if (p->pid == new_p->pid)
64246283Sdfr          thread_count_of_pid++;
64346283Sdfr        p = p->next;
64446283Sdfr      }
64546283Sdfr
64646283Sdfr    /* Did we see any other threads for this pid?  (Recall that we just
64746283Sdfr     * added this thread to the list...)
64846283Sdfr     */
64946283Sdfr    if (thread_count_of_pid == 1)
65046283Sdfr      {
65146283Sdfr        new_p->am_pseudo        = 1;
65246283Sdfr        new_p->next_pseudo      = thread_head.head_pseudo;
65346283Sdfr        thread_head.head_pseudo = new_p;
65446283Sdfr      }
65546283Sdfr
65646283Sdfr    return new_p;
65746283Sdfr}
65846283Sdfr
65946283Sdfr/* Get rid of our thread info.
66046283Sdfr */
66146283Sdfrstatic void
66246283Sdfrclear_thread_info ()
66346283Sdfr{
66446283Sdfr    thread_info *p;
66546283Sdfr    thread_info *q;
66646283Sdfr
66746283Sdfr#ifdef THREAD_DEBUG
66846283Sdfr    if( debug_on )
66946283Sdfr        printf( "Clearing all thread info\n" );
67046283Sdfr#endif
67146283Sdfr
67246283Sdfr    p = thread_head.head;
67346283Sdfr    while( p ) {
67446283Sdfr        q = p;
67546283Sdfr        p = p->next;
67646283Sdfr        free( q );
67746283Sdfr    }
67846283Sdfr
67946283Sdfr    thread_head.head        = NULL;
68046283Sdfr    thread_head.head_pseudo = NULL;
68146283Sdfr    thread_head.count       = 0;
68246283Sdfr
68346283Sdfr    p = deleted_threads.head;
68446283Sdfr    while( p ) {
68546283Sdfr        q = p;
68646283Sdfr        p = p->next;
68746283Sdfr        free( q );
68846283Sdfr    }
68946283Sdfr
69046283Sdfr    deleted_threads.head        = NULL;
69146283Sdfr    deleted_threads.head_pseudo = NULL;
69246283Sdfr    deleted_threads.count       = 0;
69346283Sdfr
69446283Sdfr    /* No threads, so can't have pending events.
69546283Sdfr     */
69646283Sdfr    more_events_left = 0;
69746283Sdfr}
69846283Sdfr
69946283Sdfr/* Given a tid, find the thread block for it.
70046283Sdfr */
70146283Sdfrstatic thread_info *
70246283Sdfrfind_thread_info (tid)
70346283Sdfr    lwpid_t tid;
70446283Sdfr{
70546283Sdfr    thread_info *p;
70646283Sdfr
70746283Sdfr    for( p = thread_head.head; p; p = p->next )  {
70846283Sdfr       if( p->tid == tid ) {
70946283Sdfr           return p;
71046283Sdfr       }
71146283Sdfr    }
71246283Sdfr
71346283Sdfr    for( p = deleted_threads.head; p; p = p->next )  {
71446283Sdfr       if( p->tid == tid ) {
71546283Sdfr           return p;
71646283Sdfr       }
71746283Sdfr    }
71846283Sdfr
71946283Sdfr    return NULL;
72046283Sdfr}
72146283Sdfr
72246283Sdfr/* For any but the pseudo thread, this maps to the
72346283Sdfr * thread ID.  For the pseudo thread, if you pass either
72446283Sdfr * the thread id or the PID, you get the pseudo thread ID.
72546283Sdfr *
72646283Sdfr * We have to be prepared for core gdb to ask about
72746283Sdfr * deleted threads.  We do the map, but we don't like it.
72846283Sdfr */
72946283Sdfrstatic lwpid_t
73046283Sdfrmap_from_gdb_tid( gdb_tid )
73146283Sdfr    lwpid_t gdb_tid;
73246283Sdfr{
73346283Sdfr    thread_info *p;
73446283Sdfr
73546283Sdfr    /* First assume gdb_tid really is a tid, and try to find a
73646283Sdfr     * matching entry on the threads list.
73746283Sdfr     */
73846283Sdfr    for( p = thread_head.head; p; p = p->next )  {
73946283Sdfr        if( p->tid == gdb_tid )
74046283Sdfr            return gdb_tid;
74146283Sdfr    }
74246283Sdfr
74346283Sdfr    /* It doesn't appear to be a tid; perhaps it's really a pid?
74446283Sdfr     * Try to find a "pseudo" thread entry on the threads list.
74546283Sdfr     */
74646283Sdfr    for (p = thread_head.head_pseudo; p != NULL; p = p->next_pseudo)
74746283Sdfr      {
74846283Sdfr        if (p->pid == gdb_tid)
74946283Sdfr          return p->tid;
75046283Sdfr      }
75146283Sdfr
75246283Sdfr    /* Perhaps it's the tid of a deleted thread we may still
75346283Sdfr     * have some knowledge of?
75446283Sdfr     */
75546283Sdfr    for( p = deleted_threads.head; p; p = p-> next ) {
75646283Sdfr        if( p->tid == gdb_tid )
75746283Sdfr            return gdb_tid;
75846283Sdfr    }
75946283Sdfr
76046283Sdfr    /* Or perhaps it's the pid of a deleted process we may still
76146283Sdfr     * have knowledge of?
76246283Sdfr     */
76346283Sdfr    for (p = deleted_threads.head_pseudo; p != NULL; p = p->next_pseudo)
76446283Sdfr      {
76546283Sdfr        if (p->pid == gdb_tid)
76646283Sdfr          return p->tid;
76746283Sdfr      }
76846283Sdfr
76946283Sdfr    return 0;  /* Error? */
77046283Sdfr}
77146283Sdfr
77246283Sdfr/* Map the other way: from a real tid to the
77346283Sdfr * "pid" known by core gdb.  This tid may be
77446283Sdfr * for a thread that just got deleted, so we
77546283Sdfr * also need to consider deleted threads.
77646283Sdfr */
77746283Sdfrstatic lwpid_t
77846283Sdfrmap_to_gdb_tid( real_tid )
77946283Sdfr    lwpid_t real_tid;
78046283Sdfr{
78146283Sdfr    thread_info *p;
78246283Sdfr
78346283Sdfr    for( p = thread_head.head; p; p = p->next )  {
78446283Sdfr        if( p->tid == real_tid ) {
78546283Sdfr            if( p->am_pseudo )
78646283Sdfr                return p->pid;
78746283Sdfr            else
78846283Sdfr                return real_tid;
78946283Sdfr       }
79046283Sdfr    }
79146283Sdfr
79246283Sdfr    for( p = deleted_threads.head; p; p = p-> next ) {
79346283Sdfr        if( p->tid == real_tid )
79446283Sdfr            if( p->am_pseudo )
79546283Sdfr                return p->pid;  /* Error? */
79646283Sdfr            else
79746283Sdfr                return real_tid;
79846283Sdfr    }
79946283Sdfr
80046283Sdfr    return 0;  /* Error?  Never heard of this thread! */
80146283Sdfr}
80246283Sdfr
80346283Sdfr/* Do any threads have saved signals?
80446283Sdfr */
80546283Sdfrstatic int
80646283Sdfrsaved_signals_exist ()
80746283Sdfr{
80846283Sdfr    thread_info *p;
80946283Sdfr
81046283Sdfr    for( p = thread_head.head; p; p = p->next )  {
81146283Sdfr       if( p->have_signal ) {
81246283Sdfr           return 1;
81346283Sdfr       }
81446283Sdfr    }
81546283Sdfr
81646283Sdfr    return 0;
81746283Sdfr}
81846283Sdfr
81946283Sdfr/* Is this the tid for the zero-th thread?
82046283Sdfr */
82146283Sdfrstatic int
82246283Sdfris_pseudo_thread (tid)
82346283Sdfr    lwpid_t tid;
82446283Sdfr{
82546283Sdfr    thread_info *p = find_thread_info( tid );
82646283Sdfr    if( NULL == p || p->terminated )
82746283Sdfr        return 0;
82846283Sdfr    else
82946283Sdfr        return p->am_pseudo;
83046283Sdfr}
83146283Sdfr
83246283Sdfr/* Is this thread terminated?
83346283Sdfr */
83446283Sdfrstatic int
83546283Sdfris_terminated (tid)
83646283Sdfr    lwpid_t tid;
83746283Sdfr{
83846283Sdfr    thread_info *p = find_thread_info( tid );
83946283Sdfr
84046283Sdfr    if( NULL != p )
84146283Sdfr        return p->terminated;
84246283Sdfr
84346283Sdfr    return 0;
84446283Sdfr}
84546283Sdfr
84646283Sdfr/* Is this pid a real PID or a TID?
84746283Sdfr */
84846283Sdfrstatic int
84946283Sdfris_process_id (pid)
85046283Sdfr  int  pid;
85146283Sdfr{
85246283Sdfr  lwpid_t  tid;
85346283Sdfr  thread_info *  tinfo;
85446283Sdfr  pid_t  this_pid;
85546283Sdfr  int  this_pid_count;
85646283Sdfr
85746283Sdfr  /* What does PID really represent?
85846283Sdfr   */
85946283Sdfr  tid = map_from_gdb_tid (pid);
86046283Sdfr  if (tid <= 0)
86146283Sdfr    return 0; /* Actually, is probably an error... */
86246283Sdfr
86346283Sdfr  tinfo = find_thread_info (tid);
86446283Sdfr
86546283Sdfr  /* Does it appear to be a true thread?
86646283Sdfr   */
86746283Sdfr  if (! tinfo->am_pseudo)
86846283Sdfr    return 0;
86946283Sdfr
87046283Sdfr  /* Else, it looks like it may be a process.  See if there's any other
87146283Sdfr   * threads with the same process ID, though.  If there are, then TID
87246283Sdfr   * just happens to be the first thread of several for this process.
87346283Sdfr   */
87446283Sdfr  this_pid = tinfo->pid;
87546283Sdfr  this_pid_count = 0;
87646283Sdfr  for (tinfo = thread_head.head; tinfo; tinfo = tinfo->next)
87746283Sdfr    {
87846283Sdfr      if (tinfo->pid == this_pid)
87946283Sdfr        this_pid_count++;
88046283Sdfr    }
88146283Sdfr
88246283Sdfr  return (this_pid_count == 1);
88346283Sdfr}
88446283Sdfr
88546283Sdfr
88646283Sdfr/* Add a thread to our info.  Prevent duplicate entries.
88746283Sdfr */
88846283Sdfrstatic thread_info *
88946283Sdfradd_tthread (pid, tid)
89046283Sdfr    int     pid;
89146283Sdfr    lwpid_t tid;
89246283Sdfr{
89346283Sdfr    thread_info *p;
89446283Sdfr
89546283Sdfr    p = find_thread_info( tid );
89646283Sdfr    if( NULL == p )
89746283Sdfr        p = create_thread_info( pid, tid );
89846283Sdfr
89946283Sdfr    return p;
90046283Sdfr}
90146283Sdfr
90246283Sdfr/* Notice that a thread was deleted.
90346283Sdfr */
90446283Sdfrstatic void
90546283Sdfrdel_tthread (tid)
90646283Sdfr    lwpid_t tid;
90746283Sdfr{
90846283Sdfr    thread_info *p;
90946283Sdfr    thread_info *chase;
91046283Sdfr
91146283Sdfr    if( thread_head.count <= 0 ) {
91246283Sdfr        error( "Internal error in thread database." );
91346283Sdfr        return;
91446283Sdfr    }
91546283Sdfr
91646283Sdfr    chase = NULL;
91746283Sdfr    for( p = thread_head.head; p; p = p->next )  {
91846283Sdfr       if( p->tid == tid ) {
91946283Sdfr
92046283Sdfr#ifdef THREAD_DEBUG
92146283Sdfr           if( debug_on )
92246283Sdfr               printf( "Delete here: %d \n", tid );
92346283Sdfr#endif
92446283Sdfr
92546283Sdfr           if( p->am_pseudo ) {
92646283Sdfr               /*
92746283Sdfr                * Deleting a main thread is ok if we're doing
92846283Sdfr                * a parent-follow on a child; this is odd but
92946283Sdfr                * not wrong.  It apparently _doesn't_ happen
93046283Sdfr                * on the child-follow, as we don't just delete
93146283Sdfr                * the pseudo while keeping the rest of the
93246283Sdfr                * threads around--instead, we clear out the whole
93346283Sdfr                * thread list at once.
93446283Sdfr                */
93546283Sdfr               thread_info *q;
93646283Sdfr               thread_info *q_chase;
93746283Sdfr
93846283Sdfr               q_chase = NULL;
93946283Sdfr               for( q = thread_head.head_pseudo; q; q = q -> next ) {
94046283Sdfr                    if( q == p ) {
94146283Sdfr                        /* Remove from pseudo list.
94246283Sdfr                         */
94346283Sdfr                        if( q_chase == NULL )
94446283Sdfr                            thread_head.head_pseudo = p->next_pseudo;
94546283Sdfr                        else
94646283Sdfr                            q_chase-> next = p->next_pseudo;
94746283Sdfr                    }
94846283Sdfr                    else
94946283Sdfr                        q_chase = q;
95046283Sdfr               }
95146283Sdfr           }
95246283Sdfr
95346283Sdfr           /* Remove from live list.
95446283Sdfr            */
95546283Sdfr           thread_head.count--;
95646283Sdfr
95746283Sdfr           if( NULL == chase )
95846283Sdfr               thread_head.head = p->next;
95946283Sdfr           else
96046283Sdfr               chase->next      = p->next;
96146283Sdfr
96246283Sdfr           /* Add to deleted thread list.
96346283Sdfr            */
96446283Sdfr           p->next = deleted_threads.head;
96546283Sdfr           deleted_threads.head = p;
96646283Sdfr           deleted_threads.count++;
96746283Sdfr           if( p->am_pseudo ) {
96846283Sdfr               p->next_pseudo              = deleted_threads.head_pseudo;
96946283Sdfr               deleted_threads.head_pseudo = p;
97046283Sdfr           }
97146283Sdfr           p->terminated = 1;
97246283Sdfr
97346283Sdfr           return;
97446283Sdfr       }
97546283Sdfr
97646283Sdfr       else
97746283Sdfr           chase = p;
97846283Sdfr    }
97946283Sdfr}
98046283Sdfr
98146283Sdfr/* Get the pid for this tid. (Has to be a real TID!).
98246283Sdfr */
98346283Sdfrstatic int
98446283Sdfrget_pid_for (tid)
98546283Sdfr    lwpid_t tid;
98646283Sdfr{
98746283Sdfr    thread_info *p;
98846283Sdfr
98946283Sdfr    for( p = thread_head.head; p; p = p->next ) {
99046283Sdfr        if( p->tid == tid ) {
99146283Sdfr            return p->pid;
99246283Sdfr        }
99346283Sdfr    }
99446283Sdfr
99546283Sdfr    for( p = deleted_threads.head; p; p = p->next ) {
99646283Sdfr        if( p->tid == tid ) {
99746283Sdfr            return p->pid;
99846283Sdfr        }
99946283Sdfr    }
100046283Sdfr
100146283Sdfr    return 0;
100246283Sdfr}
100346283Sdfr
100446283Sdfr/* Note that this thread's current event has been handled.
100546283Sdfr */
100646283Sdfrstatic void
100746283Sdfrset_handled( pid, tid )
100846283Sdfr    int     pid;
100946283Sdfr    lwpid_t tid;
101046283Sdfr{
101146283Sdfr    thread_info *p;
101246283Sdfr
101346283Sdfr    p = find_thread_info( tid );
101446283Sdfr    if( NULL == p )
101546283Sdfr        p = add_tthread( pid, tid );
101646283Sdfr
101746283Sdfr    p->handled = 1;
101846283Sdfr}
101946283Sdfr
102046283Sdfr/* Was this thread's current event handled?
102146283Sdfr */
102246283Sdfrstatic int
102346283Sdfrwas_handled( tid )
102446283Sdfr    lwpid_t tid;
102546283Sdfr{
102646283Sdfr    thread_info *p;
102746283Sdfr
102846283Sdfr    p = find_thread_info( tid );
102946283Sdfr    if( NULL != p )
103046283Sdfr        return p->handled;
103146283Sdfr
103246283Sdfr    return 0;  /* New threads have not been handled */
103346283Sdfr}
103446283Sdfr
103546283Sdfr/* Set this thread to unhandled.
103646283Sdfr */
103746283Sdfrstatic void
103846283Sdfrclear_handled( tid )
103946283Sdfr  lwpid_t  tid;
104046283Sdfr{
104146283Sdfr  thread_info *  p;
104246283Sdfr
104346283Sdfr#ifdef WAIT_BUFFER_DEBUG
104446283Sdfr    if( debug_on )
104546283Sdfr        printf( "clear_handled %d\n", (int) tid );
104646283Sdfr#endif
104746283Sdfr
104846283Sdfr  p = find_thread_info (tid);
104946283Sdfr  if (p == NULL)
105046283Sdfr    error ("Internal error: No thread state to clear?");
105146283Sdfr
105246283Sdfr  p->handled = 0;
105346283Sdfr}
105446283Sdfr
105546283Sdfr/* Set all threads to unhandled.
105646283Sdfr */
105746283Sdfrstatic void
105846283Sdfrclear_all_handled ()
105946283Sdfr{
106046283Sdfr    thread_info *p;
106146283Sdfr
106246283Sdfr#ifdef WAIT_BUFFER_DEBUG
106346283Sdfr    if( debug_on )
106446283Sdfr        printf( "clear_all_handled\n" );
106546283Sdfr#endif
106646283Sdfr
106746283Sdfr    for( p = thread_head.head; p; p = p->next ) {
106846283Sdfr        p->handled = 0;
106946283Sdfr    }
107046283Sdfr
107146283Sdfr    for( p = deleted_threads.head; p; p = p->next ) {
107246283Sdfr        p->handled = 0;
107346283Sdfr    }
107446283Sdfr}
107546283Sdfr
107646283Sdfr/* Set this thread to default stepping mode.
107746283Sdfr */
107846283Sdfrstatic void
107946283Sdfrclear_stepping_mode( tid )
108046283Sdfr  lwpid_t  tid;
108146283Sdfr{
108246283Sdfr  thread_info *  p;
108346283Sdfr
108446283Sdfr#ifdef WAIT_BUFFER_DEBUG
108546283Sdfr  if( debug_on )
108646283Sdfr       printf( "clear_stepping_mode %d\n", (int) tid );
108746283Sdfr#endif
108846283Sdfr
108946283Sdfr  p = find_thread_info (tid);
109046283Sdfr  if (p == NULL)
109146283Sdfr    error ("Internal error: No thread state to clear?");
109246283Sdfr
109346283Sdfr  p->stepping_mode = DO_DEFAULT;
109446283Sdfr}
109546283Sdfr
109646283Sdfr/* Set all threads to do default continue on resume.
109746283Sdfr */
109846283Sdfrstatic void
109946283Sdfrclear_all_stepping_mode ()
110046283Sdfr{
110146283Sdfr    thread_info *p;
110246283Sdfr
110346283Sdfr#ifdef WAIT_BUFFER_DEBUG
110446283Sdfr    if( debug_on )
110546283Sdfr        printf( "clear_all_stepping_mode\n" );
110646283Sdfr#endif
110746283Sdfr
110846283Sdfr    for( p = thread_head.head; p; p = p->next ) {
110946283Sdfr        p->stepping_mode = DO_DEFAULT;
111046283Sdfr    }
111146283Sdfr
111246283Sdfr    for( p = deleted_threads.head; p; p = p->next ) {
111346283Sdfr        p->stepping_mode = DO_DEFAULT;
111446283Sdfr    }
111546283Sdfr}
111646283Sdfr
111746283Sdfr/* Set all threads to unseen on this pass.
111846283Sdfr */
111946283Sdfrstatic void
112046283Sdfrset_all_unseen ()
112146283Sdfr{
112246283Sdfr    thread_info *p;
112346283Sdfr
112446283Sdfr    for( p = thread_head.head; p; p = p->next ) {
112546283Sdfr        p->seen = 0;
112646283Sdfr    }
112746283Sdfr}
112846283Sdfr
112946283Sdfr#if (defined( THREAD_DEBUG ) || defined( PARANOIA ))
113046283Sdfr/* debugging routine.
113146283Sdfr */
113246283Sdfrstatic void
113346283Sdfrprint_tthread (p)
113446283Sdfr    thread_info *  p;
113546283Sdfr{
113646283Sdfr    printf( " Thread pid %d, tid %d", p->pid, p->tid );
113746283Sdfr    if( p->have_state )
113846283Sdfr        printf( ", event is %s",
113946283Sdfr            get_printable_name_of_ttrace_event( p->last_stop_state.tts_event ));
114046283Sdfr
114146283Sdfr    if( p->am_pseudo )
114246283Sdfr        printf( ", pseudo thread" );
114346283Sdfr
114446283Sdfr    if( p->have_signal )
114546283Sdfr        printf( ", have signal 0x%x", p->signal_value );
114646283Sdfr
114746283Sdfr    if( p->have_start )
114846283Sdfr        printf( ", have start at 0x%x", p->start );
114946283Sdfr
115046283Sdfr    printf( ", step is %s", get_printable_name_of_stepping_mode( p->stepping_mode ));
115146283Sdfr
115246283Sdfr    if( p->handled )
115346283Sdfr        printf( ", handled" );
115446283Sdfr    else
115546283Sdfr        printf( ", not handled" );
115646283Sdfr
115746283Sdfr    if( p->seen )
115846283Sdfr        printf( ", seen" );
115946283Sdfr    else
116046283Sdfr        printf( ", not seen" );
116146283Sdfr
116246283Sdfr    printf( "\n" );
116346283Sdfr}
116446283Sdfr
116546283Sdfrstatic void
116646283Sdfrprint_tthreads ()
116746283Sdfr{
116846283Sdfr    thread_info *p;
116946283Sdfr
117046283Sdfr    if( thread_head.count == 0 )
117146283Sdfr        printf( "Thread list is empty\n" );
117246283Sdfr    else {
117346283Sdfr        printf( "Thread list has " );
117446283Sdfr        if( thread_head.count == 1 )
117546283Sdfr            printf( "1 entry:\n" );
117646283Sdfr        else
117746283Sdfr            printf( "%d entries:\n", thread_head.count );
117846283Sdfr        for( p = thread_head.head; p; p = p->next ) {
117946283Sdfr            print_tthread (p);
118046283Sdfr        }
118146283Sdfr    }
118246283Sdfr
118346283Sdfr    if( deleted_threads.count == 0 )
118446283Sdfr        printf( "Deleted thread list is empty\n" );
118546283Sdfr    else {
118646283Sdfr        printf( "Deleted thread list has " );
118746283Sdfr        if( deleted_threads.count == 1 )
118846283Sdfr            printf( "1 entry:\n" );
118946283Sdfr        else
119046283Sdfr            printf( "%d entries:\n", deleted_threads.count );
119146283Sdfr
119246283Sdfr        for( p = deleted_threads.head; p; p = p->next ) {
119346283Sdfr            print_tthread (p);
119446283Sdfr        }
119546283Sdfr    }
119646283Sdfr}
119746283Sdfr#endif
119846283Sdfr
119946283Sdfr/* Update the thread list based on the "seen" bits.
120046283Sdfr */
120146283Sdfrstatic void
120246283Sdfrupdate_thread_list ()
120346283Sdfr{
120446283Sdfr    thread_info *p;
120546283Sdfr    thread_info *chase;
120646283Sdfr
120746283Sdfr    chase = NULL;
120846283Sdfr    for( p = thread_head.head; p; p = p->next ) {
120946283Sdfr      /* Is this an "unseen" thread which really happens to be a process?
121046283Sdfr         If so, is it inferior_pid and is a vfork in flight?  If yes to
121146283Sdfr         all, then DON'T REMOVE IT!  We're in the midst of moving a vfork
121246283Sdfr         operation, which is a multiple step thing, to the point where we
121346283Sdfr         can touch the parent again.  We've most likely stopped to examine
121446283Sdfr         the child at a late stage in the vfork, and if we're not following
121546283Sdfr         the child, we'd best not treat the parent as a dead "thread"...
121646283Sdfr         */
121746283Sdfr        if( (!p->seen) && p->am_pseudo && vfork_in_flight
121846283Sdfr         && (p->pid != vforking_child_pid))
121946283Sdfr            p->seen = 1;
122046283Sdfr
122146283Sdfr        if( !p->seen ) {
122246283Sdfr            /* Remove this one
122346283Sdfr             */
122446283Sdfr
122546283Sdfr#ifdef THREAD_DEBUG
122646283Sdfr           if( debug_on )
122746283Sdfr               printf( "Delete unseen thread: %d \n", p->tid );
122846283Sdfr#endif
122946283Sdfr           del_tthread( p->tid );
123046283Sdfr       }
123146283Sdfr    }
123246283Sdfr}
123346283Sdfr
123446283Sdfr
123546283Sdfr
123646283Sdfr/************************************************
123746283Sdfr *            O/S call wrappers                 *
123846283Sdfr ************************************************
123946283Sdfr */
124046283Sdfr
124146283Sdfr/* This function simply calls ttrace with the given arguments.
124246283Sdfr * It exists so that all calls to ttrace are isolated.  All
124346283Sdfr * parameters should be as specified by "man 2 ttrace".
124446283Sdfr *
124546283Sdfr * No other "raw" calls to ttrace should exist in this module.
124646283Sdfr */
124746283Sdfrstatic int
124846283Sdfrcall_real_ttrace( request, pid, tid, addr, data, addr2 )
124946283Sdfr  ttreq_t          request;
125046283Sdfr  pid_t            pid;
125146283Sdfr  lwpid_t          tid;
125246283Sdfr  TTRACE_ARG_TYPE  addr, data, addr2;
125346283Sdfr{
125446283Sdfr  int  tt_status;
125546283Sdfr
125646283Sdfr  errno = 0;
125746283Sdfr  tt_status = ttrace( request, pid, tid, addr, data, addr2 );
125846283Sdfr
125946283Sdfr#ifdef THREAD_DEBUG
126046283Sdfr  if (errno) {
126146283Sdfr    /* Don't bother for a known benign error: if you ask for the
126246283Sdfr     * first thread state, but there is only one thread and it's
126346283Sdfr     * not stopped, ttrace complains.
126446283Sdfr     *
126546283Sdfr     * We have this inside the #ifdef because our caller will do
126646283Sdfr     * this check for real.
126746283Sdfr     */
126846283Sdfr    if( request != TT_PROC_GET_FIRST_LWP_STATE
126946283Sdfr    ||  errno   != EPROTO ) {
127046283Sdfr        if( debug_on )
127146283Sdfr            printf( "TT fail for %s, with pid %d, tid %d, status %d \n",
127246283Sdfr                    get_printable_name_of_ttrace_request (request),
127346283Sdfr                    pid, tid, tt_status );
127446283Sdfr    }
127546283Sdfr  }
127646283Sdfr#endif
127746283Sdfr
127846283Sdfr#if 0
127946283Sdfr  /* ??rehrauer: It would probably be most robust to catch and report
128046283Sdfr   * failed requests here.  However, some clients of this interface
128146283Sdfr   * seem to expect to catch & deal with them, so we'd best not.
128246283Sdfr   */
128346283Sdfr  if (errno) {
128446283Sdfr    strcpy (reason_for_failure, "ttrace (");
128546283Sdfr    strcat (reason_for_failure, get_printable_name_of_ttrace_request (request));
128646283Sdfr    strcat (reason_for_failure, ")");
128746283Sdfr    printf( "ttrace error, errno = %d\n", errno );
128846283Sdfr    perror_with_name (reason_for_failure);
128946283Sdfr  }
129046283Sdfr#endif
129146283Sdfr
129246283Sdfr  return tt_status;
129346283Sdfr}
129446283Sdfr
129546283Sdfr
129646283Sdfr/* This function simply calls ttrace_wait with the given arguments.
129746283Sdfr * It exists so that all calls to ttrace_wait are isolated.
129846283Sdfr *
129946283Sdfr * No "raw" calls to ttrace_wait should exist elsewhere.
130046283Sdfr */
130146283Sdfrstatic int
130246283Sdfrcall_real_ttrace_wait( pid, tid, option, tsp, tsp_size )
130346283Sdfr  int        pid;
130446283Sdfr  lwpid_t    tid;
130546283Sdfr  ttwopt_t   option;
130646283Sdfr  ttstate_t *tsp;
130746283Sdfr  size_t     tsp_size;
130846283Sdfr{
130946283Sdfr  int        ttw_status;
131046283Sdfr  thread_info *  tinfo = NULL;
131146283Sdfr
131246283Sdfr  errno = 0;
131346283Sdfr  ttw_status = ttrace_wait (pid, tid, option, tsp, tsp_size);
131446283Sdfr
131546283Sdfr  if (errno) {
131646283Sdfr#ifdef THREAD_DEBUG
131746283Sdfr      if( debug_on )
131846283Sdfr          printf( "TW fail with pid %d, tid %d \n", pid, tid );
131946283Sdfr#endif
132046283Sdfr
132146283Sdfr      perror_with_name ("ttrace wait");
132246283Sdfr  }
132346283Sdfr
132446283Sdfr  return ttw_status;
132546283Sdfr}
132646283Sdfr
132746283Sdfr
132846283Sdfr/* A process may have one or more kernel threads, of which all or
132946283Sdfr   none may be stopped.  This function returns the ID of the first
133046283Sdfr   kernel thread in a stopped state, or 0 if none are stopped.
133146283Sdfr
133246283Sdfr   This function can be used with get_process_next_stopped_thread_id
133346283Sdfr   to iterate over the IDs of all stopped threads of this process.
133446283Sdfr */
133546283Sdfrstatic lwpid_t
133646283Sdfrget_process_first_stopped_thread_id (pid, thread_state)
133746283Sdfr  int  pid;
133846283Sdfr  ttstate_t *  thread_state;
133946283Sdfr{
134046283Sdfr  int  tt_status;
134146283Sdfr
134246283Sdfr  tt_status = call_real_ttrace (
134346283Sdfr                      TT_PROC_GET_FIRST_LWP_STATE,
134446283Sdfr                      (pid_t) pid,
134546283Sdfr                      (lwpid_t) TT_NIL,
134646283Sdfr                      (TTRACE_ARG_TYPE) thread_state,
134746283Sdfr                      (TTRACE_ARG_TYPE) sizeof (*thread_state),
134846283Sdfr                      TT_NIL);
134946283Sdfr
135046283Sdfr  if (errno) {
135146283Sdfr    if( errno == EPROTO) {
135246283Sdfr        /* This is an error we can handle: there isn't any stopped
135346283Sdfr         * thread.  This happens when we're re-starting the application
135446283Sdfr         * and it has only one thread.  GET_NEXT handles the case of
135546283Sdfr         * no more stopped threads well; GET_FIRST doesn't.  (A ttrace
135646283Sdfr         * "feature".)
135746283Sdfr         */
135846283Sdfr        tt_status = 1;
135946283Sdfr        errno     = 0;
136046283Sdfr        return 0;
136146283Sdfr    }
136246283Sdfr    else
136346283Sdfr        perror_with_name ("ttrace");
136446283Sdfr  }
136546283Sdfr
136646283Sdfr  if( tt_status < 0 )
136746283Sdfr    /* Failed somehow.
136846283Sdfr     */
136946283Sdfr    return 0;
137046283Sdfr
137146283Sdfr  return thread_state->tts_lwpid;
137246283Sdfr}
137346283Sdfr
137446283Sdfr
137546283Sdfr/* This function returns the ID of the "next" kernel thread in a
137646283Sdfr   stopped state, or 0 if there are none.  "Next" refers to the
137746283Sdfr   thread following that of the last successful call to this
137846283Sdfr   function or to get_process_first_stopped_thread_id, using
137946283Sdfr   the value of thread_state returned by that call.
138046283Sdfr
138146283Sdfr   This function can be used with get_process_first_stopped_thread_id
138246283Sdfr   to iterate over the IDs of all stopped threads of this process.
138346283Sdfr */
138446283Sdfrstatic lwpid_t
138546283Sdfrget_process_next_stopped_thread_id (pid, thread_state)
138646283Sdfr  int  pid;
138746283Sdfr  ttstate_t *  thread_state;
138846283Sdfr{
138946283Sdfr  int  tt_status;
139046283Sdfr
139146283Sdfr  tt_status = call_real_ttrace (
139246283Sdfr                      TT_PROC_GET_NEXT_LWP_STATE,
139346283Sdfr                      (pid_t) pid,
139446283Sdfr                      (lwpid_t) TT_NIL,
139546283Sdfr                      (TTRACE_ARG_TYPE) thread_state,
139646283Sdfr                      (TTRACE_ARG_TYPE) sizeof (*thread_state),
139746283Sdfr                      TT_NIL);
139846283Sdfr  if (errno)
139946283Sdfr    perror_with_name ("ttrace");
140046283Sdfr
140146283Sdfr  if (tt_status < 0)
140246283Sdfr    /* Failed
140346283Sdfr     */
140446283Sdfr    return 0;
140546283Sdfr
140646283Sdfr  else if( tt_status == 0 ) {
140746283Sdfr    /* End of list, no next state.  Don't return the
140846283Sdfr     * tts_lwpid, as it's a meaningless "240".
140946283Sdfr     *
141046283Sdfr     * This is an HPUX "feature".
141146283Sdfr     */
141246283Sdfr    return 0;
141346283Sdfr  }
141446283Sdfr
141546283Sdfr  return thread_state->tts_lwpid;
141646283Sdfr}
141746283Sdfr
141846283Sdfr/* ??rehrauer: Eventually this function perhaps should be calling
141946283Sdfr   pid_to_thread_id.  However, that function currently does nothing
142046283Sdfr   for HP-UX.  Even then, I'm not clear whether that function
142146283Sdfr   will return a "kernel" thread ID, or a "user" thread ID.  If
142246283Sdfr   the former, we can just call it here.  If the latter, we must
142346283Sdfr   map from the "user" tid to a "kernel" tid.
142446283Sdfr
142546283Sdfr   NOTE: currently not called.
142646283Sdfr */
142746283Sdfrstatic lwpid_t
142846283Sdfrget_active_tid_of_pid (pid)
142946283Sdfr  int  pid;
143046283Sdfr{
143146283Sdfr  ttstate_t  thread_state;
143246283Sdfr
143346283Sdfr  return get_process_first_stopped_thread_id (pid, &thread_state);
143446283Sdfr}
143546283Sdfr
143646283Sdfr/* This function returns 1 if tt_request is a ttrace request that
143746283Sdfr * operates upon all threads of a (i.e., the entire) process.
143846283Sdfr */
143946283Sdfrint
144046283Sdfris_process_ttrace_request (tt_request)
144146283Sdfr  ttreq_t  tt_request;
144246283Sdfr{
144346283Sdfr  return IS_TTRACE_PROCREQ (tt_request);
144446283Sdfr}
144546283Sdfr
144646283Sdfr
144746283Sdfr/* This function translates a thread ttrace request into
144846283Sdfr * the equivalent process request for a one-thread process.
144946283Sdfr */
145046283Sdfrstatic ttreq_t
145146283Sdfrmake_process_version( request )
145246283Sdfr  ttreq_t request;
145346283Sdfr{
145446283Sdfr  if (!IS_TTRACE_REQ (request)) {
145546283Sdfr    error( "Internal error, bad ttrace request made\n" );
145646283Sdfr    return -1;
145746283Sdfr  }
145846283Sdfr
145946283Sdfr  switch (request) {
146046283Sdfr    case TT_LWP_STOP :
146146283Sdfr      return TT_PROC_STOP;
146246283Sdfr
146346283Sdfr    case TT_LWP_CONTINUE :
146446283Sdfr      return TT_PROC_CONTINUE;
146546283Sdfr
146646283Sdfr    case TT_LWP_GET_EVENT_MASK :
146746283Sdfr      return TT_PROC_GET_EVENT_MASK;
146846283Sdfr
146946283Sdfr    case TT_LWP_SET_EVENT_MASK :
147046283Sdfr      return TT_PROC_SET_EVENT_MASK;
147146283Sdfr
147246283Sdfr    case TT_LWP_SINGLE :
147346283Sdfr    case TT_LWP_RUREGS :
147446283Sdfr    case TT_LWP_WUREGS :
147546283Sdfr    case TT_LWP_GET_STATE	:
147646283Sdfr      return -1;       /* No equivalent */
147746283Sdfr
147846283Sdfr    default :
147946283Sdfr      return request;
148046283Sdfr  }
148146283Sdfr}
148246283Sdfr
148346283Sdfr
148446283Sdfr/* This function translates the "pid" used by the rest of
148546283Sdfr * gdb to a real pid and a tid.  It then calls "call_real_ttrace"
148646283Sdfr * with the given arguments.
148746283Sdfr *
148846283Sdfr * In general, other parts of this module should call this
148946283Sdfr * function when they are dealing with external users, who only
149046283Sdfr * have tids to pass (but they call it "pid" for historical
149146283Sdfr * reasons).
149246283Sdfr */
149346283Sdfrstatic int
149446283Sdfrcall_ttrace( request, gdb_tid, addr, data, addr2 )
149546283Sdfr  ttreq_t  request;
149646283Sdfr  int      gdb_tid;
149746283Sdfr  TTRACE_ARG_TYPE  addr, data, addr2;
149846283Sdfr{
149946283Sdfr  lwpid_t  real_tid;
150046283Sdfr  int      real_pid;
150146283Sdfr  ttreq_t  new_request;
150246283Sdfr  int      tt_status;
150346283Sdfr  char     reason_for_failure [100];  /* Arbitrary size, should be big enough. */
150446283Sdfr
150546283Sdfr#ifdef THREAD_DEBUG
150646283Sdfr  int	is_interesting = 0;
150746283Sdfr
150846283Sdfr  if( TT_LWP_RUREGS == request ) {
150946283Sdfr     is_interesting = 1;          /* Adjust code here as desired */
151046283Sdfr  }
151146283Sdfr
151246283Sdfr  if( is_interesting && 0 && debug_on ) {
151346283Sdfr      if( !is_process_ttrace_request( request )) {
151446283Sdfr          printf( "TT: Thread request, tid is %d", gdb_tid );
151546283Sdfr          printf( "== SINGLE at %x", addr );
151646283Sdfr      }
151746283Sdfr      else {
151846283Sdfr          printf( "TT: Process request, tid is %d\n", gdb_tid );
151946283Sdfr          printf( "==! SINGLE at %x", addr );
152046283Sdfr      }
152146283Sdfr  }
152246283Sdfr#endif
152346283Sdfr
152446283Sdfr  /* The initial SETTRC and SET_EVENT_MASK calls (and all others
152546283Sdfr   * which happen before any threads get set up) should go
152646283Sdfr   * directly to "call_real_ttrace", so they don't happen here.
152746283Sdfr   *
152846283Sdfr   * But hardware watchpoints do a SET_EVENT_MASK, so we can't
152946283Sdfr   * rule them out....
153046283Sdfr   */
153146283Sdfr#ifdef THREAD_DEBUG
153246283Sdfr  if( request == TT_PROC_SETTRC && debug_on )
153346283Sdfr      printf( "Unexpected call for TT_PROC_SETTRC\n" );
153446283Sdfr#endif
153546283Sdfr
153646283Sdfr  /* Sometimes we get called with a bogus tid (e.g., if a
153746283Sdfr   * thread has terminated, we return 0; inftarg later asks
153846283Sdfr   * whether the thread has exited/forked/vforked).
153946283Sdfr   */
154046283Sdfr  if( gdb_tid == 0 )
154146283Sdfr    {
154246283Sdfr      errno = ESRCH;  /* ttrace's response would probably be "No such process". */
154346283Sdfr      return -1;
154446283Sdfr    }
154546283Sdfr
154646283Sdfr  /* All other cases should be able to expect that there are
154746283Sdfr   * thread records.
154846283Sdfr   */
154946283Sdfr  if( !any_thread_records()) {
155046283Sdfr#ifdef THREAD_DEBUG
155146283Sdfr      if( debug_on )
155246283Sdfr          warning ("No thread records for ttrace call");
155346283Sdfr#endif
155446283Sdfr      errno = ESRCH;  /* ttrace's response would be "No such process". */
155546283Sdfr      return -1;
155646283Sdfr  }
155746283Sdfr
155846283Sdfr  /* OK, now the task is to translate the incoming tid into
155946283Sdfr   * a pid/tid pair.
156046283Sdfr   */
156146283Sdfr  real_tid = map_from_gdb_tid( gdb_tid );
156246283Sdfr  real_pid = get_pid_for( real_tid );
156346283Sdfr
156446283Sdfr  /* Now check the result.  "Real_pid" is NULL if our list
156546283Sdfr   * didn't find it.  We have some tricks we can play to fix
156646283Sdfr   * this, however.
156746283Sdfr   */
156846283Sdfr  if( 0 == real_pid ) {
156946283Sdfr    ttstate_t  thread_state;
157046283Sdfr
157146283Sdfr#ifdef THREAD_DEBUG
157246283Sdfr    if( debug_on )
157346283Sdfr        printf( "No saved pid for tid %d\n", gdb_tid );
157446283Sdfr#endif
157546283Sdfr
157646283Sdfr    if( is_process_ttrace_request( request )) {
157746283Sdfr
157846283Sdfr        /* Ok, we couldn't get a tid.  Try to translate to
157946283Sdfr         * the equivalent process operation.  We expect this
158046283Sdfr         * NOT to happen, so this is a desparation-type
158146283Sdfr         * move.  It can happen if there is an internal
158246283Sdfr         * error and so no "wait()" call is ever done.
158346283Sdfr         */
158446283Sdfr        new_request = make_process_version( request );
158546283Sdfr        if( new_request == -1 ) {
158646283Sdfr
158746283Sdfr#ifdef THREAD_DEBUG
158846283Sdfr            if( debug_on )
158946283Sdfr                printf( "...and couldn't make process version of thread operation\n" );
159046283Sdfr#endif
159146283Sdfr
159246283Sdfr            /* Use hacky saved pid, which won't always be correct
159346283Sdfr             * in the multi-process future.  Use tid as thread,
159446283Sdfr             * probably dooming this to failure.  FIX!
159546283Sdfr             */
159646283Sdfr            if( saved_real_pid != 0 ) {
159746283Sdfr#ifdef THREAD_DEBUG
159846283Sdfr                if( debug_on )
159946283Sdfr                    printf( "...using saved pid %d\n", saved_real_pid );
160046283Sdfr#endif
160146283Sdfr
160246283Sdfr                real_pid = saved_real_pid;
160346283Sdfr                real_tid = gdb_tid;
160446283Sdfr            }
160546283Sdfr
160646283Sdfr            else
160746283Sdfr                error( "Unable to perform thread operation" );
160846283Sdfr        }
160946283Sdfr
161046283Sdfr        else {
161146283Sdfr            /* Sucessfully translated this to a process request,
161246283Sdfr             * which needs no thread value.
161346283Sdfr             */
161446283Sdfr            real_pid = gdb_tid;
161546283Sdfr            real_tid = 0;
161646283Sdfr            request  = new_request;
161746283Sdfr
161846283Sdfr#ifdef THREAD_DEBUG
161946283Sdfr            if( debug_on ) {
162046283Sdfr                printf( "Translated thread request to process request\n" );
162146283Sdfr                if( saved_real_pid == 0 )
162246283Sdfr                    printf( "...but there's no saved pid\n" );
162346283Sdfr
162446283Sdfr                else {
162546283Sdfr                    if( gdb_tid != saved_real_pid )
162646283Sdfr                        printf( "...but have the wrong pid (%d rather than %d)\n",
162746283Sdfr                                gdb_tid, saved_real_pid );
162846283Sdfr                }
162946283Sdfr            }
163046283Sdfr#endif
163146283Sdfr        } /* Translated to a process request */
163246283Sdfr    }     /* Is a process request */
163346283Sdfr
163446283Sdfr    else {
163546283Sdfr        /* We have to have a thread.  Ooops.
163646283Sdfr         */
163746283Sdfr       error( "Thread request with no threads (%s)",
163846283Sdfr               get_printable_name_of_ttrace_request( request ));
163946283Sdfr    }
164046283Sdfr  }
164146283Sdfr
164246283Sdfr  /* Ttrace doesn't like to see tid values on process requests,
164346283Sdfr   * even if we have the right one.
164446283Sdfr   */
164546283Sdfr  if (is_process_ttrace_request (request)) {
164646283Sdfr      real_tid = 0;
164746283Sdfr  }
164846283Sdfr
164946283Sdfr#ifdef THREAD_DEBUG
165046283Sdfr  if( is_interesting && 0 && debug_on ) {
165146283Sdfr    printf( "    now tid %d, pid %d\n", real_tid, real_pid );
165246283Sdfr    printf( "    request is %s\n", get_printable_name_of_ttrace_request (request));
165346283Sdfr  }
165446283Sdfr#endif
165546283Sdfr
165646283Sdfr  /* Finally, the (almost) real call.
165746283Sdfr   */
165846283Sdfr  tt_status = call_real_ttrace (request, real_pid, real_tid, addr, data, addr2);
165946283Sdfr
166046283Sdfr#ifdef THREAD_DEBUG
166146283Sdfr  if(is_interesting && debug_on ) {
166246283Sdfr    if( !TT_OK( tt_status, errno )
166346283Sdfr    &&  !(tt_status == 0 & errno == 0))
166446283Sdfr      printf( " got error (errno==%d, status==%d)\n", errno, tt_status );
166546283Sdfr  }
166646283Sdfr#endif
166746283Sdfr
166846283Sdfr  return tt_status;
166946283Sdfr}
167046283Sdfr
167146283Sdfr
167246283Sdfr/* Stop all the threads of a process.
167346283Sdfr *
167446283Sdfr * NOTE: use of TT_PROC_STOP can cause a thread with a real event
167546283Sdfr *       to get a TTEVT_NONE event, discarding the old event.  Be
167646283Sdfr *       very careful, and only call TT_PROC_STOP when you mean it!
167746283Sdfr */
167846283Sdfrstatic void
167946283Sdfrstop_all_threads_of_process( real_pid )
168046283Sdfr  pid_t  real_pid;
168146283Sdfr{
168246283Sdfr  int  ttw_status;
168346283Sdfr
168446283Sdfr  ttw_status = call_real_ttrace (TT_PROC_STOP,
168546283Sdfr                                 (pid_t) real_pid,
168646283Sdfr                                 (lwpid_t) TT_NIL,
168746283Sdfr                                 (TTRACE_ARG_TYPE) TT_NIL,
168846283Sdfr                                 (TTRACE_ARG_TYPE) TT_NIL,
168946283Sdfr                                 TT_NIL );
169046283Sdfr  if (errno)
169146283Sdfr    perror_with_name ("ttrace stop of other threads");
169246283Sdfr}
169346283Sdfr
169446283Sdfr
169546283Sdfr/* Under some circumstances, it's unsafe to attempt to stop, or even
169646283Sdfr   query the state of, a process' threads.
169746283Sdfr
169846283Sdfr   In ttrace-based HP-UX, an example is a vforking child process.  The
169946283Sdfr   vforking parent and child are somewhat fragile, w/r/t what we can do
170046283Sdfr   what we can do to them with ttrace, until after the child exits or
170146283Sdfr   execs, or until the parent's vfork event is delivered.  Until that
170246283Sdfr   time, we must not try to stop the process' threads, or inquire how
170346283Sdfr   many there are, or even alter its data segments, or it typically dies
170446283Sdfr   with a SIGILL.  Sigh.
170546283Sdfr
170646283Sdfr   This function returns 1 if this stopped process, and the event that
170746283Sdfr   we're told was responsible for its current stopped state, cannot safely
170846283Sdfr   have its threads examined.
170946283Sdfr   */
171046283Sdfr#define CHILD_VFORKED(evt,pid) \
171146283Sdfr  (((evt) == TTEVT_VFORK) && ((pid) != inferior_pid))
171246283Sdfr#define CHILD_URPED(evt,pid) \
171346283Sdfr  ((((evt) == TTEVT_EXEC) || ((evt) == TTEVT_EXIT)) && ((pid) != vforking_child_pid))
171446283Sdfr#define PARENT_VFORKED(evt,pid) \
171546283Sdfr  (((evt) == TTEVT_VFORK) && ((pid) == inferior_pid))
171646283Sdfr
171746283Sdfrstatic int
171846283Sdfrcan_touch_threads_of_process (pid, stopping_event)
171946283Sdfr  int  pid;
172046283Sdfr  ttevents_t  stopping_event;
172146283Sdfr{
172246283Sdfr  if (CHILD_VFORKED (stopping_event, pid))
172346283Sdfr    {
172446283Sdfr      vforking_child_pid = pid;
172546283Sdfr      vfork_in_flight = 1;
172646283Sdfr    }
172746283Sdfr
172846283Sdfr  else if (vfork_in_flight &&
172946283Sdfr           (PARENT_VFORKED (stopping_event, pid) ||
173046283Sdfr            CHILD_URPED (stopping_event, pid)))
173146283Sdfr    {
173246283Sdfr      vfork_in_flight = 0;
173346283Sdfr      vforking_child_pid = 0;
173446283Sdfr    }
173546283Sdfr
173646283Sdfr  return ! vfork_in_flight;
173746283Sdfr}
173846283Sdfr
173946283Sdfr
174046283Sdfr/* If we can find an as-yet-unhandled thread state of a
174146283Sdfr * stopped thread of this process return 1 and set "tsp".
174246283Sdfr * Return 0 if we can't.
174346283Sdfr *
174446283Sdfr * If this function is used when the threads of PIS haven't
174546283Sdfr * been stopped, undefined behaviour is guaranteed!
174646283Sdfr */
174746283Sdfrstatic int
174846283Sdfrselect_stopped_thread_of_process (pid, tsp)
174946283Sdfr  int  pid;
175046283Sdfr  ttstate_t *  tsp;
175146283Sdfr{
175246283Sdfr  lwpid_t    candidate_tid,    tid;
175346283Sdfr  ttstate_t  candidate_tstate, tstate;
175446283Sdfr
175546283Sdfr  /* If we're not allowed to touch the process now, then just
175646283Sdfr   * return the current value of *TSP.
175746283Sdfr   *
175846283Sdfr   * This supports "vfork".  It's ok, really, to double the
175946283Sdfr   * current event (the child EXEC, we hope!).
176046283Sdfr   */
176146283Sdfr  if (! can_touch_threads_of_process (pid, tsp->tts_event))
176246283Sdfr    return 1;
176346283Sdfr
176446283Sdfr  /* Decide which of (possibly more than one) events to
176546283Sdfr   * return as the first one.  We scan them all so that
176646283Sdfr   * we always return the result of a fake-step first.
176746283Sdfr   */
176846283Sdfr  candidate_tid = 0;
176946283Sdfr  for (tid = get_process_first_stopped_thread_id (pid, &tstate);
177046283Sdfr       tid != 0;
177146283Sdfr       tid = get_process_next_stopped_thread_id (pid, &tstate))
177246283Sdfr    {
177346283Sdfr      /* TTEVT_NONE events are uninteresting to our clients.  They're
177446283Sdfr       * an artifact of our "stop the world" model--the thread is
177546283Sdfr       * stopped because we stopped it.
177646283Sdfr       */
177746283Sdfr      if (tstate.tts_event == TTEVT_NONE) {
177846283Sdfr          set_handled( pid, tstate.tts_lwpid );
177946283Sdfr      }
178046283Sdfr
178146283Sdfr      /* Did we just single-step a single thread, without letting any
178246283Sdfr       * of the others run?  Is this an event for that thread?
178346283Sdfr       *
178446283Sdfr       * If so, we believe our client would prefer to see this event
178546283Sdfr       * over any others.  (Typically the client wants to just push
178646283Sdfr       * one thread a little farther forward, and then go around
178746283Sdfr       * checking for what all threads are doing.)
178846283Sdfr       */
178946283Sdfr      else if (doing_fake_step && (tstate.tts_lwpid == fake_step_tid))
179046283Sdfr        {
179146283Sdfr#ifdef WAIT_BUFFER_DEBUG
179246283Sdfr          /* It's possible here to see either a SIGTRAP (due to
179346283Sdfr           * successful completion of a step) or a SYSCALL_ENTRY
179446283Sdfr           * (due to a step completion with active hardware
179546283Sdfr           * watchpoints).
179646283Sdfr           */
179746283Sdfr           if( debug_on )
179846283Sdfr               printf( "Ending fake step with tid %d, state %s\n",
179946283Sdfr                       tstate.tts_lwpid,
180046283Sdfr                       get_printable_name_of_ttrace_event( tstate.tts_event ));
180146283Sdfr#endif
180246283Sdfr
180346283Sdfr          /* Remember this one, and throw away any previous
180446283Sdfr           * candidate.
180546283Sdfr           */
180646283Sdfr          candidate_tid    = tstate.tts_lwpid;
180746283Sdfr          candidate_tstate = tstate;
180846283Sdfr      }
180946283Sdfr
181046283Sdfr#ifdef FORGET_DELETED_BPTS
181146283Sdfr
181246283Sdfr      /* We can't just do this, as if we do, and then wind
181346283Sdfr       * up the loop with no unhandled events, we need to
181446283Sdfr       * handle that case--the appropriate reaction is to
181546283Sdfr       * just continue, but there's no easy way to do that.
181646283Sdfr       *
181746283Sdfr       * Better to put this in the ttrace_wait call--if, when
181846283Sdfr       * we fake a wait, we update our events based on the
181946283Sdfr       * breakpoint_here_pc call and find there are no more events,
182046283Sdfr       * then we better continue and so on.
182146283Sdfr       *
182246283Sdfr       * Or we could put it in the next/continue fake.
182346283Sdfr       * But it has to go in the buffering code, not in the
182446283Sdfr       * real go/wait code.
182546283Sdfr       */
182646283Sdfr      else if( (TTEVT_SIGNAL == tstate.tts_event)
182746283Sdfr            && (5 == tstate.tts_u.tts_signal.tts_signo)
182846283Sdfr            && (0 != get_raw_pc( tstate.tts_lwpid ))
182946283Sdfr            && ! breakpoint_here_p( get_raw_pc( tstate.tts_lwpid )) ) {
183046283Sdfr          /*
183146283Sdfr           * If the user deleted a breakpoint while this
183246283Sdfr           * breakpoint-hit event was buffered, we can forget
183346283Sdfr           * it now.
183446283Sdfr           */
183546283Sdfr#ifdef WAIT_BUFFER_DEBUG
183646283Sdfr           if( debug_on )
183746283Sdfr               printf( "Forgetting deleted bp hit for thread %d\n",
183846283Sdfr                       tstate.tts_lwpid );
183946283Sdfr#endif
184046283Sdfr
184146283Sdfr          set_handled( pid, tstate.tts_lwpid );
184246283Sdfr      }
184346283Sdfr#endif
184446283Sdfr
184546283Sdfr      /* Else, is this the first "unhandled" event?  If so,
184646283Sdfr       * we believe our client wants to see it (if we don't
184746283Sdfr       * see a fake-step later on in the scan).
184846283Sdfr       */
184946283Sdfr      else if( !was_handled( tstate.tts_lwpid ) && candidate_tid == 0 ) {
185046283Sdfr          candidate_tid    = tstate.tts_lwpid;
185146283Sdfr          candidate_tstate = tstate;
185246283Sdfr      }
185346283Sdfr
185446283Sdfr      /* This is either an event that has already been "handled",
185546283Sdfr       * and thus we believe is uninteresting to our client, or we
185646283Sdfr       * already have a candidate event.  Ignore it...
185746283Sdfr       */
185846283Sdfr    }
185946283Sdfr
186046283Sdfr  /* What do we report?
186146283Sdfr   */
186246283Sdfr  if( doing_fake_step ) {
186346283Sdfr      if( candidate_tid == fake_step_tid ) {
186446283Sdfr          /* Fake step.
186546283Sdfr           */
186646283Sdfr          tstate = candidate_tstate;
186746283Sdfr      }
186846283Sdfr      else {
186946283Sdfr          warning( "Internal error: fake-step failed to complete." );
187046283Sdfr          return 0;
187146283Sdfr      }
187246283Sdfr  }
187346283Sdfr  else if( candidate_tid != 0 ) {
187446283Sdfr      /* Found a candidate unhandled event.
187546283Sdfr       */
187646283Sdfr      tstate = candidate_tstate;
187746283Sdfr  }
187846283Sdfr  else if( tid != 0 ) {
187946283Sdfr      warning( "Internal error in call of ttrace_wait." );
188046283Sdfr      return 0;
188146283Sdfr  }
188246283Sdfr  else {
188346283Sdfr      warning ("Internal error: no unhandled thread event to select");
188446283Sdfr      return 0;
188546283Sdfr  }
188646283Sdfr
188746283Sdfr  copy_ttstate_t (tsp, &tstate);
188846283Sdfr  return 1;
188946283Sdfr} /* End of select_stopped_thread_of_process */
189046283Sdfr
189146283Sdfr#ifdef PARANOIA
189246283Sdfr/* Check our internal thread data against the real thing.
189346283Sdfr */
189446283Sdfrstatic void
189546283Sdfrcheck_thread_consistency( real_pid )
189646283Sdfr    pid_t real_pid;
189746283Sdfr{
189846283Sdfr    int          tid;       /* really lwpid_t */
189946283Sdfr    ttstate_t    tstate;
190046283Sdfr    thread_info *p;
190146283Sdfr
190246283Sdfr    /* Spin down the O/S list of threads, checking that they
190346283Sdfr     * match what we've got.
190446283Sdfr     */
190546283Sdfr    for (tid = get_process_first_stopped_thread_id( real_pid, &tstate );
190646283Sdfr         tid != 0;
190746283Sdfr         tid = get_process_next_stopped_thread_id(  real_pid, &tstate )) {
190846283Sdfr
190946283Sdfr        p = find_thread_info( tid );
191046283Sdfr
191146283Sdfr        if( NULL == p ) {
191246283Sdfr            warning( "No internal thread data for thread %d.", tid );
191346283Sdfr            continue;
191446283Sdfr        }
191546283Sdfr
191646283Sdfr        if( !p->seen ) {
191746283Sdfr            warning( "Inconsistent internal thread data for thread %d.", tid );
191846283Sdfr        }
191946283Sdfr
192046283Sdfr        if( p->terminated ) {
192146283Sdfr            warning( "Thread %d is not terminated, internal error.", tid );
192246283Sdfr            continue;
192346283Sdfr        }
192446283Sdfr
192546283Sdfr
192646283Sdfr#define TT_COMPARE( fld ) \
192746283Sdfr            tstate.fld != p->last_stop_state.fld
192846283Sdfr
192946283Sdfr        if( p->have_state ) {
193046283Sdfr            if( TT_COMPARE( tts_pid      )
193146283Sdfr             || TT_COMPARE( tts_lwpid    )
193246283Sdfr             || TT_COMPARE( tts_user_tid )
193346283Sdfr             || TT_COMPARE( tts_event    )
193446283Sdfr             || TT_COMPARE( tts_flags    )
193546283Sdfr             || TT_COMPARE( tts_scno     )
193646283Sdfr             || TT_COMPARE( tts_scnargs  )) {
193746283Sdfr                warning( "Internal thread data for thread %d is wrong.", tid );
193846283Sdfr                continue;
193946283Sdfr            }
194046283Sdfr        }
194146283Sdfr    }
194246283Sdfr}
194346283Sdfr#endif  /* PARANOIA */
194446283Sdfr
194546283Sdfr
194646283Sdfr/* This function wraps calls to "call_real_ttrace_wait" so
194746283Sdfr * that a actual wait is only done when all pending events
194846283Sdfr * have been reported.
194946283Sdfr *
195046283Sdfr * Note that typically it is called with a pid of "0", i.e.
195146283Sdfr * the "don't care" value.
195246283Sdfr *
195346283Sdfr * Return value is the status of the pseudo wait.
195446283Sdfr */
195546283Sdfrstatic int
195646283Sdfrcall_ttrace_wait( pid, option, tsp, tsp_size )
195746283Sdfr  int        pid;
195846283Sdfr  ttwopt_t   option;
195946283Sdfr  ttstate_t *tsp;
196046283Sdfr  size_t     tsp_size;
196146283Sdfr{
196246283Sdfr  /* This holds the actual, for-real, true process ID.
196346283Sdfr   */
196446283Sdfr  static int real_pid;
196546283Sdfr
196646283Sdfr  /* As an argument to ttrace_wait, zero pid
196746283Sdfr   * means "Any process", and zero tid means
196846283Sdfr   * "Any thread of the specified process".
196946283Sdfr   */
197046283Sdfr  int      wait_pid = 0;
197146283Sdfr  lwpid_t  wait_tid = 0;
197246283Sdfr  lwpid_t  real_tid;
197346283Sdfr
197446283Sdfr  int       ttw_status = 0;   /* To be returned */
197546283Sdfr
197646283Sdfr  thread_info *  tinfo = NULL;
197746283Sdfr
197846283Sdfr  if( pid != 0 ) {
197946283Sdfr      /* Unexpected case.
198046283Sdfr       */
198146283Sdfr#ifdef THREAD_DEBUG
198246283Sdfr      if( debug_on )
198346283Sdfr          printf( "TW: Pid to wait on is %d\n", pid );
198446283Sdfr#endif
198546283Sdfr
198646283Sdfr      if( !any_thread_records())
198746283Sdfr          error( "No thread records for ttrace call w. specific pid" );
198846283Sdfr
198946283Sdfr      /* OK, now the task is to translate the incoming tid into
199046283Sdfr       * a pid/tid pair.
199146283Sdfr       */
199246283Sdfr      real_tid = map_from_gdb_tid( pid );
199346283Sdfr      real_pid = get_pid_for( real_tid );
199446283Sdfr#ifdef THREAD_DEBUG
199546283Sdfr      if( debug_on )
199646283Sdfr          printf( "==TW: real pid %d, real tid %d\n", real_pid, real_tid );
199746283Sdfr#endif
199846283Sdfr  }
199946283Sdfr
200046283Sdfr
200146283Sdfr  /* Sanity checks and set-up.
200246283Sdfr   *                             Process State
200346283Sdfr   *
200446283Sdfr   *                        Stopped   Running    Fake-step  (v)Fork
200546283Sdfr   *                      \________________________________________
200646283Sdfr   *                      |
200746283Sdfr   *  No buffered events  |  error     wait       wait      wait
200846283Sdfr   *                      |
200946283Sdfr   *  Buffered events     |  debuffer  error      wait      debuffer (?)
201046283Sdfr   *
201146283Sdfr   */
201246283Sdfr  if( more_events_left == 0 ) {
201346283Sdfr
201446283Sdfr      if( process_state == RUNNING ) {
201546283Sdfr          /* OK--normal call of ttrace_wait with no buffered events.
201646283Sdfr           */
201746283Sdfr          ;
201846283Sdfr      }
201946283Sdfr      else if( process_state == FAKE_STEPPING ) {
202046283Sdfr          /* Ok--call of ttrace_wait to support
202146283Sdfr           * fake stepping with no buffered events.
202246283Sdfr           *
202346283Sdfr           * But we better be fake-stepping!
202446283Sdfr           */
202546283Sdfr          if( !doing_fake_step ) {
202646283Sdfr              warning( "Inconsistent thread state." );
202746283Sdfr          }
202846283Sdfr      }
202946283Sdfr      else if( (process_state == FORKING)
203046283Sdfr            || (process_state == VFORKING)) {
203146283Sdfr          /* Ok--there are two processes, so waiting
203246283Sdfr           * for the second while the first is stopped
203346283Sdfr           * is ok.  Handled bits stay as they were.
203446283Sdfr           */
203546283Sdfr           ;
203646283Sdfr      }
203746283Sdfr      else if( process_state == STOPPED ) {
203846283Sdfr          warning( "Process not running at wait call." );
203946283Sdfr      }
204046283Sdfr      else
204146283Sdfr          /* No known state.
204246283Sdfr           */
204346283Sdfr          warning( "Inconsistent process state." );
204446283Sdfr  }
204546283Sdfr
204646283Sdfr  else {
204746283Sdfr      /* More events left
204846283Sdfr       */
204946283Sdfr      if( process_state == STOPPED ) {
205046283Sdfr          /* OK--buffered events being unbuffered.
205146283Sdfr           */
205246283Sdfr          ;
205346283Sdfr      }
205446283Sdfr      else if( process_state == RUNNING ) {
205546283Sdfr          /* An error--shouldn't have buffered events
205646283Sdfr           * when running.
205746283Sdfr           */
205846283Sdfr          warning( "Trying to continue with buffered events:" );
205946283Sdfr      }
206046283Sdfr      else if( process_state == FAKE_STEPPING ) {
206146283Sdfr          /*
206246283Sdfr           * Better be fake-stepping!
206346283Sdfr           */
206446283Sdfr          if( !doing_fake_step ) {
206546283Sdfr              warning( "Losing buffered thread events!\n" );
206646283Sdfr          }
206746283Sdfr      }
206846283Sdfr      else if( (process_state == FORKING)
206946283Sdfr            || (process_state == VFORKING)) {
207046283Sdfr          /* Ok--there are two processes, so waiting
207146283Sdfr           * for the second while the first is stopped
207246283Sdfr           * is ok.  Handled bits stay as they were.
207346283Sdfr           */
207446283Sdfr           ;
207546283Sdfr      }
207646283Sdfr      else
207746283Sdfr          warning( "Process in unknown state with buffered events." );
207846283Sdfr  }
207946283Sdfr
208046283Sdfr  /* Sometimes we have to wait for a particular thread
208146283Sdfr   * (if we're stepping over a bpt).  In that case, we
208246283Sdfr   * _know_ it's going to complete the single-step we
208346283Sdfr   * asked for (because we're only doing the step under
208446283Sdfr   * certain very well-understood circumstances), so it
208546283Sdfr   * can't block.
208646283Sdfr   */
208746283Sdfr  if( doing_fake_step ) {
208846283Sdfr      wait_tid = fake_step_tid;
208946283Sdfr      wait_pid = get_pid_for( fake_step_tid );
209046283Sdfr
209146283Sdfr#ifdef WAIT_BUFFER_DEBUG
209246283Sdfr      if( debug_on )
209346283Sdfr          printf( "Doing a wait after a fake-step for %d, pid %d\n",
209446283Sdfr                  wait_tid, wait_pid );
209546283Sdfr#endif
209646283Sdfr  }
209746283Sdfr
209846283Sdfr  if( more_events_left == 0         /* No buffered events, need real ones. */
209946283Sdfr  ||  process_state != STOPPED ) {
210046283Sdfr      /* If there are no buffered events, and so we need
210146283Sdfr       * real ones, or if we are FORKING, VFORKING,
210246283Sdfr       * FAKE_STEPPING or RUNNING, and thus have to do
210346283Sdfr       * a real wait, then do a real wait.
210446283Sdfr       */
210546283Sdfr
210646283Sdfr#ifdef WAIT_BUFFER_DEBUG
210746283Sdfr      /* Normal case... */
210846283Sdfr      if( debug_on )
210946283Sdfr          printf( "TW: do it for real; pid %d, tid %d\n", wait_pid, wait_tid );
211046283Sdfr#endif
211146283Sdfr
211246283Sdfr      /* The actual wait call.
211346283Sdfr       */
211446283Sdfr      ttw_status = call_real_ttrace_wait( wait_pid, wait_tid, option, tsp, tsp_size);
211546283Sdfr
211646283Sdfr      /* Note that the routines we'll call will be using "call_real_ttrace",
211746283Sdfr       * not "call_ttrace", and thus need the real pid rather than the pseudo-tid
211846283Sdfr       * the rest of the world uses (which is actually the tid).
211946283Sdfr       */
212046283Sdfr      real_pid = tsp->tts_pid;
212146283Sdfr
212246283Sdfr      /* For most events: Stop the world!
212346283Sdfr       *
212446283Sdfr       * It's sometimes not safe to stop all threads of a process.
212546283Sdfr       * Sometimes it's not even safe to ask for the thread state
212646283Sdfr       * of a process!
212746283Sdfr       */
212846283Sdfr      if (can_touch_threads_of_process (real_pid, tsp->tts_event))
212946283Sdfr        {
213046283Sdfr          /* If we're really only stepping a single thread, then don't
213146283Sdfr           * try to stop all the others -- we only do this single-stepping
213246283Sdfr           * business when all others were already stopped...and the stop
213346283Sdfr           * would mess up other threads' events.
213446283Sdfr           *
213546283Sdfr           * Similiarly, if there are other threads with events,
213646283Sdfr           * don't do the stop.
213746283Sdfr           */
213846283Sdfr          if( !doing_fake_step ) {
213946283Sdfr            if( more_events_left > 0 )
214046283Sdfr                warning( "Internal error in stopping process" );
214146283Sdfr
214246283Sdfr            stop_all_threads_of_process (real_pid);
214346283Sdfr
214446283Sdfr            /* At this point, we could scan and update_thread_list(),
214546283Sdfr             * and only use the local list for the rest of the
214646283Sdfr             * module! We'd get rid of the scans in the various
214746283Sdfr             * continue routines (adding one in attach).  It'd
214846283Sdfr             * be great--UPGRADE ME!
214946283Sdfr             */
215046283Sdfr            }
215146283Sdfr        }
215246283Sdfr
215346283Sdfr#ifdef PARANOIA
215446283Sdfr      else if( debug_on ) {
215546283Sdfr          if( more_events_left > 0 )
215646283Sdfr              printf( "== Can't stop process; more events!\n" );
215746283Sdfr          else
215846283Sdfr              printf( "== Can't stop process!\n" );
215946283Sdfr      }
216046283Sdfr#endif
216146283Sdfr
216246283Sdfr      process_state   = STOPPED;
216346283Sdfr
216446283Sdfr#ifdef WAIT_BUFFER_DEBUG
216546283Sdfr      if( debug_on )
216646283Sdfr          printf( "Process set to STOPPED\n" );
216746283Sdfr#endif
216846283Sdfr  }
216946283Sdfr
217046283Sdfr  else {
217146283Sdfr      /* Fake a call to ttrace_wait.  The process must be
217246283Sdfr       * STOPPED, as we aren't going to do any wait.
217346283Sdfr       */
217446283Sdfr#ifdef WAIT_BUFFER_DEBUG
217546283Sdfr      if( debug_on )
217646283Sdfr          printf( "TW: fake it\n" );
217746283Sdfr#endif
217846283Sdfr
217946283Sdfr      if( process_state != STOPPED ) {
218046283Sdfr          warning( "Process not stopped at wait call, in state '%s'.\n",
218146283Sdfr                   get_printable_name_of_process_state( process_state ));
218246283Sdfr      }
218346283Sdfr
218446283Sdfr      if( doing_fake_step )
218546283Sdfr          error( "Internal error in stepping over breakpoint" );
218646283Sdfr
218746283Sdfr      ttw_status = 0;  /* Faking it is always successful! */
218846283Sdfr  }   /* End of fake or not? if */
218946283Sdfr
219046283Sdfr  /* Pick an event to pass to our caller.  Be paranoid.
219146283Sdfr   */
219246283Sdfr  if( !select_stopped_thread_of_process( real_pid, tsp ))
219346283Sdfr      warning( "Can't find event, using previous event." );
219446283Sdfr
219546283Sdfr  else if( tsp->tts_event == TTEVT_NONE )
219646283Sdfr      warning( "Internal error: no thread has a real event." );
219746283Sdfr
219846283Sdfr  else if( doing_fake_step ) {
219946283Sdfr      if( fake_step_tid != tsp->tts_lwpid )
220046283Sdfr          warning( "Internal error in stepping over breakpoint." );
220146283Sdfr
220246283Sdfr      /* This wait clears the (current) fake-step if there was one.
220346283Sdfr       */
220446283Sdfr      doing_fake_step = 0;
220546283Sdfr      fake_step_tid   = 0;
220646283Sdfr  }
220746283Sdfr
220846283Sdfr  /* We now have a correct tsp and ttw_status for the thread
220946283Sdfr   * which we want to report.  So it's "handled"!  This call
221046283Sdfr   * will add it to our list if it's not there already.
221146283Sdfr   */
221246283Sdfr  set_handled( real_pid, tsp->tts_lwpid );
221346283Sdfr
221446283Sdfr  /* Save a copy of the ttrace state of this thread, in our local
221546283Sdfr     thread descriptor.
221646283Sdfr
221746283Sdfr     This caches the state.  The implementation of queries like
221846283Sdfr     target_has_execd can then use this cached state, rather than
221946283Sdfr     be forced to make an explicit ttrace call to get it.
222046283Sdfr
222146283Sdfr     (Guard against the condition that this is the first time we've
222246283Sdfr     waited on, i.e., seen this thread, and so haven't yet entered
222346283Sdfr     it into our list of threads.)
222446283Sdfr   */
222546283Sdfr  tinfo = find_thread_info (tsp->tts_lwpid);
222646283Sdfr  if (tinfo != NULL) {
222746283Sdfr    copy_ttstate_t (&tinfo->last_stop_state, tsp);
222846283Sdfr    tinfo->have_state = 1;
222946283Sdfr  }
223046283Sdfr
223146283Sdfr  return ttw_status;
223246283Sdfr} /* call_ttrace_wait */
223346283Sdfr
223446283Sdfr#if defined(CHILD_REPORTED_EXEC_EVENTS_PER_EXEC_CALL)
223546283Sdfrint
223646283Sdfrchild_reported_exec_events_per_exec_call ()
223746283Sdfr{
223846283Sdfr  return 1;  /* ttrace reports the event once per call. */
223946283Sdfr}
224046283Sdfr#endif
224146283Sdfr
224246283Sdfr
224346283Sdfr
224446283Sdfr/* Our implementation of hardware watchpoints involves making memory
224546283Sdfr   pages write-protected.  We must remember a page's original permissions,
224646283Sdfr   and we must also know when it is appropriate to restore a page's
224746283Sdfr   permissions to its original state.
224846283Sdfr
224946283Sdfr   We use a "dictionary" of hardware-watched pages to do this.  Each
225046283Sdfr   hardware-watched page is recorded in the dictionary.  Each page's
225146283Sdfr   dictionary entry contains the original permissions and a reference
225246283Sdfr   count.  Pages are hashed into the dictionary by their start address.
225346283Sdfr
225446283Sdfr   When hardware watchpoint is set on page X for the first time, page X
225546283Sdfr   is added to the dictionary with a reference count of 1.  If other
225646283Sdfr   hardware watchpoints are subsequently set on page X, its reference
225746283Sdfr   count is incremented.  When hardware watchpoints are removed from
225846283Sdfr   page X, its reference count is decremented.  If a page's reference
225946283Sdfr   count drops to 0, it's permissions are restored and the page's entry
226046283Sdfr   is thrown out of the dictionary.
226146283Sdfr   */
226246283Sdfrtypedef struct memory_page {
226346283Sdfr  CORE_ADDR  page_start;
226446283Sdfr  int  reference_count;
226546283Sdfr  int  original_permissions;
226646283Sdfr  struct memory_page *  next;
226746283Sdfr  struct memory_page *  previous;
226846283Sdfr} memory_page_t;
226946283Sdfr
227046283Sdfr#define MEMORY_PAGE_DICTIONARY_BUCKET_COUNT  128
227146283Sdfr
227246283Sdfrstatic struct {
227346283Sdfr  LONGEST  page_count;
227446283Sdfr  int  page_size;
227546283Sdfr  int  page_protections_allowed;
227646283Sdfr  /* These are just the heads of chains of actual page descriptors. */
227746283Sdfr  memory_page_t  buckets [MEMORY_PAGE_DICTIONARY_BUCKET_COUNT];
227846283Sdfr} memory_page_dictionary;
227946283Sdfr
228046283Sdfr
228146283Sdfrstatic void
228246283Sdfrrequire_memory_page_dictionary ()
228346283Sdfr{
228446283Sdfr  int  i;
228546283Sdfr
228646283Sdfr  /* Is the memory page dictionary ready for use?  If so, we're done. */
228746283Sdfr  if (memory_page_dictionary.page_count >= (LONGEST) 0)
228846283Sdfr    return;
228946283Sdfr
229046283Sdfr  /* Else, initialize it. */
229146283Sdfr  memory_page_dictionary.page_count = (LONGEST) 0;
229246283Sdfr
229346283Sdfr  for (i=0; i<MEMORY_PAGE_DICTIONARY_BUCKET_COUNT; i++)
229446283Sdfr    {
229546283Sdfr      memory_page_dictionary.buckets[i].page_start = (CORE_ADDR) 0;
229646283Sdfr      memory_page_dictionary.buckets[i].reference_count = 0;
229746283Sdfr      memory_page_dictionary.buckets[i].next = NULL;
229846283Sdfr      memory_page_dictionary.buckets[i].previous = NULL;
229946283Sdfr    }
230046283Sdfr}
230146283Sdfr
230246283Sdfr
230346283Sdfrstatic void
230446283Sdfrretire_memory_page_dictionary ()
230546283Sdfr{
230646283Sdfr  memory_page_dictionary.page_count = (LONGEST) -1;
230746283Sdfr}
230846283Sdfr
230946283Sdfr
231046283Sdfr/* Write-protect the memory page that starts at this address.
231146283Sdfr
231246283Sdfr   Returns the original permissions of the page.
231346283Sdfr */
231446283Sdfrstatic int
231546283Sdfrwrite_protect_page (pid, page_start)
231646283Sdfr  int       pid;
231746283Sdfr  CORE_ADDR page_start;
231846283Sdfr{
231946283Sdfr  int  tt_status;
232046283Sdfr  int  original_permissions;
232146283Sdfr  int  new_permissions;
232246283Sdfr
232346283Sdfr  tt_status = call_ttrace (TT_PROC_GET_MPROTECT,
232446283Sdfr                           pid,
232546283Sdfr                           (TTRACE_ARG_TYPE) page_start,
232646283Sdfr                           TT_NIL,
232746283Sdfr                           (TTRACE_ARG_TYPE) &original_permissions);
232846283Sdfr  if (errno || (tt_status < 0))
232946283Sdfr    {
233046283Sdfr      return 0;  /* What else can we do? */
233146283Sdfr    }
233246283Sdfr
233346283Sdfr  /* We'll also write-protect the page now, if that's allowed. */
233446283Sdfr  if (memory_page_dictionary.page_protections_allowed)
233546283Sdfr    {
233646283Sdfr      new_permissions = original_permissions & ~PROT_WRITE;
233746283Sdfr      tt_status = call_ttrace (TT_PROC_SET_MPROTECT,
233846283Sdfr                               pid,
233946283Sdfr                               (TTRACE_ARG_TYPE) page_start,
234046283Sdfr                               (TTRACE_ARG_TYPE) memory_page_dictionary.page_size,
234146283Sdfr                               (TTRACE_ARG_TYPE) new_permissions);
234246283Sdfr      if (errno || (tt_status < 0))
234346283Sdfr        {
234446283Sdfr          return 0;  /* What else can we do? */
234546283Sdfr        }
234646283Sdfr    }
234746283Sdfr
234846283Sdfr  return original_permissions;
234946283Sdfr}
235046283Sdfr
235146283Sdfr
235246283Sdfr/* Unwrite-protect the memory page that starts at this address, restoring
235346283Sdfr   (what we must assume are) its original permissions.
235446283Sdfr   */
235546283Sdfrstatic void
235646283Sdfrunwrite_protect_page (pid, page_start, original_permissions)
235746283Sdfr  int  pid;
235846283Sdfr  CORE_ADDR  page_start;
235946283Sdfr  int  original_permissions;
236046283Sdfr{
236146283Sdfr  int  tt_status;
236246283Sdfr
236346283Sdfr  tt_status = call_ttrace (TT_PROC_SET_MPROTECT,
236446283Sdfr                           pid,
236546283Sdfr                           (TTRACE_ARG_TYPE) page_start,
236646283Sdfr                           (TTRACE_ARG_TYPE) memory_page_dictionary.page_size,
236746283Sdfr                           (TTRACE_ARG_TYPE) original_permissions);
236846283Sdfr  if (errno || (tt_status < 0))
236946283Sdfr    {
237046283Sdfr      return;  /* What else can we do? */
237146283Sdfr    }
237246283Sdfr}
237346283Sdfr
237446283Sdfr
237546283Sdfr/* Memory page-protections are used to implement "hardware" watchpoints
237646283Sdfr   on HP-UX.
237746283Sdfr
237846283Sdfr   For every memory page that is currently being watched (i.e., that
237946283Sdfr   presently should be write-protected), write-protect it.
238046283Sdfr   */
238146283Sdfrvoid
238246283Sdfrhppa_enable_page_protection_events (pid)
238346283Sdfr  int  pid;
238446283Sdfr{
238546283Sdfr  int  bucket;
238646283Sdfr
238746283Sdfr  memory_page_dictionary.page_protections_allowed = 1;
238846283Sdfr
238946283Sdfr  for (bucket=0; bucket<MEMORY_PAGE_DICTIONARY_BUCKET_COUNT; bucket++)
239046283Sdfr    {
239146283Sdfr      memory_page_t *  page;
239246283Sdfr
239346283Sdfr      page = memory_page_dictionary.buckets[bucket].next;
239446283Sdfr      while (page != NULL)
239546283Sdfr        {
239646283Sdfr          page->original_permissions = write_protect_page (pid, page->page_start);
239746283Sdfr          page = page->next;
239846283Sdfr        }
239946283Sdfr    }
240046283Sdfr}
240146283Sdfr
240246283Sdfr
240346283Sdfr/* Memory page-protections are used to implement "hardware" watchpoints
240446283Sdfr   on HP-UX.
240546283Sdfr
240646283Sdfr   For every memory page that is currently being watched (i.e., that
240746283Sdfr   presently is or should be write-protected), un-write-protect it.
240846283Sdfr   */
240946283Sdfrvoid
241046283Sdfrhppa_disable_page_protection_events (pid)
241146283Sdfr  int  pid;
241246283Sdfr{
241346283Sdfr  int  bucket;
241446283Sdfr
241546283Sdfr  for (bucket=0; bucket<MEMORY_PAGE_DICTIONARY_BUCKET_COUNT; bucket++)
241646283Sdfr    {
241746283Sdfr      memory_page_t *  page;
241846283Sdfr
241946283Sdfr      page = memory_page_dictionary.buckets[bucket].next;
242046283Sdfr      while (page != NULL)
242146283Sdfr        {
242246283Sdfr          unwrite_protect_page (pid, page->page_start, page->original_permissions);
242346283Sdfr          page = page->next;
242446283Sdfr        }
242546283Sdfr    }
242646283Sdfr
242746283Sdfr  memory_page_dictionary.page_protections_allowed = 0;
242846283Sdfr}
242946283Sdfr
243046283Sdfr/* Count the number of outstanding events.  At this
243146283Sdfr * point, we have selected one thread and its event
243246283Sdfr * as the one to be "reported" upwards to core gdb.
243346283Sdfr * That thread is already marked as "handled".
243446283Sdfr *
243546283Sdfr * Note: we could just scan our own thread list.  FIXME!
243646283Sdfr */
243746283Sdfrstatic int
243846283Sdfrcount_unhandled_events( real_pid, real_tid )
243946283Sdfr  int     real_pid;
244046283Sdfr  lwpid_t real_tid;
244146283Sdfr{
244246283Sdfr  ttstate_t  tstate;
244346283Sdfr  lwpid_t    ttid;
244446283Sdfr  int        events_left;
244546283Sdfr
244646283Sdfr  /* Ok, find out how many threads have real events to report.
244746283Sdfr   */
244846283Sdfr  events_left = 0;
244946283Sdfr  ttid = get_process_first_stopped_thread_id( real_pid, &tstate );
245046283Sdfr
245146283Sdfr#ifdef THREAD_DEBUG
245246283Sdfr  if( debug_on ) {
245346283Sdfr      if( ttid == 0 )
245446283Sdfr          printf( "Process %d has no threads\n", real_pid );
245546283Sdfr      else
245646283Sdfr          printf( "Process %d has these threads:\n", real_pid );
245746283Sdfr  }
245846283Sdfr#endif
245946283Sdfr
246046283Sdfr  while (ttid > 0 ) {
246146283Sdfr      if( tstate.tts_event != TTEVT_NONE
246246283Sdfr      &&  !was_handled( ttid )) {
246346283Sdfr          /* TTEVT_NONE implies we just stopped it ourselves
246446283Sdfr           * because we're the stop-the-world guys, so it's
246546283Sdfr           * not an event from our point of view.
246646283Sdfr           *
246746283Sdfr           * If "was_handled" is true, this is an event we
246846283Sdfr           * already handled, so don't count it.
246946283Sdfr           *
247046283Sdfr           * Note that we don't count the thread with the
247146283Sdfr           * currently-reported event, as it's already marked
247246283Sdfr           * as handled.
247346283Sdfr           */
247446283Sdfr          events_left++;
247546283Sdfr      }
247646283Sdfr
247746283Sdfr#if defined( THREAD_DEBUG ) || defined( WAIT_BUFFER_DEBUG )
247846283Sdfr  if( debug_on ) {
247946283Sdfr      if( ttid == real_tid )
248046283Sdfr          printf( "*" );         /* Thread we're reporting */
248146283Sdfr      else
248246283Sdfr          printf( " " );
248346283Sdfr
248446283Sdfr      if( tstate.tts_event != TTEVT_NONE )
248546283Sdfr          printf( "+" );         /* Thread with a real event */
248646283Sdfr      else
248746283Sdfr          printf( " " );
248846283Sdfr
248946283Sdfr      if( was_handled( ttid ))
249046283Sdfr          printf( "h" );         /* Thread has been handled */
249146283Sdfr      else
249246283Sdfr          printf( " " );
249346283Sdfr
249446283Sdfr      printf( " %d, with event %s", ttid,
249546283Sdfr              get_printable_name_of_ttrace_event( tstate.tts_event ));
249646283Sdfr
249746283Sdfr      if( tstate.tts_event == TTEVT_SIGNAL
249846283Sdfr       && 5 == tstate.tts_u.tts_signal.tts_signo ) {
249946283Sdfr          CORE_ADDR pc_val;
250046283Sdfr
250146283Sdfr          pc_val = get_raw_pc( ttid );
250246283Sdfr
250346283Sdfr          if( pc_val > 0 )
250446283Sdfr              printf( " breakpoint at 0x%x\n", pc_val );
250546283Sdfr          else
250646283Sdfr              printf( " bpt, can't fetch pc.\n" );
250746283Sdfr      }
250846283Sdfr      else
250946283Sdfr          printf( "\n" );
251046283Sdfr  }
251146283Sdfr#endif
251246283Sdfr
251346283Sdfr      ttid = get_process_next_stopped_thread_id (real_pid, &tstate);
251446283Sdfr  }
251546283Sdfr
251646283Sdfr#if defined( THREAD_DEBUG ) || defined( WAIT_BUFFER_DEBUG )
251746283Sdfr  if( debug_on )
251846283Sdfr      if( events_left > 0 )
251946283Sdfr          printf( "There are thus %d pending events\n", events_left );
252046283Sdfr#endif
252146283Sdfr
252246283Sdfr  return events_left;
252346283Sdfr}
252446283Sdfr
252546283Sdfr/* This function is provided as a sop to clients that are calling
252646283Sdfr * ptrace_wait to wait for a process to stop.  (see the
252746283Sdfr * implementation of child_wait.)  Return value is the pid for
252846283Sdfr * the event that ended the wait.
252946283Sdfr *
253046283Sdfr * Note: used by core gdb and so uses the pseudo-pid (really tid).
253146283Sdfr */
253246283Sdfrint
253346283Sdfrptrace_wait (pid, status)
253446283Sdfr    int pid;
253546283Sdfr    int *status;
253646283Sdfr{
253746283Sdfr  ttstate_t  tsp;
253846283Sdfr  int        ttwait_return;
253946283Sdfr  int        real_pid;
254046283Sdfr  ttstate_t  state;
254146283Sdfr  lwpid_t    real_tid;
254246283Sdfr  int  return_pid;
254346283Sdfr
254446283Sdfr  /* The ptrace implementation of this also ignores pid.
254546283Sdfr   */
254646283Sdfr  *status = 0;
254746283Sdfr
254846283Sdfr  ttwait_return = call_ttrace_wait( 0, TTRACE_WAITOK, &tsp, sizeof (tsp) );
254946283Sdfr  if (ttwait_return < 0)
255046283Sdfr    {
255146283Sdfr      /* ??rehrauer: It appears that if our inferior exits and we
255246283Sdfr         haven't asked for exit events, that we're not getting any
255346283Sdfr         indication save a negative return from ttrace_wait and an
255446283Sdfr         errno set to ESRCH?
255546283Sdfr         */
255646283Sdfr      if (errno == ESRCH)
255746283Sdfr        {
255846283Sdfr          *status = 0;  /* WIFEXITED */
255946283Sdfr          return inferior_pid;
256046283Sdfr        }
256146283Sdfr
256246283Sdfr      warning( "Call of ttrace_wait returned with errno %d.",
256346283Sdfr               errno );
256446283Sdfr      *status = ttwait_return;
256546283Sdfr      return inferior_pid;
256646283Sdfr    }
256746283Sdfr
256846283Sdfr  real_pid = tsp.tts_pid;
256946283Sdfr  real_tid = tsp.tts_lwpid;
257046283Sdfr
257146283Sdfr  /* One complication is that the "tts_event" structure has
257246283Sdfr   * a set of flags, and more than one can be set.  So we
257346283Sdfr   * either have to force an order (as we do here), or handle
257446283Sdfr   * more than one flag at a time.
257546283Sdfr   */
257646283Sdfr  if (tsp.tts_event & TTEVT_LWP_CREATE) {
257746283Sdfr
257846283Sdfr     /* Unlike what you might expect, this event is reported in
257946283Sdfr      * the _creating_ thread, and the _created_ thread (whose tid
258046283Sdfr      * we have) is still running.  So we have to stop it.  This
258146283Sdfr      * has already been done in "call_ttrace_wait", but should we
258246283Sdfr      * ever abandon the "stop-the-world" model, here's the command
258346283Sdfr      * to use:
258446283Sdfr      *
258546283Sdfr      *    call_ttrace( TT_LWP_STOP, real_tid, TT_NIL, TT_NIL, TT_NIL );
258646283Sdfr      *
258746283Sdfr      * Note that this would depend on being called _after_ "add_tthread"
258846283Sdfr      * below for the tid-to-pid translation to be done in "call_ttrace".
258946283Sdfr      */
259046283Sdfr
259146283Sdfr#ifdef THREAD_DEBUG
259246283Sdfr     if( debug_on )
259346283Sdfr         printf( "New thread: pid %d, tid %d, creator tid %d\n",
259446283Sdfr                 real_pid, tsp.tts_u.tts_thread.tts_target_lwpid,
259546283Sdfr                 real_tid );
259646283Sdfr#endif
259746283Sdfr
259846283Sdfr     /* Now we have to return the tid of the created thread, not
259946283Sdfr      * the creating thread, or "wait_for_inferior" won't know we
260046283Sdfr      * have a new "process" (thread).  Plus we should record it
260146283Sdfr      * right, too.
260246283Sdfr      */
260346283Sdfr      real_tid = tsp.tts_u.tts_thread.tts_target_lwpid;
260446283Sdfr
260546283Sdfr      add_tthread( real_pid, real_tid );
260646283Sdfr  }
260746283Sdfr
260846283Sdfr  else if( (tsp.tts_event & TTEVT_LWP_TERMINATE )
260946283Sdfr        || (tsp.tts_event & TTEVT_LWP_EXIT) ) {
261046283Sdfr
261146283Sdfr#ifdef THREAD_DEBUG
261246283Sdfr     if( debug_on )
261346283Sdfr         printf( "Thread dies: %d\n", real_tid );
261446283Sdfr#endif
261546283Sdfr
261646283Sdfr     del_tthread( real_tid );
261746283Sdfr  }
261846283Sdfr
261946283Sdfr  else if (tsp.tts_event & TTEVT_EXEC) {
262046283Sdfr
262146283Sdfr#ifdef THREAD_DEBUG
262246283Sdfr      if( debug_on )
262346283Sdfr          printf( "Pid %d has zero'th thread %d; inferior pid is %d\n",
262446283Sdfr                  real_pid, real_tid, inferior_pid );
262546283Sdfr#endif
262646283Sdfr
262746283Sdfr     add_tthread( real_pid, real_tid );
262846283Sdfr  }
262946283Sdfr
263046283Sdfr#ifdef THREAD_DEBUG
263146283Sdfr  else if( debug_on ) {
263246283Sdfr     printf( "Process-level event %s, using tid %d\n",
263346283Sdfr             get_printable_name_of_ttrace_event( tsp.tts_event ),
263446283Sdfr             real_tid );
263546283Sdfr
263646283Sdfr     /* OK to do this, as "add_tthread" won't add
263746283Sdfr      * duplicate entries.  Also OK not to do it,
263846283Sdfr      * as this event isn't one which can change the
263946283Sdfr      * thread state.
264046283Sdfr      */
264146283Sdfr     add_tthread( real_pid, real_tid );
264246283Sdfr  }
264346283Sdfr#endif
264446283Sdfr
264546283Sdfr
264646283Sdfr  /* How many events are left to report later?
264746283Sdfr   * In a non-stop-the-world model, this isn't needed.
264846283Sdfr   *
264946283Sdfr   * Note that it's not always safe to query the thread state of a process,
265046283Sdfr   * which is what count_unhandled_events does.  (If unsafe, we're left with
265146283Sdfr   * no other resort than to assume that no more events remain...)
265246283Sdfr   */
265346283Sdfr  if (can_touch_threads_of_process (real_pid, tsp.tts_event))
265446283Sdfr      more_events_left = count_unhandled_events( real_pid, real_tid );
265546283Sdfr
265646283Sdfr  else {
265746283Sdfr      if( more_events_left > 0 )
265846283Sdfr          warning( "Vfork or fork causing loss of %d buffered events.",
265946283Sdfr                   more_events_left );
266046283Sdfr
266146283Sdfr      more_events_left = 0;
266246283Sdfr  }
266346283Sdfr
266446283Sdfr  /* Attempt to translate the ttrace_wait-returned status into the
266546283Sdfr     ptrace equivalent.
266646283Sdfr
266746283Sdfr     ??rehrauer: This is somewhat fragile.  We really ought to rewrite
266846283Sdfr     clients that expect to pick apart a ptrace wait status, to use
266946283Sdfr     something a little more abstract.
267046283Sdfr     */
267146283Sdfr  if (   (tsp.tts_event & TTEVT_EXEC)
267246283Sdfr      || (tsp.tts_event & TTEVT_FORK)
267346283Sdfr      || (tsp.tts_event & TTEVT_VFORK))
267446283Sdfr    {
267546283Sdfr      /* Forks come in pairs (parent and child), so core gdb
267646283Sdfr       * will do two waits.  Be ready to notice this.
267746283Sdfr       */
267846283Sdfr      if (tsp.tts_event & TTEVT_FORK)
267946283Sdfr        {
268046283Sdfr          process_state = FORKING;
268146283Sdfr
268246283Sdfr#ifdef WAIT_BUFFER_DEBUG
268346283Sdfr          if( debug_on )
268446283Sdfr              printf( "Process set to FORKING\n" );
268546283Sdfr#endif
268646283Sdfr        }
268746283Sdfr      else if (tsp.tts_event & TTEVT_VFORK)
268846283Sdfr        {
268946283Sdfr          process_state = VFORKING;
269046283Sdfr
269146283Sdfr#ifdef WAIT_BUFFER_DEBUG
269246283Sdfr          if( debug_on )
269346283Sdfr              printf( "Process set to VFORKING\n" );
269446283Sdfr#endif
269546283Sdfr        }
269646283Sdfr
269746283Sdfr      /* Make an exec or fork look like a breakpoint.  Definitely a hack,
269846283Sdfr         but I don't think non HP-UX-specific clients really carefully
269946283Sdfr         inspect the first events they get after inferior startup, so
270046283Sdfr         it probably almost doesn't matter what we claim this is.
270146283Sdfr         */
270246283Sdfr
270346283Sdfr#ifdef THREAD_DEBUG
270446283Sdfr      if( debug_on )
270546283Sdfr          printf( "..a process 'event'\n" );
270646283Sdfr#endif
270746283Sdfr
270846283Sdfr      /* Also make fork and exec events look like bpts, so they can be caught.
270946283Sdfr      */
271046283Sdfr      *status = 0177 | (_SIGTRAP << 8);
271146283Sdfr    }
271246283Sdfr
271346283Sdfr  /* Special-cases: We ask for syscall entry and exit events to implement
271446283Sdfr     "fast" (aka "hardware") watchpoints.
271546283Sdfr
271646283Sdfr     When we get a syscall entry, we want to disable page-protections,
271746283Sdfr     and resume the inferior; this isn't an event we wish for
271846283Sdfr     wait_for_inferior to see.  Note that we must resume ONLY the
271946283Sdfr     thread that reported the syscall entry; we don't want to allow
272046283Sdfr     other threads to run with the page protections off, as they might
272146283Sdfr     then be able to write to watch memory without it being caught.
272246283Sdfr
272346283Sdfr     When we get a syscall exit, we want to reenable page-protections,
272446283Sdfr     but we don't want to resume the inferior; this is an event we wish
272546283Sdfr     wait_for_inferior to see.  Make it look like the signal we normally
272646283Sdfr     get for a single-step completion.  This should cause wait_for_inferior
272746283Sdfr     to evaluate whether any watchpoint triggered.
272846283Sdfr
272946283Sdfr     Or rather, that's what we'd LIKE to do for syscall exit; we can't,
273046283Sdfr     due to some HP-UX "features".  Some syscalls have problems with
273146283Sdfr     write-protections on some pages, and some syscalls seem to have
273246283Sdfr     pending writes to those pages at the time we're getting the return
273346283Sdfr     event.  So, we'll single-step the inferior to get out of the syscall,
273446283Sdfr     and then reenable protections.
273546283Sdfr
273646283Sdfr     Note that we're intentionally allowing the syscall exit case to
273746283Sdfr     fall through into the succeeding cases, as sometimes we single-
273846283Sdfr     step out of one syscall only to immediately enter another...
273946283Sdfr   */
274046283Sdfr  else if ((tsp.tts_event & TTEVT_SYSCALL_ENTRY)
274146283Sdfr        || (tsp.tts_event & TTEVT_SYSCALL_RETURN))
274246283Sdfr    {
274346283Sdfr      /* Make a syscall event look like a breakpoint.  Same comments
274446283Sdfr         as for exec & fork events.
274546283Sdfr         */
274646283Sdfr#ifdef THREAD_DEBUG
274746283Sdfr      if( debug_on )
274846283Sdfr          printf( "..a syscall 'event'\n" );
274946283Sdfr#endif
275046283Sdfr
275146283Sdfr      /* Also make syscall events look like bpts, so they can be caught.
275246283Sdfr      */
275346283Sdfr      *status = 0177 | (_SIGTRAP << 8);
275446283Sdfr    }
275546283Sdfr
275646283Sdfr  else if ((tsp.tts_event & TTEVT_LWP_CREATE)
275746283Sdfr        || (tsp.tts_event & TTEVT_LWP_TERMINATE)
275846283Sdfr        || (tsp.tts_event & TTEVT_LWP_EXIT))
275946283Sdfr    {
276046283Sdfr      /* Make a thread event look like a breakpoint.  Same comments
276146283Sdfr       * as for exec & fork events.
276246283Sdfr       */
276346283Sdfr#ifdef THREAD_DEBUG
276446283Sdfr      if( debug_on )
276546283Sdfr          printf( "..a thread 'event'\n" );
276646283Sdfr#endif
276746283Sdfr
276846283Sdfr      /* Also make thread events look like bpts, so they can be caught.
276946283Sdfr      */
277046283Sdfr      *status = 0177 | (_SIGTRAP << 8);
277146283Sdfr    }
277246283Sdfr
277346283Sdfr  else if ((tsp.tts_event & TTEVT_EXIT))
277446283Sdfr    {  /* WIFEXITED */
277546283Sdfr
277646283Sdfr#ifdef THREAD_DEBUG
277746283Sdfr       if( debug_on )
277846283Sdfr           printf( "..an exit\n" );
277946283Sdfr#endif
278046283Sdfr
278146283Sdfr      /* Prevent rest of gdb from thinking this is
278246283Sdfr       * a new thread if for some reason it's never
278346283Sdfr       * seen the main thread before.
278446283Sdfr       */
278546283Sdfr      inferior_pid = map_to_gdb_tid( real_tid ); /* HACK, FIX */
278646283Sdfr
278746283Sdfr      *status = 0 | (tsp.tts_u.tts_exit.tts_exitcode);
278846283Sdfr    }
278946283Sdfr
279046283Sdfr  else if (tsp.tts_event & TTEVT_SIGNAL)
279146283Sdfr    {  /* WIFSTOPPED */
279246283Sdfr#ifdef THREAD_DEBUG
279346283Sdfr       if( debug_on )
279446283Sdfr           printf( "..a signal, %d\n", tsp.tts_u.tts_signal.tts_signo );
279546283Sdfr#endif
279646283Sdfr
279746283Sdfr      *status = 0177 | (tsp.tts_u.tts_signal.tts_signo << 8);
279846283Sdfr    }
279946283Sdfr
280046283Sdfr  else
280146283Sdfr    {  /* !WIFSTOPPED */
280246283Sdfr
280346283Sdfr      /* This means the process or thread terminated.  But we should've
280446283Sdfr         caught an explicit exit/termination above.  So warn (this is
280546283Sdfr         really an internal error) and claim the process or thread
280646283Sdfr         terminated with a SIGTRAP.
280746283Sdfr       */
280846283Sdfr
280946283Sdfr      warning ("process_wait: unknown process state");
281046283Sdfr
281146283Sdfr#ifdef THREAD_DEBUG
281246283Sdfr      if( debug_on )
281346283Sdfr          printf( "Process-level event %s, using tid %d\n",
281446283Sdfr                  get_printable_name_of_ttrace_event( tsp.tts_event ),
281546283Sdfr                  real_tid );
281646283Sdfr#endif
281746283Sdfr
281846283Sdfr      *status = _SIGTRAP;
281946283Sdfr    }
282046283Sdfr
282146283Sdfr  target_post_wait (tsp.tts_pid, *status);
282246283Sdfr
282346283Sdfr
282446283Sdfr#ifdef THREAD_DEBUG
282546283Sdfr  if( debug_on )
282646283Sdfr      printf( "Done waiting, pid is %d, tid %d\n", real_pid, real_tid );
282746283Sdfr#endif
282846283Sdfr
282946283Sdfr  /* All code external to this module uses the tid, but calls
283046283Sdfr   * it "pid".  There's some tweaking so that the outside sees
283146283Sdfr   * the first thread as having the same number as the starting
283246283Sdfr   * pid.
283346283Sdfr   */
283446283Sdfr  return_pid = map_to_gdb_tid( real_tid );
283546283Sdfr
283646283Sdfr  /* Remember this for later use in "hppa_prepare_to_proceed".
283746283Sdfr   */
283846283Sdfr  old_gdb_pid  = inferior_pid;
283946283Sdfr  reported_pid = return_pid;
284046283Sdfr  reported_bpt = ((tsp.tts_event & TTEVT_SIGNAL) && (5 == tsp.tts_u.tts_signal.tts_signo));
284146283Sdfr
284246283Sdfr  if( real_tid == 0 || return_pid == 0 ) {
284346283Sdfr      warning( "Internal error: process-wait failed." );
284446283Sdfr  }
284546283Sdfr
284646283Sdfr  return return_pid;
284746283Sdfr}
284846283Sdfr
284946283Sdfr
285046283Sdfr/* This function causes the caller's process to be traced by its
285146283Sdfr   parent.  This is intended to be called after GDB forks itself,
285246283Sdfr   and before the child execs the target.  Despite the name, it
285346283Sdfr   is called by the child.
285446283Sdfr
285546283Sdfr   Note that HP-UX ttrace is rather funky in how this is done.
285646283Sdfr   If the parent wants to get the initial exec event of a child,
285746283Sdfr   it must set the ttrace event mask of the child to include execs.
285846283Sdfr   (The child cannot do this itself.)  This must be done after the
285946283Sdfr   child is forked, but before it execs.
286046283Sdfr
286146283Sdfr   To coordinate the parent and child, we implement a semaphore using
286246283Sdfr   pipes.  After SETTRC'ing itself, the child tells the parent that
286346283Sdfr   it is now traceable by the parent, and waits for the parent's
286446283Sdfr   acknowledgement.  The parent can then set the child's event mask,
286546283Sdfr   and notify the child that it can now exec.
286646283Sdfr
286746283Sdfr   (The acknowledgement by parent happens as a result of a call to
286846283Sdfr   child_acknowledge_created_inferior.)
286946283Sdfr */
287046283Sdfrint
287146283Sdfrparent_attach_all ()
287246283Sdfr{
287346283Sdfr  int  tt_status;
287446283Sdfr
287546283Sdfr  /* We need a memory home for a constant, to pass it to ttrace.
287646283Sdfr     The value of the constant is arbitrary, so long as both
287746283Sdfr     parent and child use the same value.  Might as well use the
287846283Sdfr     "magic" constant provided by ttrace...
287946283Sdfr   */
288046283Sdfr  uint64_t  tc_magic_child = TT_VERSION;
288146283Sdfr  uint64_t  tc_magic_parent = 0;
288246283Sdfr
288346283Sdfr  tt_status = call_real_ttrace (
288446283Sdfr                            TT_PROC_SETTRC,
288546283Sdfr                            (int)     TT_NIL,
288646283Sdfr                            (lwpid_t) TT_NIL,
288746283Sdfr                            TT_NIL,
288846283Sdfr                            (TTRACE_ARG_TYPE) TT_VERSION,
288946283Sdfr                            TT_NIL );
289046283Sdfr
289146283Sdfr  if (tt_status < 0)
289246283Sdfr    return tt_status;
289346283Sdfr
289446283Sdfr  /* Notify the parent that we're potentially ready to exec(). */
289546283Sdfr  write (startup_semaphore.child_channel[SEM_TALK],
289646283Sdfr         &tc_magic_child,
289746283Sdfr         sizeof (tc_magic_child));
289846283Sdfr
289946283Sdfr  /* Wait for acknowledgement from the parent. */
290046283Sdfr  read (startup_semaphore.parent_channel[SEM_LISTEN],
290146283Sdfr        &tc_magic_parent,
290246283Sdfr        sizeof (tc_magic_parent));
290346283Sdfr
290446283Sdfr  if (tc_magic_child != tc_magic_parent)
290546283Sdfr    warning ("mismatched semaphore magic");
290646283Sdfr
290746283Sdfr  /* Discard our copy of the semaphore. */
290846283Sdfr  (void) close (startup_semaphore.parent_channel[SEM_LISTEN]);
290946283Sdfr  (void) close (startup_semaphore.parent_channel[SEM_TALK]);
291046283Sdfr  (void) close (startup_semaphore.child_channel[SEM_LISTEN]);
291146283Sdfr  (void) close (startup_semaphore.child_channel[SEM_TALK]);
291246283Sdfr
291346283Sdfr  return tt_status;
291446283Sdfr}
291546283Sdfr
291646283Sdfr/* Despite being file-local, this routine is dealing with
291746283Sdfr * actual process IDs, not thread ids.  That's because it's
291846283Sdfr * called before the first "wait" call, and there's no map
291946283Sdfr * yet from tids to pids.
292046283Sdfr *
292146283Sdfr * When it is called, a forked child is running, but waiting on
292246283Sdfr * the semaphore.  If you stop the child and re-start it,
292346283Sdfr * things get confused, so don't do that!  An attached child is
292446283Sdfr * stopped.
292546283Sdfr *
292646283Sdfr * Since this is called after either attach or run, we
292746283Sdfr * have to be the common part of both.
292846283Sdfr */
292946283Sdfrstatic void
293046283Sdfrrequire_notification_of_events ( real_pid )
293146283Sdfr  int  real_pid;
293246283Sdfr{
293346283Sdfr  int  tt_status;
293446283Sdfr  ttevent_t  notifiable_events;
293546283Sdfr
293646283Sdfr  lwpid_t    tid;
293746283Sdfr  ttstate_t  thread_state;
293846283Sdfr
293946283Sdfr#ifdef THREAD_DEBUG
294046283Sdfr  if( debug_on )
294146283Sdfr      printf( "Require notif, pid is %d\n", real_pid );
294246283Sdfr#endif
294346283Sdfr
294446283Sdfr  /* Temporary HACK: tell inftarg.c/child_wait to not
294546283Sdfr   * loop until pids are the same.
294646283Sdfr   */
294746283Sdfr  not_same_real_pid = 0;
294846283Sdfr
294946283Sdfr  sigemptyset (&notifiable_events.tte_signals);
295046283Sdfr  notifiable_events.tte_opts = TTEO_NONE;
295146283Sdfr
295246283Sdfr  /* This ensures that forked children inherit their parent's
295346283Sdfr   * event mask, which we're setting here.
295446283Sdfr   *
295546283Sdfr   * NOTE: if you debug gdb with itself, then the ultimate
295646283Sdfr   *       debuggee gets flags set by the outermost gdb, as
295746283Sdfr   *       a child of a child will still inherit.
295846283Sdfr   */
295946283Sdfr  notifiable_events.tte_opts |= TTEO_PROC_INHERIT;
296046283Sdfr
296146283Sdfr  notifiable_events.tte_events  = TTEVT_DEFAULT;
296246283Sdfr  notifiable_events.tte_events |= TTEVT_SIGNAL;
296346283Sdfr  notifiable_events.tte_events |= TTEVT_EXEC;
296446283Sdfr  notifiable_events.tte_events |= TTEVT_EXIT;
296546283Sdfr  notifiable_events.tte_events |= TTEVT_FORK;
296646283Sdfr  notifiable_events.tte_events |= TTEVT_VFORK;
296746283Sdfr  notifiable_events.tte_events |= TTEVT_LWP_CREATE;
296846283Sdfr  notifiable_events.tte_events |= TTEVT_LWP_EXIT;
296946283Sdfr  notifiable_events.tte_events |= TTEVT_LWP_TERMINATE;
297046283Sdfr
297146283Sdfr  tt_status = call_real_ttrace (
297246283Sdfr                           TT_PROC_SET_EVENT_MASK,
297346283Sdfr                           real_pid,
297446283Sdfr                           (lwpid_t) TT_NIL,
297546283Sdfr                           (TTRACE_ARG_TYPE) &notifiable_events,
297646283Sdfr                           (TTRACE_ARG_TYPE) sizeof (notifiable_events),
297746283Sdfr                           TT_NIL);
297846283Sdfr}
297946283Sdfr
298046283Sdfrstatic void
298146283Sdfrrequire_notification_of_exec_events ( real_pid )
298246283Sdfr  int  real_pid;
298346283Sdfr{
298446283Sdfr  int  tt_status;
298546283Sdfr  ttevent_t  notifiable_events;
298646283Sdfr
298746283Sdfr  lwpid_t    tid;
298846283Sdfr  ttstate_t  thread_state;
298946283Sdfr
299046283Sdfr#ifdef THREAD_DEBUG
299146283Sdfr  if( debug_on )
299246283Sdfr      printf( "Require notif, pid is %d\n", real_pid );
299346283Sdfr#endif
299446283Sdfr
299546283Sdfr  /* Temporary HACK: tell inftarg.c/child_wait to not
299646283Sdfr   * loop until pids are the same.
299746283Sdfr   */
299846283Sdfr  not_same_real_pid = 0;
299946283Sdfr
300046283Sdfr  sigemptyset (&notifiable_events.tte_signals);
300146283Sdfr  notifiable_events.tte_opts = TTEO_NOSTRCCHLD;
300246283Sdfr
300346283Sdfr  /* This ensures that forked children don't inherit their parent's
300446283Sdfr   * event mask, which we're setting here.
300546283Sdfr   */
300646283Sdfr  notifiable_events.tte_opts &= ~TTEO_PROC_INHERIT;
300746283Sdfr
300846283Sdfr  notifiable_events.tte_events  = TTEVT_DEFAULT;
300946283Sdfr  notifiable_events.tte_events |= TTEVT_EXEC;
301046283Sdfr  notifiable_events.tte_events |= TTEVT_EXIT;
301146283Sdfr
301246283Sdfr  tt_status = call_real_ttrace (
301346283Sdfr                           TT_PROC_SET_EVENT_MASK,
301446283Sdfr                           real_pid,
301546283Sdfr                           (lwpid_t) TT_NIL,
301646283Sdfr                           (TTRACE_ARG_TYPE) &notifiable_events,
301746283Sdfr                           (TTRACE_ARG_TYPE) sizeof (notifiable_events),
301846283Sdfr                           TT_NIL);
301946283Sdfr}
302046283Sdfr
302146283Sdfr
302246283Sdfr/* This function is called by the parent process, with pid being the
302346283Sdfr * ID of the child process, after the debugger has forked.
302446283Sdfr */
302546283Sdfrvoid
302646283Sdfrchild_acknowledge_created_inferior (pid)
302746283Sdfr    int  pid;
302846283Sdfr{
302946283Sdfr  /* We need a memory home for a constant, to pass it to ttrace.
303046283Sdfr     The value of the constant is arbitrary, so long as both
303146283Sdfr     parent and child use the same value.  Might as well use the
303246283Sdfr     "magic" constant provided by ttrace...
303346283Sdfr     */
303446283Sdfr  uint64_t  tc_magic_parent = TT_VERSION;
303546283Sdfr  uint64_t  tc_magic_child = 0;
303646283Sdfr
303746283Sdfr  /* Wait for the child to tell us that it has forked. */
303846283Sdfr  read (startup_semaphore.child_channel[SEM_LISTEN],
303946283Sdfr        &tc_magic_child,
304046283Sdfr        sizeof(tc_magic_child));
304146283Sdfr
304246283Sdfr  /* Clear thread info now.  We'd like to do this in
304346283Sdfr   * "require...", but that messes up attach.
304446283Sdfr   */
304546283Sdfr  clear_thread_info();
304646283Sdfr
304746283Sdfr  /* Tell the "rest of gdb" that the initial thread exists.
304846283Sdfr   * This isn't really a hack.  Other thread-based versions
304946283Sdfr   * of gdb (e.g. gnu-nat.c) seem to do the same thing.
305046283Sdfr   *
305146283Sdfr   * Q: Why don't we also add this thread to the local
305246283Sdfr   *    list via "add_tthread"?
305346283Sdfr   *
305446283Sdfr   * A: Because we don't know the tid, and can't stop the
305546283Sdfr   *    the process safely to ask what it is.  Anyway, we'll
305646283Sdfr   *    add it when it gets the EXEC event.
305746283Sdfr   */
305846283Sdfr  add_thread( pid );       /* in thread.c */
305946283Sdfr
306046283Sdfr  /* We can now set the child's ttrace event mask.
306146283Sdfr   */
306246283Sdfr  require_notification_of_exec_events (pid);
306346283Sdfr
306446283Sdfr  /* Tell ourselves that the process is running.
306546283Sdfr   */
306646283Sdfr  process_state = RUNNING;
306746283Sdfr
306846283Sdfr  /* Notify the child that it can exec. */
306946283Sdfr  write (startup_semaphore.parent_channel[SEM_TALK],
307046283Sdfr         &tc_magic_parent,
307146283Sdfr         sizeof (tc_magic_parent));
307246283Sdfr
307346283Sdfr  /* Discard our copy of the semaphore. */
307446283Sdfr  (void) close (startup_semaphore.parent_channel[SEM_LISTEN]);
307546283Sdfr  (void) close (startup_semaphore.parent_channel[SEM_TALK]);
307646283Sdfr  (void) close (startup_semaphore.child_channel[SEM_LISTEN]);
307746283Sdfr  (void) close (startup_semaphore.child_channel[SEM_TALK]);
307846283Sdfr}
307946283Sdfr
308046283Sdfr
308146283Sdfr/*
308246283Sdfr * arrange for notification of all events by
308346283Sdfr * calling require_notification_of_events.
308446283Sdfr */
308546283Sdfrvoid
308646283Sdfrchild_post_startup_inferior ( real_pid)
308746283Sdfr  int  real_pid;
308846283Sdfr{
308946283Sdfr  require_notification_of_events (real_pid);
309046283Sdfr}
309146283Sdfr
309246283Sdfr/* From here on, we should expect tids rather than pids.
309346283Sdfr */
309446283Sdfrstatic void
309546283Sdfrhppa_enable_catch_fork (tid)
309646283Sdfr  int  tid;
309746283Sdfr{
309846283Sdfr  int        tt_status;
309946283Sdfr  ttevent_t  ttrace_events;
310046283Sdfr
310146283Sdfr  /* Get the set of events that are currently enabled.
310246283Sdfr   */
310346283Sdfr  tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
310446283Sdfr                           tid,
310546283Sdfr                           (TTRACE_ARG_TYPE) &ttrace_events,
310646283Sdfr                           (TTRACE_ARG_TYPE) sizeof (ttrace_events),
310746283Sdfr                           TT_NIL );
310846283Sdfr  if (errno)
310946283Sdfr    perror_with_name ("ttrace");
311046283Sdfr
311146283Sdfr  /* Add forks to that set. */
311246283Sdfr  ttrace_events.tte_events |= TTEVT_FORK;
311346283Sdfr
311446283Sdfr#ifdef THREAD_DEBUG
311546283Sdfr  if( debug_on )
311646283Sdfr      printf( "enable fork, tid is %d\n", tid );
311746283Sdfr#endif
311846283Sdfr
311946283Sdfr  tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
312046283Sdfr                           tid,
312146283Sdfr                           (TTRACE_ARG_TYPE) &ttrace_events,
312246283Sdfr                           (TTRACE_ARG_TYPE) sizeof (ttrace_events),
312346283Sdfr                           TT_NIL);
312446283Sdfr  if (errno)
312546283Sdfr    perror_with_name ("ttrace");
312646283Sdfr}
312746283Sdfr
312846283Sdfr
312946283Sdfrstatic void
313046283Sdfrhppa_disable_catch_fork (tid)
313146283Sdfr  int  tid;
313246283Sdfr{
313346283Sdfr  int        tt_status;
313446283Sdfr  ttevent_t  ttrace_events;
313546283Sdfr
313646283Sdfr  /* Get the set of events that are currently enabled.
313746283Sdfr   */
313846283Sdfr  tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
313946283Sdfr                           tid,
314046283Sdfr                           (TTRACE_ARG_TYPE) &ttrace_events,
314146283Sdfr                           (TTRACE_ARG_TYPE) sizeof (ttrace_events),
314246283Sdfr                           TT_NIL);
314346283Sdfr
314446283Sdfr  if (errno)
314546283Sdfr    perror_with_name ("ttrace");
314646283Sdfr
314746283Sdfr  /* Remove forks from that set. */
314846283Sdfr  ttrace_events.tte_events &= ~TTEVT_FORK;
314946283Sdfr
315046283Sdfr#ifdef THREAD_DEBUG
315146283Sdfr  if( debug_on )
315246283Sdfr      printf("disable fork, tid is %d\n", tid );
315346283Sdfr#endif
315446283Sdfr
315546283Sdfr  tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
315646283Sdfr                           tid,
315746283Sdfr                           (TTRACE_ARG_TYPE) &ttrace_events,
315846283Sdfr                           (TTRACE_ARG_TYPE) sizeof (ttrace_events),
315946283Sdfr                           TT_NIL);
316046283Sdfr
316146283Sdfr  if (errno)
316246283Sdfr    perror_with_name ("ttrace");
316346283Sdfr}
316446283Sdfr
316546283Sdfr
316646283Sdfr#if defined(CHILD_INSERT_FORK_CATCHPOINT)
316746283Sdfrint
316846283Sdfrchild_insert_fork_catchpoint (tid)
316946283Sdfr  int  tid;
317046283Sdfr{
317146283Sdfr  /* Enable reporting of fork events from the kernel. */
317246283Sdfr  /* ??rehrauer: For the moment, we're always enabling these events,
317346283Sdfr     and just ignoring them if there's no catchpoint to catch them.
317446283Sdfr     */
317546283Sdfr  return 0;
317646283Sdfr}
317746283Sdfr#endif
317846283Sdfr
317946283Sdfr
318046283Sdfr#if defined(CHILD_REMOVE_FORK_CATCHPOINT)
318146283Sdfrint
318246283Sdfrchild_remove_fork_catchpoint (tid)
318346283Sdfr  int  tid;
318446283Sdfr{
318546283Sdfr  /* Disable reporting of fork events from the kernel. */
318646283Sdfr  /* ??rehrauer: For the moment, we're always enabling these events,
318746283Sdfr     and just ignoring them if there's no catchpoint to catch them.
318846283Sdfr     */
318946283Sdfr  return 0;
319046283Sdfr}
319146283Sdfr#endif
319246283Sdfr
319346283Sdfr
319446283Sdfrstatic void
319546283Sdfrhppa_enable_catch_vfork (tid)
319646283Sdfr  int  tid;
319746283Sdfr{
319846283Sdfr  int  tt_status;
319946283Sdfr  ttevent_t  ttrace_events;
320046283Sdfr
320146283Sdfr  /* Get the set of events that are currently enabled.
320246283Sdfr   */
320346283Sdfr  tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
320446283Sdfr                           tid,
320546283Sdfr                           (TTRACE_ARG_TYPE) &ttrace_events,
320646283Sdfr                           (TTRACE_ARG_TYPE) sizeof (ttrace_events),
320746283Sdfr                           TT_NIL);
320846283Sdfr
320946283Sdfr  if (errno)
321046283Sdfr    perror_with_name ("ttrace");
321146283Sdfr
321246283Sdfr  /* Add vforks to that set. */
321346283Sdfr  ttrace_events.tte_events |= TTEVT_VFORK;
321446283Sdfr
321546283Sdfr#ifdef THREAD_DEBUG
321646283Sdfr  if( debug_on )
321746283Sdfr      printf("enable vfork, tid is %d\n", tid );
321846283Sdfr#endif
321946283Sdfr
322046283Sdfr  tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
322146283Sdfr                           tid,
322246283Sdfr                           (TTRACE_ARG_TYPE) &ttrace_events,
322346283Sdfr                           (TTRACE_ARG_TYPE) sizeof (ttrace_events),
322446283Sdfr                           TT_NIL);
322546283Sdfr
322646283Sdfr  if (errno)
322746283Sdfr    perror_with_name ("ttrace");
322846283Sdfr}
322946283Sdfr
323046283Sdfr
323146283Sdfrstatic void
323246283Sdfrhppa_disable_catch_vfork (tid)
323346283Sdfr  int  tid;
323446283Sdfr{
323546283Sdfr  int  tt_status;
323646283Sdfr  ttevent_t  ttrace_events;
323746283Sdfr
323846283Sdfr  /* Get the set of events that are currently enabled. */
323946283Sdfr  tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
324046283Sdfr                           tid,
324146283Sdfr                           (TTRACE_ARG_TYPE) &ttrace_events,
324246283Sdfr                           (TTRACE_ARG_TYPE) sizeof (ttrace_events),
324346283Sdfr                           TT_NIL);
324446283Sdfr
324546283Sdfr  if (errno)
324646283Sdfr    perror_with_name ("ttrace");
324746283Sdfr
324846283Sdfr  /* Remove vforks from that set. */
324946283Sdfr  ttrace_events.tte_events &= ~TTEVT_VFORK;
325046283Sdfr
325146283Sdfr#ifdef THREAD_DEBUG
325246283Sdfr  if( debug_on )
325346283Sdfr      printf("disable vfork, tid is %d\n", tid );
325446283Sdfr#endif
325546283Sdfr  tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
325646283Sdfr                           tid,
325746283Sdfr                           (TTRACE_ARG_TYPE) &ttrace_events,
325846283Sdfr                           (TTRACE_ARG_TYPE) sizeof (ttrace_events),
325946283Sdfr                           TT_NIL);
326046283Sdfr
326146283Sdfr  if (errno)
326246283Sdfr    perror_with_name ("ttrace");
326346283Sdfr}
326446283Sdfr
326546283Sdfr
326646283Sdfr#if defined(CHILD_INSERT_VFORK_CATCHPOINT)
326746283Sdfrint
326846283Sdfrchild_insert_vfork_catchpoint (tid)
326946283Sdfr  int  tid;
327046283Sdfr{
327146283Sdfr  /* Enable reporting of vfork events from the kernel. */
327246283Sdfr  /* ??rehrauer: For the moment, we're always enabling these events,
327346283Sdfr     and just ignoring them if there's no catchpoint to catch them.
327446283Sdfr     */
327546283Sdfr  return 0;
327646283Sdfr}
327746283Sdfr#endif
327846283Sdfr
327946283Sdfr
328046283Sdfr#if defined(CHILD_REMOVE_VFORK_CATCHPOINT)
328146283Sdfrint
328246283Sdfrchild_remove_vfork_catchpoint (tid)
328346283Sdfr  int  tid;
328446283Sdfr{
328546283Sdfr  /* Disable reporting of vfork events from the kernel. */
328646283Sdfr  /* ??rehrauer: For the moment, we're always enabling these events,
328746283Sdfr     and just ignoring them if there's no catchpoint to catch them.
328846283Sdfr     */
328946283Sdfr  return 0;
329046283Sdfr}
329146283Sdfr#endif
329246283Sdfr
329346283Sdfr#if defined(CHILD_HAS_FORKED)
329446283Sdfr
329546283Sdfr/* Q: Do we need to map the returned process ID to a thread ID?
329646283Sdfr *
329746283Sdfr * A: I don't think so--here we want a _real_ pid.  Any later
329846283Sdfr *    operations will call "require_notification_of_events" and
329946283Sdfr *    start the mapping.
330046283Sdfr */
330146283Sdfrint
330246283Sdfrchild_has_forked (tid, childpid)
330346283Sdfr  int  tid;
330446283Sdfr  int *childpid;
330546283Sdfr{
330646283Sdfr  int  tt_status;
330746283Sdfr  ttstate_t  ttrace_state;
330846283Sdfr  thread_info *  tinfo;
330946283Sdfr
331046283Sdfr  /* Do we have cached thread state that we can consult?  If so, use it. */
331146283Sdfr  tinfo = find_thread_info (map_from_gdb_tid (tid));
331246283Sdfr  if (tinfo != NULL) {
331346283Sdfr    copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state);
331446283Sdfr  }
331546283Sdfr
331646283Sdfr  /* Nope, must read the thread's current state */
331746283Sdfr  else
331846283Sdfr    {
331946283Sdfr      tt_status = call_ttrace (TT_LWP_GET_STATE,
332046283Sdfr                               tid,
332146283Sdfr                               (TTRACE_ARG_TYPE) &ttrace_state,
332246283Sdfr                               (TTRACE_ARG_TYPE) sizeof (ttrace_state),
332346283Sdfr                               TT_NIL);
332446283Sdfr
332546283Sdfr      if (errno)
332646283Sdfr        perror_with_name ("ttrace");
332746283Sdfr
332846283Sdfr      if (tt_status < 0)
332946283Sdfr        return 0;
333046283Sdfr    }
333146283Sdfr
333246283Sdfr  if (ttrace_state.tts_event & TTEVT_FORK)
333346283Sdfr    {
333446283Sdfr      *childpid = ttrace_state.tts_u.tts_fork.tts_fpid;
333546283Sdfr      return 1;
333646283Sdfr    }
333746283Sdfr
333846283Sdfr  return 0;
333946283Sdfr}
334046283Sdfr#endif
334146283Sdfr
334246283Sdfr
334346283Sdfr#if defined(CHILD_HAS_VFORKED)
334446283Sdfr
334546283Sdfr/* See child_has_forked for pid discussion.
334646283Sdfr */
334746283Sdfrint
334846283Sdfrchild_has_vforked (tid, childpid)
334946283Sdfr  int  tid;
335046283Sdfr  int *  childpid;
335146283Sdfr{
335246283Sdfr  int  tt_status;
335346283Sdfr  ttstate_t  ttrace_state;
335446283Sdfr  thread_info *  tinfo;
335546283Sdfr
335646283Sdfr  /* Do we have cached thread state that we can consult?  If so, use it. */
335746283Sdfr  tinfo = find_thread_info (map_from_gdb_tid (tid));
335846283Sdfr  if (tinfo != NULL)
335946283Sdfr    copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state);
336046283Sdfr
336146283Sdfr  /* Nope, must read the thread's current state */
336246283Sdfr  else
336346283Sdfr    {
336446283Sdfr      tt_status = call_ttrace (TT_LWP_GET_STATE,
336546283Sdfr                               tid,
336646283Sdfr                               (TTRACE_ARG_TYPE) &ttrace_state,
336746283Sdfr                               (TTRACE_ARG_TYPE) sizeof (ttrace_state),
336846283Sdfr                               TT_NIL);
336946283Sdfr
337046283Sdfr      if (errno)
337146283Sdfr        perror_with_name ("ttrace");
337246283Sdfr
337346283Sdfr      if (tt_status < 0)
337446283Sdfr        return 0;
337546283Sdfr    }
337646283Sdfr
337746283Sdfr  if (ttrace_state.tts_event & TTEVT_VFORK)
337846283Sdfr    {
337946283Sdfr      *childpid = ttrace_state.tts_u.tts_fork.tts_fpid;
338046283Sdfr      return 1;
338146283Sdfr    }
338246283Sdfr
338346283Sdfr  return 0;
338446283Sdfr}
338546283Sdfr#endif
338646283Sdfr
338746283Sdfr
338846283Sdfr#if defined(CHILD_CAN_FOLLOW_VFORK_PRIOR_TO_EXEC)
338946283Sdfrint
339046283Sdfrchild_can_follow_vfork_prior_to_exec ()
339146283Sdfr{
339246283Sdfr  /* ttrace does allow this.
339346283Sdfr
339446283Sdfr     ??rehrauer: However, I had major-league problems trying to
339546283Sdfr     convince wait_for_inferior to handle that case.  Perhaps when
339646283Sdfr     it is rewritten to grok multiple processes in an explicit way...
339746283Sdfr     */
339846283Sdfr  return 0;
339946283Sdfr}
340046283Sdfr#endif
340146283Sdfr
340246283Sdfr
340346283Sdfr#if defined(CHILD_INSERT_EXEC_CATCHPOINT)
340446283Sdfrint
340546283Sdfrchild_insert_exec_catchpoint (tid)
340646283Sdfr  int  tid;
340746283Sdfr{
340846283Sdfr  /* Enable reporting of exec events from the kernel. */
340946283Sdfr  /* ??rehrauer: For the moment, we're always enabling these events,
341046283Sdfr     and just ignoring them if there's no catchpoint to catch them.
341146283Sdfr     */
341246283Sdfr  return 0;
341346283Sdfr}
341446283Sdfr#endif
341546283Sdfr
341646283Sdfr
341746283Sdfr#if defined(CHILD_REMOVE_EXEC_CATCHPOINT)
341846283Sdfrint
341946283Sdfrchild_remove_exec_catchpoint (tid)
342046283Sdfr  int  tid;
342146283Sdfr{
342246283Sdfr  /* Disable reporting of execevents from the kernel. */
342346283Sdfr  /* ??rehrauer: For the moment, we're always enabling these events,
342446283Sdfr     and just ignoring them if there's no catchpoint to catch them.
342546283Sdfr     */
342646283Sdfr  return 0;
342746283Sdfr}
342846283Sdfr#endif
342946283Sdfr
343046283Sdfr
343146283Sdfr#if defined(CHILD_HAS_EXECD)
343246283Sdfrint
343346283Sdfrchild_has_execd (tid, execd_pathname)
343446283Sdfr  int  tid;
343546283Sdfr  char **  execd_pathname;
343646283Sdfr{
343746283Sdfr  int  tt_status;
343846283Sdfr  ttstate_t  ttrace_state;
343946283Sdfr  thread_info *  tinfo;
344046283Sdfr
344146283Sdfr  /* Do we have cached thread state that we can consult?  If so, use it. */
344246283Sdfr  tinfo = find_thread_info (map_from_gdb_tid (tid));
344346283Sdfr  if (tinfo != NULL)
344446283Sdfr    copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state);
344546283Sdfr
344646283Sdfr  /* Nope, must read the thread's current state */
344746283Sdfr  else
344846283Sdfr    {
344946283Sdfr      tt_status = call_ttrace (TT_LWP_GET_STATE,
345046283Sdfr                               tid,
345146283Sdfr                               (TTRACE_ARG_TYPE) &ttrace_state,
345246283Sdfr                               (TTRACE_ARG_TYPE) sizeof (ttrace_state),
345346283Sdfr                               TT_NIL);
345446283Sdfr
345546283Sdfr      if (errno)
345646283Sdfr        perror_with_name ("ttrace");
345746283Sdfr
345846283Sdfr      if (tt_status < 0)
345946283Sdfr        return 0;
346046283Sdfr    }
346146283Sdfr
346246283Sdfr  if (ttrace_state.tts_event & TTEVT_EXEC)
346346283Sdfr    {
346446283Sdfr      /* See child_pid_to_exec_file in this file: this is a macro.
346546283Sdfr       */
346646283Sdfr      char *  exec_file = target_pid_to_exec_file (tid);
346746283Sdfr
346846283Sdfr      *execd_pathname = savestring (exec_file, strlen (exec_file));
346946283Sdfr      return 1;
347046283Sdfr    }
347146283Sdfr
347246283Sdfr  return 0;
347346283Sdfr}
347446283Sdfr#endif
347546283Sdfr
347646283Sdfr
347746283Sdfr#if defined(CHILD_HAS_SYSCALL_EVENT)
347846283Sdfrint
347946283Sdfrchild_has_syscall_event (pid, kind, syscall_id)
348046283Sdfr  int  pid;
348146283Sdfr  enum target_waitkind *  kind;
348246283Sdfr  int *  syscall_id;
348346283Sdfr{
348446283Sdfr  int  tt_status;
348546283Sdfr  ttstate_t  ttrace_state;
348646283Sdfr  thread_info *  tinfo;
348746283Sdfr
348846283Sdfr  /* Do we have cached thread state that we can consult?  If so, use it. */
348946283Sdfr  tinfo = find_thread_info (map_from_gdb_tid (pid));
349046283Sdfr  if (tinfo != NULL)
349146283Sdfr    copy_ttstate_t (&ttrace_state, &tinfo->last_stop_state);
349246283Sdfr
349346283Sdfr  /* Nope, must read the thread's current state */
349446283Sdfr  else
349546283Sdfr    {
349646283Sdfr    tt_status = call_ttrace (TT_LWP_GET_STATE,
349746283Sdfr                               pid,
349846283Sdfr                               (TTRACE_ARG_TYPE) &ttrace_state,
349946283Sdfr                               (TTRACE_ARG_TYPE) sizeof (ttrace_state),
350046283Sdfr                               TT_NIL);
350146283Sdfr
350246283Sdfr      if (errno)
350346283Sdfr        perror_with_name ("ttrace");
350446283Sdfr
350546283Sdfr      if (tt_status < 0)
350646283Sdfr        return 0;
350746283Sdfr    }
350846283Sdfr
350946283Sdfr  *kind = TARGET_WAITKIND_SPURIOUS;  /* Until proven otherwise... */
351046283Sdfr  *syscall_id = -1;
351146283Sdfr
351246283Sdfr  if (ttrace_state.tts_event & TTEVT_SYSCALL_ENTRY)
351346283Sdfr    *kind = TARGET_WAITKIND_SYSCALL_ENTRY;
351446283Sdfr  else if (ttrace_state.tts_event & TTEVT_SYSCALL_RETURN)
351546283Sdfr    *kind = TARGET_WAITKIND_SYSCALL_RETURN;
351646283Sdfr  else
351746283Sdfr    return 0;
351846283Sdfr
351946283Sdfr  *syscall_id = ttrace_state.tts_scno;
352046283Sdfr  return 1;
352146283Sdfr}
352246283Sdfr#endif
352346283Sdfr
352446283Sdfr
352546283Sdfr
352646283Sdfr#if defined(CHILD_THREAD_ALIVE)
352746283Sdfr
352846283Sdfr/* Check to see if the given thread is alive.
352946283Sdfr *
353046283Sdfr * We'll trust the thread list, as the more correct
353146283Sdfr * approach of stopping the process and spinning down
353246283Sdfr * the OS's thread list is _very_ expensive.
353346283Sdfr *
353446283Sdfr * May need a FIXME for that reason.
353546283Sdfr */
353646283Sdfrint
353746283Sdfrchild_thread_alive (gdb_tid)
353846283Sdfr     lwpid_t gdb_tid;
353946283Sdfr{
354046283Sdfr   lwpid_t  tid;
354146283Sdfr
354246283Sdfr   /* This spins down the lists twice.
354346283Sdfr    * Possible peformance improvement here!
354446283Sdfr    */
354546283Sdfr   tid = map_from_gdb_tid( gdb_tid );
354646283Sdfr   return !is_terminated( tid );
354746283Sdfr}
354846283Sdfr
354946283Sdfr#endif
355046283Sdfr
355146283Sdfr
355246283Sdfr
355346283Sdfr/* This function attempts to read the specified number of bytes from the
355446283Sdfr   save_state_t that is our view into the hardware registers, starting at
355546283Sdfr   ss_offset, and ending at ss_offset + sizeof_buf - 1
355646283Sdfr
355746283Sdfr   If this function succeeds, it deposits the fetched bytes into buf,
355846283Sdfr   and returns 0.
355946283Sdfr
356046283Sdfr   If it fails, it returns a negative result.  The contents of buf are
356146283Sdfr   undefined it this function fails.
356246283Sdfr   */
356346283Sdfrint
356446283Sdfrread_from_register_save_state (tid, ss_offset, buf, sizeof_buf)
356546283Sdfr    int  tid;
356646283Sdfr    TTRACE_ARG_TYPE  ss_offset;
356746283Sdfr    char *  buf;
356846283Sdfr    int  sizeof_buf;
356946283Sdfr{
357046283Sdfr  int  tt_status;
357146283Sdfr  register_value_t  register_value = 0;
357246283Sdfr
357346283Sdfr  tt_status = call_ttrace (TT_LWP_RUREGS,
357446283Sdfr                           tid,
357546283Sdfr                           ss_offset,
357646283Sdfr                           (TTRACE_ARG_TYPE) sizeof_buf,
357746283Sdfr                           (TTRACE_ARG_TYPE) buf);
357846283Sdfr
357946283Sdfr  if( tt_status == 1 )
358046283Sdfr      /* Map ttrace's version of success to our version.
358146283Sdfr       * Sometime ttrace returns 0, but that's ok here.
358246283Sdfr       */
358346283Sdfr      return 0;
358446283Sdfr
358546283Sdfr  return tt_status;
358646283Sdfr}
358746283Sdfr
358846283Sdfr
358946283Sdfr/* This function attempts to write the specified number of bytes to the
359046283Sdfr   save_state_t that is our view into the hardware registers, starting at
359146283Sdfr   ss_offset, and ending at ss_offset + sizeof_buf - 1
359246283Sdfr
359346283Sdfr   If this function succeeds, it deposits the bytes in buf, and returns 0.
359446283Sdfr
359546283Sdfr   If it fails, it returns a negative result.  The contents of the save_state_t
359646283Sdfr   are undefined it this function fails.
359746283Sdfr   */
359846283Sdfrint
359946283Sdfrwrite_to_register_save_state (tid, ss_offset, buf, sizeof_buf)
360046283Sdfr    int  tid;
360146283Sdfr    TTRACE_ARG_TYPE  ss_offset;
360246283Sdfr    char *  buf;
360346283Sdfr    int  sizeof_buf;
360446283Sdfr{
360546283Sdfr  int  tt_status;
360646283Sdfr  register_value_t  register_value = 0;
360746283Sdfr
360846283Sdfr  tt_status = call_ttrace (TT_LWP_WUREGS,
360946283Sdfr                           tid,
361046283Sdfr                           ss_offset,
361146283Sdfr                           (TTRACE_ARG_TYPE) sizeof_buf,
361246283Sdfr                           (TTRACE_ARG_TYPE) buf);
361346283Sdfr  return tt_status;
361446283Sdfr}
361546283Sdfr
361646283Sdfr
361746283Sdfr/* This function is a sop to the largeish number of direct calls
361846283Sdfr   to call_ptrace that exist in other files.  Rather than create
361946283Sdfr   functions whose name abstracts away from ptrace, and change all
362046283Sdfr   the present callers of call_ptrace, we'll do the expedient (and
362146283Sdfr   perhaps only practical) thing.
362246283Sdfr
362346283Sdfr   Note HP-UX explicitly disallows a mix of ptrace & ttrace on a traced
362446283Sdfr   process.  Thus, we must translate all ptrace requests into their
362546283Sdfr   process-specific, ttrace equivalents.
362646283Sdfr   */
362746283Sdfrint
362846283Sdfrcall_ptrace (pt_request, gdb_tid, addr, data)
362946283Sdfr     int               pt_request;
363046283Sdfr     int               gdb_tid;
363146283Sdfr     PTRACE_ARG3_TYPE  addr;
363246283Sdfr     int               data;
363346283Sdfr{
363446283Sdfr  ttreq_t           tt_request;
363546283Sdfr  TTRACE_ARG_TYPE   tt_addr = (TTRACE_ARG_TYPE) addr;
363646283Sdfr  TTRACE_ARG_TYPE   tt_data = (TTRACE_ARG_TYPE) data;
363746283Sdfr  TTRACE_ARG_TYPE   tt_addr2 = TT_NIL;
363846283Sdfr  int               tt_status;
363946283Sdfr  register_value_t  register_value;
364046283Sdfr  int               read_buf;
364146283Sdfr
364246283Sdfr  /* Perform the necessary argument translation.  Note that some
364346283Sdfr     cases are funky enough in the ttrace realm that we handle them
364446283Sdfr     very specially.
364546283Sdfr   */
364646283Sdfr  switch (pt_request) {
364746283Sdfr      /* The following cases cannot conveniently be handled conveniently
364846283Sdfr         by merely adjusting the ptrace arguments and feeding into the
364946283Sdfr         generic call to ttrace at the bottom of this function.
365046283Sdfr
365146283Sdfr         Note that because all branches of this switch end in "return",
365246283Sdfr         there's no need for any "break" statements.
365346283Sdfr         */
365446283Sdfr      case PT_SETTRC :
365546283Sdfr          return parent_attach_all ();
365646283Sdfr
365746283Sdfr      case PT_RUREGS :
365846283Sdfr          tt_status = read_from_register_save_state (gdb_tid,
365946283Sdfr                                                     tt_addr,
366046283Sdfr                                                     &register_value,
366146283Sdfr                                                     sizeof (register_value));
366246283Sdfr          if (tt_status < 0)
366346283Sdfr            return tt_status;
366446283Sdfr          return register_value;
366546283Sdfr
366646283Sdfr      case PT_WUREGS :
366746283Sdfr          register_value = (int) tt_data;
366846283Sdfr          tt_status = write_to_register_save_state (gdb_tid,
366946283Sdfr                                                    tt_addr,
367046283Sdfr                                                    &register_value,
367146283Sdfr                                                    sizeof (register_value));
367246283Sdfr          return tt_status;
367346283Sdfr          break;
367446283Sdfr
367546283Sdfr      case PT_READ_I :
367646283Sdfr          tt_status = call_ttrace (TT_PROC_RDTEXT,  /* Implicit 4-byte xfer becomes block-xfer. */
367746283Sdfr                                   gdb_tid,
367846283Sdfr                                   tt_addr,
367946283Sdfr                                   (TTRACE_ARG_TYPE) 4,
368046283Sdfr                                   (TTRACE_ARG_TYPE) &read_buf);
368146283Sdfr          if (tt_status < 0)
368246283Sdfr            return tt_status;
368346283Sdfr          return read_buf;
368446283Sdfr
368546283Sdfr      case PT_READ_D :
368646283Sdfr          tt_status = call_ttrace (TT_PROC_RDDATA,  /* Implicit 4-byte xfer becomes block-xfer. */
368746283Sdfr                                   gdb_tid,
368846283Sdfr                                   tt_addr,
368946283Sdfr                                   (TTRACE_ARG_TYPE) 4,
369046283Sdfr                                   (TTRACE_ARG_TYPE) &read_buf);
369146283Sdfr          if (tt_status < 0)
369246283Sdfr            return tt_status;
369346283Sdfr          return read_buf;
369446283Sdfr
369546283Sdfr      case PT_ATTACH :
369646283Sdfr          tt_status = call_real_ttrace (TT_PROC_ATTACH,
369746283Sdfr                                        map_from_gdb_tid (gdb_tid),
369846283Sdfr                                        (lwpid_t) TT_NIL,
369946283Sdfr                                        tt_addr,
370046283Sdfr                                        (TTRACE_ARG_TYPE) TT_VERSION,
370146283Sdfr                                        tt_addr2);
370246283Sdfr          if (tt_status < 0)
370346283Sdfr            return tt_status;
370446283Sdfr          return tt_status;
370546283Sdfr
370646283Sdfr      /* The following cases are handled by merely adjusting the ptrace
370746283Sdfr         arguments and feeding into the generic call to ttrace.
370846283Sdfr         */
370946283Sdfr      case PT_DETACH :
371046283Sdfr          tt_request = TT_PROC_DETACH;
371146283Sdfr          break;
371246283Sdfr
371346283Sdfr      case PT_WRITE_I :
371446283Sdfr          tt_request = TT_PROC_WRTEXT;  /* Translates 4-byte xfer to block-xfer. */
371546283Sdfr          tt_data = 4;                  /* This many bytes. */
371646283Sdfr          tt_addr2 = (TTRACE_ARG_TYPE) &data;  /* Address of xfer source. */
371746283Sdfr          break;
371846283Sdfr
371946283Sdfr      case PT_WRITE_D :
372046283Sdfr          tt_request = TT_PROC_WRDATA;  /* Translates 4-byte xfer to block-xfer. */
372146283Sdfr          tt_data = 4;                  /* This many bytes. */
372246283Sdfr          tt_addr2 = (TTRACE_ARG_TYPE) &data;  /* Address of xfer source. */
372346283Sdfr          break;
372446283Sdfr
372546283Sdfr      case PT_RDTEXT :
372646283Sdfr          tt_request = TT_PROC_RDTEXT;
372746283Sdfr          break;
372846283Sdfr
372946283Sdfr      case PT_RDDATA :
373046283Sdfr          tt_request = TT_PROC_RDDATA;
373146283Sdfr          break;
373246283Sdfr
373346283Sdfr      case PT_WRTEXT :
373446283Sdfr          tt_request = TT_PROC_WRTEXT;
373546283Sdfr          break;
373646283Sdfr
373746283Sdfr      case PT_WRDATA :
373846283Sdfr          tt_request = TT_PROC_WRDATA;
373946283Sdfr          break;
374046283Sdfr
374146283Sdfr      case PT_CONTINUE :
374246283Sdfr          tt_request = TT_PROC_CONTINUE;
374346283Sdfr          break;
374446283Sdfr
374546283Sdfr      case PT_STEP :
374646283Sdfr          tt_request = TT_LWP_SINGLE;  /* Should not be making this request? */
374746283Sdfr          break;
374846283Sdfr
374946283Sdfr      case PT_KILL :
375046283Sdfr          tt_request = TT_PROC_EXIT;
375146283Sdfr          break;
375246283Sdfr
375346283Sdfr      case PT_GET_PROCESS_PATHNAME :
375446283Sdfr          tt_request = TT_PROC_GET_PATHNAME;
375546283Sdfr          break;
375646283Sdfr
375746283Sdfr      default :
375846283Sdfr          tt_request = pt_request;  /* Let ttrace be the one to complain. */
375946283Sdfr          break;
376046283Sdfr  }
376146283Sdfr
376246283Sdfr  return call_ttrace (tt_request,
376346283Sdfr                      gdb_tid,
376446283Sdfr                      tt_addr,
376546283Sdfr                      tt_data,
376646283Sdfr                      tt_addr2);
376746283Sdfr}
376846283Sdfr
376946283Sdfr/* Kill that pesky process!
377046283Sdfr */
377146283Sdfrvoid
377246283Sdfrkill_inferior ()
377346283Sdfr{
377446283Sdfr  int  tid;
377546283Sdfr  int  wait_status;
377646283Sdfr  thread_info *  t;
377746283Sdfr  thread_info **paranoia;
377846283Sdfr  int           para_count, i;
377946283Sdfr
378046283Sdfr  if (inferior_pid == 0)
378146283Sdfr    return;
378246283Sdfr
378346283Sdfr  /* Walk the list of "threads", some of which are "pseudo threads",
378446283Sdfr     aka "processes".  For each that is NOT inferior_pid, stop it,
378546283Sdfr     and detach it.
378646283Sdfr
378746283Sdfr     You see, we may not have just a single process to kill.  If we're
378846283Sdfr     restarting or quitting or detaching just after the inferior has
378946283Sdfr     forked, then we've actually two processes to clean up.
379046283Sdfr
379146283Sdfr     But we can't just call target_mourn_inferior() for each, since that
379246283Sdfr     zaps the target vector.
379346283Sdfr     */
379446283Sdfr
379546283Sdfr  paranoia = (thread_info **) malloc( thread_head.count *
379646283Sdfr                                      sizeof(thread_info *));
379746283Sdfr  para_count = 0;
379846283Sdfr
379946283Sdfr  t = thread_head.head;
380046283Sdfr  while (t) {
380146283Sdfr
380246283Sdfr    paranoia[ para_count ] = t;
380346283Sdfr    for( i = 0; i < para_count; i++ ){
380446283Sdfr        if( t->next == paranoia[i] ) {
380546283Sdfr            warning( "Bad data in gdb's thread data; repairing." );
380646283Sdfr            t->next = 0;
380746283Sdfr        }
380846283Sdfr    }
380946283Sdfr    para_count++;
381046283Sdfr
381146283Sdfr    if (t->am_pseudo && (t->pid != inferior_pid))
381246283Sdfr      {
381346283Sdfr        /* TT_PROC_STOP doesn't require a subsequent ttrace_wait, as it
381446283Sdfr         * generates no event.
381546283Sdfr         */
381646283Sdfr        call_ttrace (TT_PROC_STOP,
381746283Sdfr                     t->pid,
381846283Sdfr                     TT_NIL,
381946283Sdfr                     TT_NIL,
382046283Sdfr                     TT_NIL);
382146283Sdfr
382246283Sdfr        call_ttrace (TT_PROC_DETACH,
382346283Sdfr                     t->pid,
382446283Sdfr                     TT_NIL,
382546283Sdfr                     (TTRACE_ARG_TYPE) TARGET_SIGNAL_0,
382646283Sdfr                     TT_NIL);
382746283Sdfr      }
382846283Sdfr    t = t->next;
382946283Sdfr  }
383046283Sdfr
383146283Sdfr  free( paranoia );
383246283Sdfr
383346283Sdfr  call_ttrace (TT_PROC_STOP,
383446283Sdfr               inferior_pid,
383546283Sdfr               TT_NIL,
383646283Sdfr               TT_NIL,
383746283Sdfr               TT_NIL);
383846283Sdfr  target_mourn_inferior ();
383946283Sdfr  clear_thread_info();
384046283Sdfr}
384146283Sdfr
384246283Sdfr
384346283Sdfr#ifndef CHILD_RESUME
384446283Sdfr
384546283Sdfr/* Sanity check a thread about to be continued.
384646283Sdfr */
384746283Sdfrstatic void
384846283Sdfrthread_dropping_event_check( p )
384946283Sdfr    thread_info *p;
385046283Sdfr{
385146283Sdfr    if( !p->handled ) {
385246283Sdfr        /*
385346283Sdfr         * This seems to happen when we "next" over a
385446283Sdfr         * "fork()" while following the parent.  If it's
385546283Sdfr         * the FORK event, that's ok.  If it's a SIGNAL
385646283Sdfr         * in the unfollowed child, that's ok to--but
385746283Sdfr         * how can we know that's what's going on?
385846283Sdfr         *
385946283Sdfr         * FIXME!
386046283Sdfr         */
386146283Sdfr         if( p->have_state ) {
386246283Sdfr             if( p->last_stop_state.tts_event == TTEVT_FORK ) {
386346283Sdfr                 /* Ok */
386446283Sdfr                 ;
386546283Sdfr             }
386646283Sdfr             else if( p->last_stop_state.tts_event == TTEVT_SIGNAL ) {
386746283Sdfr                 /* Ok, close eyes and let it happen.
386846283Sdfr                  */
386946283Sdfr                 ;
387046283Sdfr             }
387146283Sdfr             else {
387246283Sdfr                 /* This shouldn't happen--we're dropping a
387346283Sdfr                  * real event.
387446283Sdfr                  */
387546283Sdfr                 warning( "About to continue process %d, thread %d with unhandled event %s.",
387646283Sdfr                         p->pid, p->tid,
387746283Sdfr                         get_printable_name_of_ttrace_event(
387846283Sdfr                                   p->last_stop_state.tts_event ));
387946283Sdfr
388046283Sdfr#ifdef PARANOIA
388146283Sdfr                 if( debug_on )
388246283Sdfr                     print_tthread( p );
388346283Sdfr#endif
388446283Sdfr            }
388546283Sdfr        }
388646283Sdfr        else {
388746283Sdfr            /* No saved state, have to assume it failed.
388846283Sdfr             */
388946283Sdfr            warning( "About to continue process %d, thread %d with unhandled event.",
389046283Sdfr                     p->pid, p->tid );
389146283Sdfr#ifdef PARANOIA
389246283Sdfr            if( debug_on )
389346283Sdfr                print_tthread( p );
389446283Sdfr#endif
389546283Sdfr        }
389646283Sdfr    }
389746283Sdfr
389846283Sdfr}   /* thread_dropping_event_check */
389946283Sdfr
390046283Sdfr/* Use a loop over the threads to continue all the threads but
390146283Sdfr * the one specified, which is to be stepped.
390246283Sdfr */
390346283Sdfrstatic void
390446283Sdfrthreads_continue_all_but_one( gdb_tid, signal )
390546283Sdfr    lwpid_t gdb_tid;
390646283Sdfr    int     signal;
390746283Sdfr{
390846283Sdfr    thread_info  *p;
390946283Sdfr    int           thread_signal;
391046283Sdfr    lwpid_t       real_tid;
391146283Sdfr    lwpid_t       scan_tid;
391246283Sdfr    ttstate_t     state;
391346283Sdfr    int           real_pid;
391446283Sdfr
391546283Sdfr#ifdef THREAD_DEBUG
391646283Sdfr    if( debug_on )
391746283Sdfr        printf( "Using loop over threads to step/resume with signals\n" );
391846283Sdfr#endif
391946283Sdfr
392046283Sdfr    /* First update the thread list.
392146283Sdfr     */
392246283Sdfr    set_all_unseen();
392346283Sdfr    real_tid = map_from_gdb_tid( gdb_tid );
392446283Sdfr    real_pid = get_pid_for( real_tid );
392546283Sdfr
392646283Sdfr    scan_tid = get_process_first_stopped_thread_id( real_pid, &state );
392746283Sdfr    while ( 0 != scan_tid ) {
392846283Sdfr
392946283Sdfr#ifdef THREAD_DEBUG
393046283Sdfr        /* FIX: later should check state is stopped;
393146283Sdfr         * state.tts_flags & TTS_STATEMASK == TTS_WASSUSPENDED
393246283Sdfr         */
393346283Sdfr        if( debug_on )
393446283Sdfr            if( state.tts_flags & TTS_STATEMASK != TTS_WASSUSPENDED )
393546283Sdfr                printf( "About to continue non-stopped thread %d\n", scan_tid );
393646283Sdfr#endif
393746283Sdfr
393846283Sdfr        p = find_thread_info( scan_tid );
393946283Sdfr        if( NULL == p ) {
394046283Sdfr            add_tthread( real_pid, scan_tid );
394146283Sdfr            p = find_thread_info( scan_tid );
394246283Sdfr
394346283Sdfr            /* This is either a newly-created thread or the
394446283Sdfr             * result of a fork; in either case there's no
394546283Sdfr             * actual event to worry about.
394646283Sdfr             */
394746283Sdfr            p->handled = 1;
394846283Sdfr
394946283Sdfr            if( state.tts_event != TTEVT_NONE ) {
395046283Sdfr                /* Oops, do need to worry!
395146283Sdfr                 */
395246283Sdfr                warning( "Unexpected thread with \"%s\" event.",
395346283Sdfr                    get_printable_name_of_ttrace_event( state.tts_event ));
395446283Sdfr            }
395546283Sdfr        }
395646283Sdfr        else if( scan_tid != p->tid )
395746283Sdfr            error( "Bad data in thread database." );
395846283Sdfr
395946283Sdfr#ifdef THREAD_DEBUG
396046283Sdfr        if( debug_on )
396146283Sdfr            if( p->terminated )
396246283Sdfr                printf( "Why are we continuing a dead thread?\n" );
396346283Sdfr#endif
396446283Sdfr
396546283Sdfr        p->seen = 1;
396646283Sdfr
396746283Sdfr        scan_tid = get_process_next_stopped_thread_id( real_pid, &state );
396846283Sdfr    }
396946283Sdfr
397046283Sdfr    /* Remove unseen threads.
397146283Sdfr     */
397246283Sdfr    update_thread_list();
397346283Sdfr
397446283Sdfr    /* Now run down the thread list and continue or step.
397546283Sdfr     */
397646283Sdfr    for( p = thread_head.head; p; p = p->next ) {
397746283Sdfr
397846283Sdfr        /* Sanity check.
397946283Sdfr         */
398046283Sdfr        thread_dropping_event_check( p );
398146283Sdfr
398246283Sdfr        /* Pass the correct signals along.
398346283Sdfr         */
398446283Sdfr        if( p->have_signal ) {
398546283Sdfr            thread_signal  = p->signal_value;
398646283Sdfr            p->have_signal = 0;
398746283Sdfr        }
398846283Sdfr        else
398946283Sdfr            thread_signal = 0;
399046283Sdfr
399146283Sdfr        if( p->tid != real_tid ) {
399246283Sdfr            /*
399346283Sdfr             * Not the thread of interest, so continue it
399446283Sdfr             * as the user expects.
399546283Sdfr             */
399646283Sdfr            if( p->stepping_mode == DO_STEP ) {
399746283Sdfr                /* Just step this thread.
399846283Sdfr                 */
399946283Sdfr                call_ttrace(
400046283Sdfr                     TT_LWP_SINGLE,
400146283Sdfr                     p->tid,
400246283Sdfr                     TT_USE_CURRENT_PC,
400346283Sdfr                     (TTRACE_ARG_TYPE) target_signal_to_host( signal ),
400446283Sdfr                     TT_NIL );
400546283Sdfr            }
400646283Sdfr            else {
400746283Sdfr                /* Regular continue (default case).
400846283Sdfr                 */
400946283Sdfr                call_ttrace(
401046283Sdfr                         TT_LWP_CONTINUE,
401146283Sdfr                         p->tid,
401246283Sdfr                         TT_USE_CURRENT_PC,
401346283Sdfr                         (TTRACE_ARG_TYPE) target_signal_to_host( thread_signal ),
401446283Sdfr                         TT_NIL );
401546283Sdfr            }
401646283Sdfr        }
401746283Sdfr        else {
401846283Sdfr           /* Step the thread of interest.
401946283Sdfr            */
402046283Sdfr            call_ttrace(
402146283Sdfr                     TT_LWP_SINGLE,
402246283Sdfr                     real_tid,
402346283Sdfr                     TT_USE_CURRENT_PC,
402446283Sdfr                     (TTRACE_ARG_TYPE) target_signal_to_host( signal ),
402546283Sdfr                     TT_NIL );
402646283Sdfr        }
402746283Sdfr    }   /* Loop over threads */
402846283Sdfr}   /* End threads_continue_all_but_one */
402946283Sdfr
403046283Sdfr/* Use a loop over the threads to continue all the threads.
403146283Sdfr * This is done when a signal must be sent to any of the threads.
403246283Sdfr */
403346283Sdfrstatic void
403446283Sdfrthreads_continue_all_with_signals( gdb_tid, signal )
403546283Sdfr    lwpid_t gdb_tid;
403646283Sdfr    int     signal;
403746283Sdfr{
403846283Sdfr    thread_info  *p;
403946283Sdfr    int           thread_signal;
404046283Sdfr    lwpid_t       real_tid;
404146283Sdfr    lwpid_t       scan_tid;
404246283Sdfr    ttstate_t     state;
404346283Sdfr    int           real_pid;
404446283Sdfr
404546283Sdfr#ifdef THREAD_DEBUG
404646283Sdfr    if( debug_on )
404746283Sdfr        printf( "Using loop over threads to resume with signals\n" );
404846283Sdfr#endif
404946283Sdfr
405046283Sdfr    /* Scan and update thread list.
405146283Sdfr     */
405246283Sdfr    set_all_unseen();
405346283Sdfr    real_tid = map_from_gdb_tid( gdb_tid );
405446283Sdfr    real_pid = get_pid_for( real_tid );
405546283Sdfr
405646283Sdfr    scan_tid = get_process_first_stopped_thread_id( real_pid, &state );
405746283Sdfr    while ( 0 != scan_tid ) {
405846283Sdfr
405946283Sdfr#ifdef THREAD_DEBUG
406046283Sdfr        if( debug_on )
406146283Sdfr            if( state.tts_flags & TTS_STATEMASK != TTS_WASSUSPENDED )
406246283Sdfr                warning( "About to continue non-stopped thread %d\n", scan_tid );
406346283Sdfr#endif
406446283Sdfr
406546283Sdfr        p = find_thread_info( scan_tid );
406646283Sdfr        if( NULL == p ) {
406746283Sdfr            add_tthread( real_pid, scan_tid );
406846283Sdfr            p = find_thread_info( scan_tid );
406946283Sdfr
407046283Sdfr            /* This is either a newly-created thread or the
407146283Sdfr             * result of a fork; in either case there's no
407246283Sdfr             * actual event to worry about.
407346283Sdfr             */
407446283Sdfr            p->handled = 1;
407546283Sdfr
407646283Sdfr            if( state.tts_event != TTEVT_NONE ) {
407746283Sdfr                /* Oops, do need to worry!
407846283Sdfr                 */
407946283Sdfr                warning( "Unexpected thread with \"%s\" event.",
408046283Sdfr                    get_printable_name_of_ttrace_event( state.tts_event ));
408146283Sdfr            }
408246283Sdfr        }
408346283Sdfr
408446283Sdfr#ifdef THREAD_DEBUG
408546283Sdfr        if( debug_on )
408646283Sdfr            if( p->terminated )
408746283Sdfr                printf( "Why are we continuing a dead thread? (1)\n" );
408846283Sdfr#endif
408946283Sdfr
409046283Sdfr        p->seen = 1;
409146283Sdfr
409246283Sdfr        scan_tid = get_process_next_stopped_thread_id( real_pid, &state );
409346283Sdfr    }
409446283Sdfr
409546283Sdfr    /* Remove unseen threads from our list.
409646283Sdfr     */
409746283Sdfr    update_thread_list();
409846283Sdfr
409946283Sdfr    /* Continue the threads.
410046283Sdfr     */
410146283Sdfr    for( p = thread_head.head; p; p = p->next ) {
410246283Sdfr
410346283Sdfr        /* Sanity check.
410446283Sdfr         */
410546283Sdfr        thread_dropping_event_check( p );
410646283Sdfr
410746283Sdfr        /* Pass the correct signals along.
410846283Sdfr         */
410946283Sdfr        if( p->tid == real_tid ) {
411046283Sdfr            thread_signal  = signal;
411146283Sdfr            p->have_signal = 0;
411246283Sdfr        }
411346283Sdfr        else if( p->have_signal ) {
411446283Sdfr            thread_signal  = p->signal_value;
411546283Sdfr            p->have_signal = 0;
411646283Sdfr        }
411746283Sdfr        else
411846283Sdfr            thread_signal  = 0;
411946283Sdfr
412046283Sdfr        if( p->stepping_mode == DO_STEP ) {
412146283Sdfr            call_ttrace(
412246283Sdfr                     TT_LWP_SINGLE,
412346283Sdfr                     p->tid,
412446283Sdfr                     TT_USE_CURRENT_PC,
412546283Sdfr                     (TTRACE_ARG_TYPE) target_signal_to_host( signal ),
412646283Sdfr                     TT_NIL );
412746283Sdfr        }
412846283Sdfr        else {
412946283Sdfr            /* Continue this thread (default case).
413046283Sdfr             */
413146283Sdfr            call_ttrace(
413246283Sdfr                    TT_LWP_CONTINUE,
413346283Sdfr                    p->tid,
413446283Sdfr                    TT_USE_CURRENT_PC,
413546283Sdfr                    (TTRACE_ARG_TYPE) target_signal_to_host( thread_signal ),
413646283Sdfr                    TT_NIL );
413746283Sdfr        }
413846283Sdfr    }
413946283Sdfr}   /* End threads_continue_all_with_signals */
414046283Sdfr
414146283Sdfr/* Step one thread only.
414246283Sdfr */
414346283Sdfrstatic void
414446283Sdfrthread_fake_step( tid, signal )
414546283Sdfr    lwpid_t            tid;
414646283Sdfr    enum target_signal signal;
414746283Sdfr{
414846283Sdfr    thread_info *p;
414946283Sdfr
415046283Sdfr#ifdef THREAD_DEBUG
415146283Sdfr    if( debug_on ) {
415246283Sdfr        printf( "Doing a fake-step over a bpt, etc. for %d\n", tid );
415346283Sdfr
415446283Sdfr        if( is_terminated( tid ))
415546283Sdfr            printf( "Why are we continuing a dead thread? (4)\n" );
415646283Sdfr    }
415746283Sdfr#endif
415846283Sdfr
415946283Sdfr    if( doing_fake_step )
416046283Sdfr        warning( "Step while step already in progress." );
416146283Sdfr
416246283Sdfr    /* See if there's a saved signal value for this
416346283Sdfr     * thread to be passed on, but no current signal.
416446283Sdfr     */
416546283Sdfr    p = find_thread_info( tid );
416646283Sdfr    if( p != NULL ) {
416746283Sdfr        if( p->have_signal && signal == NULL ) {
416846283Sdfr            /* Pass on a saved signal.
416946283Sdfr             */
417046283Sdfr            signal = p->signal_value;
417146283Sdfr        }
417246283Sdfr
417346283Sdfr        p->have_signal  = 0;
417446283Sdfr    }
417546283Sdfr
417646283Sdfr    if( !p->handled )
417746283Sdfr        warning( "Internal error: continuing unhandled thread." );
417846283Sdfr
417946283Sdfr    call_ttrace( TT_LWP_SINGLE,
418046283Sdfr                 tid,
418146283Sdfr                 TT_USE_CURRENT_PC,
418246283Sdfr                 (TTRACE_ARG_TYPE) target_signal_to_host (signal),
418346283Sdfr                 TT_NIL );
418446283Sdfr
418546283Sdfr    /* Do bookkeeping so "call_ttrace_wait" knows it has to wait
418646283Sdfr     * for this thread only, and clear any saved signal info.
418746283Sdfr     */
418846283Sdfr    doing_fake_step   = 1;
418946283Sdfr    fake_step_tid     = tid;
419046283Sdfr
419146283Sdfr}   /* End thread_fake_step */
419246283Sdfr
419346283Sdfr/* Continue one thread when a signal must be sent to it.
419446283Sdfr */
419546283Sdfrstatic void
419646283Sdfrthreads_continue_one_with_signal( gdb_tid, signal )
419746283Sdfr    lwpid_t gdb_tid;
419846283Sdfr    int     signal;
419946283Sdfr{
420046283Sdfr    thread_info  *p;
420146283Sdfr    lwpid_t       real_tid;
420246283Sdfr    int           real_pid;
420346283Sdfr
420446283Sdfr#ifdef THREAD_DEBUG
420546283Sdfr    if( debug_on )
420646283Sdfr        printf( "Continuing one thread with a signal\n" );
420746283Sdfr#endif
420846283Sdfr
420946283Sdfr    real_tid = map_from_gdb_tid( gdb_tid );
421046283Sdfr    real_pid = get_pid_for( real_tid );
421146283Sdfr
421246283Sdfr    p = find_thread_info( real_tid );
421346283Sdfr    if( NULL == p ) {
421446283Sdfr        add_tthread( real_pid, real_tid );
421546283Sdfr    }
421646283Sdfr
421746283Sdfr#ifdef THREAD_DEBUG
421846283Sdfr    if( debug_on )
421946283Sdfr        if( p->terminated )
422046283Sdfr            printf( "Why are we continuing a dead thread? (2)\n" );
422146283Sdfr#endif
422246283Sdfr
422346283Sdfr    if( !p->handled )
422446283Sdfr        warning( "Internal error: continuing unhandled thread." );
422546283Sdfr
422646283Sdfr    p->have_signal = 0;
422746283Sdfr
422846283Sdfr    call_ttrace( TT_LWP_CONTINUE,
422946283Sdfr                 gdb_tid,
423046283Sdfr                 TT_USE_CURRENT_PC,
423146283Sdfr                 (TTRACE_ARG_TYPE) target_signal_to_host( signal ),
423246283Sdfr                 TT_NIL );
423346283Sdfr}
423446283Sdfr#endif
423546283Sdfr
423646283Sdfr#ifndef CHILD_RESUME
423746283Sdfr
423846283Sdfr/* Resume execution of the inferior process.
423946283Sdfr *
424046283Sdfr * This routine is in charge of setting the "handled" bits.
424146283Sdfr *
424246283Sdfr *   If STEP is zero,      continue it.
424346283Sdfr *   If STEP is nonzero,   single-step it.
424446283Sdfr *
424546283Sdfr *   If SIGNAL is nonzero, give it that signal.
424646283Sdfr *
424746283Sdfr *   If TID is -1,         apply to all threads.
424846283Sdfr *   If TID is not -1,     apply to specified thread.
424946283Sdfr *
425046283Sdfr *           STEP
425146283Sdfr *      \      !0                        0
425246283Sdfr *  TID  \________________________________________________
425346283Sdfr *       |
425446283Sdfr *   -1  |   Step current            Continue all threads
425546283Sdfr *       |   thread and              (but which gets any
425646283Sdfr *       |   continue others         signal?--We look at
425746283Sdfr *       |                           "inferior_pid")
425846283Sdfr *       |
425946283Sdfr *    N  |   Step _this_ thread      Continue _this_ thread
426046283Sdfr *       |   and leave others        and leave others
426146283Sdfr *       |   stopped; internally     stopped; used only for
426246283Sdfr *       |   used by gdb, never      hardware watchpoints
426346283Sdfr *       |   a user command.         and attach, never a
426446283Sdfr *       |                           user command.
426546283Sdfr */
426646283Sdfrvoid
426746283Sdfrchild_resume( gdb_tid, step, signal )
426846283Sdfr     lwpid_t gdb_tid;
426946283Sdfr     int     step;
427046283Sdfr     enum target_signal signal;
427146283Sdfr{
427246283Sdfr  int     resume_all_threads;
427346283Sdfr  lwpid_t tid;
427446283Sdfr  process_state_t  new_process_state;
427546283Sdfr
427646283Sdfr  resume_all_threads =
427746283Sdfr    (gdb_tid == INFTTRACE_ALL_THREADS) ||
427846283Sdfr    (vfork_in_flight);
427946283Sdfr
428046283Sdfr  if (resume_all_threads) {
428146283Sdfr    /* Resume all threads, but first pick a tid value
428246283Sdfr     * so we can get the pid when in call_ttrace doing
428346283Sdfr     * the map.
428446283Sdfr     */
428546283Sdfr    if (vfork_in_flight)
428646283Sdfr        tid = vforking_child_pid;
428746283Sdfr    else
428846283Sdfr        tid = map_from_gdb_tid( inferior_pid );
428946283Sdfr  }
429046283Sdfr  else
429146283Sdfr      tid = map_from_gdb_tid( gdb_tid );
429246283Sdfr
429346283Sdfr#ifdef THREAD_DEBUG
429446283Sdfr  if( debug_on ) {
429546283Sdfr      if( more_events_left )
429646283Sdfr          printf( "More events; " );
429746283Sdfr
429846283Sdfr      if( signal != 0 )
429946283Sdfr          printf( "Sending signal %d; ", signal );
430046283Sdfr
430146283Sdfr      if( resume_all_threads ) {
430246283Sdfr          if( step == 0 )
430346283Sdfr              printf( "Continue process %d\n", tid );
430446283Sdfr          else
430546283Sdfr              printf( "Step/continue thread %d\n", tid );
430646283Sdfr      }
430746283Sdfr      else {
430846283Sdfr          if( step == 0 )
430946283Sdfr              printf( "Continue thread %d\n", tid );
431046283Sdfr          else
431146283Sdfr              printf( "Step just thread %d\n", tid );
431246283Sdfr      }
431346283Sdfr
431446283Sdfr      if( vfork_in_flight )
431546283Sdfr          printf( "Vfork in flight\n" );
431646283Sdfr  }
431746283Sdfr#endif
431846283Sdfr
431946283Sdfr  if( process_state == RUNNING )
432046283Sdfr      warning( "Internal error in resume logic; doing resume or step anyway." );
432146283Sdfr
432246283Sdfr  if(   !step                    /* Asked to continue...       */
432346283Sdfr     && resume_all_threads       /* whole process..            */
432446283Sdfr     && signal != 0              /* with a signal...           */
432546283Sdfr     && more_events_left > 0 ) { /* but we can't yet--save it! */
432646283Sdfr
432746283Sdfr      /* Continue with signal means we have to set the pending
432846283Sdfr       * signal value for this thread.
432946283Sdfr       */
433046283Sdfr      thread_info *k;
433146283Sdfr
433246283Sdfr#ifdef THREAD_DEBUG
433346283Sdfr      if( debug_on )
433446283Sdfr           printf( "Saving signal %d for thread %d\n", signal, tid );
433546283Sdfr#endif
433646283Sdfr
433746283Sdfr       k = find_thread_info( tid );
433846283Sdfr       if( k != NULL ) {
433946283Sdfr           k->have_signal  = 1;
434046283Sdfr           k->signal_value = signal;
434146283Sdfr
434246283Sdfr#ifdef THREAD_DEBUG
434346283Sdfr           if( debug_on )
434446283Sdfr               if( k->terminated )
434546283Sdfr                   printf( "Why are we continuing a dead thread? (3)\n" );
434646283Sdfr#endif
434746283Sdfr
434846283Sdfr       }
434946283Sdfr
435046283Sdfr#ifdef THREAD_DEBUG
435146283Sdfr       else if( debug_on ) {
435246283Sdfr           printf( "No thread info for tid %d\n", tid );
435346283Sdfr       }
435446283Sdfr#endif
435546283Sdfr  }
435646283Sdfr
435746283Sdfr  /* Are we faking this "continue" or "step"?
435846283Sdfr   *
435946283Sdfr   * We used to do steps by continuing all the threads for
436046283Sdfr   * which the events had been handled already.  While
436146283Sdfr   * conceptually nicer (hides it all in a lower level), this
436246283Sdfr   * can lead to starvation and a hang (e.g. all but one thread
436346283Sdfr   * are unhandled at a breakpoint just before a "join" operation,
436446283Sdfr   * and one thread is in the join, and the user wants to step that
436546283Sdfr   * thread).
436646283Sdfr   */
436746283Sdfr  if( resume_all_threads       /* Whole process, therefore user command */
436846283Sdfr   && more_events_left > 0 ) { /* But we can't do this yet--fake it! */
436946283Sdfr      thread_info *p;
437046283Sdfr
437146283Sdfr      if( !step ) {
437246283Sdfr          /* No need to do any notes on a per-thread
437346283Sdfr           * basis--we're done!
437446283Sdfr           */
437546283Sdfr#ifdef WAIT_BUFFER_DEBUG
437646283Sdfr          if( debug_on )
437746283Sdfr              printf( "Faking a process resume.\n" );
437846283Sdfr#endif
437946283Sdfr
438046283Sdfr          return;
438146283Sdfr      }
438246283Sdfr      else {
438346283Sdfr
438446283Sdfr#ifdef WAIT_BUFFER_DEBUG
438546283Sdfr          if( debug_on )
438646283Sdfr              printf( "Faking a process step.\n" );
438746283Sdfr#endif
438846283Sdfr
438946283Sdfr      }
439046283Sdfr
439146283Sdfr      p = find_thread_info( tid );
439246283Sdfr      if( p == NULL ) {
439346283Sdfr          warning( "No thread information for tid %d, 'next' command ignored.\n", tid );
439446283Sdfr          return;
439546283Sdfr      }
439646283Sdfr      else {
439746283Sdfr
439846283Sdfr#ifdef THREAD_DEBUG
439946283Sdfr          if( debug_on )
440046283Sdfr              if( p->terminated )
440146283Sdfr                  printf( "Why are we continuing a dead thread? (3.5)\n" );
440246283Sdfr#endif
440346283Sdfr
440446283Sdfr          if( p->stepping_mode != DO_DEFAULT ) {
440546283Sdfr              warning( "Step or continue command applied to thread which is already stepping or continuing; command ignored." );
440646283Sdfr
440746283Sdfr              return;
440846283Sdfr          }
440946283Sdfr
441046283Sdfr          if( step )
441146283Sdfr              p->stepping_mode = DO_STEP;
441246283Sdfr          else
441346283Sdfr              p->stepping_mode = DO_CONTINUE;
441446283Sdfr
441546283Sdfr          return;
441646283Sdfr      }   /* Have thread info */
441746283Sdfr  }   /* Must fake step or go */
441846283Sdfr
441946283Sdfr  /* Execept for fake-steps, from here on we know we are
442046283Sdfr   * going to wind up with a running process which will
442146283Sdfr   * need a real wait.
442246283Sdfr   */
442346283Sdfr  new_process_state = RUNNING;
442446283Sdfr
442546283Sdfr  /* An address of TT_USE_CURRENT_PC tells ttrace to continue from where
442646283Sdfr   * it was.  (If GDB wanted it to start some other way, we have already
442746283Sdfr   * written a new PC value to the child.)
442846283Sdfr   *
442946283Sdfr   * If this system does not support PT_STEP, a higher level function will
443046283Sdfr   * have called single_step() to transmute the step request into a
443146283Sdfr   * continue request (by setting breakpoints on all possible successor
443246283Sdfr   * instructions), so we don't have to worry about that here.
443346283Sdfr   */
443446283Sdfr  if (step) {
443546283Sdfr      if( resume_all_threads ) {
443646283Sdfr          /*
443746283Sdfr           * Regular user step: other threads get a "continue".
443846283Sdfr           */
443946283Sdfr          threads_continue_all_but_one( tid, signal );
444046283Sdfr          clear_all_handled();
444146283Sdfr          clear_all_stepping_mode();
444246283Sdfr      }
444346283Sdfr
444446283Sdfr      else {
444546283Sdfr          /* "Fake step": gdb is stepping one thread over a
444646283Sdfr           * breakpoint, watchpoint, or out of a library load
444746283Sdfr           * event, etc.  The rest just stay where they are.
444846283Sdfr           *
444946283Sdfr           * Also used when there are pending events: we really
445046283Sdfr           * step the current thread, but leave the rest stopped.
445146283Sdfr           * Users can't request this, but "wait_for_inferior"
445246283Sdfr           * does--a lot!
445346283Sdfr           */
445446283Sdfr          thread_fake_step( tid, signal );
445546283Sdfr
445646283Sdfr          /* Clear the "handled" state of this thread, because
445746283Sdfr           * we'll soon get a new event for it.  Other events
445846283Sdfr           * stay as they were.
445946283Sdfr           */
446046283Sdfr          clear_handled( tid );
446146283Sdfr          clear_stepping_mode( tid );
446246283Sdfr          new_process_state = FAKE_STEPPING;
446346283Sdfr      }
446446283Sdfr  }
446546283Sdfr
446646283Sdfr  else {
446746283Sdfr      /* TT_LWP_CONTINUE can pass signals to threads,
446846283Sdfr       * TT_PROC_CONTINUE can't.  So if there are any
446946283Sdfr       * signals to pass, we have to use the (slower)
447046283Sdfr       * loop over the stopped threads.
447146283Sdfr       *
447246283Sdfr       * Equally, if we have to not continue some threads,
447346283Sdfr       * due to saved events, we have to use the loop.
447446283Sdfr       */
447546283Sdfr      if( (signal != 0) || saved_signals_exist()) {
447646283Sdfr          if( resume_all_threads ) {
447746283Sdfr
447846283Sdfr#ifdef THREAD_DEBUG
447946283Sdfr              if( debug_on )
448046283Sdfr                  printf( "Doing a continue by loop of all threads\n" );
448146283Sdfr#endif
448246283Sdfr
448346283Sdfr              threads_continue_all_with_signals( tid, signal );
448446283Sdfr
448546283Sdfr              clear_all_handled();
448646283Sdfr              clear_all_stepping_mode();
448746283Sdfr          }
448846283Sdfr
448946283Sdfr          else {
449046283Sdfr#ifdef THREAD_DEBUG
449146283Sdfr              printf( "Doing a continue w/signal of just thread %d\n", tid );
449246283Sdfr#endif
449346283Sdfr
449446283Sdfr              threads_continue_one_with_signal( tid, signal );
449546283Sdfr
449646283Sdfr              /* Clear the "handled" state of this thread, because
449746283Sdfr               * we'll soon get a new event for it.  Other events
449846283Sdfr               * can stay as they were.
449946283Sdfr               */
450046283Sdfr              clear_handled( tid );
450146283Sdfr              clear_stepping_mode( tid );
450246283Sdfr          }
450346283Sdfr      }
450446283Sdfr
450546283Sdfr      else {
450646283Sdfr          /* No signals to send.
450746283Sdfr           */
450846283Sdfr          if( resume_all_threads ) {
450946283Sdfr#ifdef THREAD_DEBUG
451046283Sdfr              if( debug_on )
451146283Sdfr                  printf( "Doing a continue by process of process %d\n", tid );
451246283Sdfr#endif
451346283Sdfr
451446283Sdfr              if( more_events_left > 0 ) {
451546283Sdfr                  warning( "Losing buffered events on continue." );
451646283Sdfr                  more_events_left = 0;
451746283Sdfr              }
451846283Sdfr
451946283Sdfr              call_ttrace( TT_PROC_CONTINUE,
452046283Sdfr                           tid,
452146283Sdfr                           TT_NIL,
452246283Sdfr                           TT_NIL,
452346283Sdfr                           TT_NIL );
452446283Sdfr
452546283Sdfr              clear_all_handled();
452646283Sdfr              clear_all_stepping_mode();
452746283Sdfr          }
452846283Sdfr
452946283Sdfr          else {
453046283Sdfr#ifdef THREAD_DEBUG
453146283Sdfr              if( debug_on ) {
453246283Sdfr                  printf( "Doing a continue of just thread %d\n", tid );
453346283Sdfr                  if( is_terminated( tid ))
453446283Sdfr                       printf( "Why are we continuing a dead thread? (5)\n" );
453546283Sdfr              }
453646283Sdfr#endif
453746283Sdfr
453846283Sdfr              call_ttrace( TT_LWP_CONTINUE,
453946283Sdfr                           tid,
454046283Sdfr                           TT_NIL,
454146283Sdfr                           TT_NIL,
454246283Sdfr                           TT_NIL );
454346283Sdfr
454446283Sdfr              /* Clear the "handled" state of this thread, because
454546283Sdfr               * we'll soon get a new event for it.  Other events
454646283Sdfr               * can stay as they were.
454746283Sdfr               */
454846283Sdfr              clear_handled( tid );
454946283Sdfr              clear_stepping_mode( tid );
455046283Sdfr          }
455146283Sdfr      }
455246283Sdfr  }
455346283Sdfr
455446283Sdfr  process_state = new_process_state;
455546283Sdfr
455646283Sdfr#ifdef WAIT_BUFFER_DEBUG
455746283Sdfr  if( debug_on )
455846283Sdfr      printf( "Process set to %s\n",
455946283Sdfr              get_printable_name_of_process_state (process_state) );
456046283Sdfr#endif
456146283Sdfr
456246283Sdfr}
456346283Sdfr#endif /* CHILD_RESUME */
456446283Sdfr
456546283Sdfr
456646283Sdfr#ifdef ATTACH_DETACH
456746283Sdfr/*
456846283Sdfr * Like it says.
456946283Sdfr *
457046283Sdfr * One worry is that we may not be attaching to "inferior_pid"
457146283Sdfr * and thus may not want to clear out our data.  FIXME?
457246283Sdfr *
457346283Sdfr */
457446283Sdfrstatic void
457546283Sdfrupdate_thread_state_after_attach( pid, kind_of_go )
457646283Sdfr  int               pid;
457746283Sdfr  attach_continue_t kind_of_go;
457846283Sdfr{
457946283Sdfr  int        tt_status;
458046283Sdfr  ttstate_t  thread_state;
458146283Sdfr  lwpid_t    a_thread;
458246283Sdfr  lwpid_t    tid;
458346283Sdfr
458446283Sdfr  /* The process better be stopped.
458546283Sdfr   */
458646283Sdfr  if( process_state != STOPPED
458746283Sdfr   && process_state != VFORKING )
458846283Sdfr      warning( "Internal error attaching." );
458946283Sdfr
459046283Sdfr  /* Clear out old tthread info and start over.  This has the
459146283Sdfr   * side effect of ensuring that the TRAP is reported as being
459246283Sdfr   * in the right thread (re-mapped from tid to pid).
459346283Sdfr   *
459446283Sdfr   * It's because we need to add the tthread _now_ that we
459546283Sdfr   * need to call "clear_thread_info" _now_, and that's why
459646283Sdfr   * "require_notification_of_events" doesn't clear the thread
459746283Sdfr   * info (it's called later than this routine).
459846283Sdfr   */
459946283Sdfr  clear_thread_info();
460046283Sdfr  a_thread = 0;
460146283Sdfr
460246283Sdfr  for (tid = get_process_first_stopped_thread_id (pid, &thread_state);
460346283Sdfr       tid != 0;
460446283Sdfr       tid = get_process_next_stopped_thread_id (pid, &thread_state))
460546283Sdfr    {
460646283Sdfr      thread_info *p;
460746283Sdfr
460846283Sdfr      if (a_thread == 0)
460946283Sdfr        {
461046283Sdfr          a_thread = tid;
461146283Sdfr#ifdef THREAD_DEBUG
461246283Sdfr          if( debug_on )
461346283Sdfr              printf( "Attaching to process %d, thread %d\n",
461446283Sdfr                      pid, a_thread );
461546283Sdfr#endif
461646283Sdfr        }
461746283Sdfr
461846283Sdfr      /* Tell ourselves and the "rest of gdb" that this thread
461946283Sdfr       * exists.
462046283Sdfr       *
462146283Sdfr       * This isn't really a hack.  Other thread-based versions
462246283Sdfr       * of gdb (e.g. gnu-nat.c) seem to do the same thing.
462346283Sdfr       *
462446283Sdfr       * We don't need to do mapping here, as we know this
462546283Sdfr       * is the first thread and thus gets the real pid
462646283Sdfr       * (and is "inferior_pid").
462746283Sdfr       *
462846283Sdfr       * NOTE: it probably isn't the originating thread,
462946283Sdfr       *       but that doesn't matter (we hope!).
463046283Sdfr       */
463146283Sdfr      add_tthread( pid, tid );
463246283Sdfr      p = find_thread_info( tid );
463346283Sdfr      if( NULL == p ) /* ?We just added it! */
463446283Sdfr          error( "Internal error adding a thread on attach." );
463546283Sdfr
463646283Sdfr      copy_ttstate_t( &p->last_stop_state, thread_state );
463746283Sdfr      p->have_state = 1;
463846283Sdfr
463946283Sdfr      if( DO_ATTACH_CONTINUE == kind_of_go ) {
464046283Sdfr          /*
464146283Sdfr           * If we are going to CONTINUE afterwards,
464246283Sdfr           * raising a SIGTRAP, don't bother trying to
464346283Sdfr           * handle this event.  But check first!
464446283Sdfr           */
464546283Sdfr          switch( p->last_stop_state.tts_event ) {
464646283Sdfr
464746283Sdfr          case TTEVT_NONE:
464846283Sdfr             /* Ok to set this handled.
464946283Sdfr              */
465046283Sdfr              break;
465146283Sdfr
465246283Sdfr          default:
465346283Sdfr              warning( "Internal error; skipping event %s on process %d, thread %d.",
465446283Sdfr                  get_printable_name_of_ttrace_event(
465546283Sdfr                       p->last_stop_state.tts_event ),
465646283Sdfr                  p->pid, p->tid);
465746283Sdfr          }
465846283Sdfr
465946283Sdfr          set_handled( pid, tid );
466046283Sdfr
466146283Sdfr      }
466246283Sdfr      else {
466346283Sdfr          /* There will be no "continue" opertion, so the
466446283Sdfr           * process remains stopped.  Don't set any events
466546283Sdfr           * handled except the "gimmies".
466646283Sdfr           */
466746283Sdfr          switch( p->last_stop_state.tts_event ) {
466846283Sdfr
466946283Sdfr          case TTEVT_NONE:
467046283Sdfr              /* Ok to ignore this.
467146283Sdfr               */
467246283Sdfr              set_handled( pid, tid );
467346283Sdfr              break;
467446283Sdfr
467546283Sdfr          case TTEVT_EXEC:
467646283Sdfr          case TTEVT_FORK:
467746283Sdfr              /* Expected "other" FORK or EXEC event from a
467846283Sdfr               * fork or vfork.
467946283Sdfr               */
468046283Sdfr              break;
468146283Sdfr
468246283Sdfr          default:
468346283Sdfr              printf( "Internal error: failed to handle event %s on process %d, thread %d.",
468446283Sdfr                  get_printable_name_of_ttrace_event(
468546283Sdfr                       p->last_stop_state.tts_event ),
468646283Sdfr                  p->pid, p->tid);
468746283Sdfr          }
468846283Sdfr      }
468946283Sdfr
469046283Sdfr      add_thread( tid );       /* in thread.c */
469146283Sdfr    }
469246283Sdfr
469346283Sdfr#ifdef PARANOIA
469446283Sdfr    if( debug_on )
469546283Sdfr        print_tthreads();
469646283Sdfr#endif
469746283Sdfr
469846283Sdfr  /* One mustn't call ttrace_wait() after attaching via ttrace,
469946283Sdfr     'cause the process is stopped already.
470046283Sdfr
470146283Sdfr     However, the upper layers of gdb's execution control will
470246283Sdfr     want to wait after attaching (but not after forks, in
470346283Sdfr     which case they will be doing a "target_resume", anticipating
470446283Sdfr     a later TTEVT_EXEC or TTEVT_FORK event).
470546283Sdfr
470646283Sdfr     To make this attach() implementation more compatible with
470746283Sdfr     others, we'll make the attached-to process raise a SIGTRAP.
470846283Sdfr
470946283Sdfr     Issue: this continues only one thread.  That could be
471046283Sdfr     dangerous if the thread is blocked--the process won't run
471146283Sdfr     and no trap will be raised.  FIX! (check state.tts_flags?
471246283Sdfr     need one that's either TTS_WASRUNNING--but we've stopped
471346283Sdfr     it and made it TTS_WASSUSPENDED.  Hum...FIXME!)
471446283Sdfr   */
471546283Sdfr  if( DO_ATTACH_CONTINUE == kind_of_go ) {
471646283Sdfr      tt_status = call_real_ttrace(
471746283Sdfr                      TT_LWP_CONTINUE,
471846283Sdfr                      pid,
471946283Sdfr                      a_thread,
472046283Sdfr                      TT_USE_CURRENT_PC,
472146283Sdfr                      (TTRACE_ARG_TYPE) target_signal_to_host (TARGET_SIGNAL_TRAP),
472246283Sdfr                      TT_NIL);
472346283Sdfr      if (errno)
472446283Sdfr          perror_with_name ("ttrace");
472546283Sdfr
472646283Sdfr      clear_handled( a_thread );  /* So TRAP will be reported. */
472746283Sdfr
472846283Sdfr      /* Now running.
472946283Sdfr       */
473046283Sdfr      process_state = RUNNING;
473146283Sdfr  }
473246283Sdfr
473346283Sdfr  attach_flag = 1;
473446283Sdfr}
473546283Sdfr#endif /* ATTACH_DETACH */
473646283Sdfr
473746283Sdfr
473846283Sdfr#ifdef ATTACH_DETACH
473946283Sdfr/* Start debugging the process whose number is PID.
474046283Sdfr * (A _real_ pid).
474146283Sdfr */
474246283Sdfrint
474346283Sdfrattach( pid )
474446283Sdfr     int pid;
474546283Sdfr{
474646283Sdfr  int       tt_status;
474746283Sdfr
474846283Sdfr  tt_status = call_real_ttrace (
474946283Sdfr                           TT_PROC_ATTACH,
475046283Sdfr                           pid,
475146283Sdfr                           (lwpid_t) TT_NIL,
475246283Sdfr                           TT_NIL,
475346283Sdfr                           (TTRACE_ARG_TYPE) TT_VERSION,
475446283Sdfr                           TT_NIL);
475546283Sdfr  if (errno)
475646283Sdfr    perror_with_name ("ttrace attach");
475746283Sdfr
475846283Sdfr  /* If successful, the process is now stopped.
475946283Sdfr   */
476046283Sdfr  process_state = STOPPED;
476146283Sdfr
476246283Sdfr  /* Our caller ("attach_command" in "infcmd.c")
476346283Sdfr   * expects to do a "wait_for_inferior" after
476446283Sdfr   * the attach, so make sure the inferior is
476546283Sdfr   * running when we're done.
476646283Sdfr   */
476746283Sdfr  update_thread_state_after_attach( pid, DO_ATTACH_CONTINUE );
476846283Sdfr
476946283Sdfr  return pid;
477046283Sdfr}
477146283Sdfr
477246283Sdfr
477346283Sdfr#if defined(CHILD_POST_ATTACH)
477446283Sdfrvoid
477546283Sdfrchild_post_attach (pid)
477646283Sdfr  int  pid;
477746283Sdfr{
477846283Sdfr#ifdef THREAD_DEBUG
477946283Sdfr  if( debug_on )
478046283Sdfr      printf( "child-post-attach call\n" );
478146283Sdfr#endif
478246283Sdfr
478346283Sdfr  require_notification_of_events (pid);
478446283Sdfr}
478546283Sdfr#endif
478646283Sdfr
478746283Sdfr
478846283Sdfr/* Stop debugging the process whose number is PID
478946283Sdfr   and continue it with signal number SIGNAL.
479046283Sdfr   SIGNAL = 0 means just continue it.
479146283Sdfr */
479246283Sdfrvoid
479346283Sdfrdetach( signal )
479446283Sdfr     int signal;
479546283Sdfr{
479646283Sdfr  errno = 0;
479746283Sdfr  call_ttrace (TT_PROC_DETACH,
479846283Sdfr               inferior_pid,
479946283Sdfr               TT_NIL,
480046283Sdfr               (TTRACE_ARG_TYPE) signal,
480146283Sdfr               TT_NIL);
480246283Sdfr  attach_flag = 0;
480346283Sdfr
480446283Sdfr  clear_thread_info();
480546283Sdfr
480646283Sdfr  /* Process-state? */
480746283Sdfr}
480846283Sdfr#endif /* ATTACH_DETACH */
480946283Sdfr
481046283Sdfr
481146283Sdfr/* Default the type of the ttrace transfer to int.  */
481246283Sdfr#ifndef TTRACE_XFER_TYPE
481346283Sdfr#define TTRACE_XFER_TYPE int
481446283Sdfr#endif
481546283Sdfr
481646283Sdfrvoid
481746283Sdfr_initialize_kernel_u_addr ()
481846283Sdfr{
481946283Sdfr}
482046283Sdfr
482146283Sdfr#if !defined (CHILD_XFER_MEMORY)
482246283Sdfr/* NOTE! I tried using TTRACE_READDATA, etc., to read and write memory
482346283Sdfr   in the NEW_SUN_TTRACE case.
482446283Sdfr   It ought to be straightforward.  But it appears that writing did
482546283Sdfr   not write the data that I specified.  I cannot understand where
482646283Sdfr   it got the data that it actually did write.  */
482746283Sdfr
482846283Sdfr/* Copy LEN bytes to or from inferior's memory starting at MEMADDR
482946283Sdfr   to debugger memory starting at MYADDR.   Copy to inferior if
483046283Sdfr   WRITE is nonzero.
483146283Sdfr
483246283Sdfr   Returns the length copied, which is either the LEN argument or zero.
483346283Sdfr   This xfer function does not do partial moves, since child_ops
483446283Sdfr   doesn't allow memory operations to cross below us in the target stack
483546283Sdfr   anyway.  */
483646283Sdfr
483746283Sdfrint
483846283Sdfrchild_xfer_memory (memaddr, myaddr, len, write, target)
483946283Sdfr     CORE_ADDR memaddr;
484046283Sdfr     char *myaddr;
484146283Sdfr     int len;
484246283Sdfr     int write;
484346283Sdfr     struct target_ops *target;		/* ignored */
484446283Sdfr{
484546283Sdfr  register int i;
484646283Sdfr  /* Round starting address down to longword boundary.  */
484746283Sdfr  register CORE_ADDR addr = memaddr & - sizeof (TTRACE_XFER_TYPE);
484846283Sdfr  /* Round ending address up; get number of longwords that makes.  */
484946283Sdfr  register int count
485046283Sdfr    = (((memaddr + len) - addr) + sizeof (TTRACE_XFER_TYPE) - 1)
485146283Sdfr      / sizeof (TTRACE_XFER_TYPE);
485246283Sdfr  /* Allocate buffer of that many longwords.  */
485346283Sdfr  register TTRACE_XFER_TYPE *buffer
485446283Sdfr    = (TTRACE_XFER_TYPE *) alloca (count * sizeof (TTRACE_XFER_TYPE));
485546283Sdfr
485646283Sdfr  if (write)
485746283Sdfr    {
485846283Sdfr      /* Fill start and end extra bytes of buffer with existing memory data.  */
485946283Sdfr
486046283Sdfr      if (addr != memaddr || len < (int) sizeof (TTRACE_XFER_TYPE)) {
486146283Sdfr	/* Need part of initial word -- fetch it.  */
486246283Sdfr        buffer[0] = call_ttrace (TT_LWP_RDTEXT,
486346283Sdfr                                 inferior_pid,
486446283Sdfr                                 (TTRACE_ARG_TYPE) addr,
486546283Sdfr                                 TT_NIL,
486646283Sdfr                                 TT_NIL);
486746283Sdfr      }
486846283Sdfr
486946283Sdfr      if (count > 1)		/* FIXME, avoid if even boundary */
487046283Sdfr	{
487146283Sdfr	  buffer[count - 1] = call_ttrace (TT_LWP_RDTEXT,
487246283Sdfr                                           inferior_pid,
487346283Sdfr                                           ((TTRACE_ARG_TYPE)
487446283Sdfr                                            (addr + (count - 1) * sizeof (TTRACE_XFER_TYPE))),
487546283Sdfr                                           TT_NIL,
487646283Sdfr                                           TT_NIL);
487746283Sdfr	}
487846283Sdfr
487946283Sdfr      /* Copy data to be written over corresponding part of buffer */
488046283Sdfr
488146283Sdfr      memcpy ((char *) buffer + (memaddr & (sizeof (TTRACE_XFER_TYPE) - 1)),
488246283Sdfr	      myaddr,
488346283Sdfr	      len);
488446283Sdfr
488546283Sdfr      /* Write the entire buffer.  */
488646283Sdfr
488746283Sdfr      for (i = 0; i < count; i++, addr += sizeof (TTRACE_XFER_TYPE))
488846283Sdfr	{
488946283Sdfr	  errno = 0;
489046283Sdfr	  call_ttrace (TT_LWP_WRDATA,
489146283Sdfr                       inferior_pid,
489246283Sdfr                       (TTRACE_ARG_TYPE) addr,
489346283Sdfr                       (TTRACE_ARG_TYPE) buffer[i],
489446283Sdfr                       TT_NIL);
489546283Sdfr	  if (errno)
489646283Sdfr	    {
489746283Sdfr	      /* Using the appropriate one (I or D) is necessary for
489846283Sdfr		 Gould NP1, at least.  */
489946283Sdfr	      errno = 0;
490046283Sdfr	      call_ttrace (TT_LWP_WRTEXT,
490146283Sdfr                           inferior_pid,
490246283Sdfr                           (TTRACE_ARG_TYPE) addr,
490346283Sdfr                           (TTRACE_ARG_TYPE) buffer[i],
490446283Sdfr                           TT_NIL);
490546283Sdfr	    }
490646283Sdfr	  if (errno)
490746283Sdfr	    return 0;
490846283Sdfr	}
490946283Sdfr    }
491046283Sdfr  else
491146283Sdfr    {
491246283Sdfr      /* Read all the longwords */
491346283Sdfr      for (i = 0; i < count; i++, addr += sizeof (TTRACE_XFER_TYPE))
491446283Sdfr	{
491546283Sdfr	  errno = 0;
491646283Sdfr	  buffer[i] = call_ttrace (TT_LWP_RDTEXT,
491746283Sdfr                                   inferior_pid,
491846283Sdfr                                   (TTRACE_ARG_TYPE) addr,
491946283Sdfr                                   TT_NIL,
492046283Sdfr                                   TT_NIL);
492146283Sdfr	  if (errno)
492246283Sdfr	    return 0;
492346283Sdfr	  QUIT;
492446283Sdfr	}
492546283Sdfr
492646283Sdfr      /* Copy appropriate bytes out of the buffer.  */
492746283Sdfr      memcpy (myaddr,
492846283Sdfr	      (char *) buffer + (memaddr & (sizeof (TTRACE_XFER_TYPE) - 1)),
492946283Sdfr	      len);
493046283Sdfr    }
493146283Sdfr  return len;
493246283Sdfr}
493346283Sdfr
493446283Sdfr
493546283Sdfrstatic void
493646283Sdfrudot_info ()
493746283Sdfr{
493846283Sdfr  int udot_off;		/* Offset into user struct */
493946283Sdfr  int udot_val;		/* Value from user struct at udot_off */
494046283Sdfr  char mess[128];	/* For messages */
494146283Sdfr
494246283Sdfr   if (!target_has_execution)
494346283Sdfr     {
494446283Sdfr       error ("The program is not being run.");
494546283Sdfr     }
494646283Sdfr
494746283Sdfr#if !defined (KERNEL_U_SIZE)
494846283Sdfr
494946283Sdfr  /* Adding support for this command is easy.  Typically you just add a
495046283Sdfr     routine, called "kernel_u_size" that returns the size of the user
495146283Sdfr     struct, to the appropriate *-nat.c file and then add to the native
495246283Sdfr     config file "#define KERNEL_U_SIZE kernel_u_size()" */
495346283Sdfr  error ("Don't know how large ``struct user'' is in this version of gdb.");
495446283Sdfr
495546283Sdfr#else
495646283Sdfr
495746283Sdfr  for (udot_off = 0; udot_off < KERNEL_U_SIZE; udot_off += sizeof (udot_val))
495846283Sdfr    {
495946283Sdfr      if ((udot_off % 24) == 0)
496046283Sdfr	{
496146283Sdfr	  if (udot_off > 0)
496246283Sdfr	    {
496346283Sdfr	      printf_filtered ("\n");
496446283Sdfr	    }
496546283Sdfr	  printf_filtered ("%04x:", udot_off);
496646283Sdfr	}
496746283Sdfr      udot_val = call_ttrace (TT_LWP_RUREGS,
496846283Sdfr                              inferior_pid,
496946283Sdfr                              (TTRACE_ARG_TYPE) udot_off,
497046283Sdfr                              TT_NIL,
497146283Sdfr                              TT_NIL);
497246283Sdfr      if (errno != 0)
497346283Sdfr	{
497446283Sdfr	  sprintf (mess, "\nreading user struct at offset 0x%x", udot_off);
497546283Sdfr	  perror_with_name (mess);
497646283Sdfr	}
497746283Sdfr      /* Avoid using nonportable (?) "*" in print specs */
497846283Sdfr      printf_filtered (sizeof (int) == 4 ? " 0x%08x" : " 0x%16x", udot_val);
497946283Sdfr    }
498046283Sdfr  printf_filtered ("\n");
498146283Sdfr
498246283Sdfr#endif
498346283Sdfr}
498446283Sdfr#endif /* !defined (CHILD_XFER_MEMORY).  */
498546283Sdfr
498646283Sdfr/* TTrace version of "target_pid_to_exec_file"
498746283Sdfr */
498846283Sdfrchar *
498946283Sdfrchild_pid_to_exec_file (tid)
499046283Sdfr    int  tid;
499146283Sdfr{
499246283Sdfr  static char  exec_file_buffer[1024];
499346283Sdfr  int  tt_status;
499446283Sdfr  CORE_ADDR  top_of_stack;
499546283Sdfr  char  four_chars[4];
499646283Sdfr  int  name_index;
499746283Sdfr  int  i;
499846283Sdfr  int  done;
499946283Sdfr  int  saved_inferior_pid;
500046283Sdfr
500146283Sdfr  /* As of 10.x HP-UX, there's an explicit request to get the
500246283Sdfr   *pathname.
500346283Sdfr   */
500446283Sdfr  tt_status = call_ttrace (TT_PROC_GET_PATHNAME,
500546283Sdfr                           tid,
500646283Sdfr                           (TTRACE_ARG_TYPE) exec_file_buffer,
500746283Sdfr                           (TTRACE_ARG_TYPE) sizeof (exec_file_buffer) - 1,
500846283Sdfr                           TT_NIL);
500946283Sdfr  if (tt_status >= 0)
501046283Sdfr    return exec_file_buffer;
501146283Sdfr
501246283Sdfr  /* ??rehrauer: The above request may or may not be broken.  It
501346283Sdfr     doesn't seem to work when I use it.  But, it may be designed
501446283Sdfr     to only work immediately after an exec event occurs.  (I'm
501546283Sdfr     waiting for COSL to explain.)
501646283Sdfr
501746283Sdfr     In any case, if it fails, try a really, truly amazingly gross
501846283Sdfr     hack that DDE uses, of pawing through the process' data
501946283Sdfr     segment to find the pathname.
502046283Sdfr     */
502146283Sdfr  top_of_stack = 0x7b03a000;
502246283Sdfr  name_index = 0;
502346283Sdfr  done = 0;
502446283Sdfr
502546283Sdfr  /* On the chance that pid != inferior_pid, set inferior_pid
502646283Sdfr     to pid, so that (grrrr!) implicit uses of inferior_pid get
502746283Sdfr     the right id.
502846283Sdfr     */
502946283Sdfr  saved_inferior_pid = inferior_pid;
503046283Sdfr  inferior_pid = tid;
503146283Sdfr
503246283Sdfr  /* Try to grab a null-terminated string. */
503346283Sdfr  while (! done) {
503446283Sdfr    if (target_read_memory (top_of_stack, four_chars, 4) != 0)
503546283Sdfr      {
503646283Sdfr        inferior_pid = saved_inferior_pid;
503746283Sdfr        return NULL;
503846283Sdfr      }
503946283Sdfr    for (i = 0; i < 4; i++) {
504046283Sdfr      exec_file_buffer[name_index++] = four_chars[i];
504146283Sdfr      done = (four_chars[i] == '\0');
504246283Sdfr      if (done)
504346283Sdfr        break;
504446283Sdfr    }
504546283Sdfr    top_of_stack += 4;
504646283Sdfr  }
504746283Sdfr
504846283Sdfr  if (exec_file_buffer[0] == '\0')
504946283Sdfr    {
505046283Sdfr      inferior_pid = saved_inferior_pid;
505146283Sdfr      return NULL;
505246283Sdfr    }
505346283Sdfr
505446283Sdfr  inferior_pid = saved_inferior_pid;
505546283Sdfr  return exec_file_buffer;
505646283Sdfr}
505746283Sdfr
505846283Sdfr
505946283Sdfrvoid
506046283Sdfrpre_fork_inferior ()
506146283Sdfr{
506246283Sdfr  int  status;
506346283Sdfr
506446283Sdfr  status = pipe (startup_semaphore.parent_channel);
506546283Sdfr  if (status < 0) {
506646283Sdfr      warning ("error getting parent pipe for startup semaphore");
506746283Sdfr      return;
506846283Sdfr  }
506946283Sdfr
507046283Sdfr  status = pipe (startup_semaphore.child_channel);
507146283Sdfr  if (status < 0) {
507246283Sdfr      warning ("error getting child pipe for startup semaphore");
507346283Sdfr      return;
507446283Sdfr  }
507546283Sdfr}
507646283Sdfr
507746283Sdfr/* Called via #define REQUIRE_ATTACH from inftarg.c,
507846283Sdfr * ultimately from "follow_inferior_fork" in infrun.c,
507946283Sdfr * itself called from "resume".
508046283Sdfr *
508146283Sdfr * This seems to be intended to attach after a fork or
508246283Sdfr * vfork, while "attach" is used to attach to a pid
508346283Sdfr * given by the user.  The check for an existing attach
508446283Sdfr * seems odd--it always fails in our test system.
508546283Sdfr */
508646283Sdfrint
508746283Sdfrhppa_require_attach (pid)
508846283Sdfr  int  pid;
508946283Sdfr{
509046283Sdfr  int             tt_status;
509146283Sdfr  CORE_ADDR       pc;
509246283Sdfr  CORE_ADDR       pc_addr;
509346283Sdfr  unsigned int    regs_offset;
509446283Sdfr  process_state_t old_process_state = process_state;
509546283Sdfr
509646283Sdfr  /* Are we already attached?  There appears to be no explicit
509746283Sdfr   * way to answer this via ttrace, so we try something which
509846283Sdfr   * should be innocuous if we are attached.  If that fails,
509946283Sdfr   * then we assume we're not attached, and so attempt to make
510046283Sdfr   * it so.
510146283Sdfr   */
510246283Sdfr  errno = 0;
510346283Sdfr  tt_status = call_real_ttrace (TT_PROC_STOP,
510446283Sdfr                                pid,
510546283Sdfr                                (lwpid_t) TT_NIL,
510646283Sdfr                                (TTRACE_ARG_TYPE) TT_NIL,
510746283Sdfr                                (TTRACE_ARG_TYPE) TT_NIL,
510846283Sdfr                                TT_NIL);
510946283Sdfr
511046283Sdfr  if (errno)
511146283Sdfr    {
511246283Sdfr      /* No change to process-state!
511346283Sdfr       */
511446283Sdfr      errno = 0;
511546283Sdfr      pid   = attach (pid);
511646283Sdfr    }
511746283Sdfr  else
511846283Sdfr    {
511946283Sdfr     /* If successful, the process is now stopped.  But if
512046283Sdfr      * we're VFORKING, the parent is still running, so don't
512146283Sdfr      * change the process state.
512246283Sdfr      */
512346283Sdfr     if( process_state != VFORKING )
512446283Sdfr         process_state = STOPPED;
512546283Sdfr
512646283Sdfr     /* If we were already attached, you'd think that we
512746283Sdfr      * would need to start going again--but you'd be wrong,
512846283Sdfr      * as the fork-following code is actually in the middle
512946283Sdfr      * of the "resume" routine in in "infrun.c" and so
513046283Sdfr      * will (almost) immediately do a resume.
513146283Sdfr      *
513246283Sdfr      * On the other hand, if we are VFORKING, which means
513346283Sdfr      * that the child and the parent share a process for a
513446283Sdfr      * while, we know that "resume" won't be resuming
513546283Sdfr      * until the child EXEC event is seen.  But we still
513646283Sdfr      * don't want to continue, as the event is already
513746283Sdfr      * there waiting.
513846283Sdfr      */
513946283Sdfr     update_thread_state_after_attach( pid, DONT_ATTACH_CONTINUE );
514046283Sdfr    }   /* STOP succeeded */
514146283Sdfr
514246283Sdfr  return pid;
514346283Sdfr}
514446283Sdfr
514546283Sdfrint
514646283Sdfrhppa_require_detach (pid, signal)
514746283Sdfr  int  pid;
514846283Sdfr  int  signal;
514946283Sdfr{
515046283Sdfr  int  tt_status;
515146283Sdfr
515246283Sdfr  /* If signal is non-zero, we must pass the signal on to the active
515346283Sdfr     thread prior to detaching.  We do this by continuing the threads
515446283Sdfr     with the signal.
515546283Sdfr   */
515646283Sdfr  if (signal != 0)
515746283Sdfr    {
515846283Sdfr      errno = 0;
515946283Sdfr      threads_continue_all_with_signals( pid, signal );
516046283Sdfr    }
516146283Sdfr
516246283Sdfr  errno = 0;
516346283Sdfr  tt_status = call_ttrace (TT_PROC_DETACH,
516446283Sdfr                           pid,
516546283Sdfr                           TT_NIL,
516646283Sdfr                           TT_NIL,
516746283Sdfr                           TT_NIL);
516846283Sdfr
516946283Sdfr  errno = 0; /* Ignore any errors. */
517046283Sdfr
517146283Sdfr  /* process_state? */
517246283Sdfr
517346283Sdfr  return pid;
517446283Sdfr}
517546283Sdfr
517646283Sdfr/* Given the starting address of a memory page, hash it to a bucket in
517746283Sdfr   the memory page dictionary.
517846283Sdfr   */
517946283Sdfrstatic int
518046283Sdfrget_dictionary_bucket_of_page (page_start)
518146283Sdfr  CORE_ADDR  page_start;
518246283Sdfr{
518346283Sdfr  int  hash;
518446283Sdfr
518546283Sdfr  hash = (page_start / memory_page_dictionary.page_size);
518646283Sdfr  hash = hash % MEMORY_PAGE_DICTIONARY_BUCKET_COUNT;
518746283Sdfr
518846283Sdfr  return hash;
518946283Sdfr}
519046283Sdfr
519146283Sdfr
519246283Sdfr/* Given a memory page's starting address, get (i.e., find an existing
519346283Sdfr   or create a new) dictionary entry for the page.  The page will be
519446283Sdfr   write-protected when this function returns, but may have a reference
519546283Sdfr   count of 0 (if the page was newly-added to the dictionary).
519646283Sdfr   */
519746283Sdfrstatic memory_page_t *
519846283Sdfrget_dictionary_entry_of_page (pid, page_start)
519946283Sdfr  int  pid;
520046283Sdfr  CORE_ADDR  page_start;
520146283Sdfr{
520246283Sdfr  int  bucket;
520346283Sdfr  memory_page_t *  page = NULL;
520446283Sdfr  memory_page_t *  previous_page = NULL;
520546283Sdfr
520646283Sdfr  /* We're going to be using the dictionary now, than-kew. */
520746283Sdfr  require_memory_page_dictionary (pid);
520846283Sdfr
520946283Sdfr  /* Try to find an existing dictionary entry for this page.  Hash
521046283Sdfr     on the page's starting address.
521146283Sdfr     */
521246283Sdfr  bucket = get_dictionary_bucket_of_page (page_start);
521346283Sdfr  page = &memory_page_dictionary.buckets[bucket];
521446283Sdfr  while (page != NULL)
521546283Sdfr    {
521646283Sdfr      if (page->page_start == page_start)
521746283Sdfr        break;
521846283Sdfr      previous_page = page;
521946283Sdfr      page = page->next;
522046283Sdfr    }
522146283Sdfr
522246283Sdfr  /* Did we find a dictionary entry for this page?  If not, then
522346283Sdfr     add it to the dictionary now.
522446283Sdfr     */
522546283Sdfr  if (page == NULL)
522646283Sdfr    {
522746283Sdfr      /* Create a new entry. */
522846283Sdfr      page = (memory_page_t *) xmalloc (sizeof (memory_page_t));
522946283Sdfr      page->page_start = page_start;
523046283Sdfr      page->reference_count = 0;
523146283Sdfr      page->next = NULL;
523246283Sdfr      page->previous = NULL;
523346283Sdfr
523446283Sdfr      /* We'll write-protect the page now, if that's allowed. */
523546283Sdfr      page->original_permissions = write_protect_page (pid, page_start);
523646283Sdfr
523746283Sdfr      /* Add the new entry to the dictionary. */
523846283Sdfr      page->previous = previous_page;
523946283Sdfr      previous_page->next = page;
524046283Sdfr
524146283Sdfr      memory_page_dictionary.page_count++;
524246283Sdfr    }
524346283Sdfr
524446283Sdfr  return page;
524546283Sdfr}
524646283Sdfr
524746283Sdfr
524846283Sdfrstatic void
524946283Sdfrremove_dictionary_entry_of_page (pid, page)
525046283Sdfr  int  pid;
525146283Sdfr  memory_page_t *  page;
525246283Sdfr{
525346283Sdfr  /* Restore the page's original permissions. */
525446283Sdfr  unwrite_protect_page (pid, page->page_start, page->original_permissions);
525546283Sdfr
525646283Sdfr  /* Kick the page out of the dictionary. */
525746283Sdfr  if (page->previous != NULL)
525846283Sdfr    page->previous->next = page->next;
525946283Sdfr  if (page->next != NULL)
526046283Sdfr    page->next->previous = page->previous;
526146283Sdfr
526246283Sdfr  /* Just in case someone retains a handle to this after it's freed. */
526346283Sdfr  page->page_start = (CORE_ADDR) 0;
526446283Sdfr
526546283Sdfr  memory_page_dictionary.page_count--;
526646283Sdfr
526746283Sdfr  free (page);
526846283Sdfr}
526946283Sdfr
527046283Sdfr
527146283Sdfrstatic void
527246283Sdfrhppa_enable_syscall_events (pid)
527346283Sdfr  int  pid;
527446283Sdfr{
527546283Sdfr  int  tt_status;
527646283Sdfr  ttevent_t  ttrace_events;
527746283Sdfr
527846283Sdfr  /* Get the set of events that are currently enabled. */
527946283Sdfr  tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
528046283Sdfr                           pid,
528146283Sdfr                           (TTRACE_ARG_TYPE) &ttrace_events,
528246283Sdfr                           (TTRACE_ARG_TYPE) sizeof (ttrace_events),
528346283Sdfr                           TT_NIL);
528446283Sdfr  if (errno)
528546283Sdfr    perror_with_name ("ttrace");
528646283Sdfr
528746283Sdfr  /* Add syscall events to that set. */
528846283Sdfr  ttrace_events.tte_events |= TTEVT_SYSCALL_ENTRY;
528946283Sdfr  ttrace_events.tte_events |= TTEVT_SYSCALL_RETURN;
529046283Sdfr
529146283Sdfr  tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
529246283Sdfr                           pid,
529346283Sdfr                           (TTRACE_ARG_TYPE) &ttrace_events,
529446283Sdfr                           (TTRACE_ARG_TYPE) sizeof (ttrace_events),
529546283Sdfr                           TT_NIL);
529646283Sdfr  if (errno)
529746283Sdfr    perror_with_name ("ttrace");
529846283Sdfr}
529946283Sdfr
530046283Sdfr
530146283Sdfrstatic void
530246283Sdfrhppa_disable_syscall_events (pid)
530346283Sdfr  int  pid;
530446283Sdfr{
530546283Sdfr  int  tt_status;
530646283Sdfr  ttevent_t  ttrace_events;
530746283Sdfr
530846283Sdfr  /* Get the set of events that are currently enabled. */
530946283Sdfr  tt_status = call_ttrace (TT_PROC_GET_EVENT_MASK,
531046283Sdfr                           pid,
531146283Sdfr                           (TTRACE_ARG_TYPE) &ttrace_events,
531246283Sdfr                           (TTRACE_ARG_TYPE) sizeof (ttrace_events),
531346283Sdfr                           TT_NIL);
531446283Sdfr  if (errno)
531546283Sdfr    perror_with_name ("ttrace");
531646283Sdfr
531746283Sdfr  /* Remove syscall events from that set. */
531846283Sdfr  ttrace_events.tte_events &= ~TTEVT_SYSCALL_ENTRY;
531946283Sdfr  ttrace_events.tte_events &= ~TTEVT_SYSCALL_RETURN;
532046283Sdfr
532146283Sdfr  tt_status = call_ttrace (TT_PROC_SET_EVENT_MASK,
532246283Sdfr                           pid,
532346283Sdfr                           (TTRACE_ARG_TYPE) &ttrace_events,
532446283Sdfr                           (TTRACE_ARG_TYPE) sizeof (ttrace_events),
532546283Sdfr                           TT_NIL);
532646283Sdfr  if (errno)
532746283Sdfr    perror_with_name ("ttrace");
532846283Sdfr}
532946283Sdfr
533046283Sdfr
533146283Sdfr/* The address range beginning with START and ending with START+LEN-1
533246283Sdfr   (inclusive) is to be watched via page-protection by a new watchpoint.
533346283Sdfr   Set protection for all pages that overlap that range.
533446283Sdfr
533546283Sdfr   Note that our caller sets TYPE to:
533646283Sdfr     0 for a bp_hardware_watchpoint,
533746283Sdfr     1 for a bp_read_watchpoint,
533846283Sdfr     2 for a bp_access_watchpoint
533946283Sdfr
534046283Sdfr   (Yes, this is intentionally (though lord only knows why) different
534146283Sdfr   from the TYPE that is passed to hppa_remove_hw_watchpoint.)
534246283Sdfr   */
534346283Sdfrint
534446283Sdfrhppa_insert_hw_watchpoint (pid, start, len, type)
534546283Sdfr  int  pid;
534646283Sdfr  CORE_ADDR  start;
534746283Sdfr  LONGEST  len;
534846283Sdfr  int  type;
534946283Sdfr{
535046283Sdfr  CORE_ADDR  page_start;
535146283Sdfr  int  dictionary_was_empty;
535246283Sdfr  int  page_size;
535346283Sdfr  int  page_id;
535446283Sdfr  LONGEST  range_size_in_pages;
535546283Sdfr
535646283Sdfr  if (type != 0)
535746283Sdfr    error ("read or access hardware watchpoints not supported on HP-UX");
535846283Sdfr
535946283Sdfr  /* Examine all pages in the address range. */
536046283Sdfr  require_memory_page_dictionary ();
536146283Sdfr
536246283Sdfr  dictionary_was_empty = (memory_page_dictionary.page_count == (LONGEST) 0);
536346283Sdfr
536446283Sdfr  page_size = memory_page_dictionary.page_size;
536546283Sdfr  page_start = (start / page_size) * page_size;
536646283Sdfr  range_size_in_pages = ((LONGEST) len + (LONGEST) page_size - 1) / (LONGEST) page_size;
536746283Sdfr
536846283Sdfr  for (page_id=0; page_id < range_size_in_pages; page_id++, page_start+=page_size)
536946283Sdfr    {
537046283Sdfr      memory_page_t *  page;
537146283Sdfr
537246283Sdfr      /* This gets the page entered into the dictionary if it was
537346283Sdfr         not already entered.
537446283Sdfr         */
537546283Sdfr      page = get_dictionary_entry_of_page (pid, page_start);
537646283Sdfr      page->reference_count++;
537746283Sdfr    }
537846283Sdfr
537946283Sdfr  /* Our implementation depends on seeing calls to kernel code, for the
538046283Sdfr     following reason.  Here we ask to be notified of syscalls.
538146283Sdfr
538246283Sdfr     When a protected page is accessed by user code, HP-UX raises a SIGBUS.
538346283Sdfr     Fine.
538446283Sdfr
538546283Sdfr     But when kernel code accesses the page, it doesn't give a SIGBUS.
538646283Sdfr     Rather, the system call that touched the page fails, with errno=EFAULT.
538746283Sdfr     Not good for us.
538846283Sdfr
538946283Sdfr     We could accomodate this "feature" by asking to be notified of syscall
539046283Sdfr     entries & exits; upon getting an entry event, disabling page-protections;
539146283Sdfr     upon getting an exit event, reenabling page-protections and then checking
539246283Sdfr     if any watchpoints triggered.
539346283Sdfr
539446283Sdfr     However, this turns out to be a real performance loser.  syscalls are
539546283Sdfr     usually a frequent occurrence.  Having to unprotect-reprotect all watched
539646283Sdfr     pages, and also to then read all watched memory locations and compare for
539746283Sdfr     triggers, can be quite expensive.
539846283Sdfr
539946283Sdfr     Instead, we'll only ask to be notified of syscall exits.  When we get
540046283Sdfr     one, we'll check whether errno is set.  If not, or if it's not EFAULT,
540146283Sdfr     we can just continue the inferior.
540246283Sdfr
540346283Sdfr     If errno is set upon syscall exit to EFAULT, we must perform some fairly
540446283Sdfr     hackish stuff to determine whether the failure really was due to a
540546283Sdfr     page-protect trap on a watched location.
540646283Sdfr     */
540746283Sdfr  if (dictionary_was_empty)
540846283Sdfr    hppa_enable_syscall_events (pid);
540946283Sdfr
541046283Sdfr  return 1;
541146283Sdfr}
541246283Sdfr
541346283Sdfr
541446283Sdfr/* The address range beginning with START and ending with START+LEN-1
541546283Sdfr   (inclusive) was being watched via page-protection by a watchpoint
541646283Sdfr   which has been removed.  Remove protection for all pages that
541746283Sdfr   overlap that range, which are not also being watched by other
541846283Sdfr   watchpoints.
541946283Sdfr   */
542046283Sdfrint
542146283Sdfrhppa_remove_hw_watchpoint (pid, start, len, type)
542246283Sdfr  int  pid;
542346283Sdfr  CORE_ADDR  start;
542446283Sdfr  LONGEST  len;
542546283Sdfr  enum bptype  type;
542646283Sdfr{
542746283Sdfr  CORE_ADDR  page_start;
542846283Sdfr  int  dictionary_is_empty;
542946283Sdfr  int  page_size;
543046283Sdfr  int  page_id;
543146283Sdfr  LONGEST  range_size_in_pages;
543246283Sdfr
543346283Sdfr  if (type != 0)
543446283Sdfr    error ("read or access hardware watchpoints not supported on HP-UX");
543546283Sdfr
543646283Sdfr  /* Examine all pages in the address range. */
543746283Sdfr  require_memory_page_dictionary ();
543846283Sdfr
543946283Sdfr  page_size = memory_page_dictionary.page_size;
544046283Sdfr  page_start = (start / page_size) * page_size;
544146283Sdfr  range_size_in_pages = ((LONGEST) len + (LONGEST) page_size - 1) / (LONGEST) page_size;
544246283Sdfr
544346283Sdfr  for (page_id=0; page_id < range_size_in_pages; page_id++, page_start+=page_size)
544446283Sdfr    {
544546283Sdfr      memory_page_t *  page;
544646283Sdfr
544746283Sdfr      page = get_dictionary_entry_of_page (pid, page_start);
544846283Sdfr      page->reference_count--;
544946283Sdfr
545046283Sdfr      /* Was this the last reference of this page?  If so, then we
545146283Sdfr         must scrub the entry from the dictionary, and also restore
545246283Sdfr         the page's original permissions.
545346283Sdfr         */
545446283Sdfr      if (page->reference_count == 0)
545546283Sdfr        remove_dictionary_entry_of_page (pid, page);
545646283Sdfr    }
545746283Sdfr
545846283Sdfr  dictionary_is_empty = (memory_page_dictionary.page_count == (LONGEST) 0);
545946283Sdfr
546046283Sdfr  /* If write protections are currently disallowed, then that implies that
546146283Sdfr     wait_for_inferior believes that the inferior is within a system call.
546246283Sdfr     Since we want to see both syscall entry and return, it's clearly not
546346283Sdfr     good to disable syscall events in this state!
546446283Sdfr
546546283Sdfr     ??rehrauer: Yeah, it'd be better if we had a specific flag that said,
546646283Sdfr     "inferior is between syscall events now".  Oh well.
546746283Sdfr     */
546846283Sdfr  if (dictionary_is_empty && memory_page_dictionary.page_protections_allowed)
546946283Sdfr    hppa_disable_syscall_events (pid);
547046283Sdfr
547146283Sdfr  return 1;
547246283Sdfr}
547346283Sdfr
547446283Sdfr
547546283Sdfr/* Could we implement a watchpoint of this type via our available
547646283Sdfr   hardware support?
547746283Sdfr
547846283Sdfr   This query does not consider whether a particular address range
547946283Sdfr   could be so watched, but just whether support is generally available
548046283Sdfr   for such things.  See hppa_range_profitable_for_hw_watchpoint for a
548146283Sdfr   query that answers whether a particular range should be watched via
548246283Sdfr   hardware support.
548346283Sdfr   */
548446283Sdfrint
548546283Sdfrhppa_can_use_hw_watchpoint (type, cnt, ot)
548646283Sdfr  enum bptype  type;
548746283Sdfr  int  cnt;
548846283Sdfr  enum bptype  ot;
548946283Sdfr{
549046283Sdfr  return (type == bp_hardware_watchpoint);
549146283Sdfr}
549246283Sdfr
549346283Sdfr
549446283Sdfr/* Assuming we could set a hardware watchpoint on this address, do
549546283Sdfr   we think it would be profitable ("a good idea") to do so?  If not,
549646283Sdfr   we can always set a regular (aka single-step & test) watchpoint
549746283Sdfr   on the address...
549846283Sdfr   */
549946283Sdfrint
550046283Sdfrhppa_range_profitable_for_hw_watchpoint (pid, start, len)
550146283Sdfr  int  pid;
550246283Sdfr  CORE_ADDR  start;
550346283Sdfr  LONGEST  len;
550446283Sdfr{
550546283Sdfr  int  range_is_stack_based;
550646283Sdfr  int  range_is_accessible;
550746283Sdfr  CORE_ADDR  page_start;
550846283Sdfr  int  page_size;
550946283Sdfr  int  page;
551046283Sdfr  LONGEST  range_size_in_pages;
551146283Sdfr
551246283Sdfr  /* ??rehrauer: For now, say that all addresses are potentially
551346283Sdfr     profitable.  Possibly later we'll want to test the address
551446283Sdfr     for "stackness"?
551546283Sdfr     */
551646283Sdfr  range_is_stack_based = 0;
551746283Sdfr
551846283Sdfr  /* If any page in the range is inaccessible, then we cannot
551946283Sdfr     really use hardware watchpointing, even though our client
552046283Sdfr     thinks we can.  In that case, it's actually an error to
552146283Sdfr     attempt to use hw watchpoints, so we'll tell our client
552246283Sdfr     that the range is "unprofitable", and hope that they listen...
552346283Sdfr     */
552446283Sdfr  range_is_accessible = 1;  /* Until proven otherwise. */
552546283Sdfr
552646283Sdfr  /* Examine all pages in the address range. */
552746283Sdfr  errno = 0;
552846283Sdfr  page_size = sysconf (_SC_PAGE_SIZE);
552946283Sdfr
553046283Sdfr  /* If we can't determine page size, we're hosed.  Tell our
553146283Sdfr     client it's unprofitable to use hw watchpoints for this
553246283Sdfr     range.
553346283Sdfr     */
553446283Sdfr  if (errno || (page_size <= 0))
553546283Sdfr    {
553646283Sdfr      errno = 0;
553746283Sdfr      return 0;
553846283Sdfr    }
553946283Sdfr
554046283Sdfr  page_start = (start / page_size) * page_size;
554146283Sdfr  range_size_in_pages = len / (LONGEST)page_size;
554246283Sdfr
554346283Sdfr  for (page=0; page < range_size_in_pages; page++, page_start+=page_size)
554446283Sdfr    {
554546283Sdfr      int  tt_status;
554646283Sdfr      int  page_permissions;
554746283Sdfr
554846283Sdfr      /* Is this page accessible? */
554946283Sdfr      errno = 0;
555046283Sdfr      tt_status = call_ttrace (TT_PROC_GET_MPROTECT,
555146283Sdfr                               pid,
555246283Sdfr                               (TTRACE_ARG_TYPE) page_start,
555346283Sdfr                               TT_NIL,
555446283Sdfr                               (TTRACE_ARG_TYPE) &page_permissions);
555546283Sdfr      if (errno || (tt_status < 0))
555646283Sdfr        {
555746283Sdfr          errno = 0;
555846283Sdfr          range_is_accessible = 0;
555946283Sdfr          break;
556046283Sdfr        }
556146283Sdfr
556246283Sdfr      /* Yes, go for another... */
556346283Sdfr    }
556446283Sdfr
556546283Sdfr  return (! range_is_stack_based && range_is_accessible);
556646283Sdfr}
556746283Sdfr
556846283Sdfr
556946283Sdfrchar *
557046283Sdfrhppa_pid_or_tid_to_str (id)
557146283Sdfr  pid_t  id;
557246283Sdfr{
557346283Sdfr  static char  buf[100]; /* Static because address returned. */
557446283Sdfr
557546283Sdfr  /* Does this appear to be a process?  If so, print it that way. */
557646283Sdfr  if (is_process_id (id))
557746283Sdfr    return hppa_pid_to_str (id);
557846283Sdfr
557946283Sdfr  /* Else, print both the GDB thread number and the system thread id. */
558046283Sdfr  sprintf (buf, "thread %d (", pid_to_thread_id (id));
558146283Sdfr  strcat (buf, hppa_tid_to_str (id));
558246283Sdfr  strcat (buf, ")\0");
558346283Sdfr
558446283Sdfr  return buf;
558546283Sdfr}
558646283Sdfr
558746283Sdfr
558846283Sdfr/* If the current pid is not the pid this module reported
558946283Sdfr * from "ptrace_wait" with the most recent event, then the
559046283Sdfr * user has switched threads.
559146283Sdfr *
559246283Sdfr * If the last reported event was a breakpoint, then return
559346283Sdfr * the old thread id, else return 0.
559446283Sdfr */
559546283Sdfrpid_t
559646283Sdfrhppa_switched_threads( gdb_pid )
559746283Sdfr  pid_t gdb_pid;
559846283Sdfr{
559946283Sdfr  if( gdb_pid == old_gdb_pid ) {
560046283Sdfr      /*
560146283Sdfr       * Core gdb is working with the same pid that it
560246283Sdfr       * was before we reported the last event.  This
560346283Sdfr       * is ok: e.g. we reported hitting a thread-specific
560446283Sdfr       * breakpoint, but we were reporting the wrong
560546283Sdfr       * thread, so the core just ignored the event.
560646283Sdfr       *
560746283Sdfr       * No thread switch has happened.
560846283Sdfr       */
560946283Sdfr      return (pid_t) 0;
561046283Sdfr  }
561146283Sdfr  else if( gdb_pid == reported_pid ) {
561246283Sdfr      /*
561346283Sdfr       * Core gdb is working with the pid we reported, so
561446283Sdfr       * any continue or step will be able to figure out
561546283Sdfr       * that it needs to step over any hit breakpoints
561646283Sdfr       * without our (i.e. PREPARE_TO_PROCEED's) help.
561746283Sdfr       */
561846283Sdfr      return (pid_t) 0;
561946283Sdfr  }
562046283Sdfr  else if( !reported_bpt ) {
562146283Sdfr       /*
562246283Sdfr        * The core switched, but we didn't just report a
562346283Sdfr        * breakpoint, so there's no just-hit breakpoint
562446283Sdfr        * instruction at "reported_pid"'s PC, and thus there
562546283Sdfr        * is no need to step over it.
562646283Sdfr        */
562746283Sdfr      return (pid_t) 0;
562846283Sdfr  }
562946283Sdfr  else {
563046283Sdfr       /* There's been a real switch, and we reported
563146283Sdfr        * a hit breakpoint.  Let "hppa_prepare_to_proceed"
563246283Sdfr        * know, so it can see whether the breakpoint is
563346283Sdfr        * still active.
563446283Sdfr        */
563546283Sdfr       return reported_pid;
563646283Sdfr  }
563746283Sdfr
563846283Sdfr  /* Keep compiler happy with an obvious return at the end.
563946283Sdfr   */
564046283Sdfr  return (pid_t) 0;
564146283Sdfr}
564246283Sdfr
564346283Sdfrvoid
564446283Sdfrhppa_ensure_vforking_parent_remains_stopped (pid)
564546283Sdfr  int  pid;
564646283Sdfr{
564746283Sdfr  /* Nothing to do when using ttrace.  Only the ptrace-based implementation
564846283Sdfr     must do real work.
564946283Sdfr   */
565046283Sdfr}
565146283Sdfr
565246283Sdfr
565346283Sdfrint
565446283Sdfrhppa_resume_execd_vforking_child_to_get_parent_vfork ()
565546283Sdfr{
565646283Sdfr  return 0;  /* No, the parent vfork is available now. */
565746283Sdfr}
565846283Sdfr
565946283Sdfr
566046283Sdfr
566146283Sdfrvoid
566246283Sdfr_initialize_infttrace ()
566346283Sdfr{
566446283Sdfr  /* Initialize the ttrace-based hardware watchpoint implementation. */
566546283Sdfr  memory_page_dictionary.page_count = (LONGEST) -1;
566646283Sdfr  memory_page_dictionary.page_protections_allowed = 1;
566746283Sdfr
566846283Sdfr  errno = 0;
566946283Sdfr  memory_page_dictionary.page_size = sysconf (_SC_PAGE_SIZE);
567046283Sdfr
567146283Sdfr  if (errno || (memory_page_dictionary.page_size <= 0))
567246283Sdfr    perror_with_name ("sysconf");
567346283Sdfr}
567446283Sdfr
5675