/* Darwin support for GDB, the GNU debugger.
- Copyright (C) 2008-2019 Free Software Foundation, Inc.
+ Copyright (C) 2008-2020 Free Software Foundation, Inc.
Contributed by AdaCore.
#define PTRACE(CMD, PID, ADDR, SIG) \
darwin_ptrace(#CMD, CMD, (PID), (ADDR), (SIG))
-static ptid_t darwin_wait (ptid_t ptid, struct target_waitstatus *status);
-
static void darwin_ptrace_me (void);
-static void darwin_ptrace_him (int pid);
-
static void darwin_encode_reply (mig_reply_error_t *reply,
mach_msg_header_t *hdr, integer_t code);
return (int)(tl - tr);
}
-static void
-darwin_check_new_threads (struct inferior *inf)
+void
+darwin_nat_target::check_new_threads (inferior *inf)
{
kern_return_t kret;
thread_array_t thread_list;
pti->msg_state = DARWIN_RUNNING;
/* Add the new thread. */
- add_thread_with_info (ptid_t (inf->pid, 0, new_id), pti);
+ add_thread_with_info (this, ptid_t (inf->pid, 0, new_id), pti);
new_thread_vec.push_back (pti);
new_ix++;
continue;
{
/* A thread was removed. */
struct thread_info *thr
- = find_thread_ptid (ptid_t (inf->pid, 0, old_id));
+ = find_thread_ptid (this, ptid_t (inf->pid, 0, old_id));
delete_thread (thr);
kret = mach_port_deallocate (gdb_task, old_id);
MACH_CHECK_ERROR (kret);
MACH_CHECK_ERROR (kret);
}
-static int
-find_inferior_task_it (struct inferior *inf, void *port_ptr)
-{
- darwin_inferior *priv = get_darwin_inferior (inf);
-
- return priv != nullptr && priv->task == *(task_t *)port_ptr;
-}
-
-static int
-find_inferior_pid_it (struct inferior *inf, void *pid_ptr)
-{
- return inf->pid == *(int *)pid_ptr;
-}
-
/* Return an inferior by task port. */
static struct inferior *
darwin_find_inferior_by_task (task_t port)
{
- return iterate_over_inferiors (&find_inferior_task_it, &port);
+ for (inferior *inf : all_inferiors ())
+ {
+ darwin_inferior *priv = get_darwin_inferior (inf);
+
+ if (priv != nullptr && priv->task == port)
+ return inf;
+ }
+ return nullptr;
}
/* Return an inferior by pid port. */
static struct inferior *
darwin_find_inferior_by_pid (int pid)
{
- return iterate_over_inferiors (&find_inferior_pid_it, &pid);
+ for (inferior *inf : all_inferiors ())
+ {
+ if (inf->pid == pid)
+ return inf;
+ }
+ return nullptr;
}
/* Return a thread by port. */
}
}
-/* Iterator functions. */
-
-static int
-darwin_suspend_inferior_it (struct inferior *inf, void *arg)
-{
- darwin_suspend_inferior (inf);
- darwin_check_new_threads (inf);
- return 0;
-}
-
-static int
-darwin_resume_inferior_it (struct inferior *inf, void *arg)
-{
- darwin_resume_inferior (inf);
- return 0;
-}
-
static void
darwin_dump_message (mach_msg_header_t *hdr, int disp_body)
{
/* Decode an exception message. */
-static int
-darwin_decode_exception_message (mach_msg_header_t *hdr,
- struct inferior **pinf,
- darwin_thread_t **pthread)
+int
+darwin_nat_target::decode_exception_message (mach_msg_header_t *hdr,
+ inferior **pinf,
+ darwin_thread_t **pthread)
{
mach_msg_body_t *bod = (mach_msg_body_t*)(hdr + 1);
mach_msg_port_descriptor_t *desc = (mach_msg_port_descriptor_t *)(bod + 1);
/* Find thread by port. */
/* Check for new threads. Do it early so that the port in the exception
message can be deallocated. */
- darwin_check_new_threads (inf);
+ check_new_threads (inf);
/* Free the thread port (as gdb knows the thread, it has already has a right
for it, so this just decrement a reference counter). */
darwin_resume_thread (inf, thread, step, nsignal);
}
-struct resume_inferior_threads_param
-{
- int step;
- int nsignal;
-};
-
-static int
-darwin_resume_inferior_threads_it (struct inferior *inf, void *param)
-{
- int step = ((struct resume_inferior_threads_param *)param)->step;
- int nsignal = ((struct resume_inferior_threads_param *)param)->nsignal;
-
- darwin_resume_inferior_threads (inf, step, nsignal);
-
- return 0;
-}
-
/* Suspend all threads of INF. */
static void
/* minus_one_ptid is RESUME_ALL. */
if (ptid == minus_one_ptid)
{
- struct resume_inferior_threads_param param;
-
- param.nsignal = nsignal;
- param.step = step;
-
/* Resume threads. */
- iterate_over_inferiors (darwin_resume_inferior_threads_it, ¶m);
+ for (inferior *inf : all_inferiors ())
+ darwin_resume_inferior_threads (inf, step, nsignal);
+
/* Resume tasks. */
- iterate_over_inferiors (darwin_resume_inferior_it, NULL);
+ for (inferior *inf : all_inferiors ())
+ darwin_resume_inferior (inf);
}
else
{
- struct inferior *inf = find_inferior_ptid (ptid);
+ inferior *inf = find_inferior_ptid (this, ptid);
long tid = ptid.tid ();
/* Stop the inferior (should be useless). */
}
}
-static ptid_t
-darwin_decode_message (mach_msg_header_t *hdr,
- darwin_thread_t **pthread,
- struct inferior **pinf,
- struct target_waitstatus *status)
+ptid_t
+darwin_nat_target::decode_message (mach_msg_header_t *hdr,
+ darwin_thread_t **pthread,
+ inferior **pinf,
+ target_waitstatus *status)
{
darwin_thread_t *thread;
struct inferior *inf;
int res;
/* Decode message. */
- res = darwin_decode_exception_message (hdr, &inf, &thread);
+ res = decode_exception_message (hdr, &inf, &thread);
if (res < 0)
{
return minus_one_ptid;
}
-static int
-cancel_breakpoint (ptid_t ptid)
+int
+darwin_nat_target::cancel_breakpoint (ptid_t ptid)
{
/* Arrange for a breakpoint to be hit again later. We will handle
the current event, eventually we will resume this thread, and this
delete or disable the breakpoint, but the thread will have already
tripped on it. */
- struct regcache *regcache = get_thread_regcache (ptid);
+ struct regcache *regcache = get_thread_regcache (this, ptid);
struct gdbarch *gdbarch = regcache->arch ();
CORE_ADDR pc;
return 0;
}
-static ptid_t
-darwin_wait (ptid_t ptid, struct target_waitstatus *status)
+ptid_t
+darwin_nat_target::wait_1 (ptid_t ptid, struct target_waitstatus *status)
{
kern_return_t kret;
union
mach_msg_header_t *hdr = &msgin.hdr;
ptid_t res;
darwin_thread_t *thread;
- struct inferior *inf;
inferior_debug
(2, _("darwin_wait: waiting for a message pid=%d thread=%lx\n"),
/* Handle fake stop events at first. */
if (darwin_inf_fake_stop != NULL)
{
- inf = darwin_inf_fake_stop;
+ inferior *inf = darwin_inf_fake_stop;
darwin_inf_fake_stop = NULL;
darwin_inferior *priv = get_darwin_inferior (inf);
if (darwin_debug_flag > 10)
darwin_dump_message (hdr, darwin_debug_flag > 11);
- res = darwin_decode_message (hdr, &thread, &inf, status);
+ inferior *inf;
+ res = decode_message (hdr, &thread, &inf, status);
if (res == minus_one_ptid)
continue;
while (status->kind == TARGET_WAITKIND_IGNORE);
/* Stop all tasks. */
- iterate_over_inferiors (darwin_suspend_inferior_it, NULL);
+ for (inferior *inf : all_inferiors (this))
+ {
+ darwin_suspend_inferior (inf);
+ check_new_threads (inf);
+ }
/* Read pending messages. */
while (1)
if (darwin_debug_flag > 10)
darwin_dump_message (hdr, darwin_debug_flag > 11);
- ptid2 = darwin_decode_message (hdr, &thread, &inf, &status2);
+ inferior *inf;
+ ptid2 = decode_message (hdr, &thread, &inf, &status2);
if (inf != NULL && thread != NULL
&& thread->event.ex_type == EXC_BREAKPOINT)
darwin_nat_target::wait (ptid_t ptid, struct target_waitstatus *status,
int options)
{
- return darwin_wait (ptid, status);
+ return wait_1 (ptid, status);
}
void
}
}
-static void
-darwin_stop_inferior (struct inferior *inf)
+void
+darwin_nat_target::stop_inferior (inferior *inf)
{
struct target_waitstatus wstatus;
ptid_t ptid;
if (priv->no_ptrace)
return;
- res = kill (inf->pid, SIGSTOP);
+ res = ::kill (inf->pid, SIGSTOP);
if (res != 0)
warning (_("cannot kill: %s"), safe_strerror (errno));
/* Wait until the process is really stopped. */
while (1)
{
- ptid = darwin_wait (inferior_ptid, &wstatus);
+ ptid = wait_1 (inferior_ptid, &wstatus);
if (wstatus.kind == TARGET_WAITKIND_STOPPED
&& wstatus.value.sig == GDB_SIGNAL_STOP)
break;
darwin_resume_inferior (inf);
- ptid = darwin_wait (inferior_ptid, &wstatus);
+ ptid = wait_1 (inferior_ptid, &wstatus);
}
else if (errno != ESRCH)
warning (_("Failed to kill inferior: kill (%d, 9) returned [%s]"),
gdb_assert_not_reached ("did not find gdb thread for darwin thread");
}
-static void
-darwin_init_thread_list (struct inferior *inf)
+void
+darwin_nat_target::init_thread_list (inferior *inf)
{
- darwin_check_new_threads (inf);
+ check_new_threads (inf);
darwin_inferior *priv = get_darwin_inferior (inf);
mark_fd_no_cloexec (ptrace_fds[1]);
}
-static void
-darwin_ptrace_him (int pid)
+void
+darwin_nat_target::ptrace_him (int pid)
{
struct inferior *inf = current_inferior ();
darwin_attach_pid (inf);
/* Let's the child run. */
- close (ptrace_fds[0]);
- close (ptrace_fds[1]);
+ ::close (ptrace_fds[0]);
+ ::close (ptrace_fds[1]);
unmark_fd_no_cloexec (ptrace_fds[0]);
unmark_fd_no_cloexec (ptrace_fds[1]);
- darwin_init_thread_list (inf);
+ init_thread_list (inf);
gdb_startup_inferior (pid, START_INFERIOR_TRAPS_EXPECTED);
}
char **env, int from_tty)
{
gdb::optional<scoped_restore_tmpl<bool>> restore_startup_with_shell;
+ darwin_nat_target *the_target = this;
if (startup_with_shell && may_have_sip ())
{
/* Do the hard work. */
fork_inferior (exec_file, allargs, env, darwin_ptrace_me,
- darwin_ptrace_him, darwin_pre_ptrace, copied_shell,
+ [the_target] (int pid)
+ {
+ the_target->ptrace_him (pid);
+ },
+ darwin_pre_ptrace, copied_shell,
darwin_execvp);
}
\f
darwin_suspend_inferior (inf);
- darwin_init_thread_list (inf);
+ init_thread_list (inf);
darwin_inferior *priv = get_darwin_inferior (inf);
/* If ptrace() is in use, stop the process. */
if (!priv->no_ptrace)
- darwin_stop_inferior (inf);
+ stop_inferior (inf);
kret = darwin_restore_exception_ports (priv);
MACH_CHECK_ERROR (kret);
return true;
}
+void _initialize_darwin_nat ();
void
_initialize_darwin_nat ()
{