1130812Smarcel/* Interface GDB to the GNU Hurd.
2130812Smarcel   Copyright 1992, 1995, 1996, 1997, 1998, 1999, 2000, 2001
3130812Smarcel   Free Software Foundation, Inc.
4130812Smarcel
5130812Smarcel   This file is part of GDB.
6130812Smarcel
7130812Smarcel   Written by Miles Bader <miles@gnu.ai.mit.edu>
8130812Smarcel
9130812Smarcel   Some code and ideas from m3-nat.c by Jukka Virtanen <jtv@hut.fi>
10130812Smarcel
11130812Smarcel   This program is free software; you can redistribute it and/or modify
12130812Smarcel   it under the terms of the GNU General Public License as published by
13130812Smarcel   the Free Software Foundation; either version 2 of the License, or
14130812Smarcel   (at your option) any later version.
15130812Smarcel
16130812Smarcel   This program is distributed in the hope that it will be useful,
17130812Smarcel   but WITHOUT ANY WARRANTY; without even the implied warranty of
18130812Smarcel   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19130812Smarcel   GNU General Public License for more details.
20130812Smarcel
21130812Smarcel   You should have received a copy of the GNU General Public License
22130812Smarcel   along with this program; if not, write to the Free Software
23130812Smarcel   Foundation, Inc., 59 Temple Place - Suite 330,
24130812Smarcel   Boston, MA 02111-1307, USA.
25130812Smarcel */
26130812Smarcel
27130812Smarcel#include <ctype.h>
28130812Smarcel#include <errno.h>
29130812Smarcel#include <limits.h>
30130812Smarcel#include <setjmp.h>
31130812Smarcel#include <signal.h>
32130812Smarcel#include <stdio.h>
33130812Smarcel#include "gdb_string.h"
34130812Smarcel#include <sys/ptrace.h>
35130812Smarcel
36130812Smarcel#include <mach.h>
37130812Smarcel#include <mach_error.h>
38130812Smarcel#include <mach/exception.h>
39130812Smarcel#include <mach/message.h>
40130812Smarcel#include <mach/notify.h>
41130812Smarcel#include <mach/vm_attributes.h>
42130812Smarcel
43130812Smarcel#include <hurd.h>
44130812Smarcel#include <hurd/interrupt.h>
45130812Smarcel#include <hurd/msg.h>
46130812Smarcel#include <hurd/msg_request.h>
47130812Smarcel#include <hurd/process.h>
48130812Smarcel#include <hurd/process_request.h>
49130812Smarcel#include <hurd/signal.h>
50130812Smarcel#include <hurd/sigpreempt.h>
51130812Smarcel
52130812Smarcel#include <portinfo.h>
53130812Smarcel
54130812Smarcel#include "defs.h"
55130812Smarcel#include "inferior.h"
56130812Smarcel#include "symtab.h"
57130812Smarcel#include "value.h"
58130812Smarcel#include "language.h"
59130812Smarcel#include "target.h"
60130812Smarcel#include "gdb_wait.h"
61130812Smarcel#include "gdbcmd.h"
62130812Smarcel#include "gdbcore.h"
63130812Smarcel#include "gdbthread.h"
64130812Smarcel#include "gdb_assert.h"
65130812Smarcel#include "gdb_obstack.h"
66130812Smarcel
67130812Smarcel#include "gnu-nat.h"
68130812Smarcel
69130812Smarcel#include "exc_request_S.h"
70130812Smarcel#include "notify_S.h"
71130812Smarcel#include "process_reply_S.h"
72130812Smarcel#include "msg_reply_S.h"
73130812Smarcel#include "exc_request_U.h"
74130812Smarcel#include "msg_U.h"
75130812Smarcel
76130812Smarcelstatic process_t proc_server = MACH_PORT_NULL;
77130812Smarcel
78130812Smarcel/* If we've sent a proc_wait_request to the proc server, the pid of the
79130812Smarcel   process we asked about.  We can only ever have one outstanding.  */
80130812Smarcelint proc_wait_pid = 0;
81130812Smarcel
82130812Smarcel/* The number of wait requests we've sent, and expect replies from.  */
83130812Smarcelint proc_waits_pending = 0;
84130812Smarcel
85130812Smarcelint gnu_debug_flag = 0;
86130812Smarcel
87130812Smarcel/* Forward decls */
88130812Smarcel
89130812Smarcelextern struct target_ops gnu_ops;
90130812Smarcel
91130812Smarcelstruct inf *make_inf ();
92130812Smarcelvoid inf_clear_wait (struct inf *inf);
93130812Smarcelvoid inf_cleanup (struct inf *inf);
94130812Smarcelvoid inf_startup (struct inf *inf, int pid);
95130812Smarcelint inf_update_suspends (struct inf *inf);
96130812Smarcelvoid inf_set_pid (struct inf *inf, pid_t pid);
97130812Smarcelvoid inf_validate_procs (struct inf *inf);
98130812Smarcelvoid inf_steal_exc_ports (struct inf *inf);
99130812Smarcelvoid inf_restore_exc_ports (struct inf *inf);
100130812Smarcelstruct proc *inf_tid_to_proc (struct inf *inf, int tid);
101130812Smarcelvoid inf_set_threads_resume_sc (struct inf *inf,
102130812Smarcel				struct proc *run_thread,
103130812Smarcel				int run_others);
104130812Smarcelint inf_set_threads_resume_sc_for_signal_thread (struct inf *inf);
105130812Smarcelvoid inf_suspend (struct inf *inf);
106130812Smarcelvoid inf_resume (struct inf *inf);
107130812Smarcelvoid inf_set_step_thread (struct inf *inf, struct proc *proc);
108130812Smarcelvoid inf_detach (struct inf *inf);
109130812Smarcelvoid inf_attach (struct inf *inf, int pid);
110130812Smarcelvoid inf_signal (struct inf *inf, enum target_signal sig);
111130812Smarcelvoid inf_continue (struct inf *inf);
112130812Smarcel
113130812Smarcel#define inf_debug(_inf, msg, args...) \
114130812Smarcel  do { struct inf *__inf = (_inf); \
115130812Smarcel       debug ("{inf %d %p}: " msg, __inf->pid, __inf , ##args); } while (0)
116130812Smarcel
117130812Smarcelvoid proc_abort (struct proc *proc, int force);
118130812Smarcelstruct proc *make_proc (struct inf *inf, mach_port_t port, int tid);
119130812Smarcelstruct proc *_proc_free (struct proc *proc);
120130812Smarcelint proc_update_sc (struct proc *proc);
121130812Smarcelerror_t proc_get_exception_port (struct proc *proc, mach_port_t * port);
122130812Smarcelerror_t proc_set_exception_port (struct proc *proc, mach_port_t port);
123130812Smarcelstatic mach_port_t _proc_get_exc_port (struct proc *proc);
124130812Smarcelvoid proc_steal_exc_port (struct proc *proc, mach_port_t exc_port);
125130812Smarcelvoid proc_restore_exc_port (struct proc *proc);
126130812Smarcelint proc_trace (struct proc *proc, int set);
127130812Smarcel
128130812Smarcel/* Evaluate RPC_EXPR in a scope with the variables MSGPORT and REFPORT bound
129130812Smarcel   to INF's msg port and task port respectively.  If it has no msg port,
130130812Smarcel   EIEIO is returned.  INF must refer to a running process!  */
131130812Smarcel#define INF_MSGPORT_RPC(inf, rpc_expr) \
132130812Smarcel  HURD_MSGPORT_RPC (proc_getmsgport (proc_server, inf->pid, &msgport), \
133130812Smarcel		    (refport = inf->task->port, 0), 0, \
134130812Smarcel		    msgport ? (rpc_expr) : EIEIO)
135130812Smarcel
136130812Smarcel/* Like INF_MSGPORT_RPC, but will also resume the signal thread to ensure
137130812Smarcel   there's someone around to deal with the RPC (and resuspend things
138130812Smarcel   afterwards).  This effects INF's threads' resume_sc count.  */
139130812Smarcel#define INF_RESUME_MSGPORT_RPC(inf, rpc_expr) \
140130812Smarcel  (inf_set_threads_resume_sc_for_signal_thread (inf) \
141130812Smarcel   ? ({ error_t __e; \
142130812Smarcel	inf_resume (inf); \
143130812Smarcel	__e = INF_MSGPORT_RPC (inf, rpc_expr); \
144130812Smarcel	inf_suspend (inf); \
145130812Smarcel	__e; }) \
146130812Smarcel   : EIEIO)
147130812Smarcel
148130812Smarcel
149130812Smarcel/* The state passed by an exception message.  */
150130812Smarcelstruct exc_state
151130812Smarcel  {
152130812Smarcel    int exception;		/* The exception code */
153130812Smarcel    int code, subcode;
154130812Smarcel    mach_port_t handler;	/* The real exception port to handle this. */
155130812Smarcel    mach_port_t reply;		/* The reply port from the exception call. */
156130812Smarcel  };
157130812Smarcel
158130812Smarcel/* The results of the last wait an inf did. */
159130812Smarcelstruct inf_wait
160130812Smarcel  {
161130812Smarcel    struct target_waitstatus status;	/* The status returned to gdb.  */
162130812Smarcel    struct exc_state exc;	/* The exception that caused us to return. */
163130812Smarcel    struct proc *thread;	/* The thread in question.  */
164130812Smarcel    int suppress;		/* Something trivial happened.  */
165130812Smarcel  };
166130812Smarcel
167130812Smarcel/* The state of an inferior.  */
168130812Smarcelstruct inf
169130812Smarcel  {
170130812Smarcel    /* Fields describing the current inferior.  */
171130812Smarcel
172130812Smarcel    struct proc *task;		/* The mach task.   */
173130812Smarcel    struct proc *threads;	/* A linked list of all threads in TASK.  */
174130812Smarcel
175130812Smarcel    /* True if THREADS needn't be validated by querying the task.  We assume that
176130812Smarcel       we and the task in question are the only ones frobbing the thread list,
177130812Smarcel       so as long as we don't let any code run, we don't have to worry about
178130812Smarcel       THREADS changing.  */
179130812Smarcel    int threads_up_to_date;
180130812Smarcel
181130812Smarcel    pid_t pid;			/* The real system PID. */
182130812Smarcel
183130812Smarcel    struct inf_wait wait;	/* What to return from target_wait.  */
184130812Smarcel
185130812Smarcel    /* One thread proc in INF may be in `single-stepping mode'.  This is it.  */
186130812Smarcel    struct proc *step_thread;
187130812Smarcel
188130812Smarcel    /* The thread we think is the signal thread.  */
189130812Smarcel    struct proc *signal_thread;
190130812Smarcel
191130812Smarcel    mach_port_t event_port;	/* Where we receive various msgs.  */
192130812Smarcel
193130812Smarcel    /* True if we think at least one thread in the inferior could currently be
194130812Smarcel       running.  */
195130812Smarcel    unsigned int running:1;
196130812Smarcel
197130812Smarcel    /* True if the process has stopped (in the proc server sense).  Note that
198130812Smarcel       since a proc server `stop' leaves the signal thread running, the inf can
199130812Smarcel       be RUNNING && STOPPED...  */
200130812Smarcel    unsigned int stopped:1;
201130812Smarcel
202130812Smarcel    /* True if the inferior has no message port.  */
203130812Smarcel    unsigned int nomsg:1;
204130812Smarcel
205130812Smarcel    /* True if the inferior is traced.  */
206130812Smarcel    unsigned int traced:1;
207130812Smarcel
208130812Smarcel    /* True if we shouldn't try waiting for the inferior, usually because we
209130812Smarcel       can't for some reason.  */
210130812Smarcel    unsigned int no_wait:1;
211130812Smarcel
212130812Smarcel    /* When starting a new inferior, we don't try to validate threads until all
213130812Smarcel       the proper execs have been done.  This is a count of how many execs we
214130812Smarcel       expect to happen.  */
215130812Smarcel    unsigned pending_execs;
216130812Smarcel
217130812Smarcel    /* Fields describing global state */
218130812Smarcel
219130812Smarcel    /* The task suspend count used when gdb has control.  This is normally 1 to
220130812Smarcel       make things easier for us, but sometimes (like when attaching to vital
221130812Smarcel       system servers) it may be desirable to let the task continue to run
222130812Smarcel       (pausing individual threads as necessary).  */
223130812Smarcel    int pause_sc;
224130812Smarcel
225130812Smarcel    /* The task suspend count left when detaching from a task.  */
226130812Smarcel    int detach_sc;
227130812Smarcel
228130812Smarcel    /* The initial values used for the run_sc and pause_sc of newly discovered
229130812Smarcel       threads -- see the definition of those fields in struct proc.  */
230130812Smarcel    int default_thread_run_sc;
231130812Smarcel    int default_thread_pause_sc;
232130812Smarcel    int default_thread_detach_sc;
233130812Smarcel
234130812Smarcel    /* True if the process should be traced when started/attached.  Newly
235130812Smarcel       started processes *must* be traced at first to exec them properly, but
236130812Smarcel       if this is false, tracing is turned off as soon it has done so.  */
237130812Smarcel    int want_signals;
238130812Smarcel
239130812Smarcel    /* True if exceptions from the inferior process should be trapped.  This
240130812Smarcel       must be on to use breakpoints.  */
241130812Smarcel    int want_exceptions;
242130812Smarcel  };
243130812Smarcel
244130812Smarcel
245130812Smarcelint
246130812Smarcel__proc_pid (struct proc *proc)
247130812Smarcel{
248130812Smarcel  return proc->inf->pid;
249130812Smarcel}
250130812Smarcel
251130812Smarcel
252130812Smarcel/* Update PROC's real suspend count to match it's desired one.  Returns true
253130812Smarcel   if we think PROC is now in a runnable state.  */
254130812Smarcelint
255130812Smarcelproc_update_sc (struct proc *proc)
256130812Smarcel{
257130812Smarcel  int running;
258130812Smarcel  int err = 0;
259130812Smarcel  int delta = proc->sc - proc->cur_sc;
260130812Smarcel
261130812Smarcel  if (delta)
262130812Smarcel    proc_debug (proc, "sc: %d --> %d", proc->cur_sc, proc->sc);
263130812Smarcel
264130812Smarcel  if (proc->sc == 0 && proc->state_changed)
265130812Smarcel    /* Since PROC may start running, we must write back any state changes. */
266130812Smarcel    {
267130812Smarcel      gdb_assert (proc_is_thread (proc));
268130812Smarcel      proc_debug (proc, "storing back changed thread state");
269130812Smarcel      err = thread_set_state (proc->port, THREAD_STATE_FLAVOR,
270130812Smarcel			 (thread_state_t) &proc->state, THREAD_STATE_SIZE);
271130812Smarcel      if (!err)
272130812Smarcel	proc->state_changed = 0;
273130812Smarcel    }
274130812Smarcel
275130812Smarcel  if (delta > 0)
276130812Smarcel    {
277130812Smarcel      while (delta-- > 0 && !err)
278130812Smarcel	{
279130812Smarcel	  if (proc_is_task (proc))
280130812Smarcel	    err = task_suspend (proc->port);
281130812Smarcel	  else
282130812Smarcel	    err = thread_suspend (proc->port);
283130812Smarcel	}
284130812Smarcel    }
285130812Smarcel  else
286130812Smarcel    {
287130812Smarcel      while (delta++ < 0 && !err)
288130812Smarcel	{
289130812Smarcel	  if (proc_is_task (proc))
290130812Smarcel	    err = task_resume (proc->port);
291130812Smarcel	  else
292130812Smarcel	    err = thread_resume (proc->port);
293130812Smarcel	}
294130812Smarcel    }
295130812Smarcel  if (!err)
296130812Smarcel    proc->cur_sc = proc->sc;
297130812Smarcel
298130812Smarcel  /* If we got an error, then the task/thread has disappeared.  */
299130812Smarcel  running = !err && proc->sc == 0;
300130812Smarcel
301130812Smarcel  proc_debug (proc, "is %s", err ? "dead" : running ? "running" : "suspended");
302130812Smarcel  if (err)
303130812Smarcel    proc_debug (proc, "err = %s", safe_strerror (err));
304130812Smarcel
305130812Smarcel  if (running)
306130812Smarcel    {
307130812Smarcel      proc->aborted = 0;
308130812Smarcel      proc->state_valid = proc->state_changed = 0;
309130812Smarcel      proc->fetched_regs = 0;
310130812Smarcel    }
311130812Smarcel
312130812Smarcel  return running;
313130812Smarcel}
314130812Smarcel
315130812Smarcel
316130812Smarcel/* Thread_abort is called on PROC if needed.  PROC must be a thread proc.
317130812Smarcel   If PROC is deemed `precious', then nothing is done unless FORCE is true.
318130812Smarcel   In particular, a thread is precious if it's running (in which case forcing
319130812Smarcel   it includes suspending it first), or if it has an exception pending.  */
320130812Smarcelvoid
321130812Smarcelproc_abort (struct proc *proc, int force)
322130812Smarcel{
323130812Smarcel  gdb_assert (proc_is_thread (proc));
324130812Smarcel
325130812Smarcel  if (!proc->aborted)
326130812Smarcel    {
327130812Smarcel      struct inf *inf = proc->inf;
328130812Smarcel      int running = (proc->cur_sc == 0 && inf->task->cur_sc == 0);
329130812Smarcel
330130812Smarcel      if (running && force)
331130812Smarcel	{
332130812Smarcel	  proc->sc = 1;
333130812Smarcel	  inf_update_suspends (proc->inf);
334130812Smarcel	  running = 0;
335130812Smarcel	  warning ("Stopped %s.", proc_string (proc));
336130812Smarcel	}
337130812Smarcel      else if (proc == inf->wait.thread && inf->wait.exc.reply && !force)
338130812Smarcel	/* An exception is pending on PROC, which don't mess with.  */
339130812Smarcel	running = 1;
340130812Smarcel
341130812Smarcel      if (!running)
342130812Smarcel	/* We only abort the thread if it's not actually running.  */
343130812Smarcel	{
344130812Smarcel	  thread_abort (proc->port);
345130812Smarcel	  proc_debug (proc, "aborted");
346130812Smarcel	  proc->aborted = 1;
347130812Smarcel	}
348130812Smarcel      else
349130812Smarcel	proc_debug (proc, "not aborting");
350130812Smarcel    }
351130812Smarcel}
352130812Smarcel
353130812Smarcel/* Make sure that the state field in PROC is up to date, and return a pointer
354130812Smarcel   to it, or 0 if something is wrong.  If WILL_MODIFY is true, makes sure
355130812Smarcel   that the thread is stopped and aborted first, and sets the state_changed
356130812Smarcel   field in PROC to true.  */
357130812Smarcelthread_state_t
358130812Smarcelproc_get_state (struct proc *proc, int will_modify)
359130812Smarcel{
360130812Smarcel  int was_aborted = proc->aborted;
361130812Smarcel
362130812Smarcel  proc_debug (proc, "updating state info%s",
363130812Smarcel	      will_modify ? " (with intention to modify)" : "");
364130812Smarcel
365130812Smarcel  proc_abort (proc, will_modify);
366130812Smarcel
367130812Smarcel  if (!was_aborted && proc->aborted)
368130812Smarcel    /* PROC's state may have changed since we last fetched it.  */
369130812Smarcel    proc->state_valid = 0;
370130812Smarcel
371130812Smarcel  if (!proc->state_valid)
372130812Smarcel    {
373130812Smarcel      mach_msg_type_number_t state_size = THREAD_STATE_SIZE;
374130812Smarcel      error_t err =
375130812Smarcel      thread_get_state (proc->port, THREAD_STATE_FLAVOR,
376130812Smarcel			(thread_state_t) &proc->state, &state_size);
377130812Smarcel      proc_debug (proc, "getting thread state");
378130812Smarcel      proc->state_valid = !err;
379130812Smarcel    }
380130812Smarcel
381130812Smarcel  if (proc->state_valid)
382130812Smarcel    {
383130812Smarcel      if (will_modify)
384130812Smarcel	proc->state_changed = 1;
385130812Smarcel      return (thread_state_t) &proc->state;
386130812Smarcel    }
387130812Smarcel  else
388130812Smarcel    return 0;
389130812Smarcel}
390130812Smarcel
391130812Smarcel
392130812Smarcel/* Set PORT to PROC's exception port.  */
393130812Smarcelerror_t
394130812Smarcelproc_get_exception_port (struct proc * proc, mach_port_t * port)
395130812Smarcel{
396130812Smarcel  if (proc_is_task (proc))
397130812Smarcel    return task_get_exception_port (proc->port, port);
398130812Smarcel  else
399130812Smarcel    return thread_get_exception_port (proc->port, port);
400130812Smarcel}
401130812Smarcel
402130812Smarcel/* Set PROC's exception port to PORT.  */
403130812Smarcelerror_t
404130812Smarcelproc_set_exception_port (struct proc * proc, mach_port_t port)
405130812Smarcel{
406130812Smarcel  proc_debug (proc, "setting exception port: %d", port);
407130812Smarcel  if (proc_is_task (proc))
408130812Smarcel    return task_set_exception_port (proc->port, port);
409130812Smarcel  else
410130812Smarcel    return thread_set_exception_port (proc->port, port);
411130812Smarcel}
412130812Smarcel
413130812Smarcel/* Get PROC's exception port, cleaning up a bit if proc has died.  */
414130812Smarcelstatic mach_port_t
415130812Smarcel_proc_get_exc_port (struct proc *proc)
416130812Smarcel{
417130812Smarcel  mach_port_t exc_port;
418130812Smarcel  error_t err = proc_get_exception_port (proc, &exc_port);
419130812Smarcel
420130812Smarcel  if (err)
421130812Smarcel    /* PROC must be dead.  */
422130812Smarcel    {
423130812Smarcel      if (proc->exc_port)
424130812Smarcel	mach_port_deallocate (mach_task_self (), proc->exc_port);
425130812Smarcel      proc->exc_port = MACH_PORT_NULL;
426130812Smarcel      if (proc->saved_exc_port)
427130812Smarcel	mach_port_deallocate (mach_task_self (), proc->saved_exc_port);
428130812Smarcel      proc->saved_exc_port = MACH_PORT_NULL;
429130812Smarcel    }
430130812Smarcel
431130812Smarcel  return exc_port;
432130812Smarcel}
433130812Smarcel
434130812Smarcel/* Replace PROC's exception port with EXC_PORT, unless it's already been
435130812Smarcel   done.  Stash away any existing exception port so we can restore it later. */
436130812Smarcelvoid
437130812Smarcelproc_steal_exc_port (struct proc *proc, mach_port_t exc_port)
438130812Smarcel{
439130812Smarcel  mach_port_t cur_exc_port = _proc_get_exc_port (proc);
440130812Smarcel
441130812Smarcel  if (cur_exc_port)
442130812Smarcel    {
443130812Smarcel      error_t err = 0;
444130812Smarcel
445130812Smarcel      proc_debug (proc, "inserting exception port: %d", exc_port);
446130812Smarcel
447130812Smarcel      if (cur_exc_port != exc_port)
448130812Smarcel	/* Put in our exception port.  */
449130812Smarcel	err = proc_set_exception_port (proc, exc_port);
450130812Smarcel
451130812Smarcel      if (err || cur_exc_port == proc->exc_port)
452130812Smarcel	/* We previously set the exception port, and it's still set.  So we
453130812Smarcel	   just keep the old saved port which is what the proc set.  */
454130812Smarcel	{
455130812Smarcel	  if (cur_exc_port)
456130812Smarcel	    mach_port_deallocate (mach_task_self (), cur_exc_port);
457130812Smarcel	}
458130812Smarcel      else
459130812Smarcel	/* Keep a copy of PROC's old exception port so it can be restored. */
460130812Smarcel	{
461130812Smarcel	  if (proc->saved_exc_port)
462130812Smarcel	    mach_port_deallocate (mach_task_self (), proc->saved_exc_port);
463130812Smarcel	  proc->saved_exc_port = cur_exc_port;
464130812Smarcel	}
465130812Smarcel
466130812Smarcel      proc_debug (proc, "saved exception port: %d", proc->saved_exc_port);
467130812Smarcel
468130812Smarcel      if (!err)
469130812Smarcel	proc->exc_port = exc_port;
470130812Smarcel      else
471130812Smarcel	warning ("Error setting exception port for %s: %s",
472130812Smarcel		 proc_string (proc), safe_strerror (err));
473130812Smarcel    }
474130812Smarcel}
475130812Smarcel
476130812Smarcel/* If we previously replaced PROC's exception port, put back what we
477130812Smarcel   found there at the time, unless *our* exception port has since been
478130812Smarcel   overwritten, in which case who knows what's going on.  */
479130812Smarcelvoid
480130812Smarcelproc_restore_exc_port (struct proc *proc)
481130812Smarcel{
482130812Smarcel  mach_port_t cur_exc_port = _proc_get_exc_port (proc);
483130812Smarcel
484130812Smarcel  if (cur_exc_port)
485130812Smarcel    {
486130812Smarcel      error_t err = 0;
487130812Smarcel
488130812Smarcel      proc_debug (proc, "restoring real exception port");
489130812Smarcel
490130812Smarcel      if (proc->exc_port == cur_exc_port)
491130812Smarcel	/* Our's is still there.  */
492130812Smarcel	err = proc_set_exception_port (proc, proc->saved_exc_port);
493130812Smarcel
494130812Smarcel      if (proc->saved_exc_port)
495130812Smarcel	mach_port_deallocate (mach_task_self (), proc->saved_exc_port);
496130812Smarcel      proc->saved_exc_port = MACH_PORT_NULL;
497130812Smarcel
498130812Smarcel      if (!err)
499130812Smarcel	proc->exc_port = MACH_PORT_NULL;
500130812Smarcel      else
501130812Smarcel	warning ("Error setting exception port for %s: %s",
502130812Smarcel		 proc_string (proc), safe_strerror (err));
503130812Smarcel    }
504130812Smarcel}
505130812Smarcel
506130812Smarcel
507130812Smarcel/* Turns hardware tracing in PROC on or off when SET is true or false,
508130812Smarcel   respectively.  Returns true on success.  */
509130812Smarcelint
510130812Smarcelproc_trace (struct proc *proc, int set)
511130812Smarcel{
512130812Smarcel  thread_state_t state = proc_get_state (proc, 1);
513130812Smarcel
514130812Smarcel  if (!state)
515130812Smarcel    return 0;			/* the thread must be dead.  */
516130812Smarcel
517130812Smarcel  proc_debug (proc, "tracing %s", set ? "on" : "off");
518130812Smarcel
519130812Smarcel  if (set)
520130812Smarcel    {
521130812Smarcel      /* XXX We don't get the exception unless the thread has its own
522130812Smarcel         exception port???? */
523130812Smarcel      if (proc->exc_port == MACH_PORT_NULL)
524130812Smarcel	proc_steal_exc_port (proc, proc->inf->event_port);
525130812Smarcel      THREAD_STATE_SET_TRACED (state);
526130812Smarcel    }
527130812Smarcel  else
528130812Smarcel    THREAD_STATE_CLEAR_TRACED (state);
529130812Smarcel
530130812Smarcel  return 1;
531130812Smarcel}
532130812Smarcel
533130812Smarcel
534130812Smarcel/* A variable from which to assign new TIDs.  */
535130812Smarcelstatic int next_thread_id = 1;
536130812Smarcel
537130812Smarcel/* Returns a new proc structure with the given fields.  Also adds a
538130812Smarcel   notification for PORT becoming dead to be sent to INF's notify port.  */
539130812Smarcelstruct proc *
540130812Smarcelmake_proc (struct inf *inf, mach_port_t port, int tid)
541130812Smarcel{
542130812Smarcel  error_t err;
543130812Smarcel  mach_port_t prev_port = MACH_PORT_NULL;
544130812Smarcel  struct proc *proc = xmalloc (sizeof (struct proc));
545130812Smarcel
546130812Smarcel  proc->port = port;
547130812Smarcel  proc->tid = tid;
548130812Smarcel  proc->inf = inf;
549130812Smarcel  proc->next = 0;
550130812Smarcel  proc->saved_exc_port = MACH_PORT_NULL;
551130812Smarcel  proc->exc_port = MACH_PORT_NULL;
552130812Smarcel
553130812Smarcel  proc->sc = 0;
554130812Smarcel  proc->cur_sc = 0;
555130812Smarcel
556130812Smarcel  /* Note that these are all the values for threads; the task simply uses the
557130812Smarcel     corresponding field in INF directly.  */
558130812Smarcel  proc->run_sc = inf->default_thread_run_sc;
559130812Smarcel  proc->pause_sc = inf->default_thread_pause_sc;
560130812Smarcel  proc->detach_sc = inf->default_thread_detach_sc;
561130812Smarcel  proc->resume_sc = proc->run_sc;
562130812Smarcel
563130812Smarcel  proc->aborted = 0;
564130812Smarcel  proc->dead = 0;
565130812Smarcel  proc->state_valid = 0;
566130812Smarcel  proc->state_changed = 0;
567130812Smarcel
568130812Smarcel  proc_debug (proc, "is new");
569130812Smarcel
570130812Smarcel  /* Get notified when things die.  */
571130812Smarcel  err =
572130812Smarcel    mach_port_request_notification (mach_task_self (), port,
573130812Smarcel				    MACH_NOTIFY_DEAD_NAME, 1,
574130812Smarcel				    inf->event_port,
575130812Smarcel				    MACH_MSG_TYPE_MAKE_SEND_ONCE,
576130812Smarcel				    &prev_port);
577130812Smarcel  if (err)
578130812Smarcel    warning ("Couldn't request notification for port %d: %s",
579130812Smarcel	     port, safe_strerror (err));
580130812Smarcel  else
581130812Smarcel    {
582130812Smarcel      proc_debug (proc, "notifications to: %d", inf->event_port);
583130812Smarcel      if (prev_port != MACH_PORT_NULL)
584130812Smarcel	mach_port_deallocate (mach_task_self (), prev_port);
585130812Smarcel    }
586130812Smarcel
587130812Smarcel  if (inf->want_exceptions)
588130812Smarcel    {
589130812Smarcel      if (proc_is_task (proc))
590130812Smarcel	/* Make the task exception port point to us.  */
591130812Smarcel	proc_steal_exc_port (proc, inf->event_port);
592130812Smarcel      else
593130812Smarcel	/* Just clear thread exception ports -- they default to the
594130812Smarcel           task one.  */
595130812Smarcel	proc_steal_exc_port (proc, MACH_PORT_NULL);
596130812Smarcel    }
597130812Smarcel
598130812Smarcel  return proc;
599130812Smarcel}
600130812Smarcel
601130812Smarcel/* Frees PROC and any resources it uses, and returns the value of PROC's
602130812Smarcel   next field.  */
603130812Smarcelstruct proc *
604130812Smarcel_proc_free (struct proc *proc)
605130812Smarcel{
606130812Smarcel  struct inf *inf = proc->inf;
607130812Smarcel  struct proc *next = proc->next;
608130812Smarcel
609130812Smarcel  proc_debug (proc, "freeing...");
610130812Smarcel
611130812Smarcel  if (proc == inf->step_thread)
612130812Smarcel    /* Turn off single stepping.  */
613130812Smarcel    inf_set_step_thread (inf, 0);
614130812Smarcel  if (proc == inf->wait.thread)
615130812Smarcel    inf_clear_wait (inf);
616130812Smarcel  if (proc == inf->signal_thread)
617130812Smarcel    inf->signal_thread = 0;
618130812Smarcel
619130812Smarcel  if (proc->port != MACH_PORT_NULL)
620130812Smarcel    {
621130812Smarcel      if (proc->exc_port != MACH_PORT_NULL)
622130812Smarcel	/* Restore the original exception port.  */
623130812Smarcel	proc_restore_exc_port (proc);
624130812Smarcel      if (proc->cur_sc != 0)
625130812Smarcel	/* Resume the thread/task.  */
626130812Smarcel	{
627130812Smarcel	  proc->sc = 0;
628130812Smarcel	  proc_update_sc (proc);
629130812Smarcel	}
630130812Smarcel      mach_port_deallocate (mach_task_self (), proc->port);
631130812Smarcel    }
632130812Smarcel
633130812Smarcel  xfree (proc);
634130812Smarcel  return next;
635130812Smarcel}
636130812Smarcel
637130812Smarcel
638130812Smarcelstruct inf *
639130812Smarcelmake_inf (void)
640130812Smarcel{
641130812Smarcel  struct inf *inf = xmalloc (sizeof (struct inf));
642130812Smarcel
643130812Smarcel  inf->task = 0;
644130812Smarcel  inf->threads = 0;
645130812Smarcel  inf->threads_up_to_date = 0;
646130812Smarcel  inf->pid = 0;
647130812Smarcel  inf->wait.status.kind = TARGET_WAITKIND_SPURIOUS;
648130812Smarcel  inf->wait.thread = 0;
649130812Smarcel  inf->wait.exc.handler = MACH_PORT_NULL;
650130812Smarcel  inf->wait.exc.reply = MACH_PORT_NULL;
651130812Smarcel  inf->step_thread = 0;
652130812Smarcel  inf->signal_thread = 0;
653130812Smarcel  inf->event_port = MACH_PORT_NULL;
654130812Smarcel  inf->running = 0;
655130812Smarcel  inf->stopped = 0;
656130812Smarcel  inf->nomsg = 1;
657130812Smarcel  inf->traced = 0;
658130812Smarcel  inf->no_wait = 0;
659130812Smarcel  inf->pending_execs = 0;
660130812Smarcel  inf->pause_sc = 1;
661130812Smarcel  inf->detach_sc = 0;
662130812Smarcel  inf->default_thread_run_sc = 0;
663130812Smarcel  inf->default_thread_pause_sc = 0;
664130812Smarcel  inf->default_thread_detach_sc = 0;
665130812Smarcel  inf->want_signals = 1;	/* By default */
666130812Smarcel  inf->want_exceptions = 1;	/* By default */
667130812Smarcel
668130812Smarcel  return inf;
669130812Smarcel}
670130812Smarcel
671130812Smarcel/* Clear INF's target wait status.  */
672130812Smarcelvoid
673130812Smarcelinf_clear_wait (struct inf *inf)
674130812Smarcel{
675130812Smarcel  inf_debug (inf, "clearing wait");
676130812Smarcel  inf->wait.status.kind = TARGET_WAITKIND_SPURIOUS;
677130812Smarcel  inf->wait.thread = 0;
678130812Smarcel  inf->wait.suppress = 0;
679130812Smarcel  if (inf->wait.exc.handler != MACH_PORT_NULL)
680130812Smarcel    {
681130812Smarcel      mach_port_deallocate (mach_task_self (), inf->wait.exc.handler);
682130812Smarcel      inf->wait.exc.handler = MACH_PORT_NULL;
683130812Smarcel    }
684130812Smarcel  if (inf->wait.exc.reply != MACH_PORT_NULL)
685130812Smarcel    {
686130812Smarcel      mach_port_deallocate (mach_task_self (), inf->wait.exc.reply);
687130812Smarcel      inf->wait.exc.reply = MACH_PORT_NULL;
688130812Smarcel    }
689130812Smarcel}
690130812Smarcel
691130812Smarcel
692130812Smarcelvoid
693130812Smarcelinf_cleanup (struct inf *inf)
694130812Smarcel{
695130812Smarcel  inf_debug (inf, "cleanup");
696130812Smarcel
697130812Smarcel  inf_clear_wait (inf);
698130812Smarcel
699130812Smarcel  inf_set_pid (inf, -1);
700130812Smarcel  inf->pid = 0;
701130812Smarcel  inf->running = 0;
702130812Smarcel  inf->stopped = 0;
703130812Smarcel  inf->nomsg = 1;
704130812Smarcel  inf->traced = 0;
705130812Smarcel  inf->no_wait = 0;
706130812Smarcel  inf->pending_execs = 0;
707130812Smarcel
708130812Smarcel  if (inf->event_port)
709130812Smarcel    {
710130812Smarcel      mach_port_destroy (mach_task_self (), inf->event_port);
711130812Smarcel      inf->event_port = MACH_PORT_NULL;
712130812Smarcel    }
713130812Smarcel}
714130812Smarcel
715130812Smarcelvoid
716130812Smarcelinf_startup (struct inf *inf, int pid)
717130812Smarcel{
718130812Smarcel  error_t err;
719130812Smarcel
720130812Smarcel  inf_debug (inf, "startup: pid = %d", pid);
721130812Smarcel
722130812Smarcel  inf_cleanup (inf);
723130812Smarcel
724130812Smarcel  /* Make the port on which we receive all events.  */
725130812Smarcel  err = mach_port_allocate (mach_task_self (),
726130812Smarcel			    MACH_PORT_RIGHT_RECEIVE, &inf->event_port);
727130812Smarcel  if (err)
728130812Smarcel    error ("Error allocating event port: %s", safe_strerror (err));
729130812Smarcel
730130812Smarcel  /* Make a send right for it, so we can easily copy it for other people.  */
731130812Smarcel  mach_port_insert_right (mach_task_self (), inf->event_port,
732130812Smarcel			  inf->event_port, MACH_MSG_TYPE_MAKE_SEND);
733130812Smarcel  inf_set_pid (inf, pid);
734130812Smarcel}
735130812Smarcel
736130812Smarcel
737130812Smarcel/* Close current process, if any, and attach INF to process PORT.  */
738130812Smarcelvoid
739130812Smarcelinf_set_pid (struct inf *inf, pid_t pid)
740130812Smarcel{
741130812Smarcel  task_t task_port;
742130812Smarcel  struct proc *task = inf->task;
743130812Smarcel
744130812Smarcel  inf_debug (inf, "setting pid: %d", pid);
745130812Smarcel
746130812Smarcel  if (pid < 0)
747130812Smarcel    task_port = MACH_PORT_NULL;
748130812Smarcel  else
749130812Smarcel    {
750130812Smarcel      error_t err = proc_pid2task (proc_server, pid, &task_port);
751130812Smarcel      if (err)
752130812Smarcel	error ("Error getting task for pid %d: %s", pid, safe_strerror (err));
753130812Smarcel    }
754130812Smarcel
755130812Smarcel  inf_debug (inf, "setting task: %d", task_port);
756130812Smarcel
757130812Smarcel  if (inf->pause_sc)
758130812Smarcel    task_suspend (task_port);
759130812Smarcel
760130812Smarcel  if (task && task->port != task_port)
761130812Smarcel    {
762130812Smarcel      inf->task = 0;
763130812Smarcel      inf_validate_procs (inf);	/* Trash all the threads. */
764130812Smarcel      _proc_free (task);	/* And the task. */
765130812Smarcel    }
766130812Smarcel
767130812Smarcel  if (task_port != MACH_PORT_NULL)
768130812Smarcel    {
769130812Smarcel      inf->task = make_proc (inf, task_port, PROC_TID_TASK);
770130812Smarcel      inf->threads_up_to_date = 0;
771130812Smarcel    }
772130812Smarcel
773130812Smarcel  if (inf->task)
774130812Smarcel    {
775130812Smarcel      inf->pid = pid;
776130812Smarcel      if (inf->pause_sc)
777130812Smarcel	/* Reflect task_suspend above.  */
778130812Smarcel	inf->task->sc = inf->task->cur_sc = 1;
779130812Smarcel    }
780130812Smarcel  else
781130812Smarcel    inf->pid = -1;
782130812Smarcel}
783130812Smarcel
784130812Smarcel
785130812Smarcel/* Validates INF's stopped, nomsg and traced field from the actual
786130812Smarcel   proc server state.  Note that the traced field is only updated from
787130812Smarcel   the proc server state if we do not have a message port.  If we do
788130812Smarcel   have a message port we'd better look at the tracemask itself.  */
789130812Smarcelstatic void
790130812Smarcelinf_validate_procinfo (struct inf *inf)
791130812Smarcel{
792130812Smarcel  char *noise;
793130812Smarcel  mach_msg_type_number_t noise_len = 0;
794130812Smarcel  struct procinfo *pi;
795130812Smarcel  mach_msg_type_number_t pi_len = 0;
796130812Smarcel  int info_flags = 0;
797130812Smarcel  error_t err =
798130812Smarcel  proc_getprocinfo (proc_server, inf->pid, &info_flags,
799130812Smarcel		    (procinfo_t *) &pi, &pi_len, &noise, &noise_len);
800130812Smarcel
801130812Smarcel  if (!err)
802130812Smarcel    {
803130812Smarcel      inf->stopped = !!(pi->state & PI_STOPPED);
804130812Smarcel      inf->nomsg = !!(pi->state & PI_NOMSG);
805130812Smarcel      if (inf->nomsg)
806130812Smarcel	inf->traced = !!(pi->state & PI_TRACED);
807130812Smarcel      vm_deallocate (mach_task_self (), (vm_address_t) pi, pi_len);
808130812Smarcel      if (noise_len > 0)
809130812Smarcel	vm_deallocate (mach_task_self (), (vm_address_t) noise, noise_len);
810130812Smarcel    }
811130812Smarcel}
812130812Smarcel
813130812Smarcel/* Validates INF's task suspend count.  If it's higher than we expect,
814130812Smarcel   verify with the user before `stealing' the extra count.  */
815130812Smarcelstatic void
816130812Smarcelinf_validate_task_sc (struct inf *inf)
817130812Smarcel{
818130812Smarcel  char *noise;
819130812Smarcel  mach_msg_type_number_t noise_len = 0;
820130812Smarcel  struct procinfo *pi;
821130812Smarcel  mach_msg_type_number_t pi_len = 0;
822130812Smarcel  int info_flags = PI_FETCH_TASKINFO;
823130812Smarcel  int suspend_count = -1;
824130812Smarcel  error_t err;
825130812Smarcel
826130812Smarcel retry:
827130812Smarcel  err = proc_getprocinfo (proc_server, inf->pid, &info_flags,
828130812Smarcel			  (procinfo_t *) &pi, &pi_len, &noise, &noise_len);
829130812Smarcel  if (err)
830130812Smarcel    {
831130812Smarcel      inf->task->dead = 1; /* oh well */
832130812Smarcel      return;
833130812Smarcel    }
834130812Smarcel
835130812Smarcel  if (inf->task->cur_sc < pi->taskinfo.suspend_count && suspend_count == -1)
836130812Smarcel    {
837130812Smarcel      /* The proc server might have suspended the task while stopping
838130812Smarcel         it.  This happens when the task is handling a traced signal.
839130812Smarcel         Refetch the suspend count.  The proc server should be
840130812Smarcel         finished stopping the task by now.  */
841130812Smarcel      suspend_count = pi->taskinfo.suspend_count;
842130812Smarcel      goto retry;
843130812Smarcel    }
844130812Smarcel
845130812Smarcel  suspend_count = pi->taskinfo.suspend_count;
846130812Smarcel
847130812Smarcel  vm_deallocate (mach_task_self (), (vm_address_t) pi, pi_len);
848130812Smarcel  if (noise_len > 0)
849130812Smarcel    vm_deallocate (mach_task_self (), (vm_address_t) pi, pi_len);
850130812Smarcel
851130812Smarcel  if (inf->task->cur_sc < suspend_count)
852130812Smarcel    {
853130812Smarcel      int abort;
854130812Smarcel
855130812Smarcel      target_terminal_ours ();	/* Allow I/O.  */
856130812Smarcel      abort = !query ("Pid %d has an additional task suspend count of %d;"
857130812Smarcel		      " clear it? ", inf->pid,
858130812Smarcel		      suspend_count - inf->task->cur_sc);
859130812Smarcel      target_terminal_inferior ();	/* Give it back to the child.  */
860130812Smarcel
861130812Smarcel      if (abort)
862130812Smarcel	error ("Additional task suspend count left untouched.");
863130812Smarcel
864130812Smarcel      inf->task->cur_sc = suspend_count;
865130812Smarcel    }
866130812Smarcel}
867130812Smarcel
868130812Smarcel/* Turns tracing for INF on or off, depending on ON, unless it already
869130812Smarcel   is.  If INF is running, the resume_sc count of INF's threads will
870130812Smarcel   be modified, and the signal thread will briefly be run to change
871130812Smarcel   the trace state.  */
872130812Smarcelvoid
873130812Smarcelinf_set_traced (struct inf *inf, int on)
874130812Smarcel{
875130812Smarcel  if (on == inf->traced)
876130812Smarcel    return;
877130812Smarcel
878130812Smarcel  if (inf->task && !inf->task->dead)
879130812Smarcel    /* Make it take effect immediately.  */
880130812Smarcel    {
881130812Smarcel      sigset_t mask = on ? ~(sigset_t) 0 : 0;
882130812Smarcel      error_t err =
883130812Smarcel	INF_RESUME_MSGPORT_RPC (inf, msg_set_init_int (msgport, refport,
884130812Smarcel						       INIT_TRACEMASK, mask));
885130812Smarcel      if (err == EIEIO)
886130812Smarcel	{
887130812Smarcel	  if (on)
888130812Smarcel	    warning ("Can't modify tracing state for pid %d: %s",
889130812Smarcel		     inf->pid, "No signal thread");
890130812Smarcel	  inf->traced = on;
891130812Smarcel	}
892130812Smarcel      else if (err)
893130812Smarcel	warning ("Can't modify tracing state for pid %d: %s",
894130812Smarcel		 inf->pid, safe_strerror (err));
895130812Smarcel      else
896130812Smarcel	inf->traced = on;
897130812Smarcel    }
898130812Smarcel  else
899130812Smarcel    inf->traced = on;
900130812Smarcel}
901130812Smarcel
902130812Smarcel
903130812Smarcel/* Makes all the real suspend count deltas of all the procs in INF
904130812Smarcel   match the desired values.  Careful to always do thread/task suspend
905130812Smarcel   counts in the safe order.  Returns true if at least one thread is
906130812Smarcel   thought to be running. */
907130812Smarcelint
908130812Smarcelinf_update_suspends (struct inf *inf)
909130812Smarcel{
910130812Smarcel  struct proc *task = inf->task;
911130812Smarcel  /* We don't have to update INF->threads even though we're iterating over it
912130812Smarcel     because we'll change a thread only if it already has an existing proc
913130812Smarcel     entry.  */
914130812Smarcel
915130812Smarcel  inf_debug (inf, "updating suspend counts");
916130812Smarcel
917130812Smarcel  if (task)
918130812Smarcel    {
919130812Smarcel      struct proc *thread;
920130812Smarcel      int task_running = (task->sc == 0), thread_running = 0;
921130812Smarcel
922130812Smarcel      if (task->sc > task->cur_sc)
923130812Smarcel	/* The task is becoming _more_ suspended; do before any threads.  */
924130812Smarcel	task_running = proc_update_sc (task);
925130812Smarcel
926130812Smarcel      if (inf->pending_execs)
927130812Smarcel	/* When we're waiting for an exec, things may be happening behind our
928130812Smarcel	   back, so be conservative.  */
929130812Smarcel	thread_running = 1;
930130812Smarcel
931130812Smarcel      /* Do all the thread suspend counts.  */
932130812Smarcel      for (thread = inf->threads; thread; thread = thread->next)
933130812Smarcel	thread_running |= proc_update_sc (thread);
934130812Smarcel
935130812Smarcel      if (task->sc != task->cur_sc)
936130812Smarcel	/* We didn't do the task first, because we wanted to wait for the
937130812Smarcel	   threads; do it now.  */
938130812Smarcel	task_running = proc_update_sc (task);
939130812Smarcel
940130812Smarcel      inf_debug (inf, "%srunning...",
941130812Smarcel		 (thread_running && task_running) ? "" : "not ");
942130812Smarcel
943130812Smarcel      inf->running = thread_running && task_running;
944130812Smarcel
945130812Smarcel      /* Once any thread has executed some code, we can't depend on the
946130812Smarcel         threads list any more.  */
947130812Smarcel      if (inf->running)
948130812Smarcel	inf->threads_up_to_date = 0;
949130812Smarcel
950130812Smarcel      return inf->running;
951130812Smarcel    }
952130812Smarcel
953130812Smarcel  return 0;
954130812Smarcel}
955130812Smarcel
956130812Smarcel
957130812Smarcel/* Converts a GDB pid to a struct proc.  */
958130812Smarcelstruct proc *
959130812Smarcelinf_tid_to_thread (struct inf *inf, int tid)
960130812Smarcel{
961130812Smarcel  struct proc *thread = inf->threads;
962130812Smarcel
963130812Smarcel  while (thread)
964130812Smarcel    if (thread->tid == tid)
965130812Smarcel      return thread;
966130812Smarcel    else
967130812Smarcel      thread = thread->next;
968130812Smarcel  return 0;
969130812Smarcel}
970130812Smarcel
971130812Smarcel/* Converts a thread port to a struct proc.  */
972130812Smarcelstruct proc *
973130812Smarcelinf_port_to_thread (struct inf *inf, mach_port_t port)
974130812Smarcel{
975130812Smarcel  struct proc *thread = inf->threads;
976130812Smarcel  while (thread)
977130812Smarcel    if (thread->port == port)
978130812Smarcel      return thread;
979130812Smarcel    else
980130812Smarcel      thread = thread->next;
981130812Smarcel  return 0;
982130812Smarcel}
983130812Smarcel
984130812Smarcel
985130812Smarcel/* Make INF's list of threads be consistent with reality of TASK.  */
986130812Smarcelvoid
987130812Smarcelinf_validate_procs (struct inf *inf)
988130812Smarcel{
989130812Smarcel  thread_array_t threads;
990130812Smarcel  mach_msg_type_number_t num_threads, i;
991130812Smarcel  struct proc *task = inf->task;
992130812Smarcel
993130812Smarcel  /* If no threads are currently running, this function will guarantee that
994130812Smarcel     things are up to date.  The exception is if there are zero threads --
995130812Smarcel     then it is almost certainly in an odd state, and probably some outside
996130812Smarcel     agent will create threads.  */
997130812Smarcel  inf->threads_up_to_date = inf->threads ? !inf->running : 0;
998130812Smarcel
999130812Smarcel  if (task)
1000130812Smarcel    {
1001130812Smarcel      error_t err = task_threads (task->port, &threads, &num_threads);
1002130812Smarcel      inf_debug (inf, "fetching threads");
1003130812Smarcel      if (err)
1004130812Smarcel	/* TASK must be dead.  */
1005130812Smarcel	{
1006130812Smarcel	  task->dead = 1;
1007130812Smarcel	  task = 0;
1008130812Smarcel	}
1009130812Smarcel    }
1010130812Smarcel
1011130812Smarcel  if (!task)
1012130812Smarcel    {
1013130812Smarcel      num_threads = 0;
1014130812Smarcel      inf_debug (inf, "no task");
1015130812Smarcel    }
1016130812Smarcel
1017130812Smarcel  {
1018130812Smarcel    /* Make things normally linear.  */
1019130812Smarcel    mach_msg_type_number_t search_start = 0;
1020130812Smarcel    /* Which thread in PROCS corresponds to each task thread, & the task.  */
1021130812Smarcel    struct proc *matched[num_threads + 1];
1022130812Smarcel    /* The last thread in INF->threads, so we can add to the end.  */
1023130812Smarcel    struct proc *last = 0;
1024130812Smarcel    /* The current thread we're considering. */
1025130812Smarcel    struct proc *thread = inf->threads;
1026130812Smarcel
1027130812Smarcel    memset (matched, 0, sizeof (matched));
1028130812Smarcel
1029130812Smarcel    while (thread)
1030130812Smarcel      {
1031130812Smarcel	mach_msg_type_number_t left;
1032130812Smarcel
1033130812Smarcel	for (i = search_start, left = num_threads; left; i++, left--)
1034130812Smarcel	  {
1035130812Smarcel	    if (i >= num_threads)
1036130812Smarcel	      i -= num_threads;	/* I wrapped around.  */
1037130812Smarcel	    if (thread->port == threads[i])
1038130812Smarcel	      /* We already know about this thread.  */
1039130812Smarcel	      {
1040130812Smarcel		matched[i] = thread;
1041130812Smarcel		last = thread;
1042130812Smarcel		thread = thread->next;
1043130812Smarcel		search_start++;
1044130812Smarcel		break;
1045130812Smarcel	      }
1046130812Smarcel	  }
1047130812Smarcel
1048130812Smarcel	if (!left)
1049130812Smarcel	  {
1050130812Smarcel	    proc_debug (thread, "died!");
1051130812Smarcel	    thread->port = MACH_PORT_NULL;
1052130812Smarcel	    thread = _proc_free (thread);	/* THREAD is dead.  */
1053130812Smarcel	    (last ? last->next : inf->threads) = thread;
1054130812Smarcel	  }
1055130812Smarcel      }
1056130812Smarcel
1057130812Smarcel    for (i = 0; i < num_threads; i++)
1058130812Smarcel      {
1059130812Smarcel	if (matched[i])
1060130812Smarcel	  /* Throw away the duplicate send right.  */
1061130812Smarcel	  mach_port_deallocate (mach_task_self (), threads[i]);
1062130812Smarcel	else
1063130812Smarcel	  /* THREADS[I] is a thread we don't know about yet!  */
1064130812Smarcel	  {
1065130812Smarcel	    thread = make_proc (inf, threads[i], next_thread_id++);
1066130812Smarcel	    (last ? last->next : inf->threads) = thread;
1067130812Smarcel	    last = thread;
1068130812Smarcel	    proc_debug (thread, "new thread: %d", threads[i]);
1069130812Smarcel	    add_thread (pid_to_ptid (thread->tid));	/* Tell GDB's generic thread code.  */
1070130812Smarcel	  }
1071130812Smarcel      }
1072130812Smarcel
1073130812Smarcel    vm_deallocate (mach_task_self (),
1074130812Smarcel		   (vm_address_t) threads, (num_threads * sizeof (thread_t)));
1075130812Smarcel  }
1076130812Smarcel}
1077130812Smarcel
1078130812Smarcel
1079130812Smarcel/* Makes sure that INF's thread list is synced with the actual process.  */
1080130812Smarcelint
1081130812Smarcelinf_update_procs (struct inf *inf)
1082130812Smarcel{
1083130812Smarcel  if (!inf->task)
1084130812Smarcel    return 0;
1085130812Smarcel  if (!inf->threads_up_to_date)
1086130812Smarcel    inf_validate_procs (inf);
1087130812Smarcel  return !!inf->task;
1088130812Smarcel}
1089130812Smarcel
1090130812Smarcel/* Sets the resume_sc of each thread in inf.  That of RUN_THREAD is set to 0,
1091130812Smarcel   and others are set to their run_sc if RUN_OTHERS is true, and otherwise
1092130812Smarcel   their pause_sc.  */
1093130812Smarcelvoid
1094130812Smarcelinf_set_threads_resume_sc (struct inf *inf,
1095130812Smarcel			   struct proc *run_thread, int run_others)
1096130812Smarcel{
1097130812Smarcel  struct proc *thread;
1098130812Smarcel  inf_update_procs (inf);
1099130812Smarcel  for (thread = inf->threads; thread; thread = thread->next)
1100130812Smarcel    if (thread == run_thread)
1101130812Smarcel      thread->resume_sc = 0;
1102130812Smarcel    else if (run_others)
1103130812Smarcel      thread->resume_sc = thread->run_sc;
1104130812Smarcel    else
1105130812Smarcel      thread->resume_sc = thread->pause_sc;
1106130812Smarcel}
1107130812Smarcel
1108130812Smarcel
1109130812Smarcel/* Cause INF to continue execution immediately; individual threads may still
1110130812Smarcel   be suspended (but their suspend counts will be updated).  */
1111130812Smarcelvoid
1112130812Smarcelinf_resume (struct inf *inf)
1113130812Smarcel{
1114130812Smarcel  struct proc *thread;
1115130812Smarcel
1116130812Smarcel  inf_update_procs (inf);
1117130812Smarcel
1118130812Smarcel  for (thread = inf->threads; thread; thread = thread->next)
1119130812Smarcel    thread->sc = thread->resume_sc;
1120130812Smarcel
1121130812Smarcel  if (inf->task)
1122130812Smarcel    {
1123130812Smarcel      if (!inf->pending_execs)
1124130812Smarcel	/* Try to make sure our task count is correct -- in the case where
1125130812Smarcel	   we're waiting for an exec though, things are too volatile, so just
1126130812Smarcel	   assume things will be reasonable (which they usually will be).  */
1127130812Smarcel	inf_validate_task_sc (inf);
1128130812Smarcel      inf->task->sc = 0;
1129130812Smarcel    }
1130130812Smarcel
1131130812Smarcel  inf_update_suspends (inf);
1132130812Smarcel}
1133130812Smarcel
1134130812Smarcel/* Cause INF to stop execution immediately; individual threads may still
1135130812Smarcel   be running.  */
1136130812Smarcelvoid
1137130812Smarcelinf_suspend (struct inf *inf)
1138130812Smarcel{
1139130812Smarcel  struct proc *thread;
1140130812Smarcel
1141130812Smarcel  inf_update_procs (inf);
1142130812Smarcel
1143130812Smarcel  for (thread = inf->threads; thread; thread = thread->next)
1144130812Smarcel    thread->sc = thread->pause_sc;
1145130812Smarcel
1146130812Smarcel  if (inf->task)
1147130812Smarcel    inf->task->sc = inf->pause_sc;
1148130812Smarcel
1149130812Smarcel  inf_update_suspends (inf);
1150130812Smarcel}
1151130812Smarcel
1152130812Smarcel
1153130812Smarcel/* INF has one thread PROC that is in single-stepping mode.  This
1154130812Smarcel   function changes it to be PROC, changing any old step_thread to be
1155130812Smarcel   a normal one.  A PROC of 0 clears any existing value.  */
1156130812Smarcelvoid
1157130812Smarcelinf_set_step_thread (struct inf *inf, struct proc *thread)
1158130812Smarcel{
1159130812Smarcel  gdb_assert (!thread || proc_is_thread (thread));
1160130812Smarcel
1161130812Smarcel  if (thread)
1162130812Smarcel    inf_debug (inf, "setting step thread: %d/%d", inf->pid, thread->tid);
1163130812Smarcel  else
1164130812Smarcel    inf_debug (inf, "clearing step thread");
1165130812Smarcel
1166130812Smarcel  if (inf->step_thread != thread)
1167130812Smarcel    {
1168130812Smarcel      if (inf->step_thread && inf->step_thread->port != MACH_PORT_NULL)
1169130812Smarcel	if (!proc_trace (inf->step_thread, 0))
1170130812Smarcel	  return;
1171130812Smarcel      if (thread && proc_trace (thread, 1))
1172130812Smarcel	inf->step_thread = thread;
1173130812Smarcel      else
1174130812Smarcel	inf->step_thread = 0;
1175130812Smarcel    }
1176130812Smarcel}
1177130812Smarcel
1178130812Smarcel
1179130812Smarcel/* Set up the thread resume_sc's so that only the signal thread is running
1180130812Smarcel   (plus whatever other thread are set to always run).  Returns true if we
1181130812Smarcel   did so, or false if we can't find a signal thread.  */
1182130812Smarcelint
1183130812Smarcelinf_set_threads_resume_sc_for_signal_thread (struct inf *inf)
1184130812Smarcel{
1185130812Smarcel  if (inf->signal_thread)
1186130812Smarcel    {
1187130812Smarcel      inf_set_threads_resume_sc (inf, inf->signal_thread, 0);
1188130812Smarcel      return 1;
1189130812Smarcel    }
1190130812Smarcel  else
1191130812Smarcel    return 0;
1192130812Smarcel}
1193130812Smarcel
1194130812Smarcelstatic void
1195130812Smarcelinf_update_signal_thread (struct inf *inf)
1196130812Smarcel{
1197130812Smarcel  /* XXX for now we assume that if there's a msgport, the 2nd thread is
1198130812Smarcel     the signal thread.  */
1199130812Smarcel  inf->signal_thread = inf->threads ? inf->threads->next : 0;
1200130812Smarcel}
1201130812Smarcel
1202130812Smarcel
1203130812Smarcel/* Detachs from INF's inferior task, letting it run once again...  */
1204130812Smarcelvoid
1205130812Smarcelinf_detach (struct inf *inf)
1206130812Smarcel{
1207130812Smarcel  struct proc *task = inf->task;
1208130812Smarcel
1209130812Smarcel  inf_debug (inf, "detaching...");
1210130812Smarcel
1211130812Smarcel  inf_clear_wait (inf);
1212130812Smarcel  inf_set_step_thread (inf, 0);
1213130812Smarcel
1214130812Smarcel  if (task)
1215130812Smarcel    {
1216130812Smarcel      struct proc *thread;
1217130812Smarcel
1218130812Smarcel      inf_validate_procinfo (inf);
1219130812Smarcel
1220130812Smarcel      inf_set_traced (inf, 0);
1221130812Smarcel      if (inf->stopped)
1222130812Smarcel	{
1223130812Smarcel	  if (inf->nomsg)
1224130812Smarcel	    inf_continue (inf);
1225130812Smarcel	  else
1226130812Smarcel	    inf_signal (inf, TARGET_SIGNAL_0);
1227130812Smarcel	}
1228130812Smarcel
1229130812Smarcel      proc_restore_exc_port (task);
1230130812Smarcel      task->sc = inf->detach_sc;
1231130812Smarcel
1232130812Smarcel      for (thread = inf->threads; thread; thread = thread->next)
1233130812Smarcel	{
1234130812Smarcel	  proc_restore_exc_port (thread);
1235130812Smarcel	  thread->sc = thread->detach_sc;
1236130812Smarcel	}
1237130812Smarcel
1238130812Smarcel      inf_update_suspends (inf);
1239130812Smarcel    }
1240130812Smarcel
1241130812Smarcel  inf_cleanup (inf);
1242130812Smarcel}
1243130812Smarcel
1244130812Smarcel/* Attaches INF to the process with process id PID, returning it in a
1245130812Smarcel   suspended state suitable for debugging.  */
1246130812Smarcelvoid
1247130812Smarcelinf_attach (struct inf *inf, int pid)
1248130812Smarcel{
1249130812Smarcel  inf_debug (inf, "attaching: %d", pid);
1250130812Smarcel
1251130812Smarcel  if (inf->pid)
1252130812Smarcel    inf_detach (inf);
1253130812Smarcel
1254130812Smarcel  inf_startup (inf, pid);
1255130812Smarcel}
1256130812Smarcel
1257130812Smarcel
1258130812Smarcel/* Makes sure that we've got our exception ports entrenched in the process. */
1259130812Smarcelvoid
1260130812Smarcelinf_steal_exc_ports (struct inf *inf)
1261130812Smarcel{
1262130812Smarcel  struct proc *thread;
1263130812Smarcel
1264130812Smarcel  inf_debug (inf, "stealing exception ports");
1265130812Smarcel
1266130812Smarcel  inf_set_step_thread (inf, 0);	/* The step thread is special. */
1267130812Smarcel
1268130812Smarcel  proc_steal_exc_port (inf->task, inf->event_port);
1269130812Smarcel  for (thread = inf->threads; thread; thread = thread->next)
1270130812Smarcel    proc_steal_exc_port (thread, MACH_PORT_NULL);
1271130812Smarcel}
1272130812Smarcel
1273130812Smarcel/* Makes sure the process has its own exception ports.  */
1274130812Smarcelvoid
1275130812Smarcelinf_restore_exc_ports (struct inf *inf)
1276130812Smarcel{
1277130812Smarcel  struct proc *thread;
1278130812Smarcel
1279130812Smarcel  inf_debug (inf, "restoring exception ports");
1280130812Smarcel
1281130812Smarcel  inf_set_step_thread (inf, 0);	/* The step thread is special. */
1282130812Smarcel
1283130812Smarcel  proc_restore_exc_port (inf->task);
1284130812Smarcel  for (thread = inf->threads; thread; thread = thread->next)
1285130812Smarcel    proc_restore_exc_port (thread);
1286130812Smarcel}
1287130812Smarcel
1288130812Smarcel
1289130812Smarcel/* Deliver signal SIG to INF.  If INF is stopped, delivering a signal, even
1290130812Smarcel   signal 0, will continue it.  INF is assumed to be in a paused state, and
1291130812Smarcel   the resume_sc's of INF's threads may be affected.  */
1292130812Smarcelvoid
1293130812Smarcelinf_signal (struct inf *inf, enum target_signal sig)
1294130812Smarcel{
1295130812Smarcel  error_t err = 0;
1296130812Smarcel  int host_sig = target_signal_to_host (sig);
1297130812Smarcel
1298130812Smarcel#define NAME target_signal_to_name (sig)
1299130812Smarcel
1300130812Smarcel  if (host_sig >= _NSIG)
1301130812Smarcel    /* A mach exception.  Exceptions are encoded in the signal space by
1302130812Smarcel       putting them after _NSIG; this assumes they're positive (and not
1303130812Smarcel       extremely large)!  */
1304130812Smarcel    {
1305130812Smarcel      struct inf_wait *w = &inf->wait;
1306130812Smarcel      if (w->status.kind == TARGET_WAITKIND_STOPPED
1307130812Smarcel	  && w->status.value.sig == sig
1308130812Smarcel	  && w->thread && !w->thread->aborted)
1309130812Smarcel	/* We're passing through the last exception we received.  This is
1310130812Smarcel	   kind of bogus, because exceptions are per-thread whereas gdb
1311130812Smarcel	   treats signals as per-process.  We just forward the exception to
1312130812Smarcel	   the correct handler, even it's not for the same thread as TID --
1313130812Smarcel	   i.e., we pretend it's global.  */
1314130812Smarcel	{
1315130812Smarcel	  struct exc_state *e = &w->exc;
1316130812Smarcel	  inf_debug (inf, "passing through exception:"
1317130812Smarcel		     " task = %d, thread = %d, exc = %d"
1318130812Smarcel		     ", code = %d, subcode = %d",
1319130812Smarcel		     w->thread->port, inf->task->port,
1320130812Smarcel		     e->exception, e->code, e->subcode);
1321130812Smarcel	  err =
1322130812Smarcel	    exception_raise_request (e->handler,
1323130812Smarcel				     e->reply, MACH_MSG_TYPE_MOVE_SEND_ONCE,
1324130812Smarcel				     w->thread->port, inf->task->port,
1325130812Smarcel				     e->exception, e->code, e->subcode);
1326130812Smarcel	}
1327130812Smarcel      else
1328130812Smarcel	error ("Can't forward spontaneous exception (%s).", NAME);
1329130812Smarcel    }
1330130812Smarcel  else
1331130812Smarcel    /* A Unix signal.  */
1332130812Smarcel  if (inf->stopped)
1333130812Smarcel    /* The process is stopped and expecting a signal.  Just send off a
1334130812Smarcel       request and let it get handled when we resume everything.  */
1335130812Smarcel    {
1336130812Smarcel      inf_debug (inf, "sending %s to stopped process", NAME);
1337130812Smarcel      err =
1338130812Smarcel	INF_MSGPORT_RPC (inf,
1339130812Smarcel			 msg_sig_post_untraced_request (msgport,
1340130812Smarcel							inf->event_port,
1341130812Smarcel					       MACH_MSG_TYPE_MAKE_SEND_ONCE,
1342130812Smarcel							host_sig, 0,
1343130812Smarcel							refport));
1344130812Smarcel      if (!err)
1345130812Smarcel	/* Posting an untraced signal automatically continues it.
1346130812Smarcel	   We clear this here rather than when we get the reply
1347130812Smarcel	   because we'd rather assume it's not stopped when it
1348130812Smarcel	   actually is, than the reverse.  */
1349130812Smarcel	inf->stopped = 0;
1350130812Smarcel    }
1351130812Smarcel  else
1352130812Smarcel    /* It's not expecting it.  We have to let just the signal thread
1353130812Smarcel       run, and wait for it to get into a reasonable state before we
1354130812Smarcel       can continue the rest of the process.  When we finally resume the
1355130812Smarcel       process the signal we request will be the very first thing that
1356130812Smarcel       happens. */
1357130812Smarcel    {
1358130812Smarcel      inf_debug (inf, "sending %s to unstopped process"
1359130812Smarcel		 " (so resuming signal thread)", NAME);
1360130812Smarcel      err =
1361130812Smarcel	INF_RESUME_MSGPORT_RPC (inf,
1362130812Smarcel				msg_sig_post_untraced (msgport, host_sig,
1363130812Smarcel						       0, refport));
1364130812Smarcel    }
1365130812Smarcel
1366130812Smarcel  if (err == EIEIO)
1367130812Smarcel    /* Can't do too much... */
1368130812Smarcel    warning ("Can't deliver signal %s: No signal thread.", NAME);
1369130812Smarcel  else if (err)
1370130812Smarcel    warning ("Delivering signal %s: %s", NAME, safe_strerror (err));
1371130812Smarcel
1372130812Smarcel#undef NAME
1373130812Smarcel}
1374130812Smarcel
1375130812Smarcel
1376130812Smarcel/* Continue INF without delivering a signal.  This is meant to be used
1377130812Smarcel   when INF does not have a message port.  */
1378130812Smarcelvoid
1379130812Smarcelinf_continue (struct inf *inf)
1380130812Smarcel{
1381130812Smarcel  process_t proc;
1382130812Smarcel  error_t err = proc_pid2proc (proc_server, inf->pid, &proc);
1383130812Smarcel
1384130812Smarcel  if (!err)
1385130812Smarcel    {
1386130812Smarcel      inf_debug (inf, "continuing process");
1387130812Smarcel
1388130812Smarcel      err = proc_mark_cont (proc);
1389130812Smarcel      if (!err)
1390130812Smarcel	{
1391130812Smarcel	  struct proc *thread;
1392130812Smarcel
1393130812Smarcel	  for (thread = inf->threads; thread; thread = thread->next)
1394130812Smarcel	    thread_resume (thread->port);
1395130812Smarcel
1396130812Smarcel	  inf->stopped = 0;
1397130812Smarcel	}
1398130812Smarcel    }
1399130812Smarcel
1400130812Smarcel  if (err)
1401130812Smarcel    warning ("Can't continue process: %s", safe_strerror (err));
1402130812Smarcel}
1403130812Smarcel
1404130812Smarcel
1405130812Smarcel/* The inferior used for all gdb target ops.  */
1406130812Smarcelstruct inf *current_inferior = 0;
1407130812Smarcel
1408130812Smarcel/* The inferior being waited for by gnu_wait.  Since GDB is decidely not
1409130812Smarcel   multi-threaded, we don't bother to lock this.  */
1410130812Smarcelstruct inf *waiting_inf;
1411130812Smarcel
1412130812Smarcel/* Wait for something to happen in the inferior, returning what in STATUS. */
1413130812Smarcelstatic ptid_t
1414130812Smarcelgnu_wait (ptid_t tid, struct target_waitstatus *status)
1415130812Smarcel{
1416130812Smarcel  struct msg
1417130812Smarcel    {
1418130812Smarcel      mach_msg_header_t hdr;
1419130812Smarcel      mach_msg_type_t type;
1420130812Smarcel      int data[8000];
1421130812Smarcel    } msg;
1422130812Smarcel  error_t err;
1423130812Smarcel  struct proc *thread;
1424130812Smarcel  struct inf *inf = current_inferior;
1425130812Smarcel
1426130812Smarcel  extern int exc_server (mach_msg_header_t *, mach_msg_header_t *);
1427130812Smarcel  extern int msg_reply_server (mach_msg_header_t *, mach_msg_header_t *);
1428130812Smarcel  extern int notify_server (mach_msg_header_t *, mach_msg_header_t *);
1429130812Smarcel  extern int process_reply_server (mach_msg_header_t *, mach_msg_header_t *);
1430130812Smarcel
1431130812Smarcel  gdb_assert (inf->task);
1432130812Smarcel
1433130812Smarcel  if (!inf->threads && !inf->pending_execs)
1434130812Smarcel    /* No threads!  Assume that maybe some outside agency is frobbing our
1435130812Smarcel       task, and really look for new threads.  If we can't find any, just tell
1436130812Smarcel       the user to try again later.  */
1437130812Smarcel    {
1438130812Smarcel      inf_validate_procs (inf);
1439130812Smarcel      if (!inf->threads && !inf->task->dead)
1440130812Smarcel	error ("There are no threads; try again later.");
1441130812Smarcel    }
1442130812Smarcel
1443130812Smarcel  waiting_inf = inf;
1444130812Smarcel
1445130812Smarcel  inf_debug (inf, "waiting for: %d", PIDGET (tid));
1446130812Smarcel
1447130812Smarcelrewait:
1448130812Smarcel  if (proc_wait_pid != inf->pid && !inf->no_wait)
1449130812Smarcel    /* Always get information on events from the proc server.  */
1450130812Smarcel    {
1451130812Smarcel      inf_debug (inf, "requesting wait on pid %d", inf->pid);
1452130812Smarcel
1453130812Smarcel      if (proc_wait_pid)
1454130812Smarcel	/* The proc server is single-threaded, and only allows a single
1455130812Smarcel	   outstanding wait request, so we have to cancel the previous one. */
1456130812Smarcel	{
1457130812Smarcel	  inf_debug (inf, "cancelling previous wait on pid %d", proc_wait_pid);
1458130812Smarcel	  interrupt_operation (proc_server, 0);
1459130812Smarcel	}
1460130812Smarcel
1461130812Smarcel      err =
1462130812Smarcel	proc_wait_request (proc_server, inf->event_port, inf->pid, WUNTRACED);
1463130812Smarcel      if (err)
1464130812Smarcel	warning ("wait request failed: %s", safe_strerror (err));
1465130812Smarcel      else
1466130812Smarcel	{
1467130812Smarcel	  inf_debug (inf, "waits pending: %d", proc_waits_pending);
1468130812Smarcel	  proc_wait_pid = inf->pid;
1469130812Smarcel	  /* Even if proc_waits_pending was > 0 before, we still won't
1470130812Smarcel	     get any other replies, because it was either from a
1471130812Smarcel	     different INF, or a different process attached to INF --
1472130812Smarcel	     and the event port, which is the wait reply port, changes
1473130812Smarcel	     when you switch processes. */
1474130812Smarcel	  proc_waits_pending = 1;
1475130812Smarcel	}
1476130812Smarcel    }
1477130812Smarcel
1478130812Smarcel  inf_clear_wait (inf);
1479130812Smarcel
1480130812Smarcel  /* What can happen? (1) Dead name notification; (2) Exceptions arrive;
1481130812Smarcel     (3) wait reply from the proc server.  */
1482130812Smarcel
1483130812Smarcel  inf_debug (inf, "waiting for an event...");
1484130812Smarcel  err = mach_msg (&msg.hdr, MACH_RCV_MSG | MACH_RCV_INTERRUPT,
1485130812Smarcel		  0, sizeof (struct msg), inf->event_port,
1486130812Smarcel		  MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
1487130812Smarcel
1488130812Smarcel  /* Re-suspend the task.  */
1489130812Smarcel  inf_suspend (inf);
1490130812Smarcel
1491130812Smarcel  if (!inf->task && inf->pending_execs)
1492130812Smarcel    /* When doing an exec, it's possible that the old task wasn't reused
1493130812Smarcel       (e.g., setuid execs).  So if the task seems to have disappeared,
1494130812Smarcel       attempt to refetch it, as the pid should still be the same.  */
1495130812Smarcel    inf_set_pid (inf, inf->pid);
1496130812Smarcel
1497130812Smarcel  if (err == EMACH_RCV_INTERRUPTED)
1498130812Smarcel    inf_debug (inf, "interrupted");
1499130812Smarcel  else if (err)
1500130812Smarcel    error ("Couldn't wait for an event: %s", safe_strerror (err));
1501130812Smarcel  else
1502130812Smarcel    {
1503130812Smarcel      struct
1504130812Smarcel	{
1505130812Smarcel	  mach_msg_header_t hdr;
1506130812Smarcel	  mach_msg_type_t err_type;
1507130812Smarcel	  kern_return_t err;
1508130812Smarcel	  char noise[200];
1509130812Smarcel	}
1510130812Smarcel      reply;
1511130812Smarcel
1512130812Smarcel      inf_debug (inf, "event: msgid = %d", msg.hdr.msgh_id);
1513130812Smarcel
1514130812Smarcel      /* Handle what we got.  */
1515130812Smarcel      if (!notify_server (&msg.hdr, &reply.hdr)
1516130812Smarcel	  && !exc_server (&msg.hdr, &reply.hdr)
1517130812Smarcel	  && !process_reply_server (&msg.hdr, &reply.hdr)
1518130812Smarcel	  && !msg_reply_server (&msg.hdr, &reply.hdr))
1519130812Smarcel	/* Whatever it is, it's something strange.  */
1520130812Smarcel	error ("Got a strange event, msg id = %d.", msg.hdr.msgh_id);
1521130812Smarcel
1522130812Smarcel      if (reply.err)
1523130812Smarcel	error ("Handling event, msgid = %d: %s",
1524130812Smarcel	       msg.hdr.msgh_id, safe_strerror (reply.err));
1525130812Smarcel    }
1526130812Smarcel
1527130812Smarcel  if (inf->pending_execs)
1528130812Smarcel    /* We're waiting for the inferior to finish execing.  */
1529130812Smarcel    {
1530130812Smarcel      struct inf_wait *w = &inf->wait;
1531130812Smarcel      enum target_waitkind kind = w->status.kind;
1532130812Smarcel
1533130812Smarcel      if (kind == TARGET_WAITKIND_SPURIOUS)
1534130812Smarcel	/* Since gdb is actually counting the number of times the inferior
1535130812Smarcel	   stops, expecting one stop per exec, we only return major events
1536130812Smarcel	   while execing.  */
1537130812Smarcel	{
1538130812Smarcel	  w->suppress = 1;
1539130812Smarcel	  inf_debug (inf, "pending_execs = %d, ignoring minor event",
1540130812Smarcel		     inf->pending_execs);
1541130812Smarcel	}
1542130812Smarcel      else if (kind == TARGET_WAITKIND_STOPPED
1543130812Smarcel	       && w->status.value.sig == TARGET_SIGNAL_TRAP)
1544130812Smarcel	/* Ah hah!  A SIGTRAP from the inferior while starting up probably
1545130812Smarcel	   means we've succesfully completed an exec!  */
1546130812Smarcel	{
1547130812Smarcel	  if (--inf->pending_execs == 0)
1548130812Smarcel	    /* We're done!  */
1549130812Smarcel	    {
1550130812Smarcel#if 0				/* do we need this? */
1551130812Smarcel	      prune_threads (1);	/* Get rid of the old shell threads */
1552130812Smarcel	      renumber_threads (0);	/* Give our threads reasonable names. */
1553130812Smarcel#endif
1554130812Smarcel	    }
1555130812Smarcel	  inf_debug (inf, "pending exec completed, pending_execs => %d",
1556130812Smarcel		     inf->pending_execs);
1557130812Smarcel	}
1558130812Smarcel      else if (kind == TARGET_WAITKIND_STOPPED)
1559130812Smarcel	/* It's possible that this signal is because of a crashed process
1560130812Smarcel	   being handled by the hurd crash server; in this case, the process
1561130812Smarcel	   will have an extra task suspend, which we need to know about.
1562130812Smarcel	   Since the code in inf_resume that normally checks for this is
1563130812Smarcel	   disabled while INF->pending_execs, we do the check here instead.  */
1564130812Smarcel	inf_validate_task_sc (inf);
1565130812Smarcel    }
1566130812Smarcel
1567130812Smarcel  if (inf->wait.suppress)
1568130812Smarcel    /* Some totally spurious event happened that we don't consider
1569130812Smarcel       worth returning to gdb.  Just keep waiting.  */
1570130812Smarcel    {
1571130812Smarcel      inf_debug (inf, "suppressing return, rewaiting...");
1572130812Smarcel      inf_resume (inf);
1573130812Smarcel      goto rewait;
1574130812Smarcel    }
1575130812Smarcel
1576130812Smarcel  /* Pass back out our results.  */
1577130812Smarcel  bcopy (&inf->wait.status, status, sizeof (*status));
1578130812Smarcel
1579130812Smarcel  thread = inf->wait.thread;
1580130812Smarcel  if (thread)
1581130812Smarcel    tid = pid_to_ptid (thread->tid);
1582130812Smarcel  else
1583130812Smarcel    thread = inf_tid_to_thread (inf, PIDGET (tid));
1584130812Smarcel
1585130812Smarcel  if (!thread || thread->port == MACH_PORT_NULL)
1586130812Smarcel    {
1587130812Smarcel      /* TID is dead; try and find a new thread.  */
1588130812Smarcel      if (inf_update_procs (inf) && inf->threads)
1589130812Smarcel	tid = pid_to_ptid (inf->threads->tid); /* The first available thread.  */
1590130812Smarcel      else
1591130812Smarcel	tid = inferior_ptid;	/* let wait_for_inferior handle exit case */
1592130812Smarcel    }
1593130812Smarcel
1594130812Smarcel  if (thread && PIDGET (tid) >= 0 && status->kind != TARGET_WAITKIND_SPURIOUS
1595130812Smarcel      && inf->pause_sc == 0 && thread->pause_sc == 0)
1596130812Smarcel    /* If something actually happened to THREAD, make sure we
1597130812Smarcel       suspend it.  */
1598130812Smarcel    {
1599130812Smarcel      thread->sc = 1;
1600130812Smarcel      inf_update_suspends (inf);
1601130812Smarcel    }
1602130812Smarcel
1603130812Smarcel  inf_debug (inf, "returning tid = %d, status = %s (%d)", PIDGET (tid),
1604130812Smarcel	     status->kind == TARGET_WAITKIND_EXITED ? "EXITED"
1605130812Smarcel	     : status->kind == TARGET_WAITKIND_STOPPED ? "STOPPED"
1606130812Smarcel	     : status->kind == TARGET_WAITKIND_SIGNALLED ? "SIGNALLED"
1607130812Smarcel	     : status->kind == TARGET_WAITKIND_LOADED ? "LOADED"
1608130812Smarcel	     : status->kind == TARGET_WAITKIND_SPURIOUS ? "SPURIOUS"
1609130812Smarcel	     : "?",
1610130812Smarcel	     status->value.integer);
1611130812Smarcel
1612130812Smarcel  return tid;
1613130812Smarcel}
1614130812Smarcel
1615130812Smarcel
1616130812Smarcel/* The rpc handler called by exc_server.  */
1617130812Smarcelerror_t
1618130812SmarcelS_exception_raise_request (mach_port_t port, mach_port_t reply_port,
1619130812Smarcel			   thread_t thread_port, task_t task_port,
1620130812Smarcel			   int exception, int code, int subcode)
1621130812Smarcel{
1622130812Smarcel  struct inf *inf = waiting_inf;
1623130812Smarcel  struct proc *thread = inf_port_to_thread (inf, thread_port);
1624130812Smarcel
1625130812Smarcel  inf_debug (waiting_inf,
1626130812Smarcel	     "thread = %d, task = %d, exc = %d, code = %d, subcode = %d",
1627130812Smarcel	     thread_port, task_port, exception, code, subcode);
1628130812Smarcel
1629130812Smarcel  if (!thread)
1630130812Smarcel    /* We don't know about thread?  */
1631130812Smarcel    {
1632130812Smarcel      inf_update_procs (inf);
1633130812Smarcel      thread = inf_port_to_thread (inf, thread_port);
1634130812Smarcel      if (!thread)
1635130812Smarcel	/* Give up, the generating thread is gone.  */
1636130812Smarcel	return 0;
1637130812Smarcel    }
1638130812Smarcel
1639130812Smarcel  mach_port_deallocate (mach_task_self (), thread_port);
1640130812Smarcel  mach_port_deallocate (mach_task_self (), task_port);
1641130812Smarcel
1642130812Smarcel  if (!thread->aborted)
1643130812Smarcel    /* THREAD hasn't been aborted since this exception happened (abortion
1644130812Smarcel       clears any exception state), so it must be real.  */
1645130812Smarcel    {
1646130812Smarcel      /* Store away the details; this will destroy any previous info.  */
1647130812Smarcel      inf->wait.thread = thread;
1648130812Smarcel
1649130812Smarcel      inf->wait.status.kind = TARGET_WAITKIND_STOPPED;
1650130812Smarcel
1651130812Smarcel      if (exception == EXC_BREAKPOINT)
1652130812Smarcel	/* GDB likes to get SIGTRAP for breakpoints.  */
1653130812Smarcel	{
1654130812Smarcel	  inf->wait.status.value.sig = TARGET_SIGNAL_TRAP;
1655130812Smarcel	  mach_port_deallocate (mach_task_self (), reply_port);
1656130812Smarcel	}
1657130812Smarcel      else
1658130812Smarcel	/* Record the exception so that we can forward it later.  */
1659130812Smarcel	{
1660130812Smarcel	  if (thread->exc_port == port)
1661130812Smarcel	    {
1662130812Smarcel	      inf_debug (waiting_inf, "Handler is thread exception port <%d>",
1663130812Smarcel			 thread->saved_exc_port);
1664130812Smarcel	      inf->wait.exc.handler = thread->saved_exc_port;
1665130812Smarcel	    }
1666130812Smarcel	  else
1667130812Smarcel	    {
1668130812Smarcel	      inf_debug (waiting_inf, "Handler is task exception port <%d>",
1669130812Smarcel			 inf->task->saved_exc_port);
1670130812Smarcel	      inf->wait.exc.handler = inf->task->saved_exc_port;
1671130812Smarcel	      gdb_assert (inf->task->exc_port == port);
1672130812Smarcel	    }
1673130812Smarcel	  if (inf->wait.exc.handler != MACH_PORT_NULL)
1674130812Smarcel	    /* Add a reference to the exception handler. */
1675130812Smarcel	    mach_port_mod_refs (mach_task_self (),
1676130812Smarcel				inf->wait.exc.handler, MACH_PORT_RIGHT_SEND,
1677130812Smarcel				1);
1678130812Smarcel
1679130812Smarcel	  inf->wait.exc.exception = exception;
1680130812Smarcel	  inf->wait.exc.code = code;
1681130812Smarcel	  inf->wait.exc.subcode = subcode;
1682130812Smarcel	  inf->wait.exc.reply = reply_port;
1683130812Smarcel
1684130812Smarcel	  /* Exceptions are encoded in the signal space by putting them after
1685130812Smarcel	     _NSIG; this assumes they're positive (and not extremely large)! */
1686130812Smarcel	  inf->wait.status.value.sig =
1687130812Smarcel	    target_signal_from_host (_NSIG + exception);
1688130812Smarcel	}
1689130812Smarcel    }
1690130812Smarcel  else
1691130812Smarcel    /* A supppressed exception, which ignore.  */
1692130812Smarcel    {
1693130812Smarcel      inf->wait.suppress = 1;
1694130812Smarcel      mach_port_deallocate (mach_task_self (), reply_port);
1695130812Smarcel    }
1696130812Smarcel
1697130812Smarcel  return 0;
1698130812Smarcel}
1699130812Smarcel
1700130812Smarcel
1701130812Smarcel/* Fill in INF's wait field after a task has died without giving us more
1702130812Smarcel   detailed information.  */
1703130812Smarcelvoid
1704130812Smarcelinf_task_died_status (struct inf *inf)
1705130812Smarcel{
1706130812Smarcel  warning ("Pid %d died with unknown exit status, using SIGKILL.", inf->pid);
1707130812Smarcel  inf->wait.status.kind = TARGET_WAITKIND_SIGNALLED;
1708130812Smarcel  inf->wait.status.value.sig = TARGET_SIGNAL_KILL;
1709130812Smarcel}
1710130812Smarcel
1711130812Smarcel/* Notify server routines.  The only real one is dead name notification.  */
1712130812Smarcelerror_t
1713130812Smarceldo_mach_notify_dead_name (mach_port_t notify, mach_port_t dead_port)
1714130812Smarcel{
1715130812Smarcel  struct inf *inf = waiting_inf;
1716130812Smarcel
1717130812Smarcel  inf_debug (waiting_inf, "port = %d", dead_port);
1718130812Smarcel
1719130812Smarcel  if (inf->task && inf->task->port == dead_port)
1720130812Smarcel    {
1721130812Smarcel      proc_debug (inf->task, "is dead");
1722130812Smarcel      inf->task->port = MACH_PORT_NULL;
1723130812Smarcel      if (proc_wait_pid == inf->pid)
1724130812Smarcel	/* We have a wait outstanding on the process, which will return more
1725130812Smarcel	   detailed information, so delay until we get that.  */
1726130812Smarcel	inf->wait.suppress = 1;
1727130812Smarcel      else
1728130812Smarcel	/* We never waited for the process (maybe it wasn't a child), so just
1729130812Smarcel	   pretend it got a SIGKILL.  */
1730130812Smarcel	inf_task_died_status (inf);
1731130812Smarcel    }
1732130812Smarcel  else
1733130812Smarcel    {
1734130812Smarcel      struct proc *thread = inf_port_to_thread (inf, dead_port);
1735130812Smarcel      if (thread)
1736130812Smarcel	{
1737130812Smarcel	  proc_debug (thread, "is dead");
1738130812Smarcel	  thread->port = MACH_PORT_NULL;
1739130812Smarcel	}
1740130812Smarcel
1741130812Smarcel      if (inf->task->dead)
1742130812Smarcel	/* Since the task is dead, its threads are dying with it.  */
1743130812Smarcel	inf->wait.suppress = 1;
1744130812Smarcel    }
1745130812Smarcel
1746130812Smarcel  mach_port_deallocate (mach_task_self (), dead_port);
1747130812Smarcel  inf->threads_up_to_date = 0;	/* Just in case */
1748130812Smarcel
1749130812Smarcel  return 0;
1750130812Smarcel}
1751130812Smarcel
1752130812Smarcel
1753130812Smarcelstatic error_t
1754130812Smarcelill_rpc (char *fun)
1755130812Smarcel{
1756130812Smarcel  warning ("illegal rpc: %s", fun);
1757130812Smarcel  return 0;
1758130812Smarcel}
1759130812Smarcel
1760130812Smarcelerror_t
1761130812Smarceldo_mach_notify_no_senders (mach_port_t notify, mach_port_mscount_t count)
1762130812Smarcel{
1763130812Smarcel  return ill_rpc ("do_mach_notify_no_senders");
1764130812Smarcel}
1765130812Smarcel
1766130812Smarcelerror_t
1767130812Smarceldo_mach_notify_port_deleted (mach_port_t notify, mach_port_t name)
1768130812Smarcel{
1769130812Smarcel  return ill_rpc ("do_mach_notify_port_deleted");
1770130812Smarcel}
1771130812Smarcel
1772130812Smarcelerror_t
1773130812Smarceldo_mach_notify_msg_accepted (mach_port_t notify, mach_port_t name)
1774130812Smarcel{
1775130812Smarcel  return ill_rpc ("do_mach_notify_msg_accepted");
1776130812Smarcel}
1777130812Smarcel
1778130812Smarcelerror_t
1779130812Smarceldo_mach_notify_port_destroyed (mach_port_t notify, mach_port_t name)
1780130812Smarcel{
1781130812Smarcel  return ill_rpc ("do_mach_notify_port_destroyed");
1782130812Smarcel}
1783130812Smarcel
1784130812Smarcelerror_t
1785130812Smarceldo_mach_notify_send_once (mach_port_t notify)
1786130812Smarcel{
1787130812Smarcel  return ill_rpc ("do_mach_notify_send_once");
1788130812Smarcel}
1789130812Smarcel
1790130812Smarcel
1791130812Smarcel/* Process_reply server routines.  We only use process_wait_reply.  */
1792130812Smarcel
1793130812Smarcelerror_t
1794130812SmarcelS_proc_wait_reply (mach_port_t reply, error_t err,
1795130812Smarcel		   int status, int sigcode, rusage_t rusage, pid_t pid)
1796130812Smarcel{
1797130812Smarcel  struct inf *inf = waiting_inf;
1798130812Smarcel
1799130812Smarcel  inf_debug (inf, "err = %s, pid = %d, status = 0x%x, sigcode = %d",
1800130812Smarcel	     err ? safe_strerror (err) : "0", pid, status, sigcode);
1801130812Smarcel
1802130812Smarcel  if (err && proc_wait_pid && (!inf->task || !inf->task->port))
1803130812Smarcel    /* Ack.  The task has died, but the task-died notification code didn't
1804130812Smarcel       tell anyone because it thought a more detailed reply from the
1805130812Smarcel       procserver was forthcoming.  However, we now learn that won't
1806130812Smarcel       happen...  So we have to act like the task just died, and this time,
1807130812Smarcel       tell the world.  */
1808130812Smarcel    inf_task_died_status (inf);
1809130812Smarcel
1810130812Smarcel  if (--proc_waits_pending == 0)
1811130812Smarcel    /* PROC_WAIT_PID represents the most recent wait.  We will always get
1812130812Smarcel       replies in order because the proc server is single threaded.  */
1813130812Smarcel    proc_wait_pid = 0;
1814130812Smarcel
1815130812Smarcel  inf_debug (inf, "waits pending now: %d", proc_waits_pending);
1816130812Smarcel
1817130812Smarcel  if (err)
1818130812Smarcel    {
1819130812Smarcel      if (err != EINTR)
1820130812Smarcel	{
1821130812Smarcel	  warning ("Can't wait for pid %d: %s", inf->pid, safe_strerror (err));
1822130812Smarcel	  inf->no_wait = 1;
1823130812Smarcel
1824130812Smarcel	  /* Since we can't see the inferior's signals, don't trap them.  */
1825130812Smarcel	  inf_set_traced (inf, 0);
1826130812Smarcel	}
1827130812Smarcel    }
1828130812Smarcel  else if (pid == inf->pid)
1829130812Smarcel    {
1830130812Smarcel      store_waitstatus (&inf->wait.status, status);
1831130812Smarcel      if (inf->wait.status.kind == TARGET_WAITKIND_STOPPED)
1832130812Smarcel	/* The process has sent us a signal, and stopped itself in a sane
1833130812Smarcel	   state pending our actions.  */
1834130812Smarcel	{
1835130812Smarcel	  inf_debug (inf, "process has stopped itself");
1836130812Smarcel	  inf->stopped = 1;
1837130812Smarcel	}
1838130812Smarcel    }
1839130812Smarcel  else
1840130812Smarcel    inf->wait.suppress = 1;	/* Something odd happened.  Ignore.  */
1841130812Smarcel
1842130812Smarcel  return 0;
1843130812Smarcel}
1844130812Smarcel
1845130812Smarcelerror_t
1846130812SmarcelS_proc_setmsgport_reply (mach_port_t reply, error_t err,
1847130812Smarcel			 mach_port_t old_msg_port)
1848130812Smarcel{
1849130812Smarcel  return ill_rpc ("S_proc_setmsgport_reply");
1850130812Smarcel}
1851130812Smarcel
1852130812Smarcelerror_t
1853130812SmarcelS_proc_getmsgport_reply (mach_port_t reply, error_t err, mach_port_t msg_port)
1854130812Smarcel{
1855130812Smarcel  return ill_rpc ("S_proc_getmsgport_reply");
1856130812Smarcel}
1857130812Smarcel
1858130812Smarcel
1859130812Smarcel/* Msg_reply server routines.  We only use msg_sig_post_untraced_reply.  */
1860130812Smarcel
1861130812Smarcelerror_t
1862130812SmarcelS_msg_sig_post_untraced_reply (mach_port_t reply, error_t err)
1863130812Smarcel{
1864130812Smarcel  struct inf *inf = waiting_inf;
1865130812Smarcel
1866130812Smarcel  if (err == EBUSY)
1867130812Smarcel    /* EBUSY is what we get when the crash server has grabbed control of the
1868130812Smarcel       process and doesn't like what signal we tried to send it.  Just act
1869130812Smarcel       like the process stopped (using a signal of 0 should mean that the
1870130812Smarcel       *next* time the user continues, it will pass signal 0, which the crash
1871130812Smarcel       server should like).  */
1872130812Smarcel    {
1873130812Smarcel      inf->wait.status.kind = TARGET_WAITKIND_STOPPED;
1874130812Smarcel      inf->wait.status.value.sig = TARGET_SIGNAL_0;
1875130812Smarcel    }
1876130812Smarcel  else if (err)
1877130812Smarcel    warning ("Signal delivery failed: %s", safe_strerror (err));
1878130812Smarcel
1879130812Smarcel  if (err)
1880130812Smarcel    /* We only get this reply when we've posted a signal to a process which we
1881130812Smarcel       thought was stopped, and which we expected to continue after the signal.
1882130812Smarcel       Given that the signal has failed for some reason, it's reasonable to
1883130812Smarcel       assume it's still stopped.  */
1884130812Smarcel    inf->stopped = 1;
1885130812Smarcel  else
1886130812Smarcel    inf->wait.suppress = 1;
1887130812Smarcel
1888130812Smarcel  return 0;
1889130812Smarcel}
1890130812Smarcel
1891130812Smarcelerror_t
1892130812SmarcelS_msg_sig_post_reply (mach_port_t reply, error_t err)
1893130812Smarcel{
1894130812Smarcel  return ill_rpc ("S_msg_sig_post_reply");
1895130812Smarcel}
1896130812Smarcel
1897130812Smarcel
1898130812Smarcel/* Returns the number of messages queued for the receive right PORT.  */
1899130812Smarcelstatic mach_port_msgcount_t
1900130812Smarcelport_msgs_queued (mach_port_t port)
1901130812Smarcel{
1902130812Smarcel  struct mach_port_status status;
1903130812Smarcel  error_t err =
1904130812Smarcel  mach_port_get_receive_status (mach_task_self (), port, &status);
1905130812Smarcel
1906130812Smarcel  if (err)
1907130812Smarcel    return 0;
1908130812Smarcel  else
1909130812Smarcel    return status.mps_msgcount;
1910130812Smarcel}
1911130812Smarcel
1912130812Smarcel
1913130812Smarcel/* Resume execution of the inferior process.
1914130812Smarcel
1915130812Smarcel   If STEP is nonzero, single-step it.
1916130812Smarcel   If SIGNAL is nonzero, give it that signal.
1917130812Smarcel
1918130812Smarcel   TID  STEP:
1919130812Smarcel   -1   true   Single step the current thread allowing other threads to run.
1920130812Smarcel   -1   false  Continue the current thread allowing other threads to run.
1921130812Smarcel   X    true   Single step the given thread, don't allow any others to run.
1922130812Smarcel   X    false  Continue the given thread, do not allow any others to run.
1923130812Smarcel   (Where X, of course, is anything except -1)
1924130812Smarcel
1925130812Smarcel   Note that a resume may not `take' if there are pending exceptions/&c
1926130812Smarcel   still unprocessed from the last resume we did (any given resume may result
1927130812Smarcel   in multiple events returned by wait).
1928130812Smarcel */
1929130812Smarcelstatic void
1930130812Smarcelgnu_resume (ptid_t tid, int step, enum target_signal sig)
1931130812Smarcel{
1932130812Smarcel  struct proc *step_thread = 0;
1933130812Smarcel  struct inf *inf = current_inferior;
1934130812Smarcel
1935130812Smarcel  inf_debug (inf, "tid = %d, step = %d, sig = %d", PIDGET (tid), step, sig);
1936130812Smarcel
1937130812Smarcel  inf_validate_procinfo (inf);
1938130812Smarcel
1939130812Smarcel  if (sig != TARGET_SIGNAL_0 || inf->stopped)
1940130812Smarcel    {
1941130812Smarcel      if (sig == TARGET_SIGNAL_0 && inf->nomsg)
1942130812Smarcel	inf_continue (inf);
1943130812Smarcel      else
1944130812Smarcel	inf_signal (inf, sig);
1945130812Smarcel    }
1946130812Smarcel  else if (inf->wait.exc.reply != MACH_PORT_NULL)
1947130812Smarcel    /* We received an exception to which we have chosen not to forward, so
1948130812Smarcel       abort the faulting thread, which will perhaps retake it.  */
1949130812Smarcel    {
1950130812Smarcel      proc_abort (inf->wait.thread, 1);
1951130812Smarcel      warning ("Aborting %s with unforwarded exception %s.",
1952130812Smarcel	       proc_string (inf->wait.thread),
1953130812Smarcel	       target_signal_to_name (inf->wait.status.value.sig));
1954130812Smarcel    }
1955130812Smarcel
1956130812Smarcel  if (port_msgs_queued (inf->event_port))
1957130812Smarcel    /* If there are still messages in our event queue, don't bother resuming
1958130812Smarcel       the process, as we're just going to stop it right away anyway. */
1959130812Smarcel    return;
1960130812Smarcel
1961130812Smarcel  inf_update_procs (inf);
1962130812Smarcel
1963130812Smarcel  if (PIDGET (tid) < 0)
1964130812Smarcel    /* Allow all threads to run, except perhaps single-stepping one.  */
1965130812Smarcel    {
1966130812Smarcel      inf_debug (inf, "running all threads; tid = %d", PIDGET (inferior_ptid));
1967130812Smarcel      tid = inferior_ptid;	/* What to step. */
1968130812Smarcel      inf_set_threads_resume_sc (inf, 0, 1);
1969130812Smarcel    }
1970130812Smarcel  else
1971130812Smarcel    /* Just allow a single thread to run.  */
1972130812Smarcel    {
1973130812Smarcel      struct proc *thread = inf_tid_to_thread (inf, PIDGET (tid));
1974130812Smarcel      if (!thread)
1975130812Smarcel	error ("Can't run single thread id %d: no such thread!");
1976130812Smarcel      inf_debug (inf, "running one thread: %d/%d", inf->pid, thread->tid);
1977130812Smarcel      inf_set_threads_resume_sc (inf, thread, 0);
1978130812Smarcel    }
1979130812Smarcel
1980130812Smarcel  if (step)
1981130812Smarcel    {
1982130812Smarcel      step_thread = inf_tid_to_thread (inf, PIDGET (tid));
1983130812Smarcel      if (!step_thread)
1984130812Smarcel	warning ("Can't step thread id %d: no such thread.", PIDGET (tid));
1985130812Smarcel      else
1986130812Smarcel	inf_debug (inf, "stepping thread: %d/%d", inf->pid, step_thread->tid);
1987130812Smarcel    }
1988130812Smarcel  if (step_thread != inf->step_thread)
1989130812Smarcel    inf_set_step_thread (inf, step_thread);
1990130812Smarcel
1991130812Smarcel  inf_debug (inf, "here we go...");
1992130812Smarcel  inf_resume (inf);
1993130812Smarcel}
1994130812Smarcel
1995130812Smarcel
1996130812Smarcelstatic void
1997130812Smarcelgnu_kill_inferior (void)
1998130812Smarcel{
1999130812Smarcel  struct proc *task = current_inferior->task;
2000130812Smarcel  if (task)
2001130812Smarcel    {
2002130812Smarcel      proc_debug (task, "terminating...");
2003130812Smarcel      task_terminate (task->port);
2004130812Smarcel      inf_set_pid (current_inferior, -1);
2005130812Smarcel    }
2006130812Smarcel  target_mourn_inferior ();
2007130812Smarcel}
2008130812Smarcel
2009130812Smarcel/* Clean up after the inferior dies.  */
2010130812Smarcelstatic void
2011130812Smarcelgnu_mourn_inferior (void)
2012130812Smarcel{
2013130812Smarcel  inf_debug (current_inferior, "rip");
2014130812Smarcel  inf_detach (current_inferior);
2015130812Smarcel  unpush_target (&gnu_ops);
2016130812Smarcel  generic_mourn_inferior ();
2017130812Smarcel}
2018130812Smarcel
2019130812Smarcel
2020130812Smarcel/* Fork an inferior process, and start debugging it.  */
2021130812Smarcel
2022130812Smarcel/* Set INFERIOR_PID to the first thread available in the child, if any.  */
2023130812Smarcelstatic int
2024130812Smarcelinf_pick_first_thread (void)
2025130812Smarcel{
2026130812Smarcel  if (current_inferior->task && current_inferior->threads)
2027130812Smarcel    /* The first thread.  */
2028130812Smarcel    return current_inferior->threads->tid;
2029130812Smarcel  else
2030130812Smarcel    /* What may be the next thread.  */
2031130812Smarcel    return next_thread_id;
2032130812Smarcel}
2033130812Smarcel
2034130812Smarcelstatic struct inf *
2035130812Smarcelcur_inf (void)
2036130812Smarcel{
2037130812Smarcel  if (!current_inferior)
2038130812Smarcel    current_inferior = make_inf ();
2039130812Smarcel  return current_inferior;
2040130812Smarcel}
2041130812Smarcel
2042130812Smarcelstatic void
2043130812Smarcelgnu_create_inferior (char *exec_file, char *allargs, char **env)
2044130812Smarcel{
2045130812Smarcel  struct inf *inf = cur_inf ();
2046130812Smarcel
2047130812Smarcel  void trace_me ()
2048130812Smarcel  {
2049130812Smarcel    /* We're in the child; make this process stop as soon as it execs.  */
2050130812Smarcel    inf_debug (inf, "tracing self");
2051130812Smarcel    if (ptrace (PTRACE_TRACEME) != 0)
2052130812Smarcel      error ("ptrace (PTRACE_TRACEME) failed!");
2053130812Smarcel  }
2054130812Smarcel  void attach_to_child (int pid)
2055130812Smarcel  {
2056130812Smarcel    /* Attach to the now stopped child, which is actually a shell...  */
2057130812Smarcel    inf_debug (inf, "attaching to child: %d", pid);
2058130812Smarcel
2059130812Smarcel    inf_attach (inf, pid);
2060130812Smarcel
2061130812Smarcel    attach_flag = 0;
2062130812Smarcel    push_target (&gnu_ops);
2063130812Smarcel
2064130812Smarcel    inf->pending_execs = 2;
2065130812Smarcel    inf->nomsg = 1;
2066130812Smarcel    inf->traced = 1;
2067130812Smarcel
2068130812Smarcel    /* Now let the child run again, knowing that it will stop immediately
2069130812Smarcel       because of the ptrace. */
2070130812Smarcel    inf_resume (inf);
2071130812Smarcel    inferior_ptid = pid_to_ptid (inf_pick_first_thread ());
2072130812Smarcel
2073130812Smarcel    startup_inferior (inf->pending_execs);
2074130812Smarcel  }
2075130812Smarcel
2076130812Smarcel  inf_debug (inf, "creating inferior");
2077130812Smarcel
2078130812Smarcel  fork_inferior (exec_file, allargs, env, trace_me, attach_to_child,
2079130812Smarcel		 NULL, NULL);
2080130812Smarcel
2081130812Smarcel  inf_validate_procinfo (inf);
2082130812Smarcel  inf_update_signal_thread (inf);
2083130812Smarcel  inf_set_traced (inf, inf->want_signals);
2084130812Smarcel
2085130812Smarcel  /* Execing the process will have trashed our exception ports; steal them
2086130812Smarcel     back (or make sure they're restored if the user wants that).  */
2087130812Smarcel  if (inf->want_exceptions)
2088130812Smarcel    inf_steal_exc_ports (inf);
2089130812Smarcel  else
2090130812Smarcel    inf_restore_exc_ports (inf);
2091130812Smarcel
2092130812Smarcel  /* Here we go!  */
2093130812Smarcel  proceed ((CORE_ADDR) -1, 0, 0);
2094130812Smarcel}
2095130812Smarcel
2096130812Smarcel/* Mark our target-struct as eligible for stray "run" and "attach"
2097130812Smarcel   commands.  */
2098130812Smarcelstatic int
2099130812Smarcelgnu_can_run (void)
2100130812Smarcel{
2101130812Smarcel  return 1;
2102130812Smarcel}
2103130812Smarcel
2104130812Smarcel
2105130812Smarcel#ifdef ATTACH_DETACH
2106130812Smarcel
2107130812Smarcel/* Attach to process PID, then initialize for debugging it
2108130812Smarcel   and wait for the trace-trap that results from attaching.  */
2109130812Smarcelstatic void
2110130812Smarcelgnu_attach (char *args, int from_tty)
2111130812Smarcel{
2112130812Smarcel  int pid;
2113130812Smarcel  char *exec_file;
2114130812Smarcel  struct inf *inf = cur_inf ();
2115130812Smarcel
2116130812Smarcel  if (!args)
2117130812Smarcel    error_no_arg ("process-id to attach");
2118130812Smarcel
2119130812Smarcel  pid = atoi (args);
2120130812Smarcel
2121130812Smarcel  if (pid == getpid ())		/* Trying to masturbate? */
2122130812Smarcel    error ("I refuse to debug myself!");
2123130812Smarcel
2124130812Smarcel  if (from_tty)
2125130812Smarcel    {
2126130812Smarcel      exec_file = (char *) get_exec_file (0);
2127130812Smarcel
2128130812Smarcel      if (exec_file)
2129130812Smarcel	printf_unfiltered ("Attaching to program `%s', pid %d\n",
2130130812Smarcel			   exec_file, pid);
2131130812Smarcel      else
2132130812Smarcel	printf_unfiltered ("Attaching to pid %d\n", pid);
2133130812Smarcel
2134130812Smarcel      gdb_flush (gdb_stdout);
2135130812Smarcel    }
2136130812Smarcel
2137130812Smarcel  inf_debug (inf, "attaching to pid: %d", pid);
2138130812Smarcel
2139130812Smarcel  inf_attach (inf, pid);
2140130812Smarcel  inf_update_procs (inf);
2141130812Smarcel
2142130812Smarcel  inferior_ptid = pid_to_ptid (inf_pick_first_thread ());
2143130812Smarcel
2144130812Smarcel  attach_flag = 1;
2145130812Smarcel  push_target (&gnu_ops);
2146130812Smarcel
2147130812Smarcel  /* We have to initialize the terminal settings now, since the code
2148130812Smarcel     below might try to restore them.  */
2149130812Smarcel  target_terminal_init ();
2150130812Smarcel
2151130812Smarcel  /* If the process was stopped before we attached, make it continue the next
2152130812Smarcel     time the user does a continue.  */
2153130812Smarcel  inf_validate_procinfo (inf);
2154130812Smarcel
2155130812Smarcel  inf_update_signal_thread (inf);
2156130812Smarcel  inf_set_traced (inf, inf->want_signals);
2157130812Smarcel
2158130812Smarcel#if 0				/* Do we need this? */
2159130812Smarcel  renumber_threads (0);		/* Give our threads reasonable names. */
2160130812Smarcel#endif
2161130812Smarcel}
2162130812Smarcel
2163130812Smarcel
2164130812Smarcel/* Take a program previously attached to and detaches it.
2165130812Smarcel   The program resumes execution and will no longer stop
2166130812Smarcel   on signals, etc.  We'd better not have left any breakpoints
2167130812Smarcel   in the program or it'll die when it hits one.  For this
2168130812Smarcel   to work, it may be necessary for the process to have been
2169130812Smarcel   previously attached.  It *might* work if the program was
2170130812Smarcel   started via fork.  */
2171130812Smarcelstatic void
2172130812Smarcelgnu_detach (char *args, int from_tty)
2173130812Smarcel{
2174130812Smarcel  if (from_tty)
2175130812Smarcel    {
2176130812Smarcel      char *exec_file = get_exec_file (0);
2177130812Smarcel      if (exec_file)
2178130812Smarcel	printf_unfiltered ("Detaching from program `%s' pid %d\n",
2179130812Smarcel			   exec_file, current_inferior->pid);
2180130812Smarcel      else
2181130812Smarcel	printf_unfiltered ("Detaching from pid %d\n", current_inferior->pid);
2182130812Smarcel      gdb_flush (gdb_stdout);
2183130812Smarcel    }
2184130812Smarcel
2185130812Smarcel  inf_detach (current_inferior);
2186130812Smarcel
2187130812Smarcel  inferior_ptid = null_ptid;
2188130812Smarcel
2189130812Smarcel  unpush_target (&gnu_ops);	/* Pop out of handling an inferior */
2190130812Smarcel}
2191130812Smarcel#endif /* ATTACH_DETACH */
2192130812Smarcel
2193130812Smarcel
2194130812Smarcelstatic void
2195130812Smarcelgnu_terminal_init_inferior (void)
2196130812Smarcel{
2197130812Smarcel  gdb_assert (current_inferior);
2198130812Smarcel  terminal_init_inferior_with_pgrp (current_inferior->pid);
2199130812Smarcel}
2200130812Smarcel
2201130812Smarcel/* Get ready to modify the registers array.  On machines which store
2202130812Smarcel   individual registers, this doesn't need to do anything.  On machines
2203130812Smarcel   which store all the registers in one fell swoop, this makes sure
2204130812Smarcel   that registers contains all the registers from the program being
2205130812Smarcel   debugged.  */
2206130812Smarcelstatic void
2207130812Smarcelgnu_prepare_to_store (void)
2208130812Smarcel{
2209130812Smarcel#ifdef CHILD_PREPARE_TO_STORE
2210130812Smarcel  CHILD_PREPARE_TO_STORE ();
2211130812Smarcel#endif
2212130812Smarcel}
2213130812Smarcel
2214130812Smarcelstatic void
2215130812Smarcelgnu_open (char *arg, int from_tty)
2216130812Smarcel{
2217130812Smarcel  error ("Use the \"run\" command to start a Unix child process.");
2218130812Smarcel}
2219130812Smarcel
2220130812Smarcelstatic void
2221130812Smarcelgnu_stop (void)
2222130812Smarcel{
2223130812Smarcel  error ("to_stop target function not implemented");
2224130812Smarcel}
2225130812Smarcel
2226130812Smarcelstatic char *
2227130812Smarcelgnu_pid_to_exec_file (int pid)
2228130812Smarcel{
2229130812Smarcel  error ("to_pid_to_exec_file target function not implemented");
2230130812Smarcel  return NULL;
2231130812Smarcel}
2232130812Smarcel
2233130812Smarcel
2234130812Smarcelstatic int
2235130812Smarcelgnu_thread_alive (ptid_t tid)
2236130812Smarcel{
2237130812Smarcel  inf_update_procs (current_inferior);
2238130812Smarcel  return !!inf_tid_to_thread (current_inferior, PIDGET (tid));
2239130812Smarcel}
2240130812Smarcel
2241130812Smarcel
2242130812Smarcel/* Read inferior task's LEN bytes from ADDR and copy it to MYADDR in
2243130812Smarcel   gdb's address space.  Return 0 on failure; number of bytes read
2244130812Smarcel   otherwise.  */
2245130812Smarcelint
2246130812Smarcelgnu_read_inferior (task_t task, CORE_ADDR addr, char *myaddr, int length)
2247130812Smarcel{
2248130812Smarcel  error_t err;
2249130812Smarcel  vm_address_t low_address = (vm_address_t) trunc_page (addr);
2250130812Smarcel  vm_size_t aligned_length =
2251130812Smarcel  (vm_size_t) round_page (addr + length) - low_address;
2252130812Smarcel  pointer_t copied;
2253130812Smarcel  int copy_count;
2254130812Smarcel
2255130812Smarcel  /* Get memory from inferior with page aligned addresses */
2256130812Smarcel  err = vm_read (task, low_address, aligned_length, &copied, &copy_count);
2257130812Smarcel  if (err)
2258130812Smarcel    return 0;
2259130812Smarcel
2260130812Smarcel  err = hurd_safe_copyin (myaddr, (void *) addr - low_address + copied, length);
2261130812Smarcel  if (err)
2262130812Smarcel    {
2263130812Smarcel      warning ("Read from inferior faulted: %s", safe_strerror (err));
2264130812Smarcel      length = 0;
2265130812Smarcel    }
2266130812Smarcel
2267130812Smarcel  err = vm_deallocate (mach_task_self (), copied, copy_count);
2268130812Smarcel  if (err)
2269130812Smarcel    warning ("gnu_read_inferior vm_deallocate failed: %s", safe_strerror (err));
2270130812Smarcel
2271130812Smarcel  return length;
2272130812Smarcel}
2273130812Smarcel
2274130812Smarcel#define CHK_GOTO_OUT(str,ret) \
2275130812Smarcel  do if (ret != KERN_SUCCESS) { errstr = #str; goto out; } while(0)
2276130812Smarcel
2277130812Smarcelstruct vm_region_list
2278130812Smarcel{
2279130812Smarcel  struct vm_region_list *next;
2280130812Smarcel  vm_prot_t protection;
2281130812Smarcel  vm_address_t start;
2282130812Smarcel  vm_size_t length;
2283130812Smarcel};
2284130812Smarcel
2285130812Smarcelstruct obstack region_obstack;
2286130812Smarcel
2287130812Smarcel/* Write gdb's LEN bytes from MYADDR and copy it to ADDR in inferior
2288130812Smarcel   task's address space.  */
2289130812Smarcelint
2290130812Smarcelgnu_write_inferior (task_t task, CORE_ADDR addr, char *myaddr, int length)
2291130812Smarcel{
2292130812Smarcel  error_t err = 0;
2293130812Smarcel  vm_address_t low_address = (vm_address_t) trunc_page (addr);
2294130812Smarcel  vm_size_t aligned_length =
2295130812Smarcel  (vm_size_t) round_page (addr + length) - low_address;
2296130812Smarcel  pointer_t copied;
2297130812Smarcel  int copy_count;
2298130812Smarcel  int deallocate = 0;
2299130812Smarcel
2300130812Smarcel  char *errstr = "Bug in gnu_write_inferior";
2301130812Smarcel
2302130812Smarcel  struct vm_region_list *region_element;
2303130812Smarcel  struct vm_region_list *region_head = (struct vm_region_list *) NULL;
2304130812Smarcel
2305130812Smarcel  /* Get memory from inferior with page aligned addresses */
2306130812Smarcel  err = vm_read (task,
2307130812Smarcel		 low_address,
2308130812Smarcel		 aligned_length,
2309130812Smarcel		 &copied,
2310130812Smarcel		 &copy_count);
2311130812Smarcel  CHK_GOTO_OUT ("gnu_write_inferior vm_read failed", err);
2312130812Smarcel
2313130812Smarcel  deallocate++;
2314130812Smarcel
2315130812Smarcel  err = hurd_safe_copyout ((void *) addr - low_address + copied,
2316130812Smarcel			   myaddr, length);
2317130812Smarcel  CHK_GOTO_OUT ("Write to inferior faulted", err);
2318130812Smarcel
2319130812Smarcel  obstack_init (&region_obstack);
2320130812Smarcel
2321130812Smarcel  /* Do writes atomically.
2322130812Smarcel     First check for holes and unwritable memory.  */
2323130812Smarcel  {
2324130812Smarcel    vm_size_t remaining_length = aligned_length;
2325130812Smarcel    vm_address_t region_address = low_address;
2326130812Smarcel
2327130812Smarcel    struct vm_region_list *scan;
2328130812Smarcel
2329130812Smarcel    while (region_address < low_address + aligned_length)
2330130812Smarcel      {
2331130812Smarcel	vm_prot_t protection;
2332130812Smarcel	vm_prot_t max_protection;
2333130812Smarcel	vm_inherit_t inheritance;
2334130812Smarcel	boolean_t shared;
2335130812Smarcel	mach_port_t object_name;
2336130812Smarcel	vm_offset_t offset;
2337130812Smarcel	vm_size_t region_length = remaining_length;
2338130812Smarcel	vm_address_t old_address = region_address;
2339130812Smarcel
2340130812Smarcel	err = vm_region (task,
2341130812Smarcel			 &region_address,
2342130812Smarcel			 &region_length,
2343130812Smarcel			 &protection,
2344130812Smarcel			 &max_protection,
2345130812Smarcel			 &inheritance,
2346130812Smarcel			 &shared,
2347130812Smarcel			 &object_name,
2348130812Smarcel			 &offset);
2349130812Smarcel	CHK_GOTO_OUT ("vm_region failed", err);
2350130812Smarcel
2351130812Smarcel	/* Check for holes in memory */
2352130812Smarcel	if (old_address != region_address)
2353130812Smarcel	  {
2354130812Smarcel	    warning ("No memory at 0x%x. Nothing written",
2355130812Smarcel		     old_address);
2356130812Smarcel	    err = KERN_SUCCESS;
2357130812Smarcel	    length = 0;
2358130812Smarcel	    goto out;
2359130812Smarcel	  }
2360130812Smarcel
2361130812Smarcel	if (!(max_protection & VM_PROT_WRITE))
2362130812Smarcel	  {
2363130812Smarcel	    warning ("Memory at address 0x%x is unwritable. Nothing written",
2364130812Smarcel		     old_address);
2365130812Smarcel	    err = KERN_SUCCESS;
2366130812Smarcel	    length = 0;
2367130812Smarcel	    goto out;
2368130812Smarcel	  }
2369130812Smarcel
2370130812Smarcel	/* Chain the regions for later use */
2371130812Smarcel	region_element =
2372130812Smarcel	  (struct vm_region_list *)
2373130812Smarcel	  obstack_alloc (&region_obstack, sizeof (struct vm_region_list));
2374130812Smarcel
2375130812Smarcel	region_element->protection = protection;
2376130812Smarcel	region_element->start = region_address;
2377130812Smarcel	region_element->length = region_length;
2378130812Smarcel
2379130812Smarcel	/* Chain the regions along with protections */
2380130812Smarcel	region_element->next = region_head;
2381130812Smarcel	region_head = region_element;
2382130812Smarcel
2383130812Smarcel	region_address += region_length;
2384130812Smarcel	remaining_length = remaining_length - region_length;
2385130812Smarcel      }
2386130812Smarcel
2387130812Smarcel    /* If things fail after this, we give up.
2388130812Smarcel       Somebody is messing up inferior_task's mappings.  */
2389130812Smarcel
2390130812Smarcel    /* Enable writes to the chained vm regions */
2391130812Smarcel    for (scan = region_head; scan; scan = scan->next)
2392130812Smarcel      {
2393130812Smarcel	if (!(scan->protection & VM_PROT_WRITE))
2394130812Smarcel	  {
2395130812Smarcel	    err = vm_protect (task,
2396130812Smarcel			      scan->start,
2397130812Smarcel			      scan->length,
2398130812Smarcel			      FALSE,
2399130812Smarcel			      scan->protection | VM_PROT_WRITE);
2400130812Smarcel	    CHK_GOTO_OUT ("vm_protect: enable write failed", err);
2401130812Smarcel	  }
2402130812Smarcel      }
2403130812Smarcel
2404130812Smarcel    err = vm_write (task,
2405130812Smarcel		    low_address,
2406130812Smarcel		    copied,
2407130812Smarcel		    aligned_length);
2408130812Smarcel    CHK_GOTO_OUT ("vm_write failed", err);
2409130812Smarcel
2410130812Smarcel    /* Set up the original region protections, if they were changed */
2411130812Smarcel    for (scan = region_head; scan; scan = scan->next)
2412130812Smarcel      {
2413130812Smarcel	if (!(scan->protection & VM_PROT_WRITE))
2414130812Smarcel	  {
2415130812Smarcel	    err = vm_protect (task,
2416130812Smarcel			      scan->start,
2417130812Smarcel			      scan->length,
2418130812Smarcel			      FALSE,
2419130812Smarcel			      scan->protection);
2420130812Smarcel	    CHK_GOTO_OUT ("vm_protect: enable write failed", err);
2421130812Smarcel	  }
2422130812Smarcel      }
2423130812Smarcel  }
2424130812Smarcel
2425130812Smarcelout:
2426130812Smarcel  if (deallocate)
2427130812Smarcel    {
2428130812Smarcel      obstack_free (&region_obstack, 0);
2429130812Smarcel
2430130812Smarcel      (void) vm_deallocate (mach_task_self (),
2431130812Smarcel			    copied,
2432130812Smarcel			    copy_count);
2433130812Smarcel    }
2434130812Smarcel
2435130812Smarcel  if (err != KERN_SUCCESS)
2436130812Smarcel    {
2437130812Smarcel      warning ("%s: %s", errstr, mach_error_string (err));
2438130812Smarcel      return 0;
2439130812Smarcel    }
2440130812Smarcel
2441130812Smarcel  return length;
2442130812Smarcel}
2443130812Smarcel
2444130812Smarcel
2445130812Smarcel/* Return 0 on failure, number of bytes handled otherwise.  TARGET
2446130812Smarcel   is ignored. */
2447130812Smarcelstatic int
2448130812Smarcelgnu_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
2449130812Smarcel		 struct mem_attrib *attrib,
2450130812Smarcel		 struct target_ops *target)
2451130812Smarcel{
2452130812Smarcel  task_t task = (current_inferior
2453130812Smarcel		 ? (current_inferior->task
2454130812Smarcel		    ? current_inferior->task->port : 0)
2455130812Smarcel		 : 0);
2456130812Smarcel
2457130812Smarcel  if (task == MACH_PORT_NULL)
2458130812Smarcel    return 0;
2459130812Smarcel  else
2460130812Smarcel    {
2461130812Smarcel      inf_debug (current_inferior, "%s %p[%d] %s %p",
2462130812Smarcel		 write ? "writing" : "reading", (void *) memaddr, len,
2463130812Smarcel		 write ? "<--" : "-->", myaddr);
2464130812Smarcel      if (write)
2465130812Smarcel	return gnu_write_inferior (task, memaddr, myaddr, len);
2466130812Smarcel      else
2467130812Smarcel	return gnu_read_inferior (task, memaddr, myaddr, len);
2468130812Smarcel    }
2469130812Smarcel}
2470130812Smarcel
2471130812Smarcel/* Call FUNC on each memory region in the task.  */
2472130812Smarcelstatic int
2473130812Smarcelgnu_find_memory_regions (int (*func) (CORE_ADDR,
2474130812Smarcel				      unsigned long,
2475130812Smarcel				      int, int, int,
2476130812Smarcel				      void *),
2477130812Smarcel			 void *data)
2478130812Smarcel{
2479130812Smarcel  error_t err;
2480130812Smarcel  task_t task;
2481130812Smarcel  vm_address_t region_address, last_region_address, last_region_end;
2482130812Smarcel  vm_prot_t last_protection;
2483130812Smarcel
2484130812Smarcel  if (current_inferior == 0 || current_inferior->task == 0)
2485130812Smarcel    return 0;
2486130812Smarcel  task = current_inferior->task->port;
2487130812Smarcel  if (task == MACH_PORT_NULL)
2488130812Smarcel    return 0;
2489130812Smarcel
2490130812Smarcel  region_address = last_region_address = last_region_end = VM_MIN_ADDRESS;
2491130812Smarcel  last_protection = VM_PROT_NONE;
2492130812Smarcel  while (region_address < VM_MAX_ADDRESS)
2493130812Smarcel    {
2494130812Smarcel      vm_prot_t protection;
2495130812Smarcel      vm_prot_t max_protection;
2496130812Smarcel      vm_inherit_t inheritance;
2497130812Smarcel      boolean_t shared;
2498130812Smarcel      mach_port_t object_name;
2499130812Smarcel      vm_offset_t offset;
2500130812Smarcel      vm_size_t region_length = VM_MAX_ADDRESS - region_address;
2501130812Smarcel      vm_address_t old_address = region_address;
2502130812Smarcel
2503130812Smarcel      err = vm_region (task,
2504130812Smarcel		       &region_address,
2505130812Smarcel		       &region_length,
2506130812Smarcel		       &protection,
2507130812Smarcel		       &max_protection,
2508130812Smarcel		       &inheritance,
2509130812Smarcel		       &shared,
2510130812Smarcel		       &object_name,
2511130812Smarcel		       &offset);
2512130812Smarcel      if (err == KERN_NO_SPACE)
2513130812Smarcel	break;
2514130812Smarcel      if (err != KERN_SUCCESS)
2515130812Smarcel	{
2516130812Smarcel	  warning ("vm_region failed: %s", mach_error_string (err));
2517130812Smarcel	  return -1;
2518130812Smarcel	}
2519130812Smarcel
2520130812Smarcel      if (protection == last_protection && region_address == last_region_end)
2521130812Smarcel	/* This region is contiguous with and indistinguishable from
2522130812Smarcel	   the previous one, so we just extend that one.  */
2523130812Smarcel	last_region_end = region_address += region_length;
2524130812Smarcel      else
2525130812Smarcel	{
2526130812Smarcel	  /* This region is distinct from the last one we saw, so report
2527130812Smarcel	     that previous one.  */
2528130812Smarcel	  if (last_protection != VM_PROT_NONE)
2529130812Smarcel	    (*func) (last_region_address,
2530130812Smarcel		     last_region_end - last_region_address,
2531130812Smarcel		     last_protection & VM_PROT_READ,
2532130812Smarcel		     last_protection & VM_PROT_WRITE,
2533130812Smarcel		     last_protection & VM_PROT_EXECUTE,
2534130812Smarcel		     data);
2535130812Smarcel	  last_region_address = region_address;
2536130812Smarcel	  last_region_end = region_address += region_length;
2537130812Smarcel	  last_protection = protection;
2538130812Smarcel	}
2539130812Smarcel    }
2540130812Smarcel
2541130812Smarcel  /* Report the final region.  */
2542130812Smarcel  if (last_region_end > last_region_address && last_protection != VM_PROT_NONE)
2543130812Smarcel    (*func) (last_region_address, last_region_end - last_region_address,
2544130812Smarcel	     last_protection & VM_PROT_READ,
2545130812Smarcel	     last_protection & VM_PROT_WRITE,
2546130812Smarcel	     last_protection & VM_PROT_EXECUTE,
2547130812Smarcel	     data);
2548130812Smarcel
2549130812Smarcel  return 0;
2550130812Smarcel}
2551130812Smarcel
2552130812Smarcel
2553130812Smarcel/* Return printable description of proc.  */
2554130812Smarcelchar *
2555130812Smarcelproc_string (struct proc *proc)
2556130812Smarcel{
2557130812Smarcel  static char tid_str[80];
2558130812Smarcel  if (proc_is_task (proc))
2559130812Smarcel    sprintf (tid_str, "process %d", proc->inf->pid);
2560130812Smarcel  else
2561130812Smarcel    sprintf (tid_str, "thread %d.%d",
2562130812Smarcel	     proc->inf->pid, pid_to_thread_id (MERGEPID (proc->tid, 0)));
2563130812Smarcel  return tid_str;
2564130812Smarcel}
2565130812Smarcel
2566130812Smarcelstatic char *
2567130812Smarcelgnu_pid_to_str (ptid_t ptid)
2568130812Smarcel{
2569130812Smarcel  struct inf *inf = current_inferior;
2570130812Smarcel  int tid = PIDGET (ptid);
2571130812Smarcel  struct proc *thread = inf_tid_to_thread (inf, tid);
2572130812Smarcel
2573130812Smarcel  if (thread)
2574130812Smarcel    return proc_string (thread);
2575130812Smarcel  else
2576130812Smarcel    {
2577130812Smarcel      static char tid_str[80];
2578130812Smarcel      sprintf (tid_str, "bogus thread id %d", tid);
2579130812Smarcel      return tid_str;
2580130812Smarcel    }
2581130812Smarcel}
2582130812Smarcel
2583130812Smarcel
2584130812Smarcelextern void gnu_store_registers (int regno);
2585130812Smarcelextern void gnu_fetch_registers (int regno);
2586130812Smarcel
2587130812Smarcelstruct target_ops gnu_ops;
2588130812Smarcel
2589130812Smarcelstatic void
2590130812Smarcelinit_gnu_ops (void)
2591130812Smarcel{
2592130812Smarcel  gnu_ops.to_shortname = "GNU";		/* to_shortname */
2593130812Smarcel  gnu_ops.to_longname = "GNU Hurd process"; /* to_longname */
2594130812Smarcel  gnu_ops.to_doc = "GNU Hurd process";	/* to_doc */
2595130812Smarcel  gnu_ops.to_open = gnu_open;		/* to_open */
2596130812Smarcel  gnu_ops.to_attach = gnu_attach;	/* to_attach */
2597130812Smarcel  gnu_ops.to_detach = gnu_detach;	/* to_detach */
2598130812Smarcel  gnu_ops.to_resume = gnu_resume;	/* to_resume */
2599130812Smarcel  gnu_ops.to_wait = gnu_wait;		/* to_wait */
2600130812Smarcel  gnu_ops.to_fetch_registers = gnu_fetch_registers;    /* to_fetch_registers */
2601130812Smarcel  gnu_ops.to_store_registers = gnu_store_registers;    /* to_store_registers */
2602130812Smarcel  gnu_ops.to_prepare_to_store = gnu_prepare_to_store; /* to_prepare_to_store */
2603130812Smarcel  gnu_ops.to_xfer_memory = gnu_xfer_memory; /* to_xfer_memory */
2604130812Smarcel  gnu_ops.to_find_memory_regions = gnu_find_memory_regions;
2605130812Smarcel  gnu_ops.to_insert_breakpoint = memory_insert_breakpoint;
2606130812Smarcel  gnu_ops.to_remove_breakpoint = memory_remove_breakpoint;
2607130812Smarcel  gnu_ops.to_terminal_init = gnu_terminal_init_inferior;
2608130812Smarcel  gnu_ops.to_terminal_inferior = terminal_inferior;
2609130812Smarcel  gnu_ops.to_terminal_ours_for_output = terminal_ours_for_output;
2610130812Smarcel  gnu_ops.to_terminal_save_ours = terminal_save_ours;
2611130812Smarcel  gnu_ops.to_terminal_ours = terminal_ours;
2612130812Smarcel  gnu_ops.to_terminal_info = child_terminal_info;
2613130812Smarcel  gnu_ops.to_kill = gnu_kill_inferior;	/* to_kill */
2614130812Smarcel  gnu_ops.to_create_inferior = gnu_create_inferior; /* to_create_inferior */
2615130812Smarcel  gnu_ops.to_mourn_inferior = gnu_mourn_inferior;	/* to_mourn_inferior */
2616130812Smarcel  gnu_ops.to_can_run = gnu_can_run;	/* to_can_run */
2617130812Smarcel  gnu_ops.to_thread_alive = gnu_thread_alive;	/* to_thread_alive */
2618130812Smarcel  gnu_ops.to_pid_to_str = gnu_pid_to_str;   /* to_pid_to_str */
2619130812Smarcel  gnu_ops.to_stop = gnu_stop;	/* to_stop */
2620130812Smarcel  gnu_ops.to_pid_to_exec_file = gnu_pid_to_exec_file; /* to_pid_to_exec_file */
2621130812Smarcel  gnu_ops.to_stratum = process_stratum;		/* to_stratum */
2622130812Smarcel  gnu_ops.to_has_all_memory = 1;	/* to_has_all_memory */
2623130812Smarcel  gnu_ops.to_has_memory = 1;		/* to_has_memory */
2624130812Smarcel  gnu_ops.to_has_stack = 1;		/* to_has_stack */
2625130812Smarcel  gnu_ops.to_has_registers = 1;		/* to_has_registers */
2626130812Smarcel  gnu_ops.to_has_execution = 1;		/* to_has_execution */
2627130812Smarcel  gnu_ops.to_magic = OPS_MAGIC;		/* to_magic */
2628130812Smarcel}				/* init_gnu_ops */
2629130812Smarcel
2630130812Smarcel
2631130812Smarcel/* User task commands.  */
2632130812Smarcel
2633130812Smarcelstruct cmd_list_element *set_task_cmd_list = 0;
2634130812Smarcelstruct cmd_list_element *show_task_cmd_list = 0;
2635130812Smarcel/* User thread commands.  */
2636130812Smarcel
2637130812Smarcel/* Commands with a prefix of `set/show thread'.  */
2638130812Smarcelextern struct cmd_list_element *thread_cmd_list;
2639130812Smarcelstruct cmd_list_element *set_thread_cmd_list = NULL;
2640130812Smarcelstruct cmd_list_element *show_thread_cmd_list = NULL;
2641130812Smarcel
2642130812Smarcel/* Commands with a prefix of `set/show thread default'.  */
2643130812Smarcelstruct cmd_list_element *set_thread_default_cmd_list = NULL;
2644130812Smarcelstruct cmd_list_element *show_thread_default_cmd_list = NULL;
2645130812Smarcel
2646130812Smarcelstatic void
2647130812Smarcelset_thread_cmd (char *args, int from_tty)
2648130812Smarcel{
2649130812Smarcel  printf_unfiltered ("\"set thread\" must be followed by the name of a thread property, or \"default\".\n");
2650130812Smarcel}
2651130812Smarcel
2652130812Smarcelstatic void
2653130812Smarcelshow_thread_cmd (char *args, int from_tty)
2654130812Smarcel{
2655130812Smarcel  printf_unfiltered ("\"show thread\" must be followed by the name of a thread property, or \"default\".\n");
2656130812Smarcel}
2657130812Smarcel
2658130812Smarcelstatic void
2659130812Smarcelset_thread_default_cmd (char *args, int from_tty)
2660130812Smarcel{
2661130812Smarcel  printf_unfiltered ("\"set thread default\" must be followed by the name of a thread property.\n");
2662130812Smarcel}
2663130812Smarcel
2664130812Smarcelstatic void
2665130812Smarcelshow_thread_default_cmd (char *args, int from_tty)
2666130812Smarcel{
2667130812Smarcel  printf_unfiltered ("\"show thread default\" must be followed by the name of a thread property.\n");
2668130812Smarcel}
2669130812Smarcel
2670130812Smarcelstatic int
2671130812Smarcelparse_int_arg (char *args, char *cmd_prefix)
2672130812Smarcel{
2673130812Smarcel  if (args)
2674130812Smarcel    {
2675130812Smarcel      char *arg_end;
2676130812Smarcel      int val = strtoul (args, &arg_end, 10);
2677130812Smarcel      if (*args && *arg_end == '\0')
2678130812Smarcel	return val;
2679130812Smarcel    }
2680130812Smarcel  error ("Illegal argument for \"%s\" command, should be an integer.", cmd_prefix);
2681130812Smarcel}
2682130812Smarcel
2683130812Smarcelstatic int
2684130812Smarcel_parse_bool_arg (char *args, char *t_val, char *f_val, char *cmd_prefix)
2685130812Smarcel{
2686130812Smarcel  if (!args || strcmp (args, t_val) == 0)
2687130812Smarcel    return 1;
2688130812Smarcel  else if (strcmp (args, f_val) == 0)
2689130812Smarcel    return 0;
2690130812Smarcel  else
2691130812Smarcel    error ("Illegal argument for \"%s\" command, should be \"%s\" or \"%s\".",
2692130812Smarcel	   cmd_prefix, t_val, f_val);
2693130812Smarcel}
2694130812Smarcel
2695130812Smarcel#define parse_bool_arg(args, cmd_prefix) \
2696130812Smarcel  _parse_bool_arg (args, "on", "off", cmd_prefix)
2697130812Smarcel
2698130812Smarcelstatic void
2699130812Smarcelcheck_empty (char *args, char *cmd_prefix)
2700130812Smarcel{
2701130812Smarcel  if (args)
2702130812Smarcel    error ("Garbage after \"%s\" command: `%s'", cmd_prefix, args);
2703130812Smarcel}
2704130812Smarcel
2705130812Smarcel/* Returns the alive thread named by INFERIOR_PID, or signals an error.  */
2706130812Smarcelstatic struct proc *
2707130812Smarcelcur_thread (void)
2708130812Smarcel{
2709130812Smarcel  struct inf *inf = cur_inf ();
2710130812Smarcel  struct proc *thread = inf_tid_to_thread (inf, PIDGET (inferior_ptid));
2711130812Smarcel  if (!thread)
2712130812Smarcel    error ("No current thread.");
2713130812Smarcel  return thread;
2714130812Smarcel}
2715130812Smarcel
2716130812Smarcel/* Returns the current inferior, but signals an error if it has no task.  */
2717130812Smarcelstatic struct inf *
2718130812Smarcelactive_inf (void)
2719130812Smarcel{
2720130812Smarcel  struct inf *inf = cur_inf ();
2721130812Smarcel  if (!inf->task)
2722130812Smarcel    error ("No current process.");
2723130812Smarcel  return inf;
2724130812Smarcel}
2725130812Smarcel
2726130812Smarcel
2727130812Smarcelstatic void
2728130812Smarcelset_task_pause_cmd (char *args, int from_tty)
2729130812Smarcel{
2730130812Smarcel  struct inf *inf = cur_inf ();
2731130812Smarcel  int old_sc = inf->pause_sc;
2732130812Smarcel
2733130812Smarcel  inf->pause_sc = parse_bool_arg (args, "set task pause");
2734130812Smarcel
2735130812Smarcel  if (old_sc == 0 && inf->pause_sc != 0)
2736130812Smarcel    /* If the task is currently unsuspended, immediately suspend it,
2737130812Smarcel       otherwise wait until the next time it gets control.  */
2738130812Smarcel    inf_suspend (inf);
2739130812Smarcel}
2740130812Smarcel
2741130812Smarcelstatic void
2742130812Smarcelshow_task_pause_cmd (char *args, int from_tty)
2743130812Smarcel{
2744130812Smarcel  struct inf *inf = cur_inf ();
2745130812Smarcel  check_empty (args, "show task pause");
2746130812Smarcel  printf_unfiltered ("The inferior task %s suspended while gdb has control.\n",
2747130812Smarcel		     inf->task
2748130812Smarcel		     ? (inf->pause_sc == 0 ? "isn't" : "is")
2749130812Smarcel		     : (inf->pause_sc == 0 ? "won't be" : "will be"));
2750130812Smarcel}
2751130812Smarcel
2752130812Smarcelstatic void
2753130812Smarcelset_task_detach_sc_cmd (char *args, int from_tty)
2754130812Smarcel{
2755130812Smarcel  cur_inf ()->detach_sc = parse_int_arg (args, "set task detach-suspend-count");
2756130812Smarcel}
2757130812Smarcel
2758130812Smarcelstatic void
2759130812Smarcelshow_task_detach_sc_cmd (char *args, int from_tty)
2760130812Smarcel{
2761130812Smarcel  check_empty (args, "show task detach-suspend-count");
2762130812Smarcel  printf_unfiltered ("The inferior task will be left with a suspend count of %d when detaching.\n",
2763130812Smarcel		     cur_inf ()->detach_sc);
2764130812Smarcel}
2765130812Smarcel
2766130812Smarcel
2767130812Smarcelstatic void
2768130812Smarcelset_thread_default_pause_cmd (char *args, int from_tty)
2769130812Smarcel{
2770130812Smarcel  struct inf *inf = cur_inf ();
2771130812Smarcel  inf->default_thread_pause_sc =
2772130812Smarcel    parse_bool_arg (args, "set thread default pause") ? 0 : 1;
2773130812Smarcel}
2774130812Smarcel
2775130812Smarcelstatic void
2776130812Smarcelshow_thread_default_pause_cmd (char *args, int from_tty)
2777130812Smarcel{
2778130812Smarcel  struct inf *inf = cur_inf ();
2779130812Smarcel  int sc = inf->default_thread_pause_sc;
2780130812Smarcel  check_empty (args, "show thread default pause");
2781130812Smarcel  printf_unfiltered ("New threads %s suspended while gdb has control%s.\n",
2782130812Smarcel		     sc ? "are" : "aren't",
2783130812Smarcel		     !sc && inf->pause_sc ? " (but the task is)" : "");
2784130812Smarcel}
2785130812Smarcel
2786130812Smarcelstatic void
2787130812Smarcelset_thread_default_run_cmd (char *args, int from_tty)
2788130812Smarcel{
2789130812Smarcel  struct inf *inf = cur_inf ();
2790130812Smarcel  inf->default_thread_run_sc =
2791130812Smarcel    parse_bool_arg (args, "set thread default run") ? 0 : 1;
2792130812Smarcel}
2793130812Smarcel
2794130812Smarcelstatic void
2795130812Smarcelshow_thread_default_run_cmd (char *args, int from_tty)
2796130812Smarcel{
2797130812Smarcel  struct inf *inf = cur_inf ();
2798130812Smarcel  check_empty (args, "show thread default run");
2799130812Smarcel  printf_unfiltered ("New threads %s allowed to run.\n",
2800130812Smarcel		     inf->default_thread_run_sc == 0 ? "are" : "aren't");
2801130812Smarcel}
2802130812Smarcel
2803130812Smarcelstatic void
2804130812Smarcelset_thread_default_detach_sc_cmd (char *args, int from_tty)
2805130812Smarcel{
2806130812Smarcel  cur_inf ()->default_thread_detach_sc =
2807130812Smarcel    parse_int_arg (args, "set thread default detach-suspend-count");
2808130812Smarcel}
2809130812Smarcel
2810130812Smarcelstatic void
2811130812Smarcelshow_thread_default_detach_sc_cmd (char *args, int from_tty)
2812130812Smarcel{
2813130812Smarcel  check_empty (args, "show thread default detach-suspend-count");
2814130812Smarcel  printf_unfiltered ("New threads will get a detach-suspend-count of %d.\n",
2815130812Smarcel		     cur_inf ()->default_thread_detach_sc);
2816130812Smarcel}
2817130812Smarcel
2818130812Smarcel
2819130812Smarcel/* Steal a send right called NAME in the inferior task, and make it PROC's
2820130812Smarcel   saved exception port.  */
2821130812Smarcelstatic void
2822130812Smarcelsteal_exc_port (struct proc *proc, mach_port_t name)
2823130812Smarcel{
2824130812Smarcel  error_t err;
2825130812Smarcel  mach_port_t port;
2826130812Smarcel  mach_msg_type_name_t port_type;
2827130812Smarcel
2828130812Smarcel  if (!proc || !proc->inf->task)
2829130812Smarcel    error ("No inferior task.");
2830130812Smarcel
2831130812Smarcel  err = mach_port_extract_right (proc->inf->task->port,
2832130812Smarcel				 name, MACH_MSG_TYPE_COPY_SEND,
2833130812Smarcel				 &port, &port_type);
2834130812Smarcel  if (err)
2835130812Smarcel    error ("Couldn't extract send right %d from inferior: %s",
2836130812Smarcel	   name, safe_strerror (err));
2837130812Smarcel
2838130812Smarcel  if (proc->saved_exc_port)
2839130812Smarcel    /* Get rid of our reference to the old one.  */
2840130812Smarcel    mach_port_deallocate (mach_task_self (), proc->saved_exc_port);
2841130812Smarcel
2842130812Smarcel  proc->saved_exc_port = port;
2843130812Smarcel
2844130812Smarcel  if (!proc->exc_port)
2845130812Smarcel    /* If PROC is a thread, we may not have set its exception port before.
2846130812Smarcel       We can't use proc_steal_exc_port because it also sets saved_exc_port. */
2847130812Smarcel    {
2848130812Smarcel      proc->exc_port = proc->inf->event_port;
2849130812Smarcel      err = proc_set_exception_port (proc, proc->exc_port);
2850130812Smarcel      error ("Can't set exception port for %s: %s",
2851130812Smarcel	     proc_string (proc), safe_strerror (err));
2852130812Smarcel    }
2853130812Smarcel}
2854130812Smarcel
2855130812Smarcelstatic void
2856130812Smarcelset_task_exc_port_cmd (char *args, int from_tty)
2857130812Smarcel{
2858130812Smarcel  struct inf *inf = cur_inf ();
2859130812Smarcel  if (!args)
2860130812Smarcel    error ("No argument to \"set task exception-port\" command.");
2861130812Smarcel  steal_exc_port (inf->task, parse_and_eval_address (args));
2862130812Smarcel}
2863130812Smarcel
2864130812Smarcelstatic void
2865130812Smarcelset_stopped_cmd (char *args, int from_tty)
2866130812Smarcel{
2867130812Smarcel  cur_inf ()->stopped = _parse_bool_arg (args, "yes", "no", "set stopped");
2868130812Smarcel}
2869130812Smarcel
2870130812Smarcelstatic void
2871130812Smarcelshow_stopped_cmd (char *args, int from_tty)
2872130812Smarcel{
2873130812Smarcel  struct inf *inf = active_inf ();
2874130812Smarcel  check_empty (args, "show stopped");
2875130812Smarcel  printf_unfiltered ("The inferior process %s stopped.\n",
2876130812Smarcel		     inf->stopped ? "is" : "isn't");
2877130812Smarcel}
2878130812Smarcel
2879130812Smarcelstatic void
2880130812Smarcelset_sig_thread_cmd (char *args, int from_tty)
2881130812Smarcel{
2882130812Smarcel  struct inf *inf = cur_inf ();
2883130812Smarcel
2884130812Smarcel  if (!args || (!isdigit (*args) && strcmp (args, "none") != 0))
2885130812Smarcel    error ("Illegal argument to \"set signal-thread\" command.\n"
2886130812Smarcel	   "Should be an integer thread ID, or `none'.");
2887130812Smarcel
2888130812Smarcel  if (strcmp (args, "none") == 0)
2889130812Smarcel    inf->signal_thread = 0;
2890130812Smarcel  else
2891130812Smarcel    {
2892130812Smarcel      int tid = PIDGET (thread_id_to_pid (atoi (args)));
2893130812Smarcel      if (tid < 0)
2894130812Smarcel	error ("Thread ID %s not known.  Use the \"info threads\" command to\n"
2895130812Smarcel	       "see the IDs of currently known threads.", args);
2896130812Smarcel      inf->signal_thread = inf_tid_to_thread (inf, tid);
2897130812Smarcel    }
2898130812Smarcel}
2899130812Smarcel
2900130812Smarcelstatic void
2901130812Smarcelshow_sig_thread_cmd (char *args, int from_tty)
2902130812Smarcel{
2903130812Smarcel  struct inf *inf = active_inf ();
2904130812Smarcel  check_empty (args, "show signal-thread");
2905130812Smarcel  if (inf->signal_thread)
2906130812Smarcel    printf_unfiltered ("The signal thread is %s.\n",
2907130812Smarcel		       proc_string (inf->signal_thread));
2908130812Smarcel  else
2909130812Smarcel    printf_unfiltered ("There is no signal thread.\n");
2910130812Smarcel}
2911130812Smarcel
2912130812Smarcel
2913130812Smarcelstatic void
2914130812Smarcelset_signals_cmd (char *args, int from_tty)
2915130812Smarcel{
2916130812Smarcel  struct inf *inf = cur_inf ();
2917130812Smarcel
2918130812Smarcel  inf->want_signals = parse_bool_arg (args, "set signals");
2919130812Smarcel
2920130812Smarcel  if (inf->task && inf->want_signals != inf->traced)
2921130812Smarcel    /* Make this take effect immediately in a running process.  */
2922130812Smarcel    inf_set_traced (inf, inf->want_signals);
2923130812Smarcel}
2924130812Smarcel
2925130812Smarcelstatic void
2926130812Smarcelshow_signals_cmd (char *args, int from_tty)
2927130812Smarcel{
2928130812Smarcel  struct inf *inf = cur_inf ();
2929130812Smarcel  check_empty (args, "show signals");
2930130812Smarcel  printf_unfiltered ("The inferior process's signals %s intercepted.\n",
2931130812Smarcel		     inf->task
2932130812Smarcel		     ? (inf->traced ? "are" : "aren't")
2933130812Smarcel		     : (inf->want_signals ? "will be" : "won't be"));
2934130812Smarcel}
2935130812Smarcel
2936130812Smarcelstatic void
2937130812Smarcelset_exceptions_cmd (char *args, int from_tty)
2938130812Smarcel{
2939130812Smarcel  struct inf *inf = cur_inf ();
2940130812Smarcel  int val = parse_bool_arg (args, "set exceptions");
2941130812Smarcel
2942130812Smarcel  if (inf->task && inf->want_exceptions != val)
2943130812Smarcel    /* Make this take effect immediately in a running process.  */
2944130812Smarcel    /* XXX */ ;
2945130812Smarcel
2946130812Smarcel  inf->want_exceptions = val;
2947130812Smarcel}
2948130812Smarcel
2949130812Smarcelstatic void
2950130812Smarcelshow_exceptions_cmd (char *args, int from_tty)
2951130812Smarcel{
2952130812Smarcel  struct inf *inf = cur_inf ();
2953130812Smarcel  check_empty (args, "show exceptions");
2954130812Smarcel  printf_unfiltered ("Exceptions in the inferior %s trapped.\n",
2955130812Smarcel		     inf->task
2956130812Smarcel		     ? (inf->want_exceptions ? "are" : "aren't")
2957130812Smarcel		     : (inf->want_exceptions ? "will be" : "won't be"));
2958130812Smarcel}
2959130812Smarcel
2960130812Smarcel
2961130812Smarcelstatic void
2962130812Smarcelset_task_cmd (char *args, int from_tty)
2963130812Smarcel{
2964130812Smarcel  printf_unfiltered ("\"set task\" must be followed by the name"
2965130812Smarcel		     " of a task property.\n");
2966130812Smarcel}
2967130812Smarcel
2968130812Smarcelstatic void
2969130812Smarcelshow_task_cmd (char *args, int from_tty)
2970130812Smarcel{
2971130812Smarcel  struct inf *inf = cur_inf ();
2972130812Smarcel
2973130812Smarcel  check_empty (args, "show task");
2974130812Smarcel
2975130812Smarcel  show_signals_cmd (0, from_tty);
2976130812Smarcel  show_exceptions_cmd (0, from_tty);
2977130812Smarcel  show_task_pause_cmd (0, from_tty);
2978130812Smarcel
2979130812Smarcel  if (inf->pause_sc == 0)
2980130812Smarcel    show_thread_default_pause_cmd (0, from_tty);
2981130812Smarcel  show_thread_default_run_cmd (0, from_tty);
2982130812Smarcel
2983130812Smarcel  if (inf->task)
2984130812Smarcel    {
2985130812Smarcel      show_stopped_cmd (0, from_tty);
2986130812Smarcel      show_sig_thread_cmd (0, from_tty);
2987130812Smarcel    }
2988130812Smarcel
2989130812Smarcel  if (inf->detach_sc != 0)
2990130812Smarcel    show_task_detach_sc_cmd (0, from_tty);
2991130812Smarcel  if (inf->default_thread_detach_sc != 0)
2992130812Smarcel    show_thread_default_detach_sc_cmd (0, from_tty);
2993130812Smarcel}
2994130812Smarcel
2995130812Smarcel
2996130812Smarcelstatic void
2997130812Smarcelset_noninvasive_cmd (char *args, int from_tty)
2998130812Smarcel{
2999130812Smarcel  /* Invert the sense of the arg for each component.  */
3000130812Smarcel  char *inv_args = parse_bool_arg (args, "set noninvasive") ? "off" : "on";
3001130812Smarcel
3002130812Smarcel  set_task_pause_cmd (inv_args, from_tty);
3003130812Smarcel  set_signals_cmd (inv_args, from_tty);
3004130812Smarcel  set_exceptions_cmd (inv_args, from_tty);
3005130812Smarcel}
3006130812Smarcel
3007130812Smarcel
3008130812Smarcelstatic void
3009130812Smarcelinfo_port_rights (char *args, mach_port_type_t only)
3010130812Smarcel{
3011130812Smarcel  struct inf *inf = active_inf ();
3012130812Smarcel  struct value *vmark = value_mark ();
3013130812Smarcel
3014130812Smarcel  if (args)
3015130812Smarcel    /* Explicit list of port rights.  */
3016130812Smarcel    {
3017130812Smarcel      while (*args)
3018130812Smarcel	{
3019130812Smarcel	  struct value *val = parse_to_comma_and_eval (&args);
3020130812Smarcel	  long right = value_as_long (val);
3021130812Smarcel	  error_t err =
3022130812Smarcel	  print_port_info (right, 0, inf->task->port, PORTINFO_DETAILS,
3023130812Smarcel			   stdout);
3024130812Smarcel	  if (err)
3025130812Smarcel	    error ("%ld: %s.", right, safe_strerror (err));
3026130812Smarcel	}
3027130812Smarcel    }
3028130812Smarcel  else
3029130812Smarcel    /* Print all of them.  */
3030130812Smarcel    {
3031130812Smarcel      error_t err =
3032130812Smarcel      print_task_ports_info (inf->task->port, only, PORTINFO_DETAILS,
3033130812Smarcel			     stdout);
3034130812Smarcel      if (err)
3035130812Smarcel	error ("%s.", safe_strerror (err));
3036130812Smarcel    }
3037130812Smarcel
3038130812Smarcel  value_free_to_mark (vmark);
3039130812Smarcel}
3040130812Smarcel
3041130812Smarcelstatic void
3042130812Smarcelinfo_send_rights_cmd (char *args, int from_tty)
3043130812Smarcel{
3044130812Smarcel  info_port_rights (args, MACH_PORT_TYPE_SEND);
3045130812Smarcel}
3046130812Smarcel
3047130812Smarcelstatic void
3048130812Smarcelinfo_recv_rights_cmd (char *args, int from_tty)
3049130812Smarcel{
3050130812Smarcel  info_port_rights (args, MACH_PORT_TYPE_RECEIVE);
3051130812Smarcel}
3052130812Smarcel
3053130812Smarcelstatic void
3054130812Smarcelinfo_port_sets_cmd (char *args, int from_tty)
3055130812Smarcel{
3056130812Smarcel  info_port_rights (args, MACH_PORT_TYPE_PORT_SET);
3057130812Smarcel}
3058130812Smarcel
3059130812Smarcelstatic void
3060130812Smarcelinfo_dead_names_cmd (char *args, int from_tty)
3061130812Smarcel{
3062130812Smarcel  info_port_rights (args, MACH_PORT_TYPE_DEAD_NAME);
3063130812Smarcel}
3064130812Smarcel
3065130812Smarcelstatic void
3066130812Smarcelinfo_port_rights_cmd (char *args, int from_tty)
3067130812Smarcel{
3068130812Smarcel  info_port_rights (args, ~0);
3069130812Smarcel}
3070130812Smarcel
3071130812Smarcel
3072130812Smarcelstatic void
3073130812Smarceladd_task_commands (void)
3074130812Smarcel{
3075130812Smarcel  add_cmd ("pause", class_run, set_thread_default_pause_cmd,
3076130812Smarcel	   "Set whether the new threads are suspended while gdb has control.\n\
3077130812SmarcelThis property normally has no effect because the whole task is\n\
3078130812Smarcelsuspended, however, that may be disabled with \"set task pause off\".\n\
3079130812SmarcelThe default value is \"off\".",
3080130812Smarcel	   &set_thread_default_cmd_list);
3081130812Smarcel  add_cmd ("pause", no_class, show_thread_default_pause_cmd,
3082130812Smarcel	   "Show whether new threads are suspended while gdb has control.",
3083130812Smarcel	   &show_thread_default_cmd_list);
3084130812Smarcel
3085130812Smarcel  add_cmd ("run", class_run, set_thread_default_run_cmd,
3086130812Smarcel	   "Set whether new threads are allowed to run \
3087130812Smarcel(once gdb has noticed them).",
3088130812Smarcel	   &set_thread_default_cmd_list);
3089130812Smarcel  add_cmd ("run", no_class, show_thread_default_run_cmd,
3090130812Smarcel	   "Show whether new threads are allowed to run \
3091130812Smarcel(once gdb has noticed them).",
3092130812Smarcel	   &show_thread_default_cmd_list);
3093130812Smarcel
3094130812Smarcel  add_cmd ("detach-suspend-count", class_run, set_thread_default_detach_sc_cmd,
3095130812Smarcel	   "Set the default detach-suspend-count value for new threads.",
3096130812Smarcel	   &set_thread_default_cmd_list);
3097130812Smarcel  add_cmd ("detach-suspend-count", no_class, show_thread_default_detach_sc_cmd,
3098130812Smarcel	   "Show the default detach-suspend-count value for new threads.",
3099130812Smarcel	   &show_thread_default_cmd_list);
3100130812Smarcel
3101130812Smarcel  add_cmd ("signals", class_run, set_signals_cmd,
3102130812Smarcel	   "Set whether the inferior process's signals will be intercepted.\n\
3103130812SmarcelMach exceptions (such as breakpoint traps) are not affected.",
3104130812Smarcel	   &setlist);
3105130812Smarcel  add_alias_cmd ("sigs", "signals", class_run, 1, &setlist);
3106130812Smarcel  add_cmd ("signals", no_class, show_signals_cmd,
3107130812Smarcel	   "Show whether the inferior process's signals will be intercepted.",
3108130812Smarcel	   &showlist);
3109130812Smarcel  add_alias_cmd ("sigs", "signals", no_class, 1, &showlist);
3110130812Smarcel
3111130812Smarcel  add_cmd ("signal-thread", class_run, set_sig_thread_cmd,
3112130812Smarcel	   "Set the thread that gdb thinks is the libc signal thread.\n\
3113130812SmarcelThis thread is run when delivering a signal to a non-stopped process.",
3114130812Smarcel	   &setlist);
3115130812Smarcel  add_alias_cmd ("sigthread", "signal-thread", class_run, 1, &setlist);
3116130812Smarcel  add_cmd ("signal-thread", no_class, show_sig_thread_cmd,
3117130812Smarcel	   "Set the thread that gdb thinks is the libc signal thread.",
3118130812Smarcel	   &showlist);
3119130812Smarcel  add_alias_cmd ("sigthread", "signal-thread", no_class, 1, &showlist);
3120130812Smarcel
3121130812Smarcel  add_cmd ("stopped", class_run, set_stopped_cmd,
3122130812Smarcel	   "Set whether gdb thinks the inferior process is stopped \
3123130812Smarcelas with SIGSTOP.\n\
3124130812SmarcelStopped process will be continued by sending them a signal.",
3125130812Smarcel	   &setlist);
3126130812Smarcel  add_cmd ("stopped", no_class, show_signals_cmd,
3127130812Smarcel	   "Show whether gdb thinks the inferior process is stopped \
3128130812Smarcelas with SIGSTOP.",
3129130812Smarcel	   &showlist);
3130130812Smarcel
3131130812Smarcel  add_cmd ("exceptions", class_run, set_exceptions_cmd,
3132130812Smarcel	   "Set whether exceptions in the inferior process will be trapped.\n\
3133130812SmarcelWhen exceptions are turned off, neither breakpoints nor single-stepping\n\
3134130812Smarcelwill work.",
3135130812Smarcel	   &setlist);
3136130812Smarcel  /* Allow `set exc' despite conflict with `set exception-port'.  */
3137130812Smarcel  add_alias_cmd ("exc", "exceptions", class_run, 1, &setlist);
3138130812Smarcel  add_cmd ("exceptions", no_class, show_exceptions_cmd,
3139130812Smarcel	   "Show whether exceptions in the inferior process will be trapped.",
3140130812Smarcel	   &showlist);
3141130812Smarcel
3142130812Smarcel  add_prefix_cmd ("task", no_class, set_task_cmd,
3143130812Smarcel		  "Command prefix for setting task attributes.",
3144130812Smarcel		  &set_task_cmd_list, "set task ", 0, &setlist);
3145130812Smarcel  add_prefix_cmd ("task", no_class, show_task_cmd,
3146130812Smarcel		  "Command prefix for showing task attributes.",
3147130812Smarcel		  &show_task_cmd_list, "show task ", 0, &showlist);
3148130812Smarcel
3149130812Smarcel  add_cmd ("pause", class_run, set_task_pause_cmd,
3150130812Smarcel	   "Set whether the task is suspended while gdb has control.\n\
3151130812SmarcelA value of \"on\" takes effect immediately, otherwise nothing happens\n\
3152130812Smarceluntil the next time the program is continued.\n\
3153130812SmarcelWhen setting this to \"off\", \"set thread default pause on\" can be\n\
3154130812Smarcelused to pause individual threads by default instead.",
3155130812Smarcel	   &set_task_cmd_list);
3156130812Smarcel  add_cmd ("pause", no_class, show_task_pause_cmd,
3157130812Smarcel	   "Show whether the task is suspended while gdb has control.",
3158130812Smarcel	   &show_task_cmd_list);
3159130812Smarcel
3160130812Smarcel  add_cmd ("detach-suspend-count", class_run, set_task_detach_sc_cmd,
3161130812Smarcel	   "Set the suspend count will leave on the thread when detaching.",
3162130812Smarcel	   &set_task_cmd_list);
3163130812Smarcel  add_cmd ("detach-suspend-count", no_class, show_task_detach_sc_cmd,
3164130812Smarcel	   "Show the suspend count will leave on the thread when detaching.",
3165130812Smarcel	   &show_task_cmd_list);
3166130812Smarcel
3167130812Smarcel  add_cmd ("exception-port", no_class, set_task_exc_port_cmd,
3168130812Smarcel	   "Set the task exception port to which we forward exceptions.\n\
3169130812SmarcelThe argument should be the value of the send right in the task.",
3170130812Smarcel	   &set_task_cmd_list);
3171130812Smarcel  add_alias_cmd ("excp", "exception-port", no_class, 1, &set_task_cmd_list);
3172130812Smarcel  add_alias_cmd ("exc-port", "exception-port", no_class, 1,
3173130812Smarcel		 &set_task_cmd_list);
3174130812Smarcel
3175130812Smarcel  /* A convenient way of turning on all options require to noninvasively
3176130812Smarcel     debug running tasks.  */
3177130812Smarcel  add_cmd ("noninvasive", no_class, set_noninvasive_cmd,
3178130812Smarcel	   "Set task options so that we interfere as little as possible.\n\
3179130812SmarcelThis is the same as setting `task pause', `exceptions', and\n\
3180130812Smarcel`signals' to the opposite value.",
3181130812Smarcel	   &setlist);
3182130812Smarcel
3183130812Smarcel  /* Commands to show information about the task's ports.  */
3184130812Smarcel  add_cmd ("send-rights", class_info, info_send_rights_cmd,
3185130812Smarcel	   "Show information about the task's send rights",
3186130812Smarcel	   &infolist);
3187130812Smarcel  add_cmd ("receive-rights", class_info, info_recv_rights_cmd,
3188130812Smarcel	   "Show information about the task's receive rights",
3189130812Smarcel	   &infolist);
3190130812Smarcel  add_cmd ("port-rights", class_info, info_port_rights_cmd,
3191130812Smarcel	   "Show information about the task's port rights",
3192130812Smarcel	   &infolist);
3193130812Smarcel  add_cmd ("port-sets", class_info, info_port_sets_cmd,
3194130812Smarcel	   "Show information about the task's port sets",
3195130812Smarcel	   &infolist);
3196130812Smarcel  add_cmd ("dead-names", class_info, info_dead_names_cmd,
3197130812Smarcel	   "Show information about the task's dead names",
3198130812Smarcel	   &infolist);
3199130812Smarcel  add_info_alias ("ports", "port-rights", 1);
3200130812Smarcel  add_info_alias ("port", "port-rights", 1);
3201130812Smarcel  add_info_alias ("psets", "port-sets", 1);
3202130812Smarcel}
3203130812Smarcel
3204130812Smarcel
3205130812Smarcelstatic void
3206130812Smarcelset_thread_pause_cmd (char *args, int from_tty)
3207130812Smarcel{
3208130812Smarcel  struct proc *thread = cur_thread ();
3209130812Smarcel  int old_sc = thread->pause_sc;
3210130812Smarcel  thread->pause_sc = parse_bool_arg (args, "set thread pause");
3211130812Smarcel  if (old_sc == 0 && thread->pause_sc != 0 && thread->inf->pause_sc == 0)
3212130812Smarcel    /* If the task is currently unsuspended, immediately suspend it,
3213130812Smarcel       otherwise wait until the next time it gets control.  */
3214130812Smarcel    inf_suspend (thread->inf);
3215130812Smarcel}
3216130812Smarcel
3217130812Smarcelstatic void
3218130812Smarcelshow_thread_pause_cmd (char *args, int from_tty)
3219130812Smarcel{
3220130812Smarcel  struct proc *thread = cur_thread ();
3221130812Smarcel  int sc = thread->pause_sc;
3222130812Smarcel  check_empty (args, "show task pause");
3223130812Smarcel  printf_unfiltered ("Thread %s %s suspended while gdb has control%s.\n",
3224130812Smarcel		     proc_string (thread),
3225130812Smarcel		     sc ? "is" : "isn't",
3226130812Smarcel		     !sc && thread->inf->pause_sc ? " (but the task is)" : "");
3227130812Smarcel}
3228130812Smarcel
3229130812Smarcelstatic void
3230130812Smarcelset_thread_run_cmd (char *args, int from_tty)
3231130812Smarcel{
3232130812Smarcel  struct proc *thread = cur_thread ();
3233130812Smarcel  thread->run_sc = parse_bool_arg (args, "set thread run") ? 0 : 1;
3234130812Smarcel}
3235130812Smarcel
3236130812Smarcelstatic void
3237130812Smarcelshow_thread_run_cmd (char *args, int from_tty)
3238130812Smarcel{
3239130812Smarcel  struct proc *thread = cur_thread ();
3240130812Smarcel  check_empty (args, "show thread run");
3241130812Smarcel  printf_unfiltered ("Thread %s %s allowed to run.",
3242130812Smarcel		     proc_string (thread),
3243130812Smarcel		     thread->run_sc == 0 ? "is" : "isn't");
3244130812Smarcel}
3245130812Smarcel
3246130812Smarcelstatic void
3247130812Smarcelset_thread_detach_sc_cmd (char *args, int from_tty)
3248130812Smarcel{
3249130812Smarcel  cur_thread ()->detach_sc = parse_int_arg (args,
3250130812Smarcel					    "set thread detach-suspend-count");
3251130812Smarcel}
3252130812Smarcel
3253130812Smarcelstatic void
3254130812Smarcelshow_thread_detach_sc_cmd (char *args, int from_tty)
3255130812Smarcel{
3256130812Smarcel  struct proc *thread = cur_thread ();
3257130812Smarcel  check_empty (args, "show thread detach-suspend-count");
3258130812Smarcel  printf_unfiltered ("Thread %s will be left with a suspend count"
3259130812Smarcel		     " of %d when detaching.\n",
3260130812Smarcel		     proc_string (thread),
3261130812Smarcel		     thread->detach_sc);
3262130812Smarcel}
3263130812Smarcel
3264130812Smarcelstatic void
3265130812Smarcelset_thread_exc_port_cmd (char *args, int from_tty)
3266130812Smarcel{
3267130812Smarcel  struct proc *thread = cur_thread ();
3268130812Smarcel  if (!args)
3269130812Smarcel    error ("No argument to \"set thread exception-port\" command.");
3270130812Smarcel  steal_exc_port (thread, parse_and_eval_address (args));
3271130812Smarcel}
3272130812Smarcel
3273130812Smarcel#if 0
3274130812Smarcelstatic void
3275130812Smarcelshow_thread_cmd (char *args, int from_tty)
3276130812Smarcel{
3277130812Smarcel  struct proc *thread = cur_thread ();
3278130812Smarcel  check_empty (args, "show thread");
3279130812Smarcel  show_thread_run_cmd (0, from_tty);
3280130812Smarcel  show_thread_pause_cmd (0, from_tty);
3281130812Smarcel  if (thread->detach_sc != 0)
3282130812Smarcel    show_thread_detach_sc_cmd (0, from_tty);
3283130812Smarcel}
3284130812Smarcel#endif
3285130812Smarcel
3286130812Smarcelstatic void
3287130812Smarcelthread_takeover_sc_cmd (char *args, int from_tty)
3288130812Smarcel{
3289130812Smarcel  struct proc *thread = cur_thread ();
3290130812Smarcel  thread_basic_info_data_t _info;
3291130812Smarcel  thread_basic_info_t info = &_info;
3292130812Smarcel  mach_msg_type_number_t info_len = THREAD_BASIC_INFO_COUNT;
3293130812Smarcel  error_t err =
3294130812Smarcel  thread_info (thread->port, THREAD_BASIC_INFO, (int *) &info, &info_len);
3295130812Smarcel  if (err)
3296130812Smarcel    error ("%s.", safe_strerror (err));
3297130812Smarcel  thread->sc = info->suspend_count;
3298130812Smarcel  if (from_tty)
3299130812Smarcel    printf_unfiltered ("Suspend count was %d.\n", thread->sc);
3300130812Smarcel  if (info != &_info)
3301130812Smarcel    vm_deallocate (mach_task_self (), (vm_address_t) info,
3302130812Smarcel		   info_len * sizeof (int));
3303130812Smarcel}
3304130812Smarcel
3305130812Smarcel
3306130812Smarcelstatic void
3307130812Smarceladd_thread_commands (void)
3308130812Smarcel{
3309130812Smarcel  add_prefix_cmd ("thread", no_class, set_thread_cmd,
3310130812Smarcel		  "Command prefix for setting thread properties.",
3311130812Smarcel		  &set_thread_cmd_list, "set thread ", 0, &setlist);
3312130812Smarcel  add_prefix_cmd ("default", no_class, show_thread_cmd,
3313130812Smarcel		  "Command prefix for setting default thread properties.",
3314130812Smarcel		  &set_thread_default_cmd_list, "set thread default ", 0,
3315130812Smarcel		  &set_thread_cmd_list);
3316130812Smarcel  add_prefix_cmd ("thread", no_class, set_thread_default_cmd,
3317130812Smarcel		  "Command prefix for showing thread properties.",
3318130812Smarcel		  &show_thread_cmd_list, "show thread ", 0, &showlist);
3319130812Smarcel  add_prefix_cmd ("default", no_class, show_thread_default_cmd,
3320130812Smarcel		  "Command prefix for showing default thread properties.",
3321130812Smarcel		  &show_thread_default_cmd_list, "show thread default ", 0,
3322130812Smarcel		  &show_thread_cmd_list);
3323130812Smarcel
3324130812Smarcel  add_cmd ("pause", class_run, set_thread_pause_cmd,
3325130812Smarcel	   "Set whether the current thread is suspended \
3326130812Smarcelwhile gdb has control.\n\
3327130812SmarcelA value of \"on\" takes effect immediately, otherwise nothing happens\n\
3328130812Smarceluntil the next time the program is continued.  This property normally\n\
3329130812Smarcelhas no effect because the whole task is suspended, however, that may\n\
3330130812Smarcelbe disabled with \"set task pause off\".\n\
3331130812SmarcelThe default value is \"off\".",
3332130812Smarcel	   &set_thread_cmd_list);
3333130812Smarcel  add_cmd ("pause", no_class, show_thread_pause_cmd,
3334130812Smarcel	   "Show whether the current thread is suspended \
3335130812Smarcelwhile gdb has control.",
3336130812Smarcel	   &show_thread_cmd_list);
3337130812Smarcel
3338130812Smarcel  add_cmd ("run", class_run, set_thread_run_cmd,
3339130812Smarcel	   "Set whether the current thread is allowed to run.",
3340130812Smarcel	   &set_thread_cmd_list);
3341130812Smarcel  add_cmd ("run", no_class, show_thread_run_cmd,
3342130812Smarcel	   "Show whether the current thread is allowed to run.",
3343130812Smarcel	   &show_thread_cmd_list);
3344130812Smarcel
3345130812Smarcel  add_cmd ("detach-suspend-count", class_run, set_thread_detach_sc_cmd,
3346130812Smarcel	   "Set the suspend count will leave on the thread when detaching.\n\
3347130812SmarcelNote that this is relative to suspend count when gdb noticed the thread;\n\
3348130812Smarceluse the `thread takeover-suspend-count' to force it to an absolute value.",
3349130812Smarcel	   &set_thread_cmd_list);
3350130812Smarcel  add_cmd ("detach-suspend-count", no_class, show_thread_detach_sc_cmd,
3351130812Smarcel	   "Show the suspend count will leave on the thread when detaching.\n\
3352130812SmarcelNote that this is relative to suspend count when gdb noticed the thread;\n\
3353130812Smarceluse the `thread takeover-suspend-count' to force it to an absolute value.",
3354130812Smarcel	   &show_thread_cmd_list);
3355130812Smarcel
3356130812Smarcel  add_cmd ("exception-port", no_class, set_thread_exc_port_cmd,
3357130812Smarcel	   "Set the thread exception port to which we forward exceptions.\n\
3358130812SmarcelThis overrides the task exception port.\n\
3359130812SmarcelThe argument should be the value of the send right in the task.",
3360130812Smarcel	   &set_thread_cmd_list);
3361130812Smarcel  add_alias_cmd ("excp", "exception-port", no_class, 1, &set_thread_cmd_list);
3362130812Smarcel  add_alias_cmd ("exc-port", "exception-port", no_class, 1,
3363130812Smarcel		 &set_thread_cmd_list);
3364130812Smarcel
3365130812Smarcel  add_cmd ("takeover-suspend-count", no_class, thread_takeover_sc_cmd,
3366130812Smarcel	   "Force the threads absolute suspend-count to be gdb's.\n\
3367130812SmarcelPrior to giving this command, gdb's thread suspend-counts are relative\n\
3368130812Smarcelto the thread's initial suspend-count when gdb notices the threads.",
3369130812Smarcel	   &thread_cmd_list);
3370130812Smarcel}
3371130812Smarcel
3372130812Smarcel
3373130812Smarcelvoid
3374130812Smarcel_initialize_gnu_nat (void)
3375130812Smarcel{
3376130812Smarcel  proc_server = getproc ();
3377130812Smarcel
3378130812Smarcel  init_gnu_ops ();
3379130812Smarcel  add_target (&gnu_ops);
3380130812Smarcel
3381130812Smarcel  add_task_commands ();
3382130812Smarcel  add_thread_commands ();
3383130812Smarcel  add_set_cmd ("gnu-debug", class_maintenance,
3384130812Smarcel	       var_boolean, (char *) &gnu_debug_flag,
3385130812Smarcel	       "Set debugging output for the gnu backend.", &maintenancelist);
3386130812Smarcel}
3387130812Smarcel
3388130812Smarcel#ifdef	FLUSH_INFERIOR_CACHE
3389130812Smarcel
3390130812Smarcel/* When over-writing code on some machines the I-Cache must be flushed
3391130812Smarcel   explicitly, because it is not kept coherent by the lazy hardware.
3392130812Smarcel   This definitely includes breakpoints, for instance, or else we
3393130812Smarcel   end up looping in mysterious Bpt traps */
3394130812Smarcel
3395130812Smarcelvoid
3396130812Smarcelflush_inferior_icache (CORE_ADDR pc, int amount)
3397130812Smarcel{
3398130812Smarcel  vm_machine_attribute_val_t flush = MATTR_VAL_ICACHE_FLUSH;
3399130812Smarcel  error_t ret;
3400130812Smarcel
3401130812Smarcel  ret = vm_machine_attribute (current_inferior->task->port,
3402130812Smarcel			      pc,
3403130812Smarcel			      amount,
3404130812Smarcel			      MATTR_CACHE,
3405130812Smarcel			      &flush);
3406130812Smarcel  if (ret != KERN_SUCCESS)
3407130812Smarcel    warning ("Error flushing inferior's cache : %s", safe_strerror (ret));
3408130812Smarcel}
3409130812Smarcel#endif /* FLUSH_INFERIOR_CACHE */
3410