]> git.saurik.com Git - apple/xnu.git/blob - osfmk/kdp/ml/i386/kdp_machdep.c
xnu-1699.32.7.tar.gz
[apple/xnu.git] / osfmk / kdp / ml / i386 / kdp_machdep.c
1 /*
2 * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29 #include <mach_kdp.h>
30 #include <mach/mach_types.h>
31 #include <mach/machine.h>
32 #include <mach/exception_types.h>
33 #include <kern/cpu_data.h>
34 #include <i386/trap.h>
35 #include <i386/mp.h>
36 #include <kdp/kdp_internal.h>
37 #include <kdp/kdp_callout.h>
38 #include <mach-o/loader.h>
39 #include <mach-o/nlist.h>
40 #include <IOKit/IOPlatformExpert.h> /* for PE_halt_restart */
41 #include <kern/machine.h> /* for halt_all_cpus */
42 #include <libkern/OSAtomic.h>
43
44 #include <kern/thread.h>
45 #include <i386/thread.h>
46 #include <vm/vm_map.h>
47 #include <i386/pmap.h>
48 #include <kern/kalloc.h>
49
50 #define KDP_TEST_HARNESS 0
51 #if KDP_TEST_HARNESS
52 #define dprintf(x) printf x
53 #else
54 #define dprintf(x)
55 #endif
56
57 extern cpu_type_t cpuid_cputype(void);
58 extern cpu_subtype_t cpuid_cpusubtype(void);
59
60 void print_saved_state(void *);
61 void kdp_call(void);
62 int kdp_getc(void);
63 boolean_t kdp_call_kdb(void);
64 void kdp_getstate(i386_thread_state_t *);
65 void kdp_setstate(i386_thread_state_t *);
66 void kdp_print_phys(int);
67
68 int
69 machine_trace_thread(thread_t thread, char *tracepos, char *tracebound, int nframes, boolean_t user_p);
70
71 int
72 machine_trace_thread64(thread_t thread, char *tracepos, char *tracebound, int nframes, boolean_t user_p);
73
74 unsigned
75 machine_read64(addr64_t srcaddr, caddr_t dstaddr, uint32_t len);
76
77 static void kdp_callouts(kdp_event_t event);
78
79 void
80 kdp_exception(
81 unsigned char *pkt,
82 int *len,
83 unsigned short *remote_port,
84 unsigned int exception,
85 unsigned int code,
86 unsigned int subcode
87 )
88 {
89 kdp_exception_t *rq = (kdp_exception_t *)pkt;
90
91 rq->hdr.request = KDP_EXCEPTION;
92 rq->hdr.is_reply = 0;
93 rq->hdr.seq = kdp.exception_seq;
94 rq->hdr.key = 0;
95 rq->hdr.len = sizeof (*rq);
96
97 rq->n_exc_info = 1;
98 rq->exc_info[0].cpu = 0;
99 rq->exc_info[0].exception = exception;
100 rq->exc_info[0].code = code;
101 rq->exc_info[0].subcode = subcode;
102
103 rq->hdr.len += rq->n_exc_info * sizeof (kdp_exc_info_t);
104
105 bcopy((char *)rq, (char *)pkt, rq->hdr.len);
106
107 kdp.exception_ack_needed = TRUE;
108
109 *remote_port = kdp.exception_port;
110 *len = rq->hdr.len;
111 }
112
113 boolean_t
114 kdp_exception_ack(
115 unsigned char *pkt,
116 int len
117 )
118 {
119 kdp_exception_ack_t *rq = (kdp_exception_ack_t *)pkt;
120
121 if (((unsigned int) len) < sizeof (*rq))
122 return(FALSE);
123
124 if (!rq->hdr.is_reply || rq->hdr.request != KDP_EXCEPTION)
125 return(FALSE);
126
127 dprintf(("kdp_exception_ack seq %x %x\n", rq->hdr.seq, kdp.exception_seq));
128
129 if (rq->hdr.seq == kdp.exception_seq) {
130 kdp.exception_ack_needed = FALSE;
131 kdp.exception_seq++;
132 }
133 return(TRUE);
134 }
135
136 void
137 kdp_getstate(
138 x86_thread_state32_t *state
139 )
140 {
141 static x86_thread_state32_t null_state;
142 x86_saved_state32_t *saved_state;
143
144 saved_state = (x86_saved_state32_t *)kdp.saved_state;
145
146 *state = null_state;
147 state->eax = saved_state->eax;
148 state->ebx = saved_state->ebx;
149 state->ecx = saved_state->ecx;
150 state->edx = saved_state->edx;
151 state->edi = saved_state->edi;
152 state->esi = saved_state->esi;
153 state->ebp = saved_state->ebp;
154
155 if ((saved_state->cs & SEL_PL) == SEL_PL_K) { /* Kernel state? */
156 if (cpu_mode_is64bit())
157 state->esp = (uint32_t) saved_state->uesp;
158 else
159 state->esp = ((uint32_t)saved_state) + offsetof(x86_saved_state_t, ss_32) + sizeof(x86_saved_state32_t);
160 state->ss = KERNEL_DS;
161 } else {
162 state->esp = saved_state->uesp;
163 state->ss = saved_state->ss;
164 }
165
166 state->eflags = saved_state->efl;
167 state->eip = saved_state->eip;
168 state->cs = saved_state->cs;
169 state->ds = saved_state->ds;
170 state->es = saved_state->es;
171 state->fs = saved_state->fs;
172 state->gs = saved_state->gs;
173 }
174
175
176 void
177 kdp_setstate(
178 x86_thread_state32_t *state
179 )
180 {
181 x86_saved_state32_t *saved_state;
182
183 saved_state = (x86_saved_state32_t *)kdp.saved_state;
184
185 saved_state->eax = state->eax;
186 saved_state->ebx = state->ebx;
187 saved_state->ecx = state->ecx;
188 saved_state->edx = state->edx;
189 saved_state->edi = state->edi;
190 saved_state->esi = state->esi;
191 saved_state->ebp = state->ebp;
192 saved_state->efl = state->eflags;
193 #if 0
194 saved_state->frame.eflags &= ~( EFL_VM | EFL_NT | EFL_IOPL | EFL_CLR );
195 saved_state->frame.eflags |= ( EFL_IF | EFL_SET );
196 #endif
197 saved_state->eip = state->eip;
198 }
199
200
201 kdp_error_t
202 kdp_machine_read_regs(
203 __unused unsigned int cpu,
204 __unused unsigned int flavor,
205 char *data,
206 __unused int *size
207 )
208 {
209 static x86_float_state32_t null_fpstate;
210
211 switch (flavor) {
212
213 case x86_THREAD_STATE32:
214 dprintf(("kdp_readregs THREAD_STATE\n"));
215 kdp_getstate((x86_thread_state32_t *)data);
216 *size = sizeof (x86_thread_state32_t);
217 return KDPERR_NO_ERROR;
218
219 case x86_FLOAT_STATE32:
220 dprintf(("kdp_readregs THREAD_FPSTATE\n"));
221 *(x86_float_state32_t *)data = null_fpstate;
222 *size = sizeof (x86_float_state32_t);
223 return KDPERR_NO_ERROR;
224
225 default:
226 dprintf(("kdp_readregs bad flavor %d\n", flavor));
227 *size = 0;
228 return KDPERR_BADFLAVOR;
229 }
230 }
231
232 kdp_error_t
233 kdp_machine_write_regs(
234 __unused unsigned int cpu,
235 unsigned int flavor,
236 char *data,
237 __unused int *size
238 )
239 {
240 switch (flavor) {
241
242 case x86_THREAD_STATE32:
243 dprintf(("kdp_writeregs THREAD_STATE\n"));
244 kdp_setstate((x86_thread_state32_t *)data);
245 return KDPERR_NO_ERROR;
246
247 case x86_FLOAT_STATE32:
248 dprintf(("kdp_writeregs THREAD_FPSTATE\n"));
249 return KDPERR_NO_ERROR;
250
251 default:
252 dprintf(("kdp_writeregs bad flavor %d\n"));
253 return KDPERR_BADFLAVOR;
254 }
255 }
256
257
258
259 void
260 kdp_machine_hostinfo(
261 kdp_hostinfo_t *hostinfo
262 )
263 {
264 int i;
265
266 hostinfo->cpus_mask = 0;
267
268 for (i = 0; i < machine_info.max_cpus; i++) {
269 if (cpu_data_ptr[i] == NULL)
270 continue;
271
272 hostinfo->cpus_mask |= (1 << i);
273 }
274
275 hostinfo->cpu_type = cpuid_cputype();
276 hostinfo->cpu_subtype = cpuid_cpusubtype();
277 }
278
279 void
280 kdp_panic(
281 const char *msg
282 )
283 {
284 kprintf("kdp panic: %s\n", msg);
285 __asm__ volatile("hlt");
286 }
287
288
289 void
290 kdp_machine_reboot(void)
291 {
292 printf("Attempting system restart...");
293 /* Call the platform specific restart*/
294 if (PE_halt_restart)
295 (*PE_halt_restart)(kPERestartCPU);
296 /* If we do reach this, give up */
297 halt_all_cpus(TRUE);
298 }
299
300 int
301 kdp_intr_disbl(void)
302 {
303 return splhigh();
304 }
305
306 void
307 kdp_intr_enbl(int s)
308 {
309 splx(s);
310 }
311
312 int
313 kdp_getc(void)
314 {
315 return cnmaygetc();
316 }
317
318 void
319 kdp_us_spin(int usec)
320 {
321 delay(usec/100);
322 }
323
324 void print_saved_state(void *state)
325 {
326 x86_saved_state32_t *saved_state;
327
328 saved_state = state;
329
330 kprintf("pc = 0x%x\n", saved_state->eip);
331 kprintf("cr2= 0x%x\n", saved_state->cr2);
332 kprintf("rp = TODO FIXME\n");
333 kprintf("sp = %p\n", saved_state);
334
335 }
336
337 void
338 kdp_sync_cache(void)
339 {
340 return; /* No op here. */
341 }
342
343 void
344 kdp_call(void)
345 {
346 __asm__ volatile ("int $3"); /* Let the processor do the work */
347 }
348
349
350 typedef struct _cframe_t {
351 struct _cframe_t *prev;
352 unsigned caller;
353 unsigned args[0];
354 } cframe_t;
355
356 #include <i386/pmap.h>
357 extern pt_entry_t *DMAP2;
358 extern caddr_t DADDR2;
359
360 void
361 kdp_print_phys(int src)
362 {
363 unsigned int *iptr;
364 int i;
365
366 *(int *) DMAP2 = 0x63 | (src & 0xfffff000);
367 invlpg((u_int) DADDR2);
368 iptr = (unsigned int *) DADDR2;
369 for (i = 0; i < 100; i++) {
370 kprintf("0x%x ", *iptr++);
371 if ((i % 8) == 0)
372 kprintf("\n");
373 }
374 kprintf("\n");
375 *(int *) DMAP2 = 0;
376
377 }
378
379 boolean_t
380 kdp_i386_trap(
381 unsigned int trapno,
382 x86_saved_state32_t *saved_state,
383 kern_return_t result,
384 vm_offset_t va
385 )
386 {
387 unsigned int exception, subcode = 0, code;
388
389 if (trapno != T_INT3 && trapno != T_DEBUG) {
390 kprintf("Debugger: Unexpected kernel trap number: "
391 "0x%x, EIP: 0x%x, CR2: 0x%x\n",
392 trapno, saved_state->eip, saved_state->cr2);
393 if (!kdp.is_conn)
394 return FALSE;
395 }
396
397 mp_kdp_enter();
398 kdp_callouts(KDP_EVENT_ENTER);
399
400 if (saved_state->efl & EFL_TF) {
401 enable_preemption_no_check();
402 }
403
404 switch (trapno) {
405
406 case T_DIVIDE_ERROR:
407 exception = EXC_ARITHMETIC;
408 code = EXC_I386_DIVERR;
409 break;
410
411 case T_OVERFLOW:
412 exception = EXC_SOFTWARE;
413 code = EXC_I386_INTOFLT;
414 break;
415
416 case T_OUT_OF_BOUNDS:
417 exception = EXC_ARITHMETIC;
418 code = EXC_I386_BOUNDFLT;
419 break;
420
421 case T_INVALID_OPCODE:
422 exception = EXC_BAD_INSTRUCTION;
423 code = EXC_I386_INVOPFLT;
424 break;
425
426 case T_SEGMENT_NOT_PRESENT:
427 exception = EXC_BAD_INSTRUCTION;
428 code = EXC_I386_SEGNPFLT;
429 subcode = saved_state->err;
430 break;
431
432 case T_STACK_FAULT:
433 exception = EXC_BAD_INSTRUCTION;
434 code = EXC_I386_STKFLT;
435 subcode = saved_state->err;
436 break;
437
438 case T_GENERAL_PROTECTION:
439 exception = EXC_BAD_INSTRUCTION;
440 code = EXC_I386_GPFLT;
441 subcode = saved_state->err;
442 break;
443
444 case T_PAGE_FAULT:
445 exception = EXC_BAD_ACCESS;
446 code = result;
447 subcode = va;
448 break;
449
450 case T_WATCHPOINT:
451 exception = EXC_SOFTWARE;
452 code = EXC_I386_ALIGNFLT;
453 break;
454
455 case T_DEBUG:
456 case T_INT3:
457 exception = EXC_BREAKPOINT;
458 code = EXC_I386_BPTFLT;
459 break;
460
461 default:
462 exception = EXC_BAD_INSTRUCTION;
463 code = trapno;
464 break;
465 }
466
467 kdp_raise_exception(exception, code, subcode, saved_state);
468 /* If the instruction single step bit is set, disable kernel preemption
469 */
470 if (saved_state->efl & EFL_TF) {
471 disable_preemption();
472 }
473
474 kdp_callouts(KDP_EVENT_EXIT);
475 mp_kdp_exit();
476
477 return TRUE;
478 }
479
480 boolean_t
481 kdp_call_kdb(
482 void)
483 {
484 return(FALSE);
485 }
486
487 void
488 kdp_machine_get_breakinsn(
489 uint8_t *bytes,
490 uint32_t *size
491 )
492 {
493 bytes[0] = 0xcc;
494 *size = 1;
495 }
496
497 extern pmap_t kdp_pmap;
498
499 #define RETURN_OFFSET 4
500 int
501 machine_trace_thread(thread_t thread, char *tracepos, char *tracebound, int nframes, boolean_t user_p)
502 {
503 uint32_t *tracebuf = (uint32_t *)tracepos;
504 uint32_t fence = 0;
505 uint32_t stackptr = 0;
506 uint32_t stacklimit = 0xfc000000;
507 int framecount = 0;
508 uint32_t init_eip = 0;
509 uint32_t prevsp = 0;
510 uint32_t framesize = 2 * sizeof(vm_offset_t);
511
512 if (user_p) {
513 x86_saved_state32_t *iss32;
514
515 iss32 = USER_REGS32(thread);
516
517 init_eip = iss32->eip;
518 stackptr = iss32->ebp;
519
520 /* This bound isn't useful, but it doesn't hinder us*/
521 stacklimit = 0xffffffff;
522 kdp_pmap = thread->task->map->pmap;
523 }
524 else {
525 /*Examine the i386_saved_state at the base of the kernel stack*/
526 stackptr = STACK_IKS(thread->kernel_stack)->k_ebp;
527 init_eip = STACK_IKS(thread->kernel_stack)->k_eip;
528 }
529
530 *tracebuf++ = init_eip;
531
532 for (framecount = 0; framecount < nframes; framecount++) {
533
534 if ((uint32_t)(tracebound - ((char *)tracebuf)) < (4 * framesize)) {
535 tracebuf--;
536 break;
537 }
538
539 *tracebuf++ = stackptr;
540 /* Invalid frame, or hit fence */
541 if (!stackptr || (stackptr == fence)) {
542 break;
543 }
544
545 /* Unaligned frame */
546 if (stackptr & 0x0000003) {
547 break;
548 }
549
550 if (stackptr > stacklimit) {
551 break;
552 }
553
554 if (stackptr <= prevsp) {
555 break;
556 }
557
558 if (kdp_machine_vm_read((mach_vm_address_t)(stackptr + RETURN_OFFSET), (caddr_t) tracebuf, sizeof(caddr_t)) != sizeof(caddr_t)) {
559 break;
560 }
561 tracebuf++;
562
563 prevsp = stackptr;
564 if (kdp_machine_vm_read((mach_vm_address_t)stackptr, (caddr_t) &stackptr, sizeof(caddr_t)) != sizeof(caddr_t)) {
565 *tracebuf++ = 0;
566 break;
567 }
568 }
569
570 kdp_pmap = 0;
571
572 return (uint32_t) (((char *) tracebuf) - tracepos);
573 }
574
575 #define RETURN_OFFSET64 8
576 /* Routine to encapsulate the 64-bit address read hack*/
577 unsigned
578 machine_read64(addr64_t srcaddr, caddr_t dstaddr, uint32_t len)
579 {
580 return (unsigned)kdp_machine_vm_read(srcaddr, dstaddr, len);
581 }
582
583 int
584 machine_trace_thread64(thread_t thread, char *tracepos, char *tracebound, int nframes, boolean_t user_p)
585 {
586 uint64_t *tracebuf = (uint64_t *)tracepos;
587 uint32_t fence = 0;
588 addr64_t stackptr = 0;
589 uint64_t stacklimit = 0xfc000000;
590 int framecount = 0;
591 addr64_t init_rip = 0;
592 addr64_t prevsp = 0;
593 unsigned framesize = 2 * sizeof(addr64_t);
594
595 if (user_p) {
596 x86_saved_state64_t *iss64;
597 iss64 = USER_REGS64(thread);
598 init_rip = iss64->isf.rip;
599 stackptr = iss64->rbp;
600 stacklimit = 0xffffffffffffffffULL;
601 kdp_pmap = thread->task->map->pmap;
602 }
603
604 *tracebuf++ = init_rip;
605
606 for (framecount = 0; framecount < nframes; framecount++) {
607
608 if ((uint32_t)(tracebound - ((char *)tracebuf)) < (4 * framesize)) {
609 tracebuf--;
610 break;
611 }
612
613 *tracebuf++ = stackptr;
614
615 if (!stackptr || (stackptr == fence)){
616 break;
617 }
618
619 if (stackptr & 0x0000003) {
620 break;
621 }
622 if (stackptr > stacklimit) {
623 break;
624 }
625
626 if (stackptr <= prevsp) {
627 break;
628 }
629
630 if (machine_read64(stackptr + RETURN_OFFSET64, (caddr_t) tracebuf, sizeof(addr64_t)) != sizeof(addr64_t)) {
631 break;
632 }
633 tracebuf++;
634
635 prevsp = stackptr;
636 if (machine_read64(stackptr, (caddr_t) &stackptr, sizeof(addr64_t)) != sizeof(addr64_t)) {
637 *tracebuf++ = 0;
638 break;
639 }
640 }
641
642 kdp_pmap = NULL;
643
644 return (uint32_t) (((char *) tracebuf) - tracepos);
645 }
646
647 static struct kdp_callout {
648 struct kdp_callout *callout_next;
649 kdp_callout_fn_t callout_fn;
650 void *callout_arg;
651 } *kdp_callout_list = NULL;
652
653
654 /*
655 * Called from kernel context to register a kdp event callout.
656 */
657 void
658 kdp_register_callout(
659 kdp_callout_fn_t fn,
660 void *arg)
661 {
662 struct kdp_callout *kcp;
663 struct kdp_callout *list_head;
664
665 kcp = kalloc(sizeof(*kcp));
666 if (kcp == NULL)
667 panic("kdp_register_callout() kalloc failed");
668
669 kcp->callout_fn = fn;
670 kcp->callout_arg = arg;
671
672 /* Lock-less list insertion using compare and exchange. */
673 do {
674 list_head = kdp_callout_list;
675 kcp->callout_next = list_head;
676 } while (!OSCompareAndSwapPtr(list_head, kcp, (void * volatile *)&kdp_callout_list));
677 }
678
679 /*
680 * Called at exception/panic time when extering or exiting kdp.
681 * We are single-threaded at this time and so we don't use locks.
682 */
683 static void
684 kdp_callouts(kdp_event_t event)
685 {
686 struct kdp_callout *kcp = kdp_callout_list;
687
688 while (kcp) {
689 kcp->callout_fn(kcp->callout_arg, event);
690 kcp = kcp->callout_next;
691 }
692 }
693
694 void
695 kdp_ml_enter_debugger(void)
696 {
697 __asm__ __volatile__("int3");
698 }