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