/* Interface GDB to the GNU Hurd.
- Copyright (C) 1992-2014 Free Software Foundation, Inc.
+ Copyright (C) 1992-2016 Free Software Foundation, Inc.
This file is part of GDB.
#include "defs.h"
#include <ctype.h>
-#include <errno.h>
#include <limits.h>
#include <setjmp.h>
#include <signal.h>
-#include <stdio.h>
-#include <string.h>
#include <sys/ptrace.h>
#include <mach.h>
#include "gdbcmd.h"
#include "gdbcore.h"
#include "gdbthread.h"
-#include "gdb_assert.h"
#include "gdb_obstack.h"
#include "gnu-nat.h"
unsigned int no_wait:1;
/* When starting a new inferior, we don't try to validate threads until all
- the proper execs have been done. This is a count of how many execs we
+ the proper execs have been done, which this flag states we still
expect to happen. */
- unsigned pending_execs;
+ unsigned int pending_execs:1;
/* Fields describing global state. */
error_t
proc_set_exception_port (struct proc * proc, mach_port_t port)
{
- proc_debug (proc, "setting exception port: %d", port);
+ proc_debug (proc, "setting exception port: %lu", port);
if (proc_is_task (proc))
return task_set_exception_port (proc->port, port);
else
{
error_t err = 0;
- proc_debug (proc, "inserting exception port: %d", exc_port);
+ proc_debug (proc, "inserting exception port: %lu", exc_port);
if (cur_exc_port != exc_port)
/* Put in our exception port. */
proc->saved_exc_port = cur_exc_port;
}
- proc_debug (proc, "saved exception port: %d", proc->saved_exc_port);
+ proc_debug (proc, "saved exception port: %lu", proc->saved_exc_port);
if (!err)
proc->exc_port = exc_port;
{
error_t err;
mach_port_t prev_port = MACH_PORT_NULL;
- struct proc *proc = xmalloc (sizeof (struct proc));
+ struct proc *proc = XNEW (struct proc);
proc->port = port;
proc->tid = tid;
MACH_MSG_TYPE_MAKE_SEND_ONCE,
&prev_port);
if (err)
- warning (_("Couldn't request notification for port %d: %s"),
+ warning (_("Couldn't request notification for port %lu: %s"),
port, safe_strerror (err));
else
{
- proc_debug (proc, "notifications to: %d", inf->event_port);
+ proc_debug (proc, "notifications to: %lu", inf->event_port);
if (prev_port != MACH_PORT_NULL)
mach_port_deallocate (mach_task_self (), prev_port);
}
static struct inf *
make_inf (void)
{
- struct inf *inf = xmalloc (sizeof (struct inf));
+ struct inf *inf = XNEW (struct inf);
inf->task = 0;
inf->threads = 0;
pid, safe_strerror (err));
}
- inf_debug (inf, "setting task: %d", task_port);
+ inf_debug (inf, "setting task: %lu", task_port);
if (inf->pause_sc)
task_suspend (task_port);
inf->nomsg = !!(pi->state & PI_NOMSG);
if (inf->nomsg)
inf->traced = !!(pi->state & PI_TRACED);
- vm_deallocate (mach_task_self (), (vm_address_t) pi, pi_len);
+ vm_deallocate (mach_task_self (), (vm_address_t) pi,
+ pi_len * sizeof (*(procinfo_t) 0));
if (noise_len > 0)
vm_deallocate (mach_task_self (), (vm_address_t) noise, noise_len);
}
suspend_count = pi->taskinfo.suspend_count;
- vm_deallocate (mach_task_self (), (vm_address_t) pi, pi_len);
+ vm_deallocate (mach_task_self (), (vm_address_t) pi,
+ pi_len * sizeof (*(procinfo_t) 0));
if (noise_len > 0)
- vm_deallocate (mach_task_self (), (vm_address_t) pi, pi_len);
+ vm_deallocate (mach_task_self (), (vm_address_t) noise, noise_len);
if (inf->task->cur_sc < suspend_count)
{
- int abort;
-
- target_terminal_ours (); /* Allow I/O. */
- abort = !query (_("Pid %d has an additional task suspend count of %d;"
- " clear it? "), inf->pid,
- suspend_count - inf->task->cur_sc);
- target_terminal_inferior (); /* Give it back to the child. */
-
- if (abort)
+ if (!query (_("Pid %d has an additional task suspend count of %d;"
+ " clear it? "), inf->pid,
+ suspend_count - inf->task->cur_sc))
error (_("Additional task suspend count left untouched."));
inf->task->cur_sc = suspend_count;
return 0;
}
+/* See gnu-nat.h. */
+
+void
+inf_threads (struct inf *inf, inf_threads_ftype *f, void *arg)
+{
+ struct proc *thread;
+
+ for (thread = inf->threads; thread; thread = thread->next)
+ f (thread, arg);
+}
+
\f
/* Make INF's list of threads be consistent with reality of TASK. */
void
else
inf->threads = thread;
last = thread;
- proc_debug (thread, "new thread: %d", threads[i]);
+ proc_debug (thread, "new thread: %lu", threads[i]);
ptid = ptid_build (inf->pid, thread->tid, 0);
struct exc_state *e = &w->exc;
inf_debug (inf, "passing through exception:"
- " task = %d, thread = %d, exc = %d"
+ " task = %lu, thread = %lu, exc = %d"
", code = %d, subcode = %d",
w->thread->port, inf->task->port,
e->exception, e->code, e->subcode);
while execing. */
{
w->suppress = 1;
- inf_debug (inf, "pending_execs = %d, ignoring minor event",
- inf->pending_execs);
+ inf_debug (inf, "pending_execs, ignoring minor event");
}
else if (kind == TARGET_WAITKIND_STOPPED
&& w->status.value.sig == GDB_SIGNAL_TRAP)
/* Ah hah! A SIGTRAP from the inferior while starting up probably
means we've succesfully completed an exec! */
{
- if (--inf->pending_execs == 0)
- /* We're done! */
- {
-#if 0 /* do we need this? */
- prune_threads (1); /* Get rid of the old shell
- threads. */
- renumber_threads (0); /* Give our threads reasonable
- names. */
-#endif
- }
- inf_debug (inf, "pending exec completed, pending_execs => %d",
- inf->pending_execs);
+ inf_debug (inf, "one pending exec completed");
}
else if (kind == TARGET_WAITKIND_STOPPED)
/* It's possible that this signal is because of a crashed process
struct proc *thread = inf_port_to_thread (inf, thread_port);
inf_debug (waiting_inf,
- "thread = %d, task = %d, exc = %d, code = %d, subcode = %d",
+ "thread = %lu, task = %lu, exc = %d, code = %d, subcode = %d",
thread_port, task_port, exception, code, subcode);
if (!thread)
{
if (thread->exc_port == port)
{
- inf_debug (waiting_inf, "Handler is thread exception port <%d>",
+ inf_debug (waiting_inf, "Handler is thread exception port <%lu>",
thread->saved_exc_port);
inf->wait.exc.handler = thread->saved_exc_port;
}
else
{
- inf_debug (waiting_inf, "Handler is task exception port <%d>",
+ inf_debug (waiting_inf, "Handler is task exception port <%lu>",
inf->task->saved_exc_port);
inf->wait.exc.handler = inf->task->saved_exc_port;
gdb_assert (inf->task->exc_port == port);
{
struct inf *inf = waiting_inf;
- inf_debug (waiting_inf, "port = %d", dead_port);
+ inf_debug (waiting_inf, "port = %lu", dead_port);
if (inf->task && inf->task->port == dead_port)
{
\f
#define ILL_RPC(fun, ...) \
+ extern kern_return_t fun (__VA_ARGS__); \
kern_return_t fun (__VA_ARGS__) \
{ \
warning (_("illegal rpc: %s"), #fun); \
task_terminate (task->port);
inf_set_pid (gnu_current_inf, -1);
}
- target_mourn_inferior ();
+ target_mourn_inferior (inferior_ptid);
}
/* Clean up after the inferior dies. */
{
inf_debug (gnu_current_inf, "rip");
inf_detach (gnu_current_inf);
- unpush_target (ops);
- generic_mourn_inferior ();
+ inf_child_mourn_inferior (ops);
}
\f
push_target (ops);
- inf->pending_execs = 2;
+ inf->pending_execs = 1;
inf->nomsg = 1;
inf->traced = 1;
thread_change_ptid (inferior_ptid,
ptid_build (inf->pid, inf_pick_first_thread (), 0));
- startup_inferior (inf->pending_execs);
+ startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
+ inf->pending_execs = 0;
inf_validate_procinfo (inf);
inf_update_signal_thread (inf);
/* Attach to process PID, then initialize for debugging it
and wait for the trace-trap that results from attaching. */
static void
-gnu_attach (struct target_ops *ops, char *args, int from_tty)
+gnu_attach (struct target_ops *ops, const char *args, int from_tty)
{
int pid;
char *exec_file;
inferior_ptid = null_ptid;
detach_inferior (pid);
- unpush_target (ops); /* Pop out of handling an inferior. */
+ inf_child_maybe_unpush_target (ops);
}
\f
static void
-gnu_terminal_init_inferior (void)
+gnu_terminal_init (struct target_ops *self)
{
gdb_assert (gnu_current_inf);
- terminal_init_inferior_with_pgrp (gnu_current_inf->pid);
+ child_terminal_init_with_pgrp (gnu_current_inf->pid);
}
static void
-gnu_stop (ptid_t ptid)
+gnu_stop (struct target_ops *self, ptid_t ptid)
{
error (_("to_stop target function not implemented"));
}
vm_size_t aligned_length =
(vm_size_t) round_page (addr + length) - low_address;
pointer_t copied;
- int copy_count;
+ mach_msg_type_number_t copy_count;
/* Get memory from inferior with page aligned addresses. */
err = vm_read (task, low_address, aligned_length, &copied, ©_count);
vm_size_t aligned_length =
(vm_size_t) round_page (addr + length) - low_address;
pointer_t copied;
- int copy_count;
+ mach_msg_type_number_t copy_count;
int deallocate = 0;
char *errstr = "Bug in gnu_write_inferior";
struct vm_region_list *region_element;
- struct vm_region_list *region_head = (struct vm_region_list *) NULL;
+ struct vm_region_list *region_head = NULL;
/* Get memory from inferior with page aligned addresses. */
err = vm_read (task,
/* Check for holes in memory. */
if (old_address != region_address)
{
- warning (_("No memory at 0x%x. Nothing written"),
+ warning (_("No memory at 0x%lx. Nothing written"),
old_address);
err = KERN_SUCCESS;
length = 0;
if (!(max_protection & VM_PROT_WRITE))
{
- warning (_("Memory at address 0x%x is unwritable. "
+ warning (_("Memory at address 0x%lx is unwritable. "
"Nothing written"),
old_address);
err = KERN_SUCCESS;
}
/* Chain the regions for later use. */
- region_element =
- (struct vm_region_list *)
- obstack_alloc (®ion_obstack, sizeof (struct vm_region_list));
+ region_element = XOBNEW (®ion_obstack, struct vm_region_list);
region_element->protection = protection;
region_element->start = region_address;
/* Call FUNC on each memory region in the task. */
static int
-gnu_find_memory_regions (find_memory_region_ftype func, void *data)
+gnu_find_memory_regions (struct target_ops *self,
+ find_memory_region_ftype func, void *data)
{
error_t err;
task_t task;
{
struct target_ops *t = inf_child_target ();
- t->to_shortname = "GNU";
- t->to_longname = "GNU Hurd process";
- t->to_doc = "GNU Hurd process";
-
t->to_attach = gnu_attach;
t->to_attach_no_wait = 1;
t->to_detach = gnu_detach;
t->to_wait = gnu_wait;
t->to_xfer_partial = gnu_xfer_partial;
t->to_find_memory_regions = gnu_find_memory_regions;
- t->to_terminal_init = gnu_terminal_init_inferior;
+ t->to_terminal_init = gnu_terminal_init;
t->to_kill = gnu_kill_inferior;
t->to_create_inferior = gnu_create_inferior;
t->to_mourn_inferior = gnu_mourn_inferior;
name, MACH_MSG_TYPE_COPY_SEND,
&port, &port_type);
if (err)
- error (_("Couldn't extract send right %d from inferior: %s"),
+ error (_("Couldn't extract send right %lu from inferior: %s"),
name, safe_strerror (err));
if (proc->saved_exc_port)
&setlist);
/* Commands to show information about the task's ports. */
- add_cmd ("send-rights", class_info, info_send_rights_cmd,
- _("Show information about the task's send rights"),
- &infolist);
- add_cmd ("receive-rights", class_info, info_recv_rights_cmd,
- _("Show information about the task's receive rights"),
- &infolist);
- add_cmd ("port-rights", class_info, info_port_rights_cmd,
- _("Show information about the task's port rights"),
- &infolist);
- add_cmd ("port-sets", class_info, info_port_sets_cmd,
- _("Show information about the task's port sets"),
- &infolist);
- add_cmd ("dead-names", class_info, info_dead_names_cmd,
- _("Show information about the task's dead names"),
- &infolist);
+ add_info ("send-rights", info_send_rights_cmd,
+ _("Show information about the task's send rights"));
+ add_info ("receive-rights", info_recv_rights_cmd,
+ _("Show information about the task's receive rights"));
+ add_info ("port-rights", info_port_rights_cmd,
+ _("Show information about the task's port rights"));
+ add_info ("port-sets", info_port_sets_cmd,
+ _("Show information about the task's port sets"));
+ add_info ("dead-names", info_dead_names_cmd,
+ _("Show information about the task's dead names"));
add_info_alias ("ports", "port-rights", 1);
add_info_alias ("port", "port-rights", 1);
add_info_alias ("psets", "port-sets", 1);