gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / gnu-nat.c
index 9b93488b41b3d1bf7099800d60462af000255d92..44adda5fe1244c343879360f2e62dabb39441d86 100644 (file)
@@ -83,8 +83,12 @@ extern "C"
 #include "msg_reply_S.h"
 #include "exc_request_U.h"
 #include "msg_U.h"
+
+#include "gnu-nat-mig.h"
 }
 
+struct gnu_nat_target *gnu_target;
+
 static process_t proc_server = MACH_PORT_NULL;
 
 /* If we've sent a proc_wait_request to the proc server, the pid of the
@@ -99,42 +103,12 @@ bool gnu_debug_flag = false;
 /* Forward decls */
 
 static struct inf *make_inf ();
-void inf_clear_wait (struct inf *inf);
-void inf_cleanup (struct inf *inf);
-void inf_startup (struct inf *inf, int pid);
-int inf_update_suspends (struct inf *inf);
-void inf_set_pid (struct inf *inf, pid_t pid);
-void inf_validate_procs (struct inf *inf);
-void inf_steal_exc_ports (struct inf *inf);
-void inf_restore_exc_ports (struct inf *inf);
-void inf_set_threads_resume_sc (struct inf *inf,
-                               struct proc *run_thread,
-                               int run_others);
-int inf_set_threads_resume_sc_for_signal_thread (struct inf *inf);
-void inf_suspend (struct inf *inf);
-void inf_resume (struct inf *inf);
-void inf_set_step_thread (struct inf *inf, struct proc *proc);
-void inf_detach (struct inf *inf);
-void inf_attach (struct inf *inf, int pid);
-void inf_signal (struct inf *inf, enum gdb_signal sig);
-void inf_continue (struct inf *inf);
 
 #define inf_debug(_inf, msg, args...) \
   do { struct inf *__inf = (_inf); \
        debug ("{inf %d %s}: " msg, __inf->pid, \
        host_address_to_string (__inf) , ##args); } while (0)
 
-void proc_abort (struct proc *proc, int force);
-struct proc *make_proc (struct inf *inf, mach_port_t port, int tid);
-struct proc *_proc_free (struct proc *proc);
-int proc_update_sc (struct proc *proc);
-kern_return_t proc_get_exception_port (struct proc *proc, mach_port_t * port);
-kern_return_t proc_set_exception_port (struct proc *proc, mach_port_t port);
-static mach_port_t _proc_get_exc_port (struct proc *proc);
-void proc_steal_exc_port (struct proc *proc, mach_port_t exc_port);
-void proc_restore_exc_port (struct proc *proc);
-int proc_trace (struct proc *proc, int set);
-
 /* Evaluate RPC_EXPR in a scope with the variables MSGPORT and REFPORT bound
    to INF's msg port and task port respectively.  If it has no msg port,
    EIEIO is returned.  INF must refer to a running process!  */
@@ -263,7 +237,7 @@ __proc_pid (struct proc *proc)
 /* Update PROC's real suspend count to match it's desired one.  Returns true
    if we think PROC is now in a runnable state.  */
 int
-proc_update_sc (struct proc *proc)
+gnu_nat_target::proc_update_sc (struct proc *proc)
 {
   int running;
   int err = 0;
@@ -329,7 +303,7 @@ proc_update_sc (struct proc *proc)
    In particular, a thread is precious if it's running (in which case forcing
    it includes suspending it first), or if it has an exception pending.  */
 void
-proc_abort (struct proc *proc, int force)
+gnu_nat_target::proc_abort (struct proc *proc, int force)
 {
   gdb_assert (proc_is_thread (proc));
 
@@ -366,7 +340,7 @@ proc_abort (struct proc *proc, int force)
    that the thread is stopped and aborted first, and sets the state_changed
    field in PROC to true.  */
 thread_state_t
-proc_get_state (struct proc *proc, int will_modify)
+gnu_nat_target::proc_get_state (struct proc *proc, int will_modify)
 {
   int was_aborted = proc->aborted;
 
@@ -403,7 +377,7 @@ proc_get_state (struct proc *proc, int will_modify)
 \f
 /* Set PORT to PROC's exception port.  */
 kern_return_t
-proc_get_exception_port (struct proc * proc, mach_port_t * port)
+gnu_nat_target::proc_get_exception_port (struct proc * proc, mach_port_t * port)
 {
   if (proc_is_task (proc))
     return task_get_exception_port (proc->port, port);
@@ -413,7 +387,7 @@ proc_get_exception_port (struct proc * proc, mach_port_t * port)
 
 /* Set PROC's exception port to PORT.  */
 kern_return_t
-proc_set_exception_port (struct proc * proc, mach_port_t port)
+gnu_nat_target::proc_set_exception_port (struct proc * proc, mach_port_t port)
 {
   proc_debug (proc, "setting exception port: %lu", port);
   if (proc_is_task (proc))
@@ -423,8 +397,8 @@ proc_set_exception_port (struct proc * proc, mach_port_t port)
 }
 
 /* Get PROC's exception port, cleaning up a bit if proc has died.  */
-static mach_port_t
-_proc_get_exc_port (struct proc *proc)
+mach_port_t
+gnu_nat_target::_proc_get_exc_port (struct proc *proc)
 {
   mach_port_t exc_port;
   kern_return_t err = proc_get_exception_port (proc, &exc_port);
@@ -447,7 +421,7 @@ _proc_get_exc_port (struct proc *proc)
    been done.  Stash away any existing exception port so we can
    restore it later.  */
 void
-proc_steal_exc_port (struct proc *proc, mach_port_t exc_port)
+gnu_nat_target::proc_steal_exc_port (struct proc *proc, mach_port_t exc_port)
 {
   mach_port_t cur_exc_port = _proc_get_exc_port (proc);
 
@@ -490,7 +464,7 @@ proc_steal_exc_port (struct proc *proc, mach_port_t exc_port)
    found there at the time, unless *our* exception port has since been
    overwritten, in which case who knows what's going on.  */
 void
-proc_restore_exc_port (struct proc *proc)
+gnu_nat_target::proc_restore_exc_port (struct proc *proc)
 {
   mach_port_t cur_exc_port = _proc_get_exc_port (proc);
 
@@ -520,7 +494,7 @@ proc_restore_exc_port (struct proc *proc)
 /* Turns hardware tracing in PROC on or off when SET is true or false,
    respectively.  Returns true on success.  */
 int
-proc_trace (struct proc *proc, int set)
+gnu_nat_target::proc_trace (struct proc *proc, int set)
 {
   thread_state_t state = proc_get_state (proc, 1);
 
@@ -550,7 +524,7 @@ static int next_thread_id = 1;
 /* Returns a new proc structure with the given fields.  Also adds a
    notification for PORT becoming dead to be sent to INF's notify port.  */
 struct proc *
-make_proc (struct inf *inf, mach_port_t port, int tid)
+gnu_nat_target::make_proc (struct inf *inf, mach_port_t port, int tid)
 {
   kern_return_t err;
   mach_port_t prev_port = MACH_PORT_NULL;
@@ -614,7 +588,7 @@ make_proc (struct inf *inf, mach_port_t port, int tid)
 /* Frees PROC and any resources it uses, and returns the value of PROC's 
    next field.  */
 struct proc *
-_proc_free (struct proc *proc)
+gnu_nat_target::_proc_free (struct proc *proc)
 {
   struct inf *inf = proc->inf;
   struct proc *next = proc->next;
@@ -683,7 +657,7 @@ make_inf (void)
 
 /* Clear INF's target wait status.  */
 void
-inf_clear_wait (struct inf *inf)
+gnu_nat_target::inf_clear_wait (struct inf *inf)
 {
   inf_debug (inf, "clearing wait");
   inf->wait.status.kind = TARGET_WAITKIND_SPURIOUS;
@@ -703,7 +677,7 @@ inf_clear_wait (struct inf *inf)
 
 \f
 void
-inf_cleanup (struct inf *inf)
+gnu_nat_target::inf_cleanup (struct inf *inf)
 {
   inf_debug (inf, "cleanup");
 
@@ -726,7 +700,7 @@ inf_cleanup (struct inf *inf)
 }
 
 void
-inf_startup (struct inf *inf, int pid)
+gnu_nat_target::inf_startup (struct inf *inf, int pid)
 {
   kern_return_t err;
 
@@ -749,7 +723,7 @@ inf_startup (struct inf *inf, int pid)
 \f
 /* Close current process, if any, and attach INF to process PORT.  */
 void
-inf_set_pid (struct inf *inf, pid_t pid)
+gnu_nat_target::inf_set_pid (struct inf *inf, pid_t pid)
 {
   task_t task_port;
   struct proc *task = inf->task;
@@ -801,8 +775,8 @@ inf_set_pid (struct inf *inf, pid_t pid)
    proc server state.  Note that the traced field is only updated from
    the proc server state if we do not have a message port.  If we do
    have a message port we'd better look at the tracemask itself.  */
-static void
-inf_validate_procinfo (struct inf *inf)
+void
+gnu_nat_target::inf_validate_procinfo (struct inf *inf)
 {
   char *noise;
   mach_msg_type_number_t noise_len = 0;
@@ -828,8 +802,8 @@ inf_validate_procinfo (struct inf *inf)
 
 /* Validates INF's task suspend count.  If it's higher than we expect,
    verify with the user before `stealing' the extra count.  */
-static void
-inf_validate_task_sc (struct inf *inf)
+void
+gnu_nat_target::inf_validate_task_sc (struct inf *inf)
 {
   char *noise;
   mach_msg_type_number_t noise_len = 0;
@@ -880,8 +854,8 @@ inf_validate_task_sc (struct inf *inf)
    is.  If INF is running, the resume_sc count of INF's threads will
    be modified, and the signal thread will briefly be run to change
    the trace state.  */
-static void
-inf_set_traced (struct inf *inf, int on)
+void
+gnu_nat_target::inf_set_traced (struct inf *inf, int on)
 {
   if (on == inf->traced)
     return;
@@ -917,7 +891,7 @@ inf_set_traced (struct inf *inf, int on)
    counts in the safe order.  Returns true if at least one thread is
    thought to be running.  */
 int
-inf_update_suspends (struct inf *inf)
+gnu_nat_target::inf_update_suspends (struct inf *inf)
 {
   struct proc *task = inf->task;
 
@@ -1008,7 +982,7 @@ inf_threads (struct inf *inf, inf_threads_ftype *f, void *arg)
 \f
 /* Make INF's list of threads be consistent with reality of TASK.  */
 void
-inf_validate_procs (struct inf *inf)
+gnu_nat_target::inf_validate_procs (struct inf *inf)
 {
   thread_array_t threads;
   mach_msg_type_number_t num_threads, i;
@@ -1107,12 +1081,12 @@ inf_validate_procs (struct inf *inf)
            if (inferior_ptid == ptid_t (inf->pid))
              /* This is the first time we're hearing about thread
                 ids, after a fork-child.  */
-             thread_change_ptid (inferior_ptid, ptid);
+             thread_change_ptid (this, inferior_ptid, ptid);
            else if (inf->pending_execs != 0)
              /* This is a shell thread.  */
-             add_thread_silent (ptid);
+             add_thread_silent (this, ptid);
            else
-             add_thread (ptid);
+             add_thread (this, ptid);
          }
       }
 
@@ -1129,7 +1103,7 @@ inf_update_procs (struct inf *inf)
   if (!inf->task)
     return 0;
   if (!inf->threads_up_to_date)
-    inf_validate_procs (inf);
+    gnu_target->inf_validate_procs (inf);
   return !!inf->task;
 }
 
@@ -1137,8 +1111,8 @@ inf_update_procs (struct inf *inf)
    and others are set to their run_sc if RUN_OTHERS is true, and otherwise
    their pause_sc.  */
 void
-inf_set_threads_resume_sc (struct inf *inf,
-                          struct proc *run_thread, int run_others)
+gnu_nat_target::inf_set_threads_resume_sc (struct inf *inf,
+                                          struct proc *run_thread, int run_others)
 {
   struct proc *thread;
 
@@ -1156,7 +1130,7 @@ inf_set_threads_resume_sc (struct inf *inf,
 /* Cause INF to continue execution immediately; individual threads may still
    be suspended (but their suspend counts will be updated).  */
 void
-inf_resume (struct inf *inf)
+gnu_nat_target::inf_resume (struct inf *inf)
 {
   struct proc *thread;
 
@@ -1181,7 +1155,7 @@ inf_resume (struct inf *inf)
 /* Cause INF to stop execution immediately; individual threads may still
    be running.  */
 void
-inf_suspend (struct inf *inf)
+gnu_nat_target::inf_suspend (struct inf *inf)
 {
   struct proc *thread;
 
@@ -1201,7 +1175,7 @@ inf_suspend (struct inf *inf)
    function changes it to be PROC, changing any old step_thread to be
    a normal one.  A PROC of 0 clears any existing value.  */
 void
-inf_set_step_thread (struct inf *inf, struct proc *thread)
+gnu_nat_target::inf_set_step_thread (struct inf *inf, struct proc *thread)
 {
   gdb_assert (!thread || proc_is_thread (thread));
 
@@ -1227,7 +1201,7 @@ inf_set_step_thread (struct inf *inf, struct proc *thread)
    (plus whatever other thread are set to always run).  Returns true if we
    did so, or false if we can't find a signal thread.  */
 int
-inf_set_threads_resume_sc_for_signal_thread (struct inf *inf)
+gnu_nat_target::inf_set_threads_resume_sc_for_signal_thread (struct inf *inf)
 {
   if (inf->signal_thread)
     {
@@ -1249,7 +1223,7 @@ inf_update_signal_thread (struct inf *inf)
 \f
 /* Detachs from INF's inferior task, letting it run once again...  */
 void
-inf_detach (struct inf *inf)
+gnu_nat_target::inf_detach (struct inf *inf)
 {
   struct proc *task = inf->task;
 
@@ -1291,7 +1265,7 @@ inf_detach (struct inf *inf)
 /* Attaches INF to the process with process id PID, returning it in a
    suspended state suitable for debugging.  */
 void
-inf_attach (struct inf *inf, int pid)
+gnu_nat_target::inf_attach (struct inf *inf, int pid)
 {
   inf_debug (inf, "attaching: %d", pid);
 
@@ -1304,7 +1278,7 @@ inf_attach (struct inf *inf, int pid)
 \f
 /* Makes sure that we've got our exception ports entrenched in the process.  */
 void
-inf_steal_exc_ports (struct inf *inf)
+gnu_nat_target::inf_steal_exc_ports (struct inf *inf)
 {
   struct proc *thread;
 
@@ -1319,7 +1293,7 @@ inf_steal_exc_ports (struct inf *inf)
 
 /* Makes sure the process has its own exception ports.  */
 void
-inf_restore_exc_ports (struct inf *inf)
+gnu_nat_target::inf_restore_exc_ports (struct inf *inf)
 {
   struct proc *thread;
 
@@ -1337,7 +1311,7 @@ inf_restore_exc_ports (struct inf *inf)
    signal 0, will continue it.  INF is assumed to be in a paused state, and
    the resume_sc's of INF's threads may be affected.  */
 void
-inf_signal (struct inf *inf, enum gdb_signal sig)
+gnu_nat_target::inf_signal (struct inf *inf, enum gdb_signal sig)
 {
   kern_return_t err = 0;
   int host_sig = gdb_signal_to_host (sig);
@@ -1425,7 +1399,7 @@ inf_signal (struct inf *inf, enum gdb_signal sig)
 /* Continue INF without delivering a signal.  This is meant to be used
    when INF does not have a message port.  */
 void
-inf_continue (struct inf *inf)
+gnu_nat_target::inf_continue (struct inf *inf)
 {
   process_t proc;
   kern_return_t err = proc_pid2proc (proc_server, inf->pid, &proc);
@@ -1456,13 +1430,7 @@ struct inf *gnu_current_inf = 0;
 
 /* The inferior being waited for by gnu_wait.  Since GDB is decidely not
    multi-threaded, we don't bother to lock this.  */
-struct inf *waiting_inf;
-
-/* MIG stubs are not yet ready for C++ compilation.  */
-extern "C" int exc_server (mach_msg_header_t *, mach_msg_header_t *);
-extern "C" int msg_reply_server (mach_msg_header_t *, mach_msg_header_t *);
-extern "C" int notify_server (mach_msg_header_t *, mach_msg_header_t *);
-extern "C" int process_reply_server (mach_msg_header_t *, mach_msg_header_t *);
+static struct inf *waiting_inf;
 
 /* Wait for something to happen in the inferior, returning what in STATUS.  */
 
@@ -1850,7 +1818,7 @@ S_proc_wait_reply (mach_port_t reply, kern_return_t err,
          inf->no_wait = 1;
 
          /* Since we can't see the inferior's signals, don't trap them.  */
-         inf_set_traced (inf, 0);
+         gnu_target->inf_set_traced (inf, 0);
        }
     }
   else if (pid == inf->pid)
@@ -2144,21 +2112,22 @@ gnu_nat_target::create_inferior (const char *exec_file,
 
   inf_debug (inf, "creating inferior");
 
+  if (!target_is_pushed (this))
+    push_target (this);
+
   pid = fork_inferior (exec_file, allargs, env, gnu_ptrace_me,
                        NULL, NULL, NULL, NULL);
 
   /* We have something that executes now.  We'll be running through
      the shell at this point (if startup-with-shell is true), but the
      pid shouldn't change.  */
-  add_thread_silent (ptid_t (pid));
+  add_thread_silent (this, ptid_t (pid));
 
   /* Attach to the now stopped child, which is actually a shell...  */
   inf_debug (inf, "attaching to child: %d", pid);
 
   inf_attach (inf, pid);
 
-  push_target (this);
-
   inf->pending_execs = 1;
   inf->nomsg = 1;
   inf->traced = 1;
@@ -2168,7 +2137,7 @@ gnu_nat_target::create_inferior (const char *exec_file,
   inf_resume (inf);
 
   /* We now have thread info.  */
-  thread_change_ptid (inferior_ptid,
+  thread_change_ptid (this, inferior_ptid,
                      ptid_t (inf->pid, inf_pick_first_thread (), 0));
 
   gdb_startup_inferior (pid, START_INFERIOR_TRAPS_EXPECTED);
@@ -2274,7 +2243,7 @@ gnu_nat_target::detach (inferior *inf, int from_tty)
   inf_detach (gnu_current_inf);
 
   inferior_ptid = null_ptid;
-  detach_inferior (find_inferior_pid (pid));
+  detach_inferior (find_inferior_pid (this, pid));
 
   maybe_unpush_target ();
 }
@@ -2552,7 +2521,6 @@ gnu_xfer_auxv (gdb_byte *readbuf, const gdb_byte *writebuf,
                    ? gnu_current_inf->task->port : 0)
                 : 0);
   process_t proc;
-  int res;
   kern_return_t err;
   vm_address_t entry;
   ElfW(auxv_t) auxv[2];
@@ -2642,7 +2610,6 @@ gnu_nat_target::find_memory_regions (find_memory_region_ftype func,
       mach_port_t object_name;
       vm_offset_t offset;
       vm_size_t region_length = VM_MAX_ADDRESS - region_address;
-      vm_address_t old_address = region_address;
 
       err = vm_region (task,
                       &region_address,
@@ -2841,7 +2808,7 @@ set_task_pause_cmd (int arg, int from_tty)
   if (old_sc == 0 && inf->pause_sc != 0)
     /* If the task is currently unsuspended, immediately suspend it,
        otherwise wait until the next time it gets control.  */
-    inf_suspend (inf);
+    gnu_target->inf_suspend (inf);
 }
 
 static void
@@ -2937,8 +2904,8 @@ show_thread_default_detach_sc_cmd (const char *args, int from_tty)
 \f
 /* Steal a send right called NAME in the inferior task, and make it PROC's
    saved exception port.  */
-static void
-steal_exc_port (struct proc *proc, mach_port_t name)
+void
+gnu_nat_target::steal_exc_port (struct proc *proc, mach_port_t name)
 {
   kern_return_t err;
   mach_port_t port;
@@ -2979,7 +2946,7 @@ set_task_exc_port_cmd (const char *args, int from_tty)
 
   if (!args)
     error (_("No argument to \"set task exception-port\" command."));
-  steal_exc_port (inf->task, parse_and_eval_address (args));
+  gnu_target->steal_exc_port (inf->task, parse_and_eval_address (args));
 }
 
 static void
@@ -3039,7 +3006,7 @@ set_signals_cmd (int arg, int from_tty)
 
   if (inf->task && inf->want_signals != inf->traced)
     /* Make this take effect immediately in a running process.  */
-    inf_set_traced (inf, inf->want_signals);
+    gnu_target->inf_set_traced (inf, inf->want_signals);
 }
 
 static void
@@ -3337,7 +3304,7 @@ set_thread_pause_cmd (const char *args, int from_tty)
   if (old_sc == 0 && thread->pause_sc != 0 && thread->inf->pause_sc == 0)
     /* If the task is currently unsuspended, immediately suspend it,
        otherwise wait until the next time it gets control.  */
-    inf_suspend (thread->inf);
+    gnu_target->inf_suspend (thread->inf);
 }
 
 static void
@@ -3398,7 +3365,7 @@ set_thread_exc_port_cmd (const char *args, int from_tty)
 
   if (!args)
     error (_("No argument to \"set thread exception-port\" command."));
-  steal_exc_port (thread, parse_and_eval_address (args));
+  gnu_target->steal_exc_port (thread, parse_and_eval_address (args));
 }
 
 #if 0
This page took 0.057032 seconds and 4 git commands to generate.