]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/darwin-nat.c
gdb/
[thirdparty/binutils-gdb.git] / gdb / darwin-nat.c
CommitLineData
a80b95ba 1/* Darwin support for GDB, the GNU debugger.
0fb0cc75 2 Copyright (C) 2008, 2009 Free Software Foundation, Inc.
a80b95ba
TG
3
4 Contributed by AdaCore.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include "defs.h"
23#include "top.h"
24#include "inferior.h"
25#include "target.h"
26#include "symfile.h"
27#include "symtab.h"
28#include "objfiles.h"
29#include "gdb.h"
30#include "gdbcmd.h"
31#include "gdbcore.h"
32#include "gdbthread.h"
33#include "regcache.h"
34#include "event-top.h"
35#include "inf-loop.h"
36#include "gdb_stat.h"
37#include "exceptions.h"
38#include "inf-child.h"
39#include "value.h"
40#include "arch-utils.h"
41#include "bfd.h"
42
43#include <sys/ptrace.h>
44#include <sys/signal.h>
45#include <machine/setjmp.h>
46#include <sys/types.h>
47#include <unistd.h>
48#include <signal.h>
49#include <string.h>
50#include <ctype.h>
51#include <sys/param.h>
52#include <sys/sysctl.h>
53#include <sys/proc.h>
54
55#include <mach/mach_error.h>
56#include <mach/mach_vm.h>
57#include <mach/mach_init.h>
58#include <mach/vm_map.h>
59#include <mach/task.h>
60#include <mach/mach_port.h>
61#include <mach/thread_act.h>
62#include <mach/port.h>
63
64#include "darwin-nat.h"
65
66/* Quick overview.
67 Darwin kernel is Mach + BSD derived kernel. Note that they share the
68 same memory space and are linked together (ie there is no micro-kernel).
69
70 Although ptrace(2) is available on Darwin, it is not complete. We have
71 to use Mach calls to read and write memory and to modify registers. We
72 also use Mach to get inferior faults. As we cannot use select(2) or
73 signals with Mach port (the Mach communication channel), signals are
74 reported to gdb as an exception. Furthermore we detect death of the
75 inferior through a Mach notification message. This way we only wait
76 on Mach ports.
77
78 Some Mach documentation is available for Apple xnu source package or
79 from the web. */
80
81
82#define PTRACE(CMD, PID, ADDR, SIG) \
83 darwin_ptrace(#CMD, CMD, (PID), (ADDR), (SIG))
84
85extern boolean_t exc_server (mach_msg_header_t *in, mach_msg_header_t *out);
86
87static void darwin_stop (ptid_t);
88
89static void darwin_resume (ptid_t ptid, int step,
90 enum target_signal signal);
91
92static ptid_t darwin_wait (ptid_t ptid, struct target_waitstatus *status);
93
94static void darwin_mourn_inferior (struct target_ops *ops);
95
96static int darwin_lookup_task (char *args, task_t * ptask, int *ppid);
97
98static void darwin_kill_inferior (void);
99
100static void darwin_ptrace_me (void);
101
102static void darwin_ptrace_him (int pid);
103
104static void darwin_create_inferior (struct target_ops *ops, char *exec_file,
105 char *allargs, char **env, int from_tty);
106
107static void darwin_files_info (struct target_ops *ops);
108
109static char *darwin_pid_to_str (ptid_t tpid);
110
111static int darwin_thread_alive (ptid_t tpid);
112
113/* Current inferior. */
114darwin_inferior *darwin_inf = NULL;
115
116/* Target operations for Darwin. */
117static struct target_ops *darwin_ops;
118
119/* Task identifier of gdb. */
120static task_t gdb_task;
121
122/* A copy of mach_host_self (). */
123mach_port_t darwin_host_self;
124
125/* Exception port. */
126mach_port_t darwin_ex_port;
127
128/* Notification port. */
129mach_port_t darwin_not_port;
130
131/* Port set. */
132mach_port_t darwin_port_set;
133
134/* Page size. */
135static vm_size_t mach_page_size;
136
137/* If Set, catch all mach exceptions (before they are converted to signals
138 by the kernel). */
139static int enable_mach_exceptions;
140
141#define PAGE_TRUNC(x) ((x) & ~(mach_page_size - 1))
142#define PAGE_ROUND(x) PAGE_TRUNC((x) + mach_page_size - 1)
143
144/* Buffer containing received message and to be sent message. */
145static union
146{
147 mach_msg_header_t hdr;
148 char data[1024];
149} msgin, msgout;
150
151/* Current message state.
152 If the kernel has sent a message it expects a reply and the inferior
153 can't be killed before. */
154static enum msg_state { NO_MESSAGE, GOT_MESSAGE, REPLY_SENT } msg_state;
155
156/* Unmarshalled received message. */
157static struct exc_msg
158{
159 /* Receive port. */
160 mach_port_t port;
161
162 /* Thread and task taking the exception. */
163 mach_port_t thread_port;
164 mach_port_t task_port;
165
166 /* Type of the exception. */
167 exception_type_t ex_type;
168
169 /* Machine dependent details. */
170 mach_msg_type_number_t data_count;
171 integer_t ex_data[4];
172} exc_msg;
173
174
175/* This controls output of inferior debugging.
176 1 = basic exception handling
177 2 = task management
178 3 = thread management
179 4 = pending_event_handler
180 6 = most chatty level. */
181
182static int darwin_debug_flag = 0;
183
184static void
185inferior_debug (int level, const char *fmt, ...)
186{
187 va_list ap;
188
189 if (darwin_debug_flag < level)
190 return;
191
192 va_start (ap, fmt);
193 printf_unfiltered (_("[%d inferior]: "), getpid ());
194 vprintf_unfiltered (fmt, ap);
195 va_end (ap);
196}
197
198void
199mach_check_error (kern_return_t ret, const char *file,
200 unsigned int line, const char *func)
201{
202 if (ret == KERN_SUCCESS)
203 return;
204 if (func == NULL)
205 func = _("[UNKNOWN]");
206
207 error (_("error on line %u of \"%s\" in function \"%s\": %s (0x%lx)\n"),
208 line, file, func, mach_error_string (ret), (unsigned long) ret);
209}
210
211static const char *
212unparse_exception_type (unsigned int i)
213{
214 static char unknown_exception_buf[32];
215
216 switch (i)
217 {
218 case EXC_BAD_ACCESS:
219 return "EXC_BAD_ACCESS";
220 case EXC_BAD_INSTRUCTION:
221 return "EXC_BAD_INSTRUCTION";
222 case EXC_ARITHMETIC:
223 return "EXC_ARITHMETIC";
224 case EXC_EMULATION:
225 return "EXC_EMULATION";
226 case EXC_SOFTWARE:
227 return "EXC_SOFTWARE";
228 case EXC_BREAKPOINT:
229 return "EXC_BREAKPOINT";
230 case EXC_SYSCALL:
231 return "EXC_SYSCALL";
232 case EXC_MACH_SYSCALL:
233 return "EXC_MACH_SYSCALL";
234 case EXC_RPC_ALERT:
235 return "EXC_RPC_ALERT";
236 case EXC_CRASH:
237 return "EXC_CRASH";
238 default:
239 snprintf (unknown_exception_buf, 32, _("unknown (%d)"), i);
240 return unknown_exception_buf;
241 }
242}
243
244static int
245darwin_ptrace (const char *name,
246 int request, int pid, PTRACE_TYPE_ARG3 arg3, int arg4)
247{
248 int ret;
249
250 ret = ptrace (request, pid, (caddr_t) arg3, arg4);
251
252 inferior_debug (2, _("ptrace (%s, %d, 0x%x, %d): %d (%s)\n"),
253 name, pid, arg3, arg4, ret,
254 (ret != 0) ? strerror (errno) : _("no error"));
255 return ret;
256}
257
258static int
259cmp_thread_t (const void *l, const void *r)
260{
261 thread_t lt = *(const thread_t *)l;
262 thread_t lr = *(const thread_t *)r;
263 return (int)(lr - lt);
264}
265
266static void
267darwin_check_new_threads (darwin_inferior *inf)
268{
269 kern_return_t kret;
270 unsigned int i;
271 thread_array_t thread_list;
272 unsigned int new_nbr;
273 unsigned int old_nbr;
274 unsigned int new_ix, old_ix;
275 VEC (thread_t) *thread_vec;
276
277 /* Get list of threads. */
278 kret = task_threads (inf->task, &thread_list, &new_nbr);
279 MACH_CHECK_ERROR (kret);
280 if (kret != KERN_SUCCESS)
281 return;
282
283 if (new_nbr > 1)
284 qsort (thread_list, new_nbr, sizeof (thread_t), cmp_thread_t);
285
286 thread_vec = VEC_alloc (thread_t, new_nbr);
287
288 if (inf->threads)
289 old_nbr = VEC_length (thread_t, inf->threads);
290 else
291 old_nbr = 0;
292
293 for (new_ix = 0, old_ix = 0; new_ix < new_nbr || old_ix < old_nbr;)
294 {
295 thread_t new_id = (new_ix < new_nbr) ?
296 thread_list[new_ix] : THREAD_NULL;
297 thread_t old_id = (old_ix < old_nbr) ?
298 VEC_index (thread_t, inf->threads, old_ix) : THREAD_NULL;
299
300 if (old_id == new_id)
301 {
302 /* Thread still exist. */
303 VEC_safe_push (thread_t, thread_vec, old_id);
304 new_ix++;
305 old_ix++;
306
307 kret = mach_port_deallocate (gdb_task, old_id);
308 MACH_CHECK_ERROR (kret);
309 continue;
310 }
311 if (new_id < old_id || old_ix == old_nbr)
312 {
313 /* A thread was created. */
314 struct thread_info *tp;
315
316 tp = add_thread (ptid_build (inf->pid, 0, new_id));
317 VEC_safe_push (thread_t, thread_vec, new_id);
318 new_ix++;
319 continue;
320 }
321 if (new_id > old_id || new_ix == new_nbr)
322 {
323 /* A thread was removed. */
324 delete_thread (ptid_build (inf->pid, 0, old_id));
325 kret = mach_port_deallocate (gdb_task, old_id);
326 MACH_CHECK_ERROR (kret);
327 old_ix++;
328 }
329 }
330
331 if (inf->threads)
332 VEC_free (thread_t, inf->threads);
333 inf->threads = thread_vec;
334
335 kret = vm_deallocate (gdb_task, (vm_address_t) thread_list,
336 new_nbr * sizeof (int));
337 MACH_CHECK_ERROR (kret);
338}
339
340static void
341darwin_stop (ptid_t t)
342{
343 int ret;
344
345 ret = kill (ptid_get_pid (inferior_ptid), SIGINT);
346}
347
348static void
349darwin_resume (ptid_t ptid, int step, enum target_signal signal)
350{
351 struct target_waitstatus status;
352 int pid;
353 thread_t thread;
354 kern_return_t kret;
355 int res;
356
357 /* minus_one_ptid is RESUME_ALL. */
358 if (ptid_equal (ptid, minus_one_ptid))
359 ptid = inferior_ptid;
360
361 pid = ptid_get_pid (ptid);
362 thread = ptid_get_tid (ptid);
363
364 inferior_debug
365 (2, _("darwin_resume: state=%d, thread=0x%x, step=%d signal=%d\n"),
366 msg_state, thread, step, signal);
367
368 switch (msg_state)
369 {
370 case GOT_MESSAGE:
371 switch (exc_msg.ex_type)
372 {
373 case EXC_SOFTWARE:
374 if (exc_msg.ex_data[0] == EXC_SOFT_SIGNAL)
375 {
376 int nsignal = target_signal_to_host (signal);
377 res = PTRACE (PT_THUPDATE, pid,
378 (void *)exc_msg.thread_port, nsignal);
379 if (res < 0)
380 printf_unfiltered (_("ptrace THUP: res=%d\n"), res);
381 }
382 break;
383
384 default:
385 break;
386 }
387
388 if (thread != 0)
389 {
390 inferior_debug (2, _("darwin_set_sstep (thread=%x, enable=%d)\n"),
391 thread, step);
392 darwin_set_sstep (thread, step);
393 }
394
395 kret = mach_msg (&msgout.hdr, MACH_SEND_MSG | MACH_SEND_INTERRUPT,
396 msgout.hdr.msgh_size, 0,
397 MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
398 MACH_PORT_NULL);
399 if (kret != 0)
400 printf_unfiltered (_("mach_msg (reply) ret=%d\n"), kret);
401
402 msg_state = REPLY_SENT;
403 break;
404
405 case NO_MESSAGE:
406 if (step)
407 res = PTRACE (PT_STEP, pid, (caddr_t)1, 0);
408 else
409 res = PTRACE (PT_CONTINUE, pid, (caddr_t)1, 0);
410 break;
411
412 default:
413 gdb_assert (0);
414 }
415}
416
417kern_return_t
418catch_exception_raise_state
419 (mach_port_t port,
420 exception_type_t exception_type, mach_exception_data_t exception_data,
421 mach_msg_type_number_t data_count, thread_state_flavor_t * state_flavor,
422 thread_state_t in_state, mach_msg_type_number_t in_state_count,
423 thread_state_t out_state, mach_msg_type_number_t out_state_count)
424{
425 return KERN_FAILURE;
426}
427
428kern_return_t
429catch_exception_raise_state_identity
430 (mach_port_t port, mach_port_t thread_port, mach_port_t task_port,
431 exception_type_t exception_type, mach_exception_data_t exception_data,
432 mach_msg_type_number_t data_count, thread_state_flavor_t * state_flavor,
433 thread_state_t in_state, mach_msg_type_number_t in_state_count,
434 thread_state_t out_state, mach_msg_type_number_t out_state_count)
435{
436 kern_return_t kret;
437
438 kret = mach_port_deallocate (mach_task_self (), task_port);
439 MACH_CHECK_ERROR (kret);
440 kret = mach_port_deallocate (mach_task_self (), thread_port);
441 MACH_CHECK_ERROR (kret);
442
443 return KERN_FAILURE;
444}
445
446kern_return_t
447catch_exception_raise (mach_port_t port,
448 mach_port_t thread_port,
449 mach_port_t task_port,
450 exception_type_t exception_type,
451 exception_data_t exception_data,
452 mach_msg_type_number_t data_count)
453{
454 kern_return_t kret;
455 int i;
456 int res;
457
458 /* We got new rights to the task. Get rid of it. */
459 kret = mach_port_deallocate (mach_task_self (), task_port);
460 MACH_CHECK_ERROR (kret);
461
462 inferior_debug
463 (7, _("catch_exception_raise: exception_type=%d, data_count=%d\n"),
464 exception_type, data_count);
465 if (darwin_debug_flag > 7)
466 {
467 for (i = 0; i < data_count; i++)
468 printf_unfiltered (" %08x", exception_data[i]);
469 printf_unfiltered ("\n");
470 }
471
472 /* Save the message.
473 FIXME: this should be in a per-thread variable. */
474 exc_msg.port = port;
475 exc_msg.thread_port = thread_port;
476 exc_msg.task_port = task_port;
477 exc_msg.ex_type = exception_type;
478 exc_msg.data_count = data_count;
479 for (i = 0; i < data_count && i < 4; i++)
480 exc_msg.ex_data[i] = exception_data[i];
481
482 return KERN_SUCCESS;
483}
484
485static ptid_t
486darwin_wait (ptid_t ptid, struct target_waitstatus *status)
487{
488 kern_return_t kret;
489 mach_msg_header_t *hdr = &msgin.hdr;
490 pid_t pid = ptid_get_pid (inferior_ptid); /* FIXME. */
491
492 gdb_assert (msg_state != GOT_MESSAGE);
493
494 inferior_debug (6, _("darwin_wait: waiting for a message\n"));
495
496 /* Wait for a message. */
497 kret = mach_msg (&msgin.hdr, MACH_RCV_MSG | MACH_RCV_INTERRUPT, 0,
498 sizeof (msgin.data), darwin_port_set, 0, MACH_PORT_NULL);
499
500 if (kret == MACH_RCV_INTERRUPTED)
501 {
502 status->kind = TARGET_WAITKIND_IGNORE;
503 return minus_one_ptid;
504 }
505
506 if (kret != MACH_MSG_SUCCESS)
507 {
508 inferior_debug (1, _("mach_msg: ret=%x\n"), kret);
509 status->kind = TARGET_WAITKIND_SPURIOUS;
510 return minus_one_ptid;
511 }
512
513 /* Debug: display message. */
514 if (darwin_debug_flag > 10)
515 {
516 const unsigned long *buf = (unsigned long *) hdr;
517 unsigned int i;
518
519 printf_unfiltered (_(" bits: 0x%x"), hdr->msgh_bits);
520 printf_unfiltered (_(", size: 0x%x"), hdr->msgh_size);
521 printf_unfiltered (_(", remote-port: 0x%x"), hdr->msgh_remote_port);
522 printf_unfiltered (_(", local-port: 0x%x"), hdr->msgh_local_port);
523 printf_unfiltered (_(", reserved: 0x%x"), hdr->msgh_reserved);
524 printf_unfiltered (_(", id: 0x%x\n"), hdr->msgh_id);
525
526 if (darwin_debug_flag > 11)
527 {
528 printf_unfiltered (_(" data:"));
529 for (i = 0; i < hdr->msgh_size; i++)
530 printf_unfiltered (" %08lx", buf[i]);
531 printf_unfiltered (_("\n"));
532 }
533 }
534
535 /* Exception message. */
536 if (hdr->msgh_local_port == darwin_ex_port)
537 {
538 /* Handle it via the exception server. */
539 if (!exc_server (&msgin.hdr, &msgout.hdr))
540 {
541 printf_unfiltered (_("exc_server: unknown message (id=%x)\n"),
542 hdr->msgh_id);
543 status->kind = TARGET_WAITKIND_SPURIOUS;
544 return minus_one_ptid;
545 }
546
547 status->kind = TARGET_WAITKIND_STOPPED;
548
549 inferior_debug (2, _("darwin_wait: thread=%x, got %s\n"),
550 exc_msg.thread_port,
551 unparse_exception_type (exc_msg.ex_type));
552
553 switch (exc_msg.ex_type)
554 {
555 case EXC_BAD_ACCESS:
556 status->value.sig = TARGET_EXC_BAD_ACCESS;
557 break;
558 case EXC_BAD_INSTRUCTION:
559 status->value.sig = TARGET_EXC_BAD_INSTRUCTION;
560 break;
561 case EXC_ARITHMETIC:
562 status->value.sig = TARGET_EXC_ARITHMETIC;
563 break;
564 case EXC_EMULATION:
565 status->value.sig = TARGET_EXC_EMULATION;
566 break;
567 case EXC_SOFTWARE:
568 if (exc_msg.ex_data[0] == EXC_SOFT_SIGNAL)
569 {
570 status->value.sig = target_signal_from_host (exc_msg.ex_data[1]);
571 inferior_debug (2, _(" (signal %d: %s)\n"),
572 exc_msg.ex_data[1],
573 target_signal_to_name (status->value.sig));
574 }
575 else
576 status->value.sig = TARGET_EXC_SOFTWARE;
577 break;
578 case EXC_BREAKPOINT:
579 /* Many internal GDB routines expect breakpoints to be reported
580 as TARGET_SIGNAL_TRAP, and will report TARGET_EXC_BREAKPOINT
581 as a spurious signal. */
582 status->value.sig = TARGET_SIGNAL_TRAP;
583 break;
584 default:
585 status->value.sig = TARGET_SIGNAL_UNKNOWN;
586 break;
587 }
588
589 msg_state = GOT_MESSAGE;
590
591 return ptid_build (pid, 0, exc_msg.thread_port);
592 }
593 else if (hdr->msgh_local_port == darwin_not_port)
594 {
595 pid_t res;
596 int wstatus;
597
598 /* FIXME: translate task port to pid. */
599 res = wait4 (pid, &wstatus, 0, NULL);
600 if (res != pid)
601 {
602 printf_unfiltered (_("wait4: res=%x\n"), res);
603 wstatus = 0;
604 }
605 status->kind = TARGET_WAITKIND_EXITED;
606 status->value.integer = WEXITSTATUS (wstatus);
607
608 inferior_debug (2, _("darwin_wait: pid=%d exit, status=%x\n"),
609 pid, wstatus);
610
611 msg_state = NO_MESSAGE;
612
613 return ptid;
614 }
615 else
616 {
617 printf_unfiltered (_("Bad local-port: %x\n"), hdr->msgh_local_port);
618 status->kind = TARGET_WAITKIND_SPURIOUS;
619 return minus_one_ptid;
620 }
621}
622
623static void
624darwin_mourn_inferior (struct target_ops *ops)
625{
626 struct inferior *inf = current_inferior ();
627 kern_return_t kret;
628 mach_port_t prev;
629 int i;
630
631 unpush_target (darwin_ops);
632
633 /* Deallocate threads. */
634 if (darwin_inf->threads)
635 {
636 int k;
637 thread_t t;
638 for (k = 0; VEC_iterate (thread_t, darwin_inf->threads, k, t); k++)
639 {
640 kret = mach_port_deallocate (gdb_task, t);
641 MACH_CHECK_ERROR (kret);
642 }
643 VEC_free (thread_t, darwin_inf->threads);
644 darwin_inf->threads = NULL;
645 }
646
647 kret = mach_port_request_notification (gdb_task, darwin_inf->task,
648 MACH_NOTIFY_DEAD_NAME, 0,
649 darwin_inf->prev_not_port,
650 MACH_MSG_TYPE_MAKE_SEND_ONCE,
651 &prev);
652 /* This can fail if the task is dead. */
653 if (kret == KERN_SUCCESS)
654 {
655 kret = mach_port_deallocate (gdb_task, prev);
656 MACH_CHECK_ERROR (kret);
657 }
658
659 /* Deallocate saved exception ports. */
660 for (i = 0; i < darwin_inf->exception_info.count; i++)
661 {
662 kret = mach_port_deallocate
663 (gdb_task, darwin_inf->exception_info.ports[i]);
664 MACH_CHECK_ERROR (kret);
665 }
666 darwin_inf->exception_info.count = 0;
667
668 kret = mach_port_deallocate (gdb_task, darwin_inf->task);
669 MACH_CHECK_ERROR (kret);
670
671 darwin_inf->task = 0;
672 darwin_inf->pid = 0;
673
674 generic_mourn_inferior ();
675}
676
677static void
678darwin_stop_inferior (darwin_inferior *inf)
679{
680 struct target_waitstatus wstatus;
681 ptid_t ptid;
682 kern_return_t kret;
683 int status;
684 int res;
685
686 gdb_assert (inf != NULL);
687
688 kret = task_suspend (inf->task);
689 MACH_CHECK_ERROR (kret);
690
691 if (msg_state == GOT_MESSAGE)
692 darwin_resume (inferior_ptid, 0, 0);
693
694 res = kill (inf->pid, SIGSTOP);
695 if (res != 0)
696 warning (_("cannot kill: %s\n"), strerror (errno));
697
698 ptid = darwin_wait (inferior_ptid, &wstatus);
699 gdb_assert (wstatus.kind = TARGET_WAITKIND_STOPPED);
700}
701
702static void
703darwin_kill_inferior (void)
704{
705 struct target_waitstatus wstatus;
706 ptid_t ptid;
707 kern_return_t kret;
708 int status;
709 int res;
710
711 gdb_assert (darwin_inf != NULL);
712
713 if (ptid_equal (inferior_ptid, null_ptid))
714 return;
715
716 darwin_stop_inferior (darwin_inf);
717
718 res = PTRACE (PT_KILL, darwin_inf->pid, 0, 0);
719 gdb_assert (res == 0);
720
721 if (msg_state == GOT_MESSAGE)
722 {
723 exc_msg.ex_type = 0;
724 darwin_resume (inferior_ptid, 0, 0);
725 }
726
727 kret = task_resume (darwin_inf->task);
728 MACH_CHECK_ERROR (kret);
729
730 ptid = darwin_wait (inferior_ptid, &wstatus);
731
732 /* This double wait seems required... */
733 res = waitpid (darwin_inf->pid, &status, 0);
734 gdb_assert (res == darwin_inf->pid);
735
736 msg_state = NO_MESSAGE;
737
738 target_mourn_inferior ();
739}
740
741/* The child must synchronize with gdb: gdb must set the exception port
742 before the child call PTRACE_SIGEXC. We use a pipe to achieve this.
743 FIXME: is there a lighter way ? */
744static int ptrace_fds[2];
745
746static void
747darwin_ptrace_me (void)
748{
749 int res;
750 char c;
751
752 /* Close write end point. */
753 close (ptrace_fds[1]);
754
755 /* Wait until gdb is ready. */
756 res = read (ptrace_fds[0], &c, 1);
757 gdb_assert (res == 0);
758 close (ptrace_fds[0]);
759
760 /* Get rid of privileges. */
761 setegid (getgid ());
762
763 /* Set TRACEME. */
764 PTRACE (PT_TRACE_ME, 0, 0, 0);
765
766 /* Redirect signals to exception port. */
767 PTRACE (PT_SIGEXC, 0, 0, 0);
768}
769
770/* Dummy function to be sure fork_inferior uses fork(2) and not vfork(2). */
771static void
772darwin_pre_ptrace (void)
773{
774 if (pipe (ptrace_fds) != 0)
775 {
776 ptrace_fds[0] = -1;
777 ptrace_fds[1] = -1;
778 error (_("unable to create a pipe: %s"), safe_strerror (errno));
779 }
780}
781
782static kern_return_t
783darwin_save_exception_ports (darwin_inferior *inf)
784{
785 kern_return_t kret;
786
787 inf->exception_info.count =
788 sizeof (inf->exception_info.ports) / sizeof (inf->exception_info.ports[0]);
789
790 kret = task_get_exception_ports
791 (inf->task, EXC_MASK_ALL, inf->exception_info.masks,
792 &inf->exception_info.count, inf->exception_info.ports,
793 inf->exception_info.behaviors, inf->exception_info.flavors);
794 return kret;
795}
796
797static kern_return_t
798darwin_restore_exception_ports (darwin_inferior *inf)
799{
800 int i;
801 kern_return_t kret;
802
803 for (i = 0; i < inf->exception_info.count; i++)
804 {
805 kret = task_set_exception_ports
806 (inf->task, inf->exception_info.masks[i], inf->exception_info.ports[i],
807 inf->exception_info.behaviors[i], inf->exception_info.flavors[i]);
808 if (kret != KERN_SUCCESS)
809 return kret;
810 }
811
812 return KERN_SUCCESS;
813}
814
815static void
816darwin_attach_pid (int pid)
817{
818 task_t itask;
819 kern_return_t kret;
820 mach_port_t prev_port;
821 int traps_expected;
822 exception_mask_t mask;
823
824 kret = task_for_pid (gdb_task, pid, &itask);
825 if (kret != KERN_SUCCESS)
826 {
827 int status;
828 struct inferior *inf = current_inferior ();
829
830 if (!inf->attach_flag)
831 {
832 kill (pid, 9);
833 waitpid (pid, &status, 0);
834 }
835
836 error (_("Unable to find Mach task port for process-id %d: %s (0x%lx).\n"
837 " (please check gdb is setgid procmod)"),
838 pid, mach_error_string (kret), (unsigned long) kret);
839 }
840
841 inferior_debug (2, _("inferior task: 0x%08x, pid: %d\n"), itask, pid);
842
843 if (darwin_ex_port == MACH_PORT_NULL)
844 {
845 /* Create a port to get exceptions. */
846 kret = mach_port_allocate (gdb_task, MACH_PORT_RIGHT_RECEIVE,
847 &darwin_ex_port);
848 gdb_assert (kret == KERN_SUCCESS);
849
850 kret = mach_port_insert_right (gdb_task, darwin_ex_port, darwin_ex_port,
851 MACH_MSG_TYPE_MAKE_SEND);
852 gdb_assert (kret == KERN_SUCCESS);
853
854 /* Create a port set and put ex_port in it. */
855 kret = mach_port_allocate (gdb_task, MACH_PORT_RIGHT_PORT_SET,
856 &darwin_port_set);
857 gdb_assert (kret == KERN_SUCCESS);
858
859 kret = mach_port_move_member (gdb_task, darwin_ex_port, darwin_port_set);
860 gdb_assert (kret == KERN_SUCCESS);
861
862 /* Create a port to be notified when the child task terminates. */
863 kret = mach_port_allocate (gdb_task, MACH_PORT_RIGHT_RECEIVE,
864 &darwin_not_port);
865 gdb_assert (kret == KERN_SUCCESS);
866
867 kret = mach_port_insert_right (gdb_task, darwin_not_port, darwin_not_port,
868 MACH_MSG_TYPE_MAKE_SEND);
869 gdb_assert (kret == KERN_SUCCESS);
870
871 kret = mach_port_move_member (gdb_task, darwin_not_port, darwin_port_set);
872 gdb_assert (kret == KERN_SUCCESS);
873 }
874
875 kret = mach_port_request_notification (gdb_task, itask,
876 MACH_NOTIFY_DEAD_NAME, 0,
877 darwin_not_port,
878 MACH_MSG_TYPE_MAKE_SEND_ONCE,
879 &darwin_inf->prev_not_port);
880 gdb_assert (kret == KERN_SUCCESS);
881
882 darwin_inf->task = itask;
883 darwin_inf->pid = pid;
884
885 kret = darwin_save_exception_ports (darwin_inf);
886 gdb_assert (kret == KERN_SUCCESS);
887
888 /* Set exception port. */
889 if (enable_mach_exceptions)
890 mask = EXC_MASK_ALL;
891 else
892 mask = EXC_MASK_SOFTWARE;
893 kret = task_set_exception_ports
894 (itask, mask, darwin_ex_port, EXCEPTION_DEFAULT, THREAD_STATE_NONE);
895 gdb_assert (kret == KERN_SUCCESS);
896
897 push_target (darwin_ops);
898}
899
900static void
901darwin_init_thread_list (darwin_inferior *inf)
902{
903 thread_t thread;
904
905 darwin_check_new_threads (inf);
906
907 gdb_assert (inf->threads && VEC_length (thread_t, inf->threads) > 0);
908 thread = VEC_index (thread_t, inf->threads, 0);
909 inferior_ptid = ptid_build (inf->pid, 0, thread);
910}
911
912static void
913darwin_ptrace_him (int pid)
914{
915 task_t itask;
916 kern_return_t kret;
917 mach_port_t prev_port;
918 int traps_expected;
919
920 darwin_attach_pid (pid);
921
922 /* Let's the child run. */
923 close (ptrace_fds[0]);
924 close (ptrace_fds[1]);
925
926 /* fork_inferior automatically add a thread - but it uses a wrong tid. */
927 delete_thread_silent (inferior_ptid);
928 darwin_init_thread_list (darwin_inf);
929
930 startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
931}
932
933static void
934darwin_create_inferior (struct target_ops *ops, char *exec_file,
935 char *allargs, char **env, int from_tty)
936{
937 /* Do the hard work. */
938 fork_inferior (exec_file, allargs, env, darwin_ptrace_me, darwin_ptrace_him,
939 darwin_pre_ptrace, NULL);
940
941 /* Return now in case of error. */
942 if (ptid_equal (inferior_ptid, null_ptid))
943 return;
944}
945\f
946
947/* Attach to process PID, then initialize for debugging it
948 and wait for the trace-trap that results from attaching. */
949static void
950darwin_attach (struct target_ops *ops, char *args, int from_tty)
951{
952 pid_t pid;
953 pid_t pid2;
954 int wstatus;
955 int res;
956 struct inferior *inf;
957
958 gdb_assert (msg_state == NO_MESSAGE);
959
960 if (!args)
961 error_no_arg (_("process-id to attach"));
962
963 pid = atoi (args);
964
965 if (pid == getpid ()) /* Trying to masturbate? */
966 error (_("I refuse to debug myself!"));
967
968 if (from_tty)
969 printf_unfiltered (_("Attaching to pid %d\n"), pid);
970
971 res = PTRACE (PT_ATTACHEXC, pid, 0, 0);
972 if (res != 0)
973 error (_("Unable to attach to process-id %d: %s (%d)"),
974 pid, strerror (errno), errno);
975
976 inf = add_inferior (pid);
977 inf->attach_flag = 1;
978
979 darwin_attach_pid (pid);
980
981 pid2 = wait4 (pid, &wstatus, WUNTRACED, NULL);
982 gdb_assert (pid2 == pid);
983 inferior_debug (1, _("darwin_attach: wait4 pid=%d, status=0x%x\n"),
984 pid2, wstatus);
985
986
987 darwin_init_thread_list (darwin_inf);
988
989 darwin_check_osabi (darwin_inf, ptid_get_tid (inferior_ptid));
990
991 /* Looks strange, but the kernel doesn't stop the process...
992 (Bug in Leopard ?)
993 Do it manually. */
994 /* FIXME: doesn't look to work with multi-threads!! */
995 kill (pid, SIGSTOP);
996}
997
998/* Take a program previously attached to and detaches it.
999 The program resumes execution and will no longer stop
1000 on signals, etc. We'd better not have left any breakpoints
1001 in the program or it'll die when it hits one. For this
1002 to work, it may be necessary for the process to have been
1003 previously attached. It *might* work if the program was
1004 started via fork. */
1005static void
1006darwin_detach (struct target_ops *ops, char *args, int from_tty)
1007{
1008 kern_return_t kret;
1009 int res;
1010
1011 if (from_tty)
1012 {
1013 char *exec_file = get_exec_file (0);
1014 if (exec_file == 0)
1015 exec_file = "";
1016 printf_unfiltered (_("Detaching from program: %s, %d\n"), exec_file,
1017 ptid_get_pid (inferior_ptid));
1018 gdb_flush (gdb_stdout);
1019 }
1020
1021 darwin_stop_inferior (darwin_inf);
1022
1023 kret = darwin_restore_exception_ports (darwin_inf);
1024 MACH_CHECK_ERROR (kret);
1025
1026 if (msg_state == GOT_MESSAGE)
1027 {
1028 exc_msg.ex_type = 0;
1029 darwin_resume (inferior_ptid, 0, 0);
1030 }
1031
1032 kret = task_resume (darwin_inf->task);
1033 gdb_assert (kret == KERN_SUCCESS);
1034
1035 res = PTRACE (PT_DETACH, darwin_inf->pid, 0, 0);
1036 if (res != 0)
1037 printf_unfiltered (_("Unable to detach from process-id %d: %s (%d)"),
1038 darwin_inf->pid, strerror (errno), errno);
1039
1040 msg_state = NO_MESSAGE;
1041
1042 darwin_mourn_inferior (ops);
1043}
1044
1045static void
1046darwin_files_info (struct target_ops *ops)
1047{
1048 gdb_assert (darwin_inf != NULL);
1049}
1050
1051static char *
1052darwin_pid_to_str (ptid_t ptid)
1053{
1054 static char buf[128];
1055
1056 snprintf (buf, sizeof (buf),
1057 _("process %d gdb-thread 0x%lx"),
1058 (unsigned) ptid_get_pid (ptid),
1059 (unsigned long) ptid_get_tid (ptid));
1060 return buf;
1061}
1062
1063static int
1064darwin_thread_alive (ptid_t ptid)
1065{
1066 return 1;
1067}
1068
1069/* If RDADDR is not NULL, read inferior task's LEN bytes from ADDR and
1070 copy it to RDADDR in gdb's address space.
1071 If WRADDR is not NULL, write gdb's LEN bytes from WRADDR and copy it
1072 to ADDR in inferior task's address space.
1073 Return 0 on failure; number of bytes read / writen otherwise. */
1074static int
1075darwin_read_write_inferior (task_t task, CORE_ADDR addr,
1076 char *rdaddr, const char *wraddr, int length)
1077{
1078 kern_return_t err;
1079 mach_vm_address_t offset = addr & (mach_page_size - 1);
1080 mach_vm_address_t low_address = (mach_vm_address_t) (addr - offset);
1081 mach_vm_size_t aligned_length = (mach_vm_size_t) PAGE_ROUND (offset + length);
1082 pointer_t copied;
1083 int copy_count;
1084 mach_vm_size_t remaining_length;
1085 mach_vm_address_t region_address;
1086 mach_vm_size_t region_length;
1087
1088 inferior_debug (8, _("darwin_read_write_inferior(%s, len=%d)\n"),
1089 core_addr_to_string (addr), length);
1090
1091 /* Get memory from inferior with page aligned addresses */
1092 err = mach_vm_read (task, low_address, aligned_length,
1093 &copied, &copy_count);
1094 if (err != KERN_SUCCESS)
1095 {
1096 warning (_("darwin_read_write_inferior: vm_read failed: %s"),
1097 mach_error_string (err));
1098 return 0;
1099 }
1100
1101 if (rdaddr != NULL)
1102 memcpy (rdaddr, (char *)copied + offset, length);
1103
1104 if (wraddr == NULL)
1105 goto out;
1106
1107 memcpy ((char *)copied + offset, wraddr, length);
1108
1109 /* Do writes atomically.
1110 First check for holes and unwritable memory. */
1111 for (region_address = low_address, remaining_length = aligned_length;
1112 region_address < low_address + aligned_length;
1113 region_address += region_length, remaining_length -= region_length)
1114 {
1115 vm_region_basic_info_data_64_t info;
1116 mach_port_t object_name;
1117 mach_vm_address_t old_address = region_address;
1118 mach_msg_type_number_t count;
1119
1120 region_length = remaining_length;
1121 count = VM_REGION_BASIC_INFO_COUNT_64;
1122 err = mach_vm_region (task, &region_address, &region_length,
1123 VM_REGION_BASIC_INFO_64,
1124 (vm_region_info_t) &info, &count, &object_name);
1125
1126 if (err != KERN_SUCCESS)
1127 {
1128 warning (_("darwin_write_inferior: mach_vm_region failed: %s"),
1129 mach_error_string (err));
1130 goto out;
1131 }
1132
1133 /* Check for holes in memory */
1134 if (region_address > old_address)
1135 {
1136 warning (_("No memory at %s (vs %s+0x%x). Nothing written"),
1137 core_addr_to_string (old_address),
1138 core_addr_to_string (region_address),
1139 (unsigned)region_length);
1140 length = 0;
1141 goto out;
1142 }
1143
1144 if (!(info.max_protection & VM_PROT_WRITE))
1145 {
1146 warning (_("Memory at address %s is unwritable. Nothing written"),
1147 core_addr_to_string (old_address));
1148 length = 0;
1149 goto out;
1150 }
1151
1152 if (!(info.protection & VM_PROT_WRITE))
1153 {
1154 err = mach_vm_protect (task, old_address, region_length,
1155 FALSE, info.protection | VM_PROT_WRITE);
1156 if (err != KERN_SUCCESS)
1157 {
1158 warning
1159 (_("darwin_read_write_inferior: mach_vm_protect failed: %s"),
1160 mach_error_string (err));
1161 length = 0;
1162 goto out;
1163 }
1164 }
1165 }
1166
1167 err = mach_vm_write (task, low_address, copied, aligned_length);
1168
1169 if (err != KERN_SUCCESS)
1170 {
1171 warning (_("darwin_read_write_inferior: mach_vm_write failed: %s"),
1172 mach_error_string (err));
1173 length = 0;
1174 }
1175out:
1176 mach_vm_deallocate (mach_task_self (), copied, copy_count);
1177 return length;
1178}
1179
1180\f
1181/* Return 0 on failure, number of bytes handled otherwise. TARGET
1182 is ignored. */
1183static int
1184darwin_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int write,
1185 struct mem_attrib *attrib, struct target_ops *target)
1186{
1187 task_t task = darwin_inf->task;
1188
1189 if (task == MACH_PORT_NULL)
1190 return 0;
1191
1192 inferior_debug (8, _("darwin_xfer_memory(%s, %d, %c)\n"),
1193 core_addr_to_string (memaddr), len, write ? 'w' : 'r');
1194
1195 if (write)
1196 return darwin_read_write_inferior (task, memaddr, NULL, myaddr, len);
1197 else
1198 return darwin_read_write_inferior (task, memaddr, myaddr, NULL, len);
1199}
1200
1201static LONGEST
1202darwin_xfer_partial (struct target_ops *ops,
1203 enum target_object object, const char *annex,
1204 gdb_byte *readbuf, const gdb_byte *writebuf,
1205 ULONGEST offset, LONGEST len)
1206{
1207 inferior_debug (8, _("darwin_xfer_partial(%s, %d, rbuf=%p, wbuf=%p)\n"),
1208 core_addr_to_string (offset), (int)len, readbuf, writebuf);
1209
1210 if (object != TARGET_OBJECT_MEMORY)
1211 return -1;
1212
1213 return darwin_read_write_inferior (darwin_inf->task, offset,
1214 readbuf, writebuf, len);
1215}
1216
1217static void
1218set_enable_mach_exceptions (char *args, int from_tty,
1219 struct cmd_list_element *c)
1220{
1221 if (darwin_inf && darwin_inf->task != TASK_NULL)
1222 {
1223 exception_mask_t mask;
1224 kern_return_t kret;
1225
1226 if (enable_mach_exceptions)
1227 mask = EXC_MASK_ALL;
1228 else
1229 {
1230 darwin_restore_exception_ports (darwin_inf);
1231 mask = EXC_MASK_SOFTWARE;
1232 }
1233 kret = task_set_exception_ports (darwin_inf->task, mask, darwin_ex_port,
1234 EXCEPTION_DEFAULT, THREAD_STATE_NONE);
1235 MACH_CHECK_ERROR (kret);
1236 }
1237}
1238
1239void
1240_initialize_darwin_inferior ()
1241{
1242 kern_return_t kret;
1243
1244 gdb_assert (darwin_inf == NULL);
1245
1246 gdb_task = mach_task_self ();
1247 darwin_host_self = mach_host_self ();
1248
1249 /* Read page size. */
1250 kret = host_page_size (darwin_host_self, &mach_page_size);
1251 if (kret != KERN_SUCCESS)
1252 {
1253 mach_page_size = 0x1000;
1254 MACH_CHECK_ERROR (kret);
1255 }
1256
1257 darwin_inf = (struct darwin_inferior *)
1258 xmalloc (sizeof (struct darwin_inferior));
1259
1260 memset (darwin_inf, 0, sizeof (*darwin_inf));
1261
1262 darwin_ops = inf_child_target ();
1263
1264 darwin_ops->to_shortname = "darwin-child";
1265 darwin_ops->to_longname = _("Darwin child process");
1266 darwin_ops->to_doc =
1267 _("Darwin child process (started by the \"run\" command).");
1268 darwin_ops->to_create_inferior = darwin_create_inferior;
1269 darwin_ops->to_attach = darwin_attach;
1270 darwin_ops->to_attach_no_wait = 0;
1271 darwin_ops->to_detach = darwin_detach;
1272 darwin_ops->to_files_info = darwin_files_info;
1273 darwin_ops->to_wait = darwin_wait;
1274 darwin_ops->to_mourn_inferior = darwin_mourn_inferior;
1275 darwin_ops->to_kill = darwin_kill_inferior;
1276 darwin_ops->to_stop = darwin_stop;
1277 darwin_ops->to_resume = darwin_resume;
1278 darwin_ops->to_thread_alive = darwin_thread_alive;
1279 darwin_ops->to_pid_to_str = darwin_pid_to_str;
1280 darwin_ops->to_load = NULL;
1281 darwin_ops->deprecated_xfer_memory = darwin_xfer_memory;
1282 darwin_ops->to_xfer_partial = darwin_xfer_partial;
1283 darwin_ops->to_has_thread_control = tc_schedlock /*| tc_switch */;
1284
1285 darwin_complete_target (darwin_ops);
1286
1287 add_target (darwin_ops);
1288
1289 inferior_debug (2, _("GDB task: 0x%lx, pid: %d\n"), mach_task_self (),
1290 getpid ());
1291
1292 add_setshow_zinteger_cmd ("darwin", class_obscure,
1293 &darwin_debug_flag, _("\
1294Set if printing inferior communication debugging statements."), _("\
1295Show if printing inferior communication debugging statements."), NULL,
1296 NULL, NULL,
1297 &setdebuglist, &showdebuglist);
1298
1299 add_setshow_boolean_cmd ("mach-exceptions", class_support,
1300 &enable_mach_exceptions, _("\
1301Set if mach exceptions are caught."), _("\
1302Show if mach exceptions are caught."), _("\
1303When this mode is on, all low level exceptions are reported before being\n\
1304reported by the kernel."),
1305 &set_enable_mach_exceptions, NULL,
1306 &setlist, &showlist);
1307}