/* Darwin support for GDB, the GNU debugger.
- Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
Contributed by AdaCore.
static void darwin_mourn_inferior (struct target_ops *ops);
-static int darwin_lookup_task (char *args, task_t * ptask, int *ppid);
-
static void darwin_kill_inferior (struct target_ops *ops);
static void darwin_ptrace_me (void);
/* Port set. */
mach_port_t darwin_port_set;
-/* Page size. */
+/* Page size. */
static vm_size_t mach_page_size;
/* If Set, catch all mach exceptions (before they are converted to signals
/* This controls output of inferior debugging. */
static int darwin_debug_flag = 0;
+/* Create a __TEXT __info_plist section in the executable so that gdb could
+ be signed. This is required to get an authorization for task_for_pid.
+
+ Once gdb is built, you can either:
+ * make it setgid procmod
+ * or codesign it with any system-trusted signing authority.
+ See taskgated(8) for details. */
+static const unsigned char info_plist[]
+__attribute__ ((section ("__TEXT,__info_plist"),used)) =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\""
+ " \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
+ "<plist version=\"1.0\">\n"
+ "<dict>\n"
+ " <key>CFBundleIdentifier</key>\n"
+ " <string>org.gnu.gdb</string>\n"
+ " <key>CFBundleName</key>\n"
+ " <string>gdb</string>\n"
+ " <key>CFBundleVersion</key>\n"
+ " <string>1.0</string>\n"
+ " <key>SecTaskAccess</key>\n"
+ " <array>\n"
+ " <string>allowed</string>\n"
+ " <string>debug</string>\n"
+ " </array>\n"
+ "</dict>\n"
+ "</plist>\n";
+
static void
inferior_debug (int level, const char *fmt, ...)
{
old_ix++;
continue;
}
- gdb_assert (0);
+ gdb_assert_not_reached ("unexpected thread case");
}
if (darwin_inf->threads)
case EXC_BREAKPOINT:
/* Many internal GDB routines expect breakpoints to be reported
as TARGET_SIGNAL_TRAP, and will report TARGET_EXC_BREAKPOINT
- as a spurious signal. */
+ as a spurious signal. */
status->value.sig = TARGET_SIGNAL_TRAP;
break;
default:
static int
cancel_breakpoint (ptid_t ptid)
{
- /* Arrange for a breakpoint to be hit again later. We will handle
+ /* Arrange for a breakpoint to be hit again later. We will handle
the current event, eventually we will resume this thread, and this
breakpoint will trap again.
CORE_ADDR pc;
pc = regcache_read_pc (regcache) - gdbarch_decr_pc_after_break (gdbarch);
- if (breakpoint_inserted_here_p (pc))
+ if (breakpoint_inserted_here_p (get_regcache_aspace (regcache), pc))
{
inferior_debug (4, "cancel_breakpoint for thread %x\n",
ptid_get_tid (ptid));
res = kill (inf->pid, SIGSTOP);
if (res != 0)
- warning (_("cannot kill: %s\n"), safe_strerror (errno));
+ warning (_("cannot kill: %s"), safe_strerror (errno));
/* Wait until the process is really stopped. */
while (1)
}
error (_("Unable to find Mach task port for process-id %d: %s (0x%lx).\n"
- " (please check gdb is setgid procmod)"),
+ " (please check gdb is codesigned - see taskgated(8))"),
inf->pid, mach_error_string (kret), (unsigned long) kret);
}
struct inferior *inf;
kern_return_t kret;
- if (!args)
- error_no_arg (_("process-id to attach"));
+ pid = parse_pid_to_attach (args);
- pid = atoi (args);
-
- if (pid == getpid ()) /* Trying to masturbate? */
+ if (pid == getpid ()) /* Trying to masturbate? */
error (_("I refuse to debug myself!"));
if (from_tty)
pid, safe_strerror (errno), errno);
inferior_ptid = pid_to_ptid (pid);
- inf = add_inferior (pid);
+ inf = current_inferior ();
+ inferior_appeared (inf, pid);
inf->attach_flag = 1;
+
/* Always add a main thread. */
add_thread_silent (inferior_ptid);
inferior_debug (8, _("darwin_read_write_inferior(task=%x, %s, len=%d)\n"),
task, core_addr_to_string (addr), length);
- /* Get memory from inferior with page aligned addresses */
+ /* Get memory from inferior with page aligned addresses. */
kret = mach_vm_read (task, low_address, aligned_length,
&copied, ©_count);
if (kret != KERN_SUCCESS)
core_addr_to_string (region_start),
core_addr_to_string (region_length));
- /* Check for holes in memory */
+ /* Check for holes in memory. */
if (region_start > region_address)
{
- warning (_("No memory at %s (vs %s+0x%x). Nothing written"),
+ warning (_("No memory at %s (vs %s+0x%x). Nothing written"),
core_addr_to_string (region_address),
core_addr_to_string (region_start),
(unsigned)region_length);
\f
/* Return 0 on failure, number of bytes handled otherwise. TARGET
- is ignored. */
+ is ignored. */
static int
darwin_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int write,
struct mem_attrib *attrib, struct target_ops *target)