Add missing files to previous commit (Allow Python notification of new object-file...
[deliverable/binutils-gdb.git] / gdb / darwin-nat.c
1 /* Darwin support for GDB, the GNU debugger.
2 Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
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 #include <libproc.h>
55 #include <sys/syscall.h>
56 #include <spawn.h>
57
58 #include <mach/mach_error.h>
59 #include <mach/mach_vm.h>
60 #include <mach/mach_init.h>
61 #include <mach/vm_map.h>
62 #include <mach/task.h>
63 #include <mach/mach_port.h>
64 #include <mach/thread_act.h>
65 #include <mach/port.h>
66
67 #include "darwin-nat.h"
68
69 /* Quick overview.
70 Darwin kernel is Mach + BSD derived kernel. Note that they share the
71 same memory space and are linked together (ie there is no micro-kernel).
72
73 Although ptrace(2) is available on Darwin, it is not complete. We have
74 to use Mach calls to read and write memory and to modify registers. We
75 also use Mach to get inferior faults. As we cannot use select(2) or
76 signals with Mach port (the Mach communication channel), signals are
77 reported to gdb as an exception. Furthermore we detect death of the
78 inferior through a Mach notification message. This way we only wait
79 on Mach ports.
80
81 Some Mach documentation is available for Apple xnu source package or
82 from the web. */
83
84
85 #define PTRACE(CMD, PID, ADDR, SIG) \
86 darwin_ptrace(#CMD, CMD, (PID), (ADDR), (SIG))
87
88 extern boolean_t exc_server (mach_msg_header_t *in, mach_msg_header_t *out);
89
90 static void darwin_stop (ptid_t);
91
92 static void darwin_resume_to (struct target_ops *ops, ptid_t ptid, int step,
93 enum target_signal signal);
94 static void darwin_resume (ptid_t ptid, int step,
95 enum target_signal signal);
96
97 static ptid_t darwin_wait_to (struct target_ops *ops, ptid_t ptid,
98 struct target_waitstatus *status, int options);
99 static ptid_t darwin_wait (ptid_t ptid, struct target_waitstatus *status);
100
101 static void darwin_mourn_inferior (struct target_ops *ops);
102
103 static void darwin_kill_inferior (struct target_ops *ops);
104
105 static void darwin_ptrace_me (void);
106
107 static void darwin_ptrace_him (int pid);
108
109 static void darwin_create_inferior (struct target_ops *ops, char *exec_file,
110 char *allargs, char **env, int from_tty);
111
112 static void darwin_files_info (struct target_ops *ops);
113
114 static char *darwin_pid_to_str (struct target_ops *ops, ptid_t tpid);
115
116 static int darwin_thread_alive (struct target_ops *ops, ptid_t tpid);
117
118 /* Target operations for Darwin. */
119 static struct target_ops *darwin_ops;
120
121 /* Task identifier of gdb. */
122 static task_t gdb_task;
123
124 /* A copy of mach_host_self (). */
125 mach_port_t darwin_host_self;
126
127 /* Exception port. */
128 mach_port_t darwin_ex_port;
129
130 /* Port set. */
131 mach_port_t darwin_port_set;
132
133 /* Page size. */
134 static vm_size_t mach_page_size;
135
136 /* If Set, catch all mach exceptions (before they are converted to signals
137 by the kernel). */
138 static int enable_mach_exceptions;
139
140 /* Inferior that should report a fake stop event. */
141 static struct inferior *darwin_inf_fake_stop;
142
143 #define PAGE_TRUNC(x) ((x) & ~(mach_page_size - 1))
144 #define PAGE_ROUND(x) PAGE_TRUNC((x) + mach_page_size - 1)
145
146 /* This controls output of inferior debugging. */
147 static int darwin_debug_flag = 0;
148
149 /* Create a __TEXT __info_plist section in the executable so that gdb could
150 be signed. This is required to get an authorization for task_for_pid.
151
152 Once gdb is built, you can either:
153 * make it setgid procmod
154 * or codesign it with any system-trusted signing authority.
155 See taskgated(8) for details. */
156 static const unsigned char info_plist[]
157 __attribute__ ((section ("__TEXT,__info_plist"),used)) =
158 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
159 "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\""
160 " \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
161 "<plist version=\"1.0\">\n"
162 "<dict>\n"
163 " <key>CFBundleIdentifier</key>\n"
164 " <string>org.gnu.gdb</string>\n"
165 " <key>CFBundleName</key>\n"
166 " <string>gdb</string>\n"
167 " <key>CFBundleVersion</key>\n"
168 " <string>1.0</string>\n"
169 " <key>SecTaskAccess</key>\n"
170 " <array>\n"
171 " <string>allowed</string>\n"
172 " <string>debug</string>\n"
173 " </array>\n"
174 "</dict>\n"
175 "</plist>\n";
176
177 static void
178 inferior_debug (int level, const char *fmt, ...)
179 {
180 va_list ap;
181
182 if (darwin_debug_flag < level)
183 return;
184
185 va_start (ap, fmt);
186 printf_unfiltered (_("[%d inferior]: "), getpid ());
187 vprintf_unfiltered (fmt, ap);
188 va_end (ap);
189 }
190
191 void
192 mach_check_error (kern_return_t ret, const char *file,
193 unsigned int line, const char *func)
194 {
195 if (ret == KERN_SUCCESS)
196 return;
197 if (func == NULL)
198 func = _("[UNKNOWN]");
199
200 warning (_("Mach error at \"%s:%u\" in function \"%s\": %s (0x%lx)"),
201 file, line, func, mach_error_string (ret), (unsigned long) ret);
202 }
203
204 static const char *
205 unparse_exception_type (unsigned int i)
206 {
207 static char unknown_exception_buf[32];
208
209 switch (i)
210 {
211 case EXC_BAD_ACCESS:
212 return "EXC_BAD_ACCESS";
213 case EXC_BAD_INSTRUCTION:
214 return "EXC_BAD_INSTRUCTION";
215 case EXC_ARITHMETIC:
216 return "EXC_ARITHMETIC";
217 case EXC_EMULATION:
218 return "EXC_EMULATION";
219 case EXC_SOFTWARE:
220 return "EXC_SOFTWARE";
221 case EXC_BREAKPOINT:
222 return "EXC_BREAKPOINT";
223 case EXC_SYSCALL:
224 return "EXC_SYSCALL";
225 case EXC_MACH_SYSCALL:
226 return "EXC_MACH_SYSCALL";
227 case EXC_RPC_ALERT:
228 return "EXC_RPC_ALERT";
229 case EXC_CRASH:
230 return "EXC_CRASH";
231 default:
232 snprintf (unknown_exception_buf, 32, _("unknown (%d)"), i);
233 return unknown_exception_buf;
234 }
235 }
236
237 /* Set errno to zero, and then call ptrace with the given arguments.
238 If inferior debugging traces are on, then also print a debug
239 trace.
240
241 The returned value is the same as the value returned by ptrace,
242 except in the case where that value is -1 but errno is zero.
243 This case is documented to be a non-error situation, so we
244 return zero in that case. */
245
246 static int
247 darwin_ptrace (const char *name,
248 int request, int pid, PTRACE_TYPE_ARG3 arg3, int arg4)
249 {
250 int ret;
251
252 errno = 0;
253 ret = ptrace (request, pid, (caddr_t) arg3, arg4);
254 if (ret == -1 && errno == 0)
255 ret = 0;
256
257 inferior_debug (4, _("ptrace (%s, %d, 0x%x, %d): %d (%s)\n"),
258 name, pid, arg3, arg4, ret,
259 (ret != 0) ? safe_strerror (errno) : _("no error"));
260 return ret;
261 }
262
263 static int
264 cmp_thread_t (const void *l, const void *r)
265 {
266 thread_t tl = *(const thread_t *)l;
267 thread_t tr = *(const thread_t *)r;
268 return (int)(tl - tr);
269 }
270
271 static void
272 darwin_check_new_threads (struct inferior *inf)
273 {
274 kern_return_t kret;
275 unsigned int i;
276 thread_array_t thread_list;
277 unsigned int new_nbr;
278 unsigned int old_nbr;
279 unsigned int new_ix, old_ix;
280 darwin_inferior *darwin_inf = inf->private;
281 VEC (darwin_thread_t) *thread_vec;
282
283 /* Get list of threads. */
284 kret = task_threads (darwin_inf->task, &thread_list, &new_nbr);
285 MACH_CHECK_ERROR (kret);
286 if (kret != KERN_SUCCESS)
287 return;
288
289 /* Sort the list. */
290 if (new_nbr > 1)
291 qsort (thread_list, new_nbr, sizeof (thread_t), cmp_thread_t);
292
293 if (darwin_inf->threads)
294 old_nbr = VEC_length (darwin_thread_t, darwin_inf->threads);
295 else
296 old_nbr = 0;
297
298 /* Quick check for no changes. */
299 if (old_nbr == new_nbr)
300 {
301 for (i = 0; i < new_nbr; i++)
302 if (thread_list[i]
303 != VEC_index (darwin_thread_t, darwin_inf->threads, i)->gdb_port)
304 break;
305 if (i == new_nbr)
306 {
307 kret = vm_deallocate (gdb_task, (vm_address_t) thread_list,
308 new_nbr * sizeof (int));
309 MACH_CHECK_ERROR (kret);
310 return;
311 }
312 }
313
314 thread_vec = VEC_alloc (darwin_thread_t, new_nbr);
315
316 for (new_ix = 0, old_ix = 0; new_ix < new_nbr || old_ix < old_nbr;)
317 {
318 thread_t new_id = (new_ix < new_nbr) ?
319 thread_list[new_ix] : THREAD_NULL;
320 darwin_thread_t *old = (old_ix < old_nbr) ?
321 VEC_index (darwin_thread_t, darwin_inf->threads, old_ix) : NULL;
322 thread_t old_id = old ? old->gdb_port : THREAD_NULL;
323
324 inferior_debug
325 (12, _(" new_ix:%d/%d, old_ix:%d/%d, new_id:%x old_id:%x\n"),
326 new_ix, new_nbr, old_ix, old_nbr, new_id, old_id);
327
328 if (old_id == new_id)
329 {
330 /* Thread still exist. */
331 VEC_safe_push (darwin_thread_t, thread_vec, old);
332 new_ix++;
333 old_ix++;
334
335 kret = mach_port_deallocate (gdb_task, old_id);
336 MACH_CHECK_ERROR (kret);
337 continue;
338 }
339 if (new_ix < new_nbr && new_id == MACH_PORT_DEAD)
340 {
341 /* Ignore dead ports.
342 In some weird cases, we might get dead ports. They should
343 correspond to dead thread so they could safely be ignored. */
344 new_ix++;
345 continue;
346 }
347 if (new_ix < new_nbr && (old_ix == old_nbr || new_id < old_id))
348 {
349 /* A thread was created. */
350 struct thread_info *tp;
351 struct private_thread_info *pti;
352
353 pti = XZALLOC (struct private_thread_info);
354 pti->gdb_port = new_id;
355 pti->msg_state = DARWIN_RUNNING;
356
357 /* Add a new thread unless this is the first one ever met. */
358 if (!(old_nbr == 0 && new_ix == 0))
359 tp = add_thread_with_info (ptid_build (inf->pid, 0, new_id), pti);
360 else
361 {
362 tp = find_thread_ptid (ptid_build (inf->pid, 0, 0));
363 gdb_assert (tp);
364 tp->private = pti;
365 }
366 VEC_safe_push (darwin_thread_t, thread_vec, pti);
367 new_ix++;
368 continue;
369 }
370 if (old_ix < old_nbr && (new_ix == new_nbr || new_id > old_id))
371 {
372 /* A thread was removed. */
373 delete_thread (ptid_build (inf->pid, 0, old_id));
374 kret = mach_port_deallocate (gdb_task, old_id);
375 MACH_CHECK_ERROR (kret);
376 old_ix++;
377 continue;
378 }
379 gdb_assert_not_reached ("unexpected thread case");
380 }
381
382 if (darwin_inf->threads)
383 VEC_free (darwin_thread_t, darwin_inf->threads);
384 darwin_inf->threads = thread_vec;
385
386 kret = vm_deallocate (gdb_task, (vm_address_t) thread_list,
387 new_nbr * sizeof (int));
388 MACH_CHECK_ERROR (kret);
389 }
390
391 static int
392 find_inferior_task_it (struct inferior *inf, void *port_ptr)
393 {
394 return inf->private->task == *(task_t*)port_ptr;
395 }
396
397 static int
398 find_inferior_notify_it (struct inferior *inf, void *port_ptr)
399 {
400 return inf->private->notify_port == *(task_t*)port_ptr;
401 }
402
403 /* Return an inferior by task port. */
404 static struct inferior *
405 darwin_find_inferior_by_task (task_t port)
406 {
407 return iterate_over_inferiors (&find_inferior_task_it, &port);
408 }
409
410 /* Return an inferior by notification port. */
411 static struct inferior *
412 darwin_find_inferior_by_notify (mach_port_t port)
413 {
414 return iterate_over_inferiors (&find_inferior_notify_it, &port);
415 }
416
417 /* Return a thread by port. */
418 static darwin_thread_t *
419 darwin_find_thread (struct inferior *inf, thread_t thread)
420 {
421 darwin_thread_t *t;
422 int k;
423
424 for (k = 0;
425 VEC_iterate (darwin_thread_t, inf->private->threads, k, t);
426 k++)
427 if (t->gdb_port == thread)
428 return t;
429 return NULL;
430 }
431
432 /* Suspend (ie stop) an inferior at Mach level. */
433
434 static void
435 darwin_suspend_inferior (struct inferior *inf)
436 {
437 if (!inf->private->suspended)
438 {
439 kern_return_t kret;
440
441 kret = task_suspend (inf->private->task);
442 MACH_CHECK_ERROR (kret);
443
444 inf->private->suspended = 1;
445 }
446 }
447
448 /* Resume an inferior at Mach level. */
449
450 static void
451 darwin_resume_inferior (struct inferior *inf)
452 {
453 if (inf->private->suspended)
454 {
455 kern_return_t kret;
456
457 kret = task_resume (inf->private->task);
458 MACH_CHECK_ERROR (kret);
459
460 inf->private->suspended = 0;
461 }
462 }
463
464 /* Iterator functions. */
465
466 static int
467 darwin_suspend_inferior_it (struct inferior *inf, void *arg)
468 {
469 darwin_suspend_inferior (inf);
470 darwin_check_new_threads (inf);
471 return 0;
472 }
473
474 static int
475 darwin_resume_inferior_it (struct inferior *inf, void *arg)
476 {
477 darwin_resume_inferior (inf);
478 return 0;
479 }
480
481 static void
482 darwin_dump_message (mach_msg_header_t *hdr, int disp_body)
483 {
484 printf_unfiltered (_("message header:\n"));
485 printf_unfiltered (_(" bits: 0x%x\n"), hdr->msgh_bits);
486 printf_unfiltered (_(" size: 0x%x\n"), hdr->msgh_size);
487 printf_unfiltered (_(" remote-port: 0x%x\n"), hdr->msgh_remote_port);
488 printf_unfiltered (_(" local-port: 0x%x\n"), hdr->msgh_local_port);
489 printf_unfiltered (_(" reserved: 0x%x\n"), hdr->msgh_reserved);
490 printf_unfiltered (_(" id: 0x%x\n"), hdr->msgh_id);
491
492 if (disp_body)
493 {
494 const unsigned char *data;
495 const unsigned long *ldata;
496 int size;
497 int i;
498
499 data = (unsigned char *)(hdr + 1);
500 size = hdr->msgh_size - sizeof (mach_msg_header_t);
501
502 if (hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX)
503 {
504 mach_msg_body_t *bod = (mach_msg_body_t*)data;
505 mach_msg_port_descriptor_t *desc =
506 (mach_msg_port_descriptor_t *)(bod + 1);
507 int k;
508 NDR_record_t *ndr;
509 printf_unfiltered (_("body: descriptor_count=%u\n"),
510 bod->msgh_descriptor_count);
511 data += sizeof (mach_msg_body_t);
512 size -= sizeof (mach_msg_body_t);
513 for (k = 0; k < bod->msgh_descriptor_count; k++)
514 switch (desc[k].type)
515 {
516 case MACH_MSG_PORT_DESCRIPTOR:
517 printf_unfiltered
518 (_(" descr %d: type=%u (port) name=0x%x, dispo=%d\n"),
519 k, desc[k].type, desc[k].name, desc[k].disposition);
520 break;
521 default:
522 printf_unfiltered (_(" descr %d: type=%u\n"),
523 k, desc[k].type);
524 break;
525 }
526 data += bod->msgh_descriptor_count
527 * sizeof (mach_msg_port_descriptor_t);
528 size -= bod->msgh_descriptor_count
529 * sizeof (mach_msg_port_descriptor_t);
530 ndr = (NDR_record_t *)(desc + bod->msgh_descriptor_count);
531 printf_unfiltered
532 (_("NDR: mig=%02x if=%02x encod=%02x "
533 "int=%02x char=%02x float=%02x\n"),
534 ndr->mig_vers, ndr->if_vers, ndr->mig_encoding,
535 ndr->int_rep, ndr->char_rep, ndr->float_rep);
536 data += sizeof (NDR_record_t);
537 size -= sizeof (NDR_record_t);
538 }
539
540 printf_unfiltered (_(" data:"));
541 ldata = (const unsigned long *)data;
542 for (i = 0; i < size / sizeof (unsigned long); i++)
543 printf_unfiltered (" %08lx", ldata[i]);
544 printf_unfiltered (_("\n"));
545 }
546 }
547
548 static int
549 darwin_decode_exception_message (mach_msg_header_t *hdr,
550 struct inferior **pinf,
551 darwin_thread_t **pthread)
552 {
553 mach_msg_body_t *bod = (mach_msg_body_t*)(hdr + 1);
554 mach_msg_port_descriptor_t *desc = (mach_msg_port_descriptor_t *)(bod + 1);
555 NDR_record_t *ndr;
556 integer_t *data;
557 struct inferior *inf;
558 darwin_thread_t *thread;
559 task_t task_port;
560 thread_t thread_port;
561 kern_return_t kret;
562 int i;
563
564 /* Check message identifier. 2401 is exc. */
565 if (hdr->msgh_id != 2401)
566 return -1;
567
568 /* Check message header. */
569 if (!(hdr->msgh_bits & MACH_MSGH_BITS_COMPLEX))
570 return -1;
571
572 /* Check descriptors. */
573 if (hdr->msgh_size < (sizeof (*hdr) + sizeof (*bod) + 2 * sizeof (*desc)
574 + sizeof (*ndr) + 2 * sizeof (integer_t))
575 || bod->msgh_descriptor_count != 2
576 || desc[0].type != MACH_MSG_PORT_DESCRIPTOR
577 || desc[0].disposition != MACH_MSG_TYPE_MOVE_SEND
578 || desc[1].type != MACH_MSG_PORT_DESCRIPTOR
579 || desc[1].disposition != MACH_MSG_TYPE_MOVE_SEND)
580 return -1;
581
582 /* Check data representation. */
583 ndr = (NDR_record_t *)(desc + 2);
584 if (ndr->mig_vers != NDR_PROTOCOL_2_0
585 || ndr->if_vers != NDR_PROTOCOL_2_0
586 || ndr->mig_encoding != NDR_record.mig_encoding
587 || ndr->int_rep != NDR_record.int_rep
588 || ndr->char_rep != NDR_record.char_rep
589 || ndr->float_rep != NDR_record.float_rep)
590 return -1;
591
592 /* Ok, the hard work. */
593 data = (integer_t *)(ndr + 1);
594
595 /* Find process by port. */
596 task_port = desc[1].name;
597 thread_port = desc[0].name;
598 inf = darwin_find_inferior_by_task (task_port);
599 if (inf == NULL)
600 return -1;
601 *pinf = inf;
602
603 /* Find thread by port. */
604 /* Check for new threads. Do it early so that the port in the exception
605 message can be deallocated. */
606 darwin_check_new_threads (inf);
607
608 /* We got new rights to the task and the thread. Get rid of them. */
609 kret = mach_port_deallocate (mach_task_self (), task_port);
610 MACH_CHECK_ERROR (kret);
611 kret = mach_port_deallocate (mach_task_self (), thread_port);
612 MACH_CHECK_ERROR (kret);
613
614 thread = darwin_find_thread (inf, thread_port);
615 if (thread == NULL)
616 return -1;
617 *pthread = thread;
618
619 /* The thread should be running. However we have observed cases where a thread
620 got a SIGTTIN message after being stopped. */
621 gdb_assert (thread->msg_state != DARWIN_MESSAGE);
622
623 /* Finish decoding. */
624 thread->event.header = *hdr;
625 thread->event.thread_port = thread_port;
626 thread->event.task_port = task_port;
627 thread->event.ex_type = data[0];
628 thread->event.data_count = data[1];
629
630 if (hdr->msgh_size < (sizeof (*hdr) + sizeof (*bod) + 2 * sizeof (*desc)
631 + sizeof (*ndr) + 2 * sizeof (integer_t)
632 + data[1] * sizeof (integer_t)))
633 return -1;
634 for (i = 0; i < data[1]; i++)
635 thread->event.ex_data[i] = data[2 + i];
636
637 thread->msg_state = DARWIN_MESSAGE;
638
639 return 0;
640 }
641
642 static void
643 darwin_encode_reply (mig_reply_error_t *reply, mach_msg_header_t *hdr,
644 integer_t code)
645 {
646 mach_msg_header_t *rh = &reply->Head;
647 rh->msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(hdr->msgh_bits), 0);
648 rh->msgh_remote_port = hdr->msgh_remote_port;
649 rh->msgh_size = (mach_msg_size_t)sizeof(mig_reply_error_t);
650 rh->msgh_local_port = MACH_PORT_NULL;
651 rh->msgh_id = hdr->msgh_id + 100;
652
653 reply->NDR = NDR_record;
654 reply->RetCode = code;
655 }
656
657 static void
658 darwin_send_reply (struct inferior *inf, darwin_thread_t *thread)
659 {
660 kern_return_t kret;
661 mig_reply_error_t reply;
662
663 darwin_encode_reply (&reply, &thread->event.header, KERN_SUCCESS);
664
665 kret = mach_msg (&reply.Head, MACH_SEND_MSG | MACH_SEND_INTERRUPT,
666 reply.Head.msgh_size, 0,
667 MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE,
668 MACH_PORT_NULL);
669 MACH_CHECK_ERROR (kret);
670
671 inf->private->pending_messages--;
672 }
673
674 static void
675 darwin_resume_thread (struct inferior *inf, darwin_thread_t *thread,
676 int step, int nsignal)
677 {
678 kern_return_t kret;
679 int res;
680
681 inferior_debug
682 (3, _("darwin_resume_thread: state=%d, thread=0x%x, step=%d nsignal=%d\n"),
683 thread->msg_state, thread->gdb_port, step, nsignal);
684
685 switch (thread->msg_state)
686 {
687 case DARWIN_MESSAGE:
688 if (thread->event.ex_type == EXC_SOFTWARE
689 && thread->event.ex_data[0] == EXC_SOFT_SIGNAL)
690 {
691 /* Either deliver a new signal or cancel the signal received. */
692 res = PTRACE (PT_THUPDATE, inf->pid,
693 (void *)(uintptr_t)thread->gdb_port, nsignal);
694 if (res < 0)
695 inferior_debug (1, _("ptrace THUP: res=%d\n"), res);
696 }
697 else if (nsignal)
698 {
699 /* Note: ptrace is allowed only if the process is stopped.
700 Directly send the signal to the thread. */
701 res = syscall (SYS___pthread_kill, thread->gdb_port, nsignal);
702 inferior_debug (4, _("darwin_resume_thread: kill 0x%x %d: %d\n"),
703 thread->gdb_port, nsignal, res);
704 thread->signaled = 1;
705 }
706
707 /* Set single step. */
708 inferior_debug (4, _("darwin_set_sstep (thread=%x, enable=%d)\n"),
709 thread->gdb_port, step);
710 darwin_set_sstep (thread->gdb_port, step);
711 thread->single_step = step;
712
713 darwin_send_reply (inf, thread);
714 thread->msg_state = DARWIN_RUNNING;
715 break;
716
717 case DARWIN_RUNNING:
718 break;
719
720 case DARWIN_STOPPED:
721 kret = thread_resume (thread->gdb_port);
722 MACH_CHECK_ERROR (kret);
723
724 thread->msg_state = DARWIN_RUNNING;
725 break;
726 }
727 }
728
729 /* Resume all threads of the inferior. */
730
731 static void
732 darwin_resume_inferior_threads (struct inferior *inf, int step, int nsignal)
733 {
734 darwin_thread_t *thread;
735 int k;
736
737 for (k = 0;
738 VEC_iterate (darwin_thread_t, inf->private->threads, k, thread);
739 k++)
740 darwin_resume_thread (inf, thread, step, nsignal);
741 }
742
743 struct resume_inferior_threads_param
744 {
745 int step;
746 int nsignal;
747 };
748
749 static int
750 darwin_resume_inferior_threads_it (struct inferior *inf, void *param)
751 {
752 int step = ((struct resume_inferior_threads_param *)param)->step;
753 int nsignal = ((struct resume_inferior_threads_param *)param)->nsignal;
754
755 darwin_resume_inferior_threads (inf, step, nsignal);
756
757 return 0;
758 }
759
760 /* Suspend all threads of INF. */
761
762 static void
763 darwin_suspend_inferior_threads (struct inferior *inf)
764 {
765 darwin_thread_t *thread;
766 kern_return_t kret;
767 int k;
768
769 for (k = 0;
770 VEC_iterate (darwin_thread_t, inf->private->threads, k, thread);
771 k++)
772 switch (thread->msg_state)
773 {
774 case DARWIN_STOPPED:
775 case DARWIN_MESSAGE:
776 break;
777 case DARWIN_RUNNING:
778 kret = thread_suspend (thread->gdb_port);
779 MACH_CHECK_ERROR (kret);
780 thread->msg_state = DARWIN_STOPPED;
781 break;
782 }
783 }
784
785 static void
786 darwin_resume (ptid_t ptid, int step, enum target_signal signal)
787 {
788 struct target_waitstatus status;
789 int pid;
790
791 kern_return_t kret;
792 int res;
793 int nsignal;
794 struct inferior *inf;
795
796 inferior_debug
797 (2, _("darwin_resume: pid=%d, tid=0x%x, step=%d, signal=%d\n"),
798 ptid_get_pid (ptid), ptid_get_tid (ptid), step, signal);
799
800 if (signal == TARGET_SIGNAL_0)
801 nsignal = 0;
802 else
803 nsignal = target_signal_to_host (signal);
804
805 /* Don't try to single step all threads. */
806 if (step)
807 ptid = inferior_ptid;
808
809 /* minus_one_ptid is RESUME_ALL. */
810 if (ptid_equal (ptid, minus_one_ptid))
811 {
812 struct resume_inferior_threads_param param;
813
814 param.nsignal = nsignal;
815 param.step = step;
816
817 /* Resume threads. */
818 iterate_over_inferiors (darwin_resume_inferior_threads_it, &param);
819 /* Resume tasks. */
820 iterate_over_inferiors (darwin_resume_inferior_it, NULL);
821 }
822 else
823 {
824 struct inferior *inf = find_inferior_pid (ptid_get_pid (ptid));
825 long tid = ptid_get_tid (ptid);
826
827 /* Stop the inferior (should be useless). */
828 darwin_suspend_inferior (inf);
829
830 if (tid == 0)
831 darwin_resume_inferior_threads (inf, step, nsignal);
832 else
833 {
834 darwin_thread_t *thread;
835
836 /* Suspend threads of the task. */
837 darwin_suspend_inferior_threads (inf);
838
839 /* Resume the selected thread. */
840 thread = darwin_find_thread (inf, tid);
841 gdb_assert (thread);
842 darwin_resume_thread (inf, thread, step, nsignal);
843 }
844
845 /* Resume the task. */
846 darwin_resume_inferior (inf);
847 }
848 }
849
850 static void
851 darwin_resume_to (struct target_ops *ops, ptid_t ptid, int step,
852 enum target_signal signal)
853 {
854 return darwin_resume (ptid, step, signal);
855 }
856
857 static ptid_t
858 darwin_decode_message (mach_msg_header_t *hdr,
859 darwin_thread_t **pthread,
860 struct inferior **pinf,
861 struct target_waitstatus *status)
862 {
863 darwin_thread_t *thread;
864 struct inferior *inf;
865
866 /* Exception message. */
867 if (hdr->msgh_local_port == darwin_ex_port)
868 {
869 int res;
870
871 /* Decode message. */
872 res = darwin_decode_exception_message (hdr, &inf, &thread);
873
874 if (res < 0)
875 {
876 /* Should not happen... */
877 printf_unfiltered (_("darwin_wait: ill-formatted message (id=%x)\n"),
878 hdr->msgh_id);
879 /* FIXME: send a failure reply? */
880 status->kind = TARGET_WAITKIND_SPURIOUS;
881 return minus_one_ptid;
882 }
883 *pinf = inf;
884 *pthread = thread;
885 inf->private->pending_messages++;
886
887 status->kind = TARGET_WAITKIND_STOPPED;
888 thread->msg_state = DARWIN_MESSAGE;
889
890 inferior_debug (4, _("darwin_wait: thread=%x, got %s\n"),
891 thread->gdb_port,
892 unparse_exception_type (thread->event.ex_type));
893
894 switch (thread->event.ex_type)
895 {
896 case EXC_BAD_ACCESS:
897 status->value.sig = TARGET_EXC_BAD_ACCESS;
898 break;
899 case EXC_BAD_INSTRUCTION:
900 status->value.sig = TARGET_EXC_BAD_INSTRUCTION;
901 break;
902 case EXC_ARITHMETIC:
903 status->value.sig = TARGET_EXC_ARITHMETIC;
904 break;
905 case EXC_EMULATION:
906 status->value.sig = TARGET_EXC_EMULATION;
907 break;
908 case EXC_SOFTWARE:
909 if (thread->event.ex_data[0] == EXC_SOFT_SIGNAL)
910 {
911 status->value.sig =
912 target_signal_from_host (thread->event.ex_data[1]);
913 inferior_debug (5, _(" (signal %d: %s)\n"),
914 thread->event.ex_data[1],
915 target_signal_to_name (status->value.sig));
916
917 /* If the thread is stopped because it has received a signal
918 that gdb has just sent, continue. */
919 if (thread->signaled)
920 {
921 thread->signaled = 0;
922 darwin_send_reply (inf, thread);
923 thread->msg_state = DARWIN_RUNNING;
924 status->kind = TARGET_WAITKIND_IGNORE;
925 }
926 }
927 else
928 status->value.sig = TARGET_EXC_SOFTWARE;
929 break;
930 case EXC_BREAKPOINT:
931 /* Many internal GDB routines expect breakpoints to be reported
932 as TARGET_SIGNAL_TRAP, and will report TARGET_EXC_BREAKPOINT
933 as a spurious signal. */
934 status->value.sig = TARGET_SIGNAL_TRAP;
935 break;
936 default:
937 status->value.sig = TARGET_SIGNAL_UNKNOWN;
938 break;
939 }
940
941 return ptid_build (inf->pid, 0, thread->gdb_port);
942 }
943
944 *pinf = NULL;
945 *pthread = NULL;
946
947 inf = darwin_find_inferior_by_notify (hdr->msgh_local_port);
948 if (inf != NULL)
949 {
950 if (!inf->private->no_ptrace)
951 {
952 pid_t res;
953 int wstatus;
954
955 res = wait4 (inf->pid, &wstatus, 0, NULL);
956 if (res < 0 || res != inf->pid)
957 {
958 printf_unfiltered (_("wait4: res=%d: %s\n"),
959 res, safe_strerror (errno));
960 status->kind = TARGET_WAITKIND_SPURIOUS;
961 return minus_one_ptid;
962 }
963 if (WIFEXITED (wstatus))
964 {
965 status->kind = TARGET_WAITKIND_EXITED;
966 status->value.integer = WEXITSTATUS (wstatus);
967 }
968 else
969 {
970 status->kind = TARGET_WAITKIND_SIGNALLED;
971 status->value.sig = WTERMSIG (wstatus);
972 }
973
974 inferior_debug (4, _("darwin_wait: pid=%d exit, status=%x\n"),
975 res, wstatus);
976
977 /* Looks necessary on Leopard and harmless... */
978 wait4 (inf->pid, &wstatus, 0, NULL);
979
980 return ptid_build (inf->pid, 0, 0);
981 }
982 else
983 {
984 inferior_debug (4, _("darwin_wait: pid=%d\n"), inf->pid);
985 status->kind = TARGET_WAITKIND_EXITED;
986 status->value.integer = 0; /* Don't know. */
987 return ptid_build (inf->pid, 0, 0);
988 }
989 }
990
991 printf_unfiltered (_("Bad local-port: %x\n"), hdr->msgh_local_port);
992 status->kind = TARGET_WAITKIND_SPURIOUS;
993 return minus_one_ptid;
994 }
995
996 static int
997 cancel_breakpoint (ptid_t ptid)
998 {
999 /* Arrange for a breakpoint to be hit again later. We will handle
1000 the current event, eventually we will resume this thread, and this
1001 breakpoint will trap again.
1002
1003 If we do not do this, then we run the risk that the user will
1004 delete or disable the breakpoint, but the thread will have already
1005 tripped on it. */
1006
1007 struct regcache *regcache = get_thread_regcache (ptid);
1008 struct gdbarch *gdbarch = get_regcache_arch (regcache);
1009 CORE_ADDR pc;
1010
1011 pc = regcache_read_pc (regcache) - gdbarch_decr_pc_after_break (gdbarch);
1012 if (breakpoint_inserted_here_p (get_regcache_aspace (regcache), pc))
1013 {
1014 inferior_debug (4, "cancel_breakpoint for thread %x\n",
1015 ptid_get_tid (ptid));
1016
1017 /* Back up the PC if necessary. */
1018 if (gdbarch_decr_pc_after_break (gdbarch))
1019 regcache_write_pc (regcache, pc);
1020
1021 return 1;
1022 }
1023 return 0;
1024 }
1025
1026 static ptid_t
1027 darwin_wait (ptid_t ptid, struct target_waitstatus *status)
1028 {
1029 kern_return_t kret;
1030 union
1031 {
1032 mach_msg_header_t hdr;
1033 char data[0x100];
1034 } msgin;
1035 mach_msg_header_t *hdr = &msgin.hdr;
1036 ptid_t res;
1037 darwin_thread_t *thread;
1038 struct inferior *inf;
1039
1040 inferior_debug
1041 (2, _("darwin_wait: waiting for a message pid=%d thread=%lx\n"),
1042 ptid_get_pid (ptid), ptid_get_tid (ptid));
1043
1044 /* Handle fake stop events at first. */
1045 if (darwin_inf_fake_stop != NULL)
1046 {
1047 inf = darwin_inf_fake_stop;
1048 darwin_inf_fake_stop = NULL;
1049
1050 status->kind = TARGET_WAITKIND_STOPPED;
1051 status->value.sig = TARGET_SIGNAL_TRAP;
1052 thread = VEC_index (darwin_thread_t, inf->private->threads, 0);
1053 thread->msg_state = DARWIN_STOPPED;
1054 return ptid_build (inf->pid, 0, thread->gdb_port);
1055 }
1056
1057 do
1058 {
1059 /* set_sigint_trap (); */
1060
1061 /* Wait for a message. */
1062 kret = mach_msg (&msgin.hdr, MACH_RCV_MSG | MACH_RCV_INTERRUPT, 0,
1063 sizeof (msgin.data), darwin_port_set, 0, MACH_PORT_NULL);
1064
1065 /* clear_sigint_trap (); */
1066
1067 if (kret == MACH_RCV_INTERRUPTED)
1068 {
1069 status->kind = TARGET_WAITKIND_IGNORE;
1070 return minus_one_ptid;
1071 }
1072
1073 if (kret != MACH_MSG_SUCCESS)
1074 {
1075 inferior_debug (5, _("mach_msg: ret=%x\n"), kret);
1076 status->kind = TARGET_WAITKIND_SPURIOUS;
1077 return minus_one_ptid;
1078 }
1079
1080 /* Debug: display message. */
1081 if (darwin_debug_flag > 10)
1082 darwin_dump_message (hdr, darwin_debug_flag > 11);
1083
1084 res = darwin_decode_message (hdr, &thread, &inf, status);
1085
1086 if (inf == NULL)
1087 return res;
1088 }
1089 while (status->kind == TARGET_WAITKIND_IGNORE);
1090
1091 /* Stop all tasks. */
1092 iterate_over_inferiors (darwin_suspend_inferior_it, NULL);
1093
1094 /* Read pending messages. */
1095 while (1)
1096 {
1097 struct target_waitstatus status2;
1098 ptid_t ptid2;
1099
1100 kret = mach_msg (&msgin.hdr,
1101 MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0,
1102 sizeof (msgin.data), darwin_port_set, 1, MACH_PORT_NULL);
1103
1104 if (kret == MACH_RCV_TIMED_OUT)
1105 break;
1106 if (kret != MACH_MSG_SUCCESS)
1107 {
1108 inferior_debug
1109 (5, _("darwin_wait: mach_msg(pending) ret=%x\n"), kret);
1110 break;
1111 }
1112
1113 ptid2 = darwin_decode_message (hdr, &thread, &inf, &status2);
1114
1115 if (inf != NULL && thread != NULL
1116 && thread->event.ex_type == EXC_BREAKPOINT)
1117 {
1118 if (thread->single_step
1119 || cancel_breakpoint (ptid_build (inf->pid, 0, thread->gdb_port)))
1120 {
1121 gdb_assert (thread->msg_state == DARWIN_MESSAGE);
1122 darwin_send_reply (inf, thread);
1123 thread->msg_state = DARWIN_RUNNING;
1124 }
1125 else
1126 inferior_debug
1127 (3, _("darwin_wait: thread %x hit a non-gdb breakpoint\n"),
1128 thread->gdb_port);
1129 }
1130 else
1131 inferior_debug (3, _("darwin_wait: unhandled pending message\n"));
1132 }
1133 return res;
1134 }
1135
1136 static ptid_t
1137 darwin_wait_to (struct target_ops *ops,
1138 ptid_t ptid, struct target_waitstatus *status, int options)
1139 {
1140 return darwin_wait (ptid, status);
1141 }
1142
1143 static void
1144 darwin_stop (ptid_t t)
1145 {
1146 struct inferior *inf = current_inferior ();
1147
1148 /* FIXME: handle in no_ptrace mode. */
1149 gdb_assert (!inf->private->no_ptrace);
1150 kill (inf->pid, SIGINT);
1151 }
1152
1153 static void
1154 darwin_mourn_inferior (struct target_ops *ops)
1155 {
1156 struct inferior *inf = current_inferior ();
1157 kern_return_t kret;
1158 mach_port_t prev;
1159 int i;
1160
1161 unpush_target (darwin_ops);
1162
1163 /* Deallocate threads. */
1164 if (inf->private->threads)
1165 {
1166 int k;
1167 darwin_thread_t *t;
1168 for (k = 0;
1169 VEC_iterate (darwin_thread_t, inf->private->threads, k, t);
1170 k++)
1171 {
1172 kret = mach_port_deallocate (gdb_task, t->gdb_port);
1173 MACH_CHECK_ERROR (kret);
1174 }
1175 VEC_free (darwin_thread_t, inf->private->threads);
1176 inf->private->threads = NULL;
1177 }
1178
1179 kret = mach_port_move_member (gdb_task,
1180 inf->private->notify_port, MACH_PORT_NULL);
1181 gdb_assert (kret == KERN_SUCCESS);
1182
1183 kret = mach_port_request_notification (gdb_task, inf->private->task,
1184 MACH_NOTIFY_DEAD_NAME, 0,
1185 MACH_PORT_NULL,
1186 MACH_MSG_TYPE_MAKE_SEND_ONCE,
1187 &prev);
1188 /* This can fail if the task is dead. */
1189 inferior_debug (4, "task=%x, prev=%x, notify_port=%x\n",
1190 inf->private->task, prev, inf->private->notify_port);
1191
1192 if (kret == KERN_SUCCESS)
1193 {
1194 kret = mach_port_deallocate (gdb_task, prev);
1195 MACH_CHECK_ERROR (kret);
1196 }
1197
1198 kret = mach_port_destroy (gdb_task, inf->private->notify_port);
1199 MACH_CHECK_ERROR (kret);
1200
1201
1202 /* Deallocate saved exception ports. */
1203 for (i = 0; i < inf->private->exception_info.count; i++)
1204 {
1205 kret = mach_port_deallocate
1206 (gdb_task, inf->private->exception_info.ports[i]);
1207 MACH_CHECK_ERROR (kret);
1208 }
1209 inf->private->exception_info.count = 0;
1210
1211 kret = mach_port_deallocate (gdb_task, inf->private->task);
1212 MACH_CHECK_ERROR (kret);
1213
1214 xfree (inf->private);
1215 inf->private = NULL;
1216
1217 generic_mourn_inferior ();
1218 }
1219
1220 static void
1221 darwin_reply_to_all_pending_messages (struct inferior *inf)
1222 {
1223 int k;
1224 darwin_thread_t *t;
1225
1226 for (k = 0;
1227 VEC_iterate (darwin_thread_t, inf->private->threads, k, t);
1228 k++)
1229 {
1230 if (t->msg_state == DARWIN_MESSAGE)
1231 darwin_resume_thread (inf, t, 0, 0);
1232 }
1233 }
1234
1235 static void
1236 darwin_stop_inferior (struct inferior *inf)
1237 {
1238 struct target_waitstatus wstatus;
1239 ptid_t ptid;
1240 kern_return_t kret;
1241 int status;
1242 int res;
1243
1244 gdb_assert (inf != NULL);
1245
1246 darwin_suspend_inferior (inf);
1247
1248 darwin_reply_to_all_pending_messages (inf);
1249
1250 if (inf->private->no_ptrace)
1251 return;
1252
1253 res = kill (inf->pid, SIGSTOP);
1254 if (res != 0)
1255 warning (_("cannot kill: %s"), safe_strerror (errno));
1256
1257 /* Wait until the process is really stopped. */
1258 while (1)
1259 {
1260 ptid = darwin_wait (inferior_ptid, &wstatus);
1261 if (wstatus.kind == TARGET_WAITKIND_STOPPED
1262 && wstatus.value.sig == TARGET_SIGNAL_STOP)
1263 break;
1264 }
1265 }
1266
1267 static kern_return_t
1268 darwin_save_exception_ports (darwin_inferior *inf)
1269 {
1270 kern_return_t kret;
1271
1272 inf->exception_info.count =
1273 sizeof (inf->exception_info.ports) / sizeof (inf->exception_info.ports[0]);
1274
1275 kret = task_get_exception_ports
1276 (inf->task, EXC_MASK_ALL, inf->exception_info.masks,
1277 &inf->exception_info.count, inf->exception_info.ports,
1278 inf->exception_info.behaviors, inf->exception_info.flavors);
1279 return kret;
1280 }
1281
1282 static kern_return_t
1283 darwin_restore_exception_ports (darwin_inferior *inf)
1284 {
1285 int i;
1286 kern_return_t kret;
1287
1288 for (i = 0; i < inf->exception_info.count; i++)
1289 {
1290 kret = task_set_exception_ports
1291 (inf->task, inf->exception_info.masks[i], inf->exception_info.ports[i],
1292 inf->exception_info.behaviors[i], inf->exception_info.flavors[i]);
1293 if (kret != KERN_SUCCESS)
1294 return kret;
1295 }
1296
1297 return KERN_SUCCESS;
1298 }
1299
1300 static void
1301 darwin_kill_inferior (struct target_ops *ops)
1302 {
1303 struct inferior *inf = current_inferior ();
1304 struct target_waitstatus wstatus;
1305 ptid_t ptid;
1306 kern_return_t kret;
1307 int status;
1308 int res;
1309
1310 if (ptid_equal (inferior_ptid, null_ptid))
1311 return;
1312
1313 gdb_assert (inf != NULL);
1314
1315 if (!inf->private->no_ptrace)
1316 {
1317 darwin_stop_inferior (inf);
1318
1319 res = PTRACE (PT_KILL, inf->pid, 0, 0);
1320 if (res != 0)
1321 warning (_("Failed to kill inferior: ptrace returned %d "
1322 "[%s] (pid=%d)"),
1323 res, safe_strerror (errno), inf->pid);
1324
1325 darwin_reply_to_all_pending_messages (inf);
1326
1327 darwin_resume_inferior (inf);
1328
1329 ptid = darwin_wait (inferior_ptid, &wstatus);
1330 }
1331 else
1332 {
1333 kret = darwin_restore_exception_ports (inf->private);
1334 MACH_CHECK_ERROR (kret);
1335
1336 darwin_reply_to_all_pending_messages (inf);
1337
1338 darwin_resume_inferior (inf);
1339
1340 res = kill (inf->pid, 9);
1341
1342 ptid = darwin_wait (inferior_ptid, &wstatus);
1343 }
1344
1345 target_mourn_inferior ();
1346 }
1347
1348 static void
1349 darwin_attach_pid (struct inferior *inf)
1350 {
1351 kern_return_t kret;
1352 mach_port_t prev_port;
1353 int traps_expected;
1354 mach_port_t prev_not;
1355 exception_mask_t mask;
1356
1357 inf->private = XZALLOC (darwin_inferior);
1358
1359 kret = task_for_pid (gdb_task, inf->pid, &inf->private->task);
1360 if (kret != KERN_SUCCESS)
1361 {
1362 int status;
1363
1364 if (!inf->attach_flag)
1365 {
1366 kill (inf->pid, 9);
1367 waitpid (inf->pid, &status, 0);
1368 }
1369
1370 error (_("Unable to find Mach task port for process-id %d: %s (0x%lx).\n"
1371 " (please check gdb is codesigned - see taskgated(8))"),
1372 inf->pid, mach_error_string (kret), (unsigned long) kret);
1373 }
1374
1375 inferior_debug (2, _("inferior task: 0x%x, pid: %d\n"),
1376 inf->private->task, inf->pid);
1377
1378 if (darwin_ex_port == MACH_PORT_NULL)
1379 {
1380 /* Create a port to get exceptions. */
1381 kret = mach_port_allocate (gdb_task, MACH_PORT_RIGHT_RECEIVE,
1382 &darwin_ex_port);
1383 gdb_assert (kret == KERN_SUCCESS);
1384
1385 kret = mach_port_insert_right (gdb_task, darwin_ex_port, darwin_ex_port,
1386 MACH_MSG_TYPE_MAKE_SEND);
1387 gdb_assert (kret == KERN_SUCCESS);
1388
1389 /* Create a port set and put ex_port in it. */
1390 kret = mach_port_allocate (gdb_task, MACH_PORT_RIGHT_PORT_SET,
1391 &darwin_port_set);
1392 gdb_assert (kret == KERN_SUCCESS);
1393
1394 kret = mach_port_move_member (gdb_task, darwin_ex_port, darwin_port_set);
1395 gdb_assert (kret == KERN_SUCCESS);
1396 }
1397
1398 /* Create a port to be notified when the child task terminates. */
1399 kret = mach_port_allocate (gdb_task, MACH_PORT_RIGHT_RECEIVE,
1400 &inf->private->notify_port);
1401 gdb_assert (kret == KERN_SUCCESS);
1402
1403 kret = mach_port_move_member (gdb_task,
1404 inf->private->notify_port, darwin_port_set);
1405 gdb_assert (kret == KERN_SUCCESS);
1406
1407 kret = mach_port_request_notification (gdb_task, inf->private->task,
1408 MACH_NOTIFY_DEAD_NAME, 0,
1409 inf->private->notify_port,
1410 MACH_MSG_TYPE_MAKE_SEND_ONCE,
1411 &prev_not);
1412 gdb_assert (kret == KERN_SUCCESS);
1413 gdb_assert (prev_not == MACH_PORT_NULL);
1414
1415 kret = darwin_save_exception_ports (inf->private);
1416 gdb_assert (kret == KERN_SUCCESS);
1417
1418 /* Set exception port. */
1419 if (enable_mach_exceptions)
1420 mask = EXC_MASK_ALL;
1421 else
1422 mask = EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT;
1423 kret = task_set_exception_ports (inf->private->task, mask, darwin_ex_port,
1424 EXCEPTION_DEFAULT, THREAD_STATE_NONE);
1425 gdb_assert (kret == KERN_SUCCESS);
1426
1427 push_target (darwin_ops);
1428 }
1429
1430 static void
1431 darwin_init_thread_list (struct inferior *inf)
1432 {
1433 darwin_thread_t *thread;
1434 ptid_t new_ptid;
1435
1436 darwin_check_new_threads (inf);
1437
1438 gdb_assert (inf->private->threads
1439 && VEC_length (darwin_thread_t, inf->private->threads) > 0);
1440 thread = VEC_index (darwin_thread_t, inf->private->threads, 0);
1441
1442 /* Note: fork_inferior automatically add a thead but it uses a wrong ptid.
1443 Fix up. */
1444 new_ptid = ptid_build (inf->pid, 0, thread->gdb_port);
1445 thread_change_ptid (inferior_ptid, new_ptid);
1446 inferior_ptid = new_ptid;
1447 }
1448
1449 /* The child must synchronize with gdb: gdb must set the exception port
1450 before the child call PTRACE_SIGEXC. We use a pipe to achieve this.
1451 FIXME: is there a lighter way ? */
1452 static int ptrace_fds[2];
1453
1454 static void
1455 darwin_ptrace_me (void)
1456 {
1457 int res;
1458 char c;
1459
1460 /* Close write end point. */
1461 close (ptrace_fds[1]);
1462
1463 /* Wait until gdb is ready. */
1464 res = read (ptrace_fds[0], &c, 1);
1465 gdb_assert (res == 0);
1466 close (ptrace_fds[0]);
1467
1468 /* Get rid of privileges. */
1469 setegid (getgid ());
1470
1471 /* Set TRACEME. */
1472 PTRACE (PT_TRACE_ME, 0, 0, 0);
1473
1474 /* Redirect signals to exception port. */
1475 PTRACE (PT_SIGEXC, 0, 0, 0);
1476 }
1477
1478 /* Dummy function to be sure fork_inferior uses fork(2) and not vfork(2). */
1479 static void
1480 darwin_pre_ptrace (void)
1481 {
1482 if (pipe (ptrace_fds) != 0)
1483 {
1484 ptrace_fds[0] = -1;
1485 ptrace_fds[1] = -1;
1486 error (_("unable to create a pipe: %s"), safe_strerror (errno));
1487 }
1488 }
1489
1490 static void
1491 darwin_ptrace_him (int pid)
1492 {
1493 task_t itask;
1494 kern_return_t kret;
1495 mach_port_t prev_port;
1496 int traps_expected;
1497 struct inferior *inf = current_inferior ();
1498
1499 darwin_attach_pid (inf);
1500
1501 /* Let's the child run. */
1502 close (ptrace_fds[0]);
1503 close (ptrace_fds[1]);
1504
1505 darwin_init_thread_list (inf);
1506
1507 startup_inferior (START_INFERIOR_TRAPS_EXPECTED);
1508 }
1509
1510 static void
1511 darwin_execvp (const char *file, char * const argv[], char * const env[])
1512 {
1513 posix_spawnattr_t attr;
1514 short ps_flags = 0;
1515 int res;
1516
1517 res = posix_spawnattr_init (&attr);
1518 if (res != 0)
1519 {
1520 fprintf_unfiltered
1521 (gdb_stderr, "Cannot initialize attribute for posix_spawn\n");
1522 return;
1523 }
1524
1525 /* Do like execve: replace the image. */
1526 ps_flags = POSIX_SPAWN_SETEXEC;
1527
1528 /* Disable ASLR. The constant doesn't look to be available outside the
1529 kernel include files. */
1530 #ifndef _POSIX_SPAWN_DISABLE_ASLR
1531 #define _POSIX_SPAWN_DISABLE_ASLR 0x0100
1532 #endif
1533 ps_flags |= _POSIX_SPAWN_DISABLE_ASLR;
1534 res = posix_spawnattr_setflags (&attr, ps_flags);
1535 if (res != 0)
1536 {
1537 fprintf_unfiltered (gdb_stderr, "Cannot set posix_spawn flags\n");
1538 return;
1539 }
1540
1541 posix_spawnp (NULL, argv[0], NULL, &attr, argv, env);
1542 }
1543
1544 static void
1545 darwin_create_inferior (struct target_ops *ops, char *exec_file,
1546 char *allargs, char **env, int from_tty)
1547 {
1548 /* Do the hard work. */
1549 fork_inferior (exec_file, allargs, env, darwin_ptrace_me, darwin_ptrace_him,
1550 darwin_pre_ptrace, NULL, darwin_execvp);
1551
1552 /* Return now in case of error. */
1553 if (ptid_equal (inferior_ptid, null_ptid))
1554 return;
1555 }
1556 \f
1557
1558 /* Attach to process PID, then initialize for debugging it
1559 and wait for the trace-trap that results from attaching. */
1560 static void
1561 darwin_attach (struct target_ops *ops, char *args, int from_tty)
1562 {
1563 pid_t pid;
1564 pid_t pid2;
1565 int wstatus;
1566 int res;
1567 struct inferior *inf;
1568 kern_return_t kret;
1569
1570 pid = parse_pid_to_attach (args);
1571
1572 if (pid == getpid ()) /* Trying to masturbate? */
1573 error (_("I refuse to debug myself!"));
1574
1575 if (from_tty)
1576 {
1577 char *exec_file = get_exec_file (0);
1578
1579 if (exec_file)
1580 printf_unfiltered (_("Attaching to program: %s, %s\n"), exec_file,
1581 target_pid_to_str (pid_to_ptid (pid)));
1582 else
1583 printf_unfiltered (_("Attaching to %s\n"),
1584 target_pid_to_str (pid_to_ptid (pid)));
1585
1586 gdb_flush (gdb_stdout);
1587 }
1588
1589 if (pid == 0 || kill (pid, 0) < 0)
1590 error (_("Can't attach to process %d: %s (%d)"),
1591 pid, safe_strerror (errno), errno);
1592
1593 inferior_ptid = pid_to_ptid (pid);
1594 inf = current_inferior ();
1595 inferior_appeared (inf, pid);
1596 inf->attach_flag = 1;
1597
1598 /* Always add a main thread. */
1599 add_thread_silent (inferior_ptid);
1600
1601 darwin_attach_pid (inf);
1602
1603 darwin_suspend_inferior (inf);
1604
1605 darwin_init_thread_list (inf);
1606
1607 darwin_check_osabi (inf->private, ptid_get_tid (inferior_ptid));
1608
1609 gdb_assert (darwin_inf_fake_stop == NULL);
1610 darwin_inf_fake_stop = inf;
1611 inf->private->no_ptrace = 1;
1612 }
1613
1614 /* Take a program previously attached to and detaches it.
1615 The program resumes execution and will no longer stop
1616 on signals, etc. We'd better not have left any breakpoints
1617 in the program or it'll die when it hits one. For this
1618 to work, it may be necessary for the process to have been
1619 previously attached. It *might* work if the program was
1620 started via fork. */
1621 static void
1622 darwin_detach (struct target_ops *ops, char *args, int from_tty)
1623 {
1624 pid_t pid = ptid_get_pid (inferior_ptid);
1625 struct inferior *inf = current_inferior ();
1626 kern_return_t kret;
1627 int res;
1628
1629 /* Display message. */
1630 if (from_tty)
1631 {
1632 char *exec_file = get_exec_file (0);
1633 if (exec_file == 0)
1634 exec_file = "";
1635 printf_unfiltered (_("Detaching from program: %s, %s\n"), exec_file,
1636 target_pid_to_str (pid_to_ptid (pid)));
1637 gdb_flush (gdb_stdout);
1638 }
1639
1640 /* If ptrace() is in use, stop the process. */
1641 if (!inf->private->no_ptrace)
1642 darwin_stop_inferior (inf);
1643
1644 kret = darwin_restore_exception_ports (inf->private);
1645 MACH_CHECK_ERROR (kret);
1646
1647 if (!inf->private->no_ptrace)
1648 {
1649 res = PTRACE (PT_DETACH, inf->pid, 0, 0);
1650 if (res != 0)
1651 printf_unfiltered (_("Unable to detach from process-id %d: %s (%d)"),
1652 inf->pid, safe_strerror (errno), errno);
1653 }
1654
1655 darwin_reply_to_all_pending_messages (inf);
1656
1657 /* When using ptrace, we have just performed a PT_DETACH, which
1658 resumes the inferior. On the other hand, when we are not using
1659 ptrace, we need to resume its execution ourselves. */
1660 if (inf->private->no_ptrace)
1661 darwin_resume_inferior (inf);
1662
1663 darwin_mourn_inferior (ops);
1664 }
1665
1666 static void
1667 darwin_files_info (struct target_ops *ops)
1668 {
1669 }
1670
1671 static char *
1672 darwin_pid_to_str (struct target_ops *ops, ptid_t ptid)
1673 {
1674 static char buf[80];
1675 long tid = ptid_get_tid (ptid);
1676
1677 if (tid != 0)
1678 {
1679 snprintf (buf, sizeof (buf), _("Thread 0x%lx of process %u"),
1680 tid, ptid_get_pid (ptid));
1681 return buf;
1682 }
1683
1684 return normal_pid_to_str (ptid);
1685 }
1686
1687 static int
1688 darwin_thread_alive (struct target_ops *ops, ptid_t ptid)
1689 {
1690 return 1;
1691 }
1692
1693 /* If RDADDR is not NULL, read inferior task's LEN bytes from ADDR and
1694 copy it to RDADDR in gdb's address space.
1695 If WRADDR is not NULL, write gdb's LEN bytes from WRADDR and copy it
1696 to ADDR in inferior task's address space.
1697 Return 0 on failure; number of bytes read / writen otherwise. */
1698 static int
1699 darwin_read_write_inferior (task_t task, CORE_ADDR addr,
1700 char *rdaddr, const char *wraddr, int length)
1701 {
1702 kern_return_t kret;
1703 mach_vm_address_t offset = addr & (mach_page_size - 1);
1704 mach_vm_address_t low_address = (mach_vm_address_t) (addr - offset);
1705 mach_vm_size_t aligned_length = (mach_vm_size_t) PAGE_ROUND (offset + length);
1706 pointer_t copied;
1707 int copy_count;
1708 mach_vm_size_t remaining_length;
1709 mach_vm_address_t region_address;
1710 mach_vm_size_t region_length;
1711
1712 inferior_debug (8, _("darwin_read_write_inferior(task=%x, %s, len=%d)\n"),
1713 task, core_addr_to_string (addr), length);
1714
1715 /* Get memory from inferior with page aligned addresses. */
1716 kret = mach_vm_read (task, low_address, aligned_length,
1717 &copied, &copy_count);
1718 if (kret != KERN_SUCCESS)
1719 {
1720 inferior_debug
1721 (1, _("darwin_read_write_inferior: mach_vm_read failed at %s: %s"),
1722 core_addr_to_string (addr), mach_error_string (kret));
1723 return 0;
1724 }
1725
1726 if (rdaddr != NULL)
1727 memcpy (rdaddr, (char *)copied + offset, length);
1728
1729 if (wraddr == NULL)
1730 goto out;
1731
1732 memcpy ((char *)copied + offset, wraddr, length);
1733
1734 /* Do writes atomically.
1735 First check for holes and unwritable memory. */
1736 for (region_address = low_address, remaining_length = aligned_length;
1737 region_address < low_address + aligned_length;
1738 region_address += region_length, remaining_length -= region_length)
1739 {
1740 vm_region_submap_short_info_data_64_t info;
1741 mach_vm_address_t region_start = region_address;
1742 mach_msg_type_number_t count;
1743 natural_t region_depth;
1744
1745 region_depth = 100000;
1746 count = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
1747 kret = mach_vm_region_recurse
1748 (task, &region_start, &region_length, &region_depth,
1749 (vm_region_recurse_info_t) &info, &count);
1750
1751 if (kret != KERN_SUCCESS)
1752 {
1753 inferior_debug (1, _("darwin_read_write_inferior: "
1754 "mach_vm_region_recurse failed at %s: %s\n"),
1755 core_addr_to_string (region_address),
1756 mach_error_string (kret));
1757 goto out;
1758 }
1759
1760 inferior_debug
1761 (9, _("darwin_read_write_inferior: "
1762 "mach_vm_region_recurse addr=%s, start=%s, len=%s\n"),
1763 core_addr_to_string (region_address),
1764 core_addr_to_string (region_start),
1765 core_addr_to_string (region_length));
1766
1767 /* Check for holes in memory. */
1768 if (region_start > region_address)
1769 {
1770 warning (_("No memory at %s (vs %s+0x%x). Nothing written"),
1771 core_addr_to_string (region_address),
1772 core_addr_to_string (region_start),
1773 (unsigned)region_length);
1774 length = 0;
1775 goto out;
1776 }
1777
1778 /* Adjust the length. */
1779 region_length -= (region_address - region_start);
1780
1781 if (!(info.max_protection & VM_PROT_WRITE))
1782 {
1783 kret = mach_vm_protect
1784 (task, region_address, region_length,
1785 TRUE, info.max_protection | VM_PROT_WRITE | VM_PROT_COPY);
1786 if (kret != KERN_SUCCESS)
1787 {
1788 warning (_("darwin_read_write_inf: "
1789 "mach_vm_protect max failed at %s: %s"),
1790 core_addr_to_string (region_address),
1791 mach_error_string (kret));
1792 length = 0;
1793 goto out;
1794 }
1795 }
1796
1797 if (!(info.protection & VM_PROT_WRITE))
1798 {
1799 kret = mach_vm_protect (task, region_address, region_length,
1800 FALSE, info.protection | VM_PROT_WRITE);
1801 if (kret != KERN_SUCCESS)
1802 {
1803 warning (_("darwin_read_write_inf: "
1804 "mach_vm_protect failed at %s (len=0x%lx): %s"),
1805 core_addr_to_string (region_address),
1806 (unsigned long)region_length, mach_error_string (kret));
1807 length = 0;
1808 goto out;
1809 }
1810 }
1811 }
1812
1813 kret = mach_vm_write (task, low_address, copied, aligned_length);
1814
1815 if (kret != KERN_SUCCESS)
1816 {
1817 warning (_("darwin_read_write_inferior: mach_vm_write failed: %s"),
1818 mach_error_string (kret));
1819 length = 0;
1820 }
1821 out:
1822 mach_vm_deallocate (mach_task_self (), copied, copy_count);
1823 return length;
1824 }
1825
1826 /* Read LENGTH bytes at offset ADDR of task_dyld_info for TASK, and copy them
1827 to RDADDR.
1828 Return 0 on failure; number of bytes read / writen otherwise. */
1829
1830 static int
1831 darwin_read_dyld_info (task_t task, CORE_ADDR addr, char *rdaddr, int length)
1832 {
1833 struct task_dyld_info task_dyld_info;
1834 mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
1835 int sz = TASK_DYLD_INFO_COUNT * sizeof (natural_t);
1836 kern_return_t kret;
1837
1838 if (addr >= sz)
1839 return 0;
1840
1841 kret = task_info (task, TASK_DYLD_INFO, (task_info_t) &task_dyld_info, &count);
1842 MACH_CHECK_ERROR (kret);
1843 if (kret != KERN_SUCCESS)
1844 return -1;
1845 /* Truncate. */
1846 if (addr + length > sz)
1847 length = sz - addr;
1848 memcpy (rdaddr, (char *)&task_dyld_info + addr, length);
1849 return length;
1850 }
1851
1852 \f
1853 /* Return 0 on failure, number of bytes handled otherwise. TARGET
1854 is ignored. */
1855 static int
1856 darwin_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int write,
1857 struct mem_attrib *attrib, struct target_ops *target)
1858 {
1859 struct inferior *inf = current_inferior ();
1860 task_t task = inf->private->task;
1861
1862 if (task == MACH_PORT_NULL)
1863 return 0;
1864
1865 inferior_debug (8, _("darwin_xfer_memory(%s, %d, %c)\n"),
1866 core_addr_to_string (memaddr), len, write ? 'w' : 'r');
1867
1868 if (write)
1869 return darwin_read_write_inferior (task, memaddr, NULL, myaddr, len);
1870 else
1871 return darwin_read_write_inferior (task, memaddr, myaddr, NULL, len);
1872 }
1873
1874 static LONGEST
1875 darwin_xfer_partial (struct target_ops *ops,
1876 enum target_object object, const char *annex,
1877 gdb_byte *readbuf, const gdb_byte *writebuf,
1878 ULONGEST offset, LONGEST len)
1879 {
1880 struct inferior *inf = current_inferior ();
1881
1882 inferior_debug
1883 (8, _("darwin_xfer_partial(%s, %d, rbuf=%s, wbuf=%s) pid=%u\n"),
1884 core_addr_to_string (offset), (int)len,
1885 host_address_to_string (readbuf), host_address_to_string (writebuf),
1886 inf->pid);
1887
1888 switch (object)
1889 {
1890 case TARGET_OBJECT_MEMORY:
1891 return darwin_read_write_inferior (inf->private->task, offset,
1892 readbuf, writebuf, len);
1893 case TARGET_OBJECT_DARWIN_DYLD_INFO:
1894 if (writebuf != NULL || readbuf == NULL)
1895 {
1896 /* Support only read. */
1897 return -1;
1898 }
1899 return darwin_read_dyld_info (inf->private->task, offset, readbuf, len);
1900 default:
1901 return -1;
1902 }
1903
1904 }
1905
1906 static void
1907 set_enable_mach_exceptions (char *args, int from_tty,
1908 struct cmd_list_element *c)
1909 {
1910 if (!ptid_equal (inferior_ptid, null_ptid))
1911 {
1912 struct inferior *inf = current_inferior ();
1913 exception_mask_t mask;
1914 kern_return_t kret;
1915
1916 if (enable_mach_exceptions)
1917 mask = EXC_MASK_ALL;
1918 else
1919 {
1920 darwin_restore_exception_ports (inf->private);
1921 mask = EXC_MASK_SOFTWARE | EXC_MASK_BREAKPOINT;
1922 }
1923 kret = task_set_exception_ports (inf->private->task, mask, darwin_ex_port,
1924 EXCEPTION_DEFAULT, THREAD_STATE_NONE);
1925 MACH_CHECK_ERROR (kret);
1926 }
1927 }
1928
1929 static char *
1930 darwin_pid_to_exec_file (int pid)
1931 {
1932 char *path;
1933 int res;
1934
1935 path = xmalloc (MAXPATHLEN);
1936 make_cleanup (xfree, path);
1937
1938 res = proc_pidinfo (pid, PROC_PIDPATHINFO, 0, path, MAXPATHLEN);
1939 if (res >= 0)
1940 return path;
1941 else
1942 return NULL;
1943 }
1944
1945 static ptid_t
1946 darwin_get_ada_task_ptid (long lwp, long thread)
1947 {
1948 int i;
1949 darwin_thread_t *t;
1950 int k;
1951 struct inferior *inf = current_inferior ();
1952 kern_return_t kret;
1953 mach_port_name_array_t names;
1954 mach_msg_type_number_t names_count;
1955 mach_port_type_array_t types;
1956 mach_msg_type_number_t types_count;
1957 long res = 0;
1958
1959 /* First linear search. */
1960 for (k = 0;
1961 VEC_iterate (darwin_thread_t, inf->private->threads, k, t);
1962 k++)
1963 if (t->inf_port == lwp)
1964 return ptid_build (ptid_get_pid (inferior_ptid), 0, t->gdb_port);
1965
1966 /* Maybe the port was never extract. Do it now. */
1967
1968 /* First get inferior port names. */
1969 kret = mach_port_names (inf->private->task, &names, &names_count, &types,
1970 &types_count);
1971 MACH_CHECK_ERROR (kret);
1972 if (kret != KERN_SUCCESS)
1973 return null_ptid;
1974
1975 /* For each name, copy the right in the gdb space and then compare with
1976 our view of the inferior threads. We don't forget to deallocate the
1977 right. */
1978 for (i = 0; i < names_count; i++)
1979 {
1980 mach_port_t local_name;
1981 mach_msg_type_name_t local_type;
1982
1983 /* We just need to know the corresponding name in gdb name space.
1984 So extract and deallocate the right. */
1985 kret = mach_port_extract_right (inf->private->task, names[i],
1986 MACH_MSG_TYPE_COPY_SEND,
1987 &local_name, &local_type);
1988 if (kret != KERN_SUCCESS)
1989 continue;
1990 mach_port_deallocate (gdb_task, local_name);
1991
1992 for (k = 0;
1993 VEC_iterate (darwin_thread_t, inf->private->threads, k, t);
1994 k++)
1995 if (t->gdb_port == local_name)
1996 {
1997 t->inf_port = names[i];
1998 if (names[i] == lwp)
1999 res = t->gdb_port;
2000 }
2001 }
2002
2003 vm_deallocate (gdb_task, (vm_address_t) names,
2004 names_count * sizeof (mach_port_t));
2005
2006 if (res)
2007 return ptid_build (ptid_get_pid (inferior_ptid), 0, res);
2008 else
2009 return null_ptid;
2010 }
2011
2012 static int
2013 darwin_supports_multi_process (void)
2014 {
2015 return 1;
2016 }
2017
2018 void
2019 _initialize_darwin_inferior (void)
2020 {
2021 kern_return_t kret;
2022
2023 gdb_task = mach_task_self ();
2024 darwin_host_self = mach_host_self ();
2025
2026 /* Read page size. */
2027 kret = host_page_size (darwin_host_self, &mach_page_size);
2028 if (kret != KERN_SUCCESS)
2029 {
2030 mach_page_size = 0x1000;
2031 MACH_CHECK_ERROR (kret);
2032 }
2033
2034 darwin_ops = inf_child_target ();
2035
2036 darwin_ops->to_shortname = "darwin-child";
2037 darwin_ops->to_longname = _("Darwin child process");
2038 darwin_ops->to_doc =
2039 _("Darwin child process (started by the \"run\" command).");
2040 darwin_ops->to_create_inferior = darwin_create_inferior;
2041 darwin_ops->to_attach = darwin_attach;
2042 darwin_ops->to_attach_no_wait = 0;
2043 darwin_ops->to_detach = darwin_detach;
2044 darwin_ops->to_files_info = darwin_files_info;
2045 darwin_ops->to_wait = darwin_wait_to;
2046 darwin_ops->to_mourn_inferior = darwin_mourn_inferior;
2047 darwin_ops->to_kill = darwin_kill_inferior;
2048 darwin_ops->to_stop = darwin_stop;
2049 darwin_ops->to_resume = darwin_resume_to;
2050 darwin_ops->to_thread_alive = darwin_thread_alive;
2051 darwin_ops->to_pid_to_str = darwin_pid_to_str;
2052 darwin_ops->to_pid_to_exec_file = darwin_pid_to_exec_file;
2053 darwin_ops->to_load = NULL;
2054 darwin_ops->deprecated_xfer_memory = darwin_xfer_memory;
2055 darwin_ops->to_xfer_partial = darwin_xfer_partial;
2056 darwin_ops->to_supports_multi_process = darwin_supports_multi_process;
2057 darwin_ops->to_get_ada_task_ptid = darwin_get_ada_task_ptid;
2058
2059 darwin_complete_target (darwin_ops);
2060
2061 add_target (darwin_ops);
2062
2063 inferior_debug (2, _("GDB task: 0x%lx, pid: %d\n"), mach_task_self (),
2064 getpid ());
2065
2066 add_setshow_zinteger_cmd ("darwin", class_obscure,
2067 &darwin_debug_flag, _("\
2068 Set if printing inferior communication debugging statements."), _("\
2069 Show if printing inferior communication debugging statements."), NULL,
2070 NULL, NULL,
2071 &setdebuglist, &showdebuglist);
2072
2073 add_setshow_boolean_cmd ("mach-exceptions", class_support,
2074 &enable_mach_exceptions, _("\
2075 Set if mach exceptions are caught."), _("\
2076 Show if mach exceptions are caught."), _("\
2077 When this mode is on, all low level exceptions are reported before being\n\
2078 reported by the kernel."),
2079 &set_enable_mach_exceptions, NULL,
2080 &setlist, &showlist);
2081 }
This page took 0.109421 seconds and 4 git commands to generate.