2 * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
32 * Mach Operating System
33 * Copyright (c) 1991,1990,1989, 1988 Carnegie Mellon University
34 * All Rights Reserved.
36 * Permission to use, copy, modify and distribute this software and its
37 * documentation is hereby granted, provided that both the copyright
38 * notice and this permission notice appear in all copies of the
39 * software, derivative works or modified versions, and any portions
40 * thereof, and that both notices appear in supporting documentation.
42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
43 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
44 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
46 * Carnegie Mellon requests users of this software to return to
48 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
49 * School of Computer Science
50 * Carnegie Mellon University
51 * Pittsburgh PA 15213-3890
53 * any improvements or extensions that they make and grant Carnegie Mellon
54 * the rights to redistribute these changes.
62 * Author: Avadis Tevanian, Jr., Michael Wayne Young
64 * Copyright (C) 1986, Avadis Tevanian, Jr., Michael Wayne Young
66 * Basic initialization for I386 - ISA bus machines.
70 #define __APPLE_API_PRIVATE 1
71 #define __APPLE_API_UNSTABLE 1
72 #include <kern/debug.h>
74 #include <mach/i386/vm_param.h>
77 #include <mach/vm_param.h>
78 #include <mach/vm_prot.h>
79 #include <mach/machine.h>
80 #include <mach/time_value.h>
81 #include <sys/kdebug.h>
83 #include <kern/assert.h>
84 #include <kern/misc_protos.h>
85 #include <kern/startup.h>
86 #include <kern/clock.h>
87 #include <kern/cpu_data.h>
88 #include <kern/machine.h>
89 #include <i386/postcode.h>
90 #include <i386/mp_desc.h>
91 #include <i386/misc_protos.h>
92 #include <i386/thread.h>
93 #include <i386/trap.h>
94 #include <i386/machine_routines.h>
95 #include <i386/mp.h> /* mp_rendezvous_break_lock */
96 #include <i386/cpuid.h>
98 #include <i386/machine_cpu.h>
99 #include <i386/pmap.h>
101 #include <i386/mtrr.h>
103 #include <i386/ucode.h>
104 #include <i386/pmCPU.h>
105 #include <i386/panic_hooks.h>
107 #include <architecture/i386/pio.h> /* inb() */
108 #include <pexpert/i386/boot.h>
110 #include <kdp/kdp_dyld.h>
111 #include <kdp/kdp_core.h>
113 #include <vm/vm_map.h>
114 #include <vm/vm_kern.h>
116 #include <IOKit/IOPlatformExpert.h>
117 #include <IOKit/IOHibernatePrivate.h>
119 #include <pexpert/i386/efi.h>
121 #include <kern/thread.h>
122 #include <kern/sched.h>
123 #include <mach-o/loader.h>
124 #include <mach-o/nlist.h>
126 #include <libkern/kernel_mach_header.h>
127 #include <libkern/OSKextLibPrivate.h>
129 #include <mach/branch_predicates.h>
130 #include <libkern/section_keywords.h>
132 #if DEBUG || DEVELOPMENT
133 #define DPRINTF(x...) kprintf(x)
135 #define DPRINTF(x...)
138 static void machine_conf(void);
139 void panic_print_symbol_name(vm_address_t search
);
140 void RecordPanicStackshot(void);
142 extern const char version
[];
143 extern char osversion
[];
144 extern int max_unsafe_quanta
;
145 extern int max_poll_quanta
;
146 extern unsigned int panic_is_inited
;
148 extern int proc_pid(void *p
);
150 /* Definitions for frame pointers */
151 #define FP_ALIGNMENT_MASK ((uint32_t)(0x3))
152 #define FP_LR_OFFSET ((uint32_t)4)
153 #define FP_LR_OFFSET64 ((uint32_t)8)
154 #define FP_MAX_NUM_TO_EVALUATE (50)
156 volatile int pbtcpu
= -1;
157 hw_lock_data_t pbtlock
; /* backtrace print lock */
160 volatile int panic_double_fault_cpu
= -1;
162 #define PRINT_ARGS_FROM_STACK_FRAME 0
164 typedef struct _cframe_t
{
165 struct _cframe_t
*prev
;
167 #if PRINT_ARGS_FROM_STACK_FRAME
172 static unsigned panic_io_port
;
173 static unsigned commit_paniclog_to_nvram
;
174 boolean_t coprocessor_paniclog_flush
= FALSE
;
176 #if DEVELOPMENT || DEBUG
177 struct kcdata_descriptor kc_panic_data
;
178 static boolean_t begun_panic_stackshot
= FALSE
;
180 vm_offset_t panic_stackshot_buf
= 0;
181 size_t panic_stackshot_len
= 0;
183 extern kern_return_t
do_stackshot(void *);
184 extern void kdp_snapshot_preflight(int pid
, void *tracebuf
,
185 uint32_t tracebuf_size
, uint32_t flags
,
186 kcdata_descriptor_t data_p
,
187 boolean_t enable_faulting
);
188 extern int kdp_stack_snapshot_bytes_traced(void);
191 SECURITY_READ_ONLY_LATE(unsigned int) debug_boot_arg
;
194 * Backtrace a single frame.
197 print_one_backtrace(pmap_t pmap
, vm_offset_t topfp
, const char *cur_marker
,
205 boolean_t dump_kernel_stack
;
211 if (fp
>= VM_MIN_KERNEL_ADDRESS
)
212 dump_kernel_stack
= TRUE
;
214 dump_kernel_stack
= FALSE
;
217 if ((fp
== 0) || ((fp
& FP_ALIGNMENT_MASK
) != 0))
219 if (dump_kernel_stack
&& ((fp
< VM_MIN_KERNEL_ADDRESS
) || (fp
> VM_MAX_KERNEL_ADDRESS
)))
221 if ((!dump_kernel_stack
) && (fp
>=VM_MIN_KERNEL_ADDRESS
))
224 /* Check to see if current address will result in a different
225 ppn than previously computed (to avoid recomputation) via
226 (addr) ^ fp_for_ppn) >> PAGE_SHIFT) */
228 if ((((fp
+ FP_LR_OFFSET
) ^ fp_for_ppn
) >> PAGE_SHIFT
) != 0x0U
) {
229 ppn
= pmap_find_phys(pmap
, fp
+ FP_LR_OFFSET
);
230 fp_for_ppn
= fp
+ (is_64_bit
? FP_LR_OFFSET64
: FP_LR_OFFSET
);
232 if (ppn
!= (ppnum_t
)NULL
) {
234 lr
= ml_phys_read_double_64(((((vm_offset_t
)ppn
) << PAGE_SHIFT
)) | ((fp
+ FP_LR_OFFSET64
) & PAGE_MASK
));
236 lr
= ml_phys_read_word(((((vm_offset_t
)ppn
) << PAGE_SHIFT
)) | ((fp
+ FP_LR_OFFSET
) & PAGE_MASK
));
240 paniclog_append_noflush("%s\t Could not read LR from frame at 0x%016llx\n", cur_marker
, fp
+ FP_LR_OFFSET64
);
242 paniclog_append_noflush("%s\t Could not read LR from frame at 0x%08x\n", cur_marker
, (uint32_t)(fp
+ FP_LR_OFFSET
));
246 if (((fp
^ fp_for_ppn
) >> PAGE_SHIFT
) != 0x0U
) {
247 ppn
= pmap_find_phys(pmap
, fp
);
250 if (ppn
!= (ppnum_t
)NULL
) {
252 fp
= ml_phys_read_double_64(((((vm_offset_t
)ppn
) << PAGE_SHIFT
)) | (fp
& PAGE_MASK
));
254 fp
= ml_phys_read_word(((((vm_offset_t
)ppn
) << PAGE_SHIFT
)) | (fp
& PAGE_MASK
));
258 paniclog_append_noflush("%s\t Could not read FP from frame at 0x%016llx\n", cur_marker
, fp
);
260 paniclog_append_noflush("%s\t Could not read FP from frame at 0x%08x\n", cur_marker
, (uint32_t)fp
);
266 paniclog_append_noflush("%s\t0x%016llx\n", cur_marker
, lr
);
268 paniclog_append_noflush("%s\t0x%08x\n", cur_marker
, (uint32_t)lr
);
270 } while ((++i
< FP_MAX_NUM_TO_EVALUATE
) && (fp
!= topfp
));
273 machine_startup(void)
278 if( PE_get_hotkey( kPEControlKey
))
279 halt_in_debugger
= halt_in_debugger
? 0 : 1;
282 if (PE_parse_boot_argn("debug", &debug_boot_arg
, sizeof (debug_boot_arg
))) {
283 panicDebugging
= TRUE
;
284 #if DEVELOPMENT || DEBUG
285 if (debug_boot_arg
& DB_HALT
) halt_in_debugger
=1;
287 #if KDEBUG_MOJO_TRACE
288 if (debug_boot_arg
& DB_PRT_KDEBUG
) {
289 kdebug_serial
= TRUE
;
296 if (!PE_parse_boot_argn("nvram_paniclog", &commit_paniclog_to_nvram
, sizeof (commit_paniclog_to_nvram
)))
297 commit_paniclog_to_nvram
= 1;
300 * Entering the debugger will put the CPUs into a "safe"
303 if (PE_parse_boot_argn("pmsafe_debug", &boot_arg
, sizeof (boot_arg
)))
304 pmsafe_debug
= boot_arg
;
307 hw_lock_init(&debugger_lock
); /* initialize debugger lock */
309 hw_lock_init(&pbtlock
); /* initialize print backtrace lock */
311 if (PE_parse_boot_argn("preempt", &boot_arg
, sizeof (boot_arg
))) {
312 default_preemption_rate
= boot_arg
;
314 if (PE_parse_boot_argn("unsafe", &boot_arg
, sizeof (boot_arg
))) {
315 max_unsafe_quanta
= boot_arg
;
317 if (PE_parse_boot_argn("poll", &boot_arg
, sizeof (boot_arg
))) {
318 max_poll_quanta
= boot_arg
;
320 if (PE_parse_boot_argn("yield", &boot_arg
, sizeof (boot_arg
))) {
321 sched_poll_yield_shift
= boot_arg
;
323 /* The I/O port to issue a read from, in the event of a panic. Useful for
324 * triggering logic analyzers.
326 if (PE_parse_boot_argn("panic_io_port", &boot_arg
, sizeof (boot_arg
))) {
327 /*I/O ports range from 0 through 0xFFFF */
328 panic_io_port
= boot_arg
& 0xffff;
346 machine_info
.memory_size
= (typeof(machine_info
.memory_size
))mem_size
;
350 extern void *gPEEFIRuntimeServices
;
351 extern void *gPEEFISystemTable
;
354 * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
355 * code or tables extracted from it, as desired without restriction.
357 * First, the polynomial itself and its table of feedback terms. The
359 * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
361 * Note that we take it "backwards" and put the highest-order term in
362 * the lowest-order bit. The X^32 term is "implied"; the LSB is the
363 * X^31 term, etc. The X^0 term (usually shown as "+1") results in
366 * Note that the usual hardware shift register implementation, which
367 * is what we're using (we're merely optimizing it by doing eight-bit
368 * chunks at a time) shifts bits into the lowest-order term. In our
369 * implementation, that means shifting towards the right. Why do we
370 * do it this way? Because the calculated CRC must be transmitted in
371 * order from highest-order term to lowest-order term. UARTs transmit
372 * characters in order from LSB to MSB. By storing the CRC this way
373 * we hand it to the UART in the order low-byte to high-byte; the UART
374 * sends each low-bit to hight-bit; and the result is transmission bit
375 * by bit from highest- to lowest-order term without requiring any bit
376 * shuffling on our part. Reception works similarly
378 * The feedback terms table consists of 256, 32-bit entries. Notes
380 * The table can be generated at runtime if desired; code to do so
381 * is shown later. It might not be obvious, but the feedback
382 * terms simply represent the results of eight shift/xor opera
383 * tions for all combinations of data and CRC register values
385 * The values must be right-shifted by eight bits by the "updcrc
386 * logic; the shift must be unsigned (bring in zeroes). On some
387 * hardware you could probably optimize the shift in assembler by
388 * using byte-swap instructions
389 * polynomial $edb88320
392 * CRC32 code derived from work by Gary S. Brown.
395 static uint32_t crc32_tab
[] = {
396 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
397 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
398 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
399 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
400 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
401 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
402 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
403 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
404 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
405 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
406 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
407 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
408 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
409 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
410 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
411 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
412 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
413 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
414 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
415 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
416 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
417 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
418 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
419 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
420 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
421 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
422 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
423 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
424 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
425 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
426 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
427 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
428 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
429 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
430 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
431 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
432 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
433 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
434 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
435 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
436 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
437 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
438 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
442 crc32(uint32_t crc
, const void *buf
, size_t size
)
450 crc
= crc32_tab
[(crc
^ *p
++) & 0xFF] ^ (crc
>> 8);
456 efi_set_tables_64(EFI_SYSTEM_TABLE_64
* system_table
)
458 EFI_RUNTIME_SERVICES_64
*runtime
;
462 DPRINTF("Processing 64-bit EFI tables at %p\n", system_table
);
464 DPRINTF("Header:\n");
465 DPRINTF(" Signature: 0x%016llx\n", system_table
->Hdr
.Signature
);
466 DPRINTF(" Revision: 0x%08x\n", system_table
->Hdr
.Revision
);
467 DPRINTF(" HeaderSize: 0x%08x\n", system_table
->Hdr
.HeaderSize
);
468 DPRINTF(" CRC32: 0x%08x\n", system_table
->Hdr
.CRC32
);
469 DPRINTF("RuntimeServices: 0x%016llx\n", system_table
->RuntimeServices
);
470 if (system_table
->Hdr
.Signature
!= EFI_SYSTEM_TABLE_SIGNATURE
) {
471 kprintf("Bad EFI system table signature\n");
474 // Verify signature of the system table
475 hdr_cksum
= system_table
->Hdr
.CRC32
;
476 system_table
->Hdr
.CRC32
= 0;
477 cksum
= crc32(0L, system_table
, system_table
->Hdr
.HeaderSize
);
479 DPRINTF("System table calculated CRC32 = 0x%x, header = 0x%x\n", cksum
, hdr_cksum
);
480 system_table
->Hdr
.CRC32
= hdr_cksum
;
481 if (cksum
!= hdr_cksum
) {
482 kprintf("Bad EFI system table checksum\n");
486 gPEEFISystemTable
= system_table
;
488 if(system_table
->RuntimeServices
== 0) {
489 kprintf("No runtime table present\n");
492 DPRINTF("RuntimeServices table at 0x%qx\n", system_table
->RuntimeServices
);
493 // 64-bit virtual address is OK for 64-bit EFI and 64/32-bit kernel.
494 runtime
= (EFI_RUNTIME_SERVICES_64
*) (uintptr_t)system_table
->RuntimeServices
;
495 DPRINTF("Checking runtime services table %p\n", runtime
);
496 if (runtime
->Hdr
.Signature
!= EFI_RUNTIME_SERVICES_SIGNATURE
) {
497 kprintf("Bad EFI runtime table signature\n");
501 // Verify signature of runtime services table
502 hdr_cksum
= runtime
->Hdr
.CRC32
;
503 runtime
->Hdr
.CRC32
= 0;
504 cksum
= crc32(0L, runtime
, runtime
->Hdr
.HeaderSize
);
506 DPRINTF("Runtime table calculated CRC32 = 0x%x, header = 0x%x\n", cksum
, hdr_cksum
);
507 runtime
->Hdr
.CRC32
= hdr_cksum
;
508 if (cksum
!= hdr_cksum
) {
509 kprintf("Bad EFI runtime table checksum\n");
513 gPEEFIRuntimeServices
= runtime
;
519 efi_set_tables_32(EFI_SYSTEM_TABLE_32
* system_table
)
521 EFI_RUNTIME_SERVICES_32
*runtime
;
525 DPRINTF("Processing 32-bit EFI tables at %p\n", system_table
);
527 DPRINTF("Header:\n");
528 DPRINTF(" Signature: 0x%016llx\n", system_table
->Hdr
.Signature
);
529 DPRINTF(" Revision: 0x%08x\n", system_table
->Hdr
.Revision
);
530 DPRINTF(" HeaderSize: 0x%08x\n", system_table
->Hdr
.HeaderSize
);
531 DPRINTF(" CRC32: 0x%08x\n", system_table
->Hdr
.CRC32
);
532 DPRINTF("RuntimeServices: 0x%08x\n", system_table
->RuntimeServices
);
533 if (system_table
->Hdr
.Signature
!= EFI_SYSTEM_TABLE_SIGNATURE
) {
534 kprintf("Bad EFI system table signature\n");
537 // Verify signature of the system table
538 hdr_cksum
= system_table
->Hdr
.CRC32
;
539 system_table
->Hdr
.CRC32
= 0;
540 DPRINTF("System table at %p HeaderSize 0x%x\n", system_table
, system_table
->Hdr
.HeaderSize
);
541 cksum
= crc32(0L, system_table
, system_table
->Hdr
.HeaderSize
);
543 DPRINTF("System table calculated CRC32 = 0x%x, header = 0x%x\n", cksum
, hdr_cksum
);
544 system_table
->Hdr
.CRC32
= hdr_cksum
;
545 if (cksum
!= hdr_cksum
) {
546 kprintf("Bad EFI system table checksum\n");
550 gPEEFISystemTable
= system_table
;
552 if(system_table
->RuntimeServices
== 0) {
553 kprintf("No runtime table present\n");
556 DPRINTF("RuntimeServices table at 0x%x\n", system_table
->RuntimeServices
);
557 // 32-bit virtual address is OK for 32-bit EFI and 32-bit kernel.
558 // For a 64-bit kernel, booter provides a virtual address mod 4G
559 runtime
= (EFI_RUNTIME_SERVICES_32
*)
560 (system_table
->RuntimeServices
| VM_MIN_KERNEL_ADDRESS
);
561 DPRINTF("Runtime table addressed at %p\n", runtime
);
562 if (runtime
->Hdr
.Signature
!= EFI_RUNTIME_SERVICES_SIGNATURE
) {
563 kprintf("Bad EFI runtime table signature\n");
567 // Verify signature of runtime services table
568 hdr_cksum
= runtime
->Hdr
.CRC32
;
569 runtime
->Hdr
.CRC32
= 0;
570 cksum
= crc32(0L, runtime
, runtime
->Hdr
.HeaderSize
);
572 DPRINTF("Runtime table calculated CRC32 = 0x%x, header = 0x%x\n", cksum
, hdr_cksum
);
573 runtime
->Hdr
.CRC32
= hdr_cksum
;
574 if (cksum
!= hdr_cksum
) {
575 kprintf("Bad EFI runtime table checksum\n");
579 DPRINTF("Runtime functions\n");
580 DPRINTF(" GetTime : 0x%x\n", runtime
->GetTime
);
581 DPRINTF(" SetTime : 0x%x\n", runtime
->SetTime
);
582 DPRINTF(" GetWakeupTime : 0x%x\n", runtime
->GetWakeupTime
);
583 DPRINTF(" SetWakeupTime : 0x%x\n", runtime
->SetWakeupTime
);
584 DPRINTF(" SetVirtualAddressMap : 0x%x\n", runtime
->SetVirtualAddressMap
);
585 DPRINTF(" ConvertPointer : 0x%x\n", runtime
->ConvertPointer
);
586 DPRINTF(" GetVariable : 0x%x\n", runtime
->GetVariable
);
587 DPRINTF(" GetNextVariableName : 0x%x\n", runtime
->GetNextVariableName
);
588 DPRINTF(" SetVariable : 0x%x\n", runtime
->SetVariable
);
589 DPRINTF(" GetNextHighMonotonicCount: 0x%x\n", runtime
->GetNextHighMonotonicCount
);
590 DPRINTF(" ResetSystem : 0x%x\n", runtime
->ResetSystem
);
592 gPEEFIRuntimeServices
= runtime
;
598 /* Map in EFI runtime areas. */
602 boot_args
*args
= (boot_args
*)PE_state
.bootArgs
;
604 kprintf("Initializing EFI runtime services\n");
608 vm_offset_t vm_size
, vm_addr
;
609 vm_map_offset_t phys_addr
;
610 EfiMemoryRange
*mptr
;
611 unsigned int msize
, mcount
;
614 msize
= args
->MemoryMapDescriptorSize
;
615 mcount
= args
->MemoryMapSize
/ msize
;
617 DPRINTF("efi_init() kernel base: 0x%x size: 0x%x\n",
618 args
->kaddr
, args
->ksize
);
619 DPRINTF(" efiSystemTable physical: 0x%x virtual: %p\n",
620 args
->efiSystemTable
,
621 (void *) ml_static_ptovirt(args
->efiSystemTable
));
622 DPRINTF(" efiRuntimeServicesPageStart: 0x%x\n",
623 args
->efiRuntimeServicesPageStart
);
624 DPRINTF(" efiRuntimeServicesPageCount: 0x%x\n",
625 args
->efiRuntimeServicesPageCount
);
626 DPRINTF(" efiRuntimeServicesVirtualPageStart: 0x%016llx\n",
627 args
->efiRuntimeServicesVirtualPageStart
);
628 mptr
= (EfiMemoryRange
*)ml_static_ptovirt(args
->MemoryMap
);
629 for (i
=0; i
< mcount
; i
++, mptr
= (EfiMemoryRange
*)(((vm_offset_t
)mptr
) + msize
)) {
630 if (((mptr
->Attribute
& EFI_MEMORY_RUNTIME
) == EFI_MEMORY_RUNTIME
) ) {
631 vm_size
= (vm_offset_t
)i386_ptob((uint32_t)mptr
->NumberOfPages
);
632 vm_addr
= (vm_offset_t
) mptr
->VirtualStart
;
633 /* For K64 on EFI32, shadow-map into high KVA */
634 if (vm_addr
< VM_MIN_KERNEL_ADDRESS
)
635 vm_addr
|= VM_MIN_KERNEL_ADDRESS
;
636 phys_addr
= (vm_map_offset_t
) mptr
->PhysicalStart
;
637 DPRINTF(" Type: %x phys: %p EFIv: %p kv: %p size: %p\n",
639 (void *) (uintptr_t) phys_addr
,
640 (void *) (uintptr_t) mptr
->VirtualStart
,
643 pmap_map_bd(vm_addr
, phys_addr
, phys_addr
+ round_page(vm_size
),
644 (mptr
->Type
== kEfiRuntimeServicesCode
) ? VM_PROT_READ
| VM_PROT_EXECUTE
: VM_PROT_READ
|VM_PROT_WRITE
,
645 (mptr
->Type
== EfiMemoryMappedIO
) ? VM_WIMG_IO
: VM_WIMG_USE_DEFAULT
);
649 if (args
->Version
!= kBootArgsVersion2
)
650 panic("Incompatible boot args version %d revision %d\n", args
->Version
, args
->Revision
);
652 DPRINTF("Boot args version %d revision %d mode %d\n", args
->Version
, args
->Revision
, args
->efiMode
);
653 if (args
->efiMode
== kBootArgsEfiMode64
) {
654 efi_set_tables_64((EFI_SYSTEM_TABLE_64
*) ml_static_ptovirt(args
->efiSystemTable
));
656 efi_set_tables_32((EFI_SYSTEM_TABLE_32
*) ml_static_ptovirt(args
->efiSystemTable
));
664 /* Returns TRUE if a page belongs to the EFI Runtime Services (code or data) */
666 efi_valid_page(ppnum_t ppn
)
668 boot_args
*args
= (boot_args
*)PE_state
.bootArgs
;
669 ppnum_t pstart
= args
->efiRuntimeServicesPageStart
;
670 ppnum_t pend
= pstart
+ args
->efiRuntimeServicesPageCount
;
672 return pstart
<= ppn
&& ppn
< pend
;
675 /* Remap EFI runtime areas. */
677 hibernate_newruntime_map(void * map
, vm_size_t map_size
, uint32_t system_table_offset
)
679 boot_args
*args
= (boot_args
*)PE_state
.bootArgs
;
681 kprintf("Reinitializing EFI runtime services\n");
685 vm_offset_t vm_size
, vm_addr
;
686 vm_map_offset_t phys_addr
;
687 EfiMemoryRange
*mptr
;
688 unsigned int msize
, mcount
;
691 gPEEFISystemTable
= 0;
692 gPEEFIRuntimeServices
= 0;
694 system_table_offset
+= ptoa_32(args
->efiRuntimeServicesPageStart
);
696 kprintf("Old system table 0x%x, new 0x%x\n",
697 (uint32_t)args
->efiSystemTable
, system_table_offset
);
699 args
->efiSystemTable
= system_table_offset
;
701 kprintf("Old map:\n");
702 msize
= args
->MemoryMapDescriptorSize
;
703 mcount
= args
->MemoryMapSize
/ msize
;
704 mptr
= (EfiMemoryRange
*)ml_static_ptovirt(args
->MemoryMap
);
705 for (i
=0; i
< mcount
; i
++, mptr
= (EfiMemoryRange
*)(((vm_offset_t
)mptr
) + msize
)) {
706 if ((mptr
->Attribute
& EFI_MEMORY_RUNTIME
) == EFI_MEMORY_RUNTIME
) {
708 vm_size
= (vm_offset_t
)i386_ptob((uint32_t)mptr
->NumberOfPages
);
709 vm_addr
= (vm_offset_t
) mptr
->VirtualStart
;
711 if (vm_addr
< VM_MIN_KERNEL_ADDRESS
)
712 vm_addr
|= VM_MIN_KERNEL_ADDRESS
;
713 phys_addr
= (vm_map_offset_t
) mptr
->PhysicalStart
;
715 kprintf("mapping[%u] %qx @ %lx, %llu\n", mptr
->Type
, phys_addr
, (unsigned long)vm_addr
, mptr
->NumberOfPages
);
719 pmap_remove(kernel_pmap
, i386_ptob(args
->efiRuntimeServicesPageStart
),
720 i386_ptob(args
->efiRuntimeServicesPageStart
+ args
->efiRuntimeServicesPageCount
));
722 kprintf("New map:\n");
723 msize
= args
->MemoryMapDescriptorSize
;
724 mcount
= (unsigned int )(map_size
/ msize
);
726 for (i
=0; i
< mcount
; i
++, mptr
= (EfiMemoryRange
*)(((vm_offset_t
)mptr
) + msize
)) {
727 if ((mptr
->Attribute
& EFI_MEMORY_RUNTIME
) == EFI_MEMORY_RUNTIME
) {
729 vm_size
= (vm_offset_t
)i386_ptob((uint32_t)mptr
->NumberOfPages
);
730 vm_addr
= (vm_offset_t
) mptr
->VirtualStart
;
731 if (vm_addr
< VM_MIN_KERNEL_ADDRESS
)
732 vm_addr
|= VM_MIN_KERNEL_ADDRESS
;
733 phys_addr
= (vm_map_offset_t
) mptr
->PhysicalStart
;
735 kprintf("mapping[%u] %qx @ %lx, %llu\n", mptr
->Type
, phys_addr
, (unsigned long)vm_addr
, mptr
->NumberOfPages
);
737 pmap_map(vm_addr
, phys_addr
, phys_addr
+ round_page(vm_size
),
738 (mptr
->Type
== kEfiRuntimeServicesCode
) ? VM_PROT_READ
| VM_PROT_EXECUTE
: VM_PROT_READ
|VM_PROT_WRITE
,
739 (mptr
->Type
== EfiMemoryMappedIO
) ? VM_WIMG_IO
: VM_WIMG_USE_DEFAULT
);
743 if (args
->Version
!= kBootArgsVersion2
)
744 panic("Incompatible boot args version %d revision %d\n", args
->Version
, args
->Revision
);
746 kprintf("Boot args version %d revision %d mode %d\n", args
->Version
, args
->Revision
, args
->efiMode
);
747 if (args
->efiMode
== kBootArgsEfiMode64
) {
748 efi_set_tables_64((EFI_SYSTEM_TABLE_64
*) ml_static_ptovirt(args
->efiSystemTable
));
750 efi_set_tables_32((EFI_SYSTEM_TABLE_32
*) ml_static_ptovirt(args
->efiSystemTable
));
755 kprintf("Done reinitializing EFI runtime services\n");
761 * Find devices. The system is alive.
766 /* Now with VM up, switch to dynamically allocated cpu data */
769 /* Ensure panic buffer is initialized. */
773 * Display CPU identification
775 cpuid_cpu_display("CPU identification");
776 cpuid_feature_display("CPU features");
777 cpuid_extfeature_display("CPU extended features");
780 * Initialize EFI runtime services.
787 * Set up to use floating point.
792 * Configure clock devices.
798 * Initialize MTRR from boot processor.
803 * Set up PAT for boot processor.
809 * Free lowmem pages and complete other setup
811 pmap_lowmem_finalize();
820 halt_all_cpus(FALSE
);
823 int reset_mem_on_reboot
= 1;
826 * Halt the system or reboot.
828 __attribute__((noreturn
))
830 halt_all_cpus(boolean_t reboot
)
833 printf("MACH Reboot\n");
834 PEHaltRestart( kPERestartCPU
);
836 printf("CPU halted\n");
837 PEHaltRestart( kPEHaltCPU
);
843 /* Issue an I/O port read if one has been requested - this is an event logic
844 * analyzers can use as a trigger point.
848 panic_io_port_read(void) {
850 (void)inb(panic_io_port
);
853 /* For use with the MP rendezvous mechanism
856 uint64_t panic_restart_timeout
= ~(0ULL);
858 #define PANIC_RESTART_TIMEOUT (3ULL * NSEC_PER_SEC)
861 RecordPanicStackshot()
863 #if DEVELOPMENT || DEBUG
864 int err
= 0, bytes_traced
= 0, bytes_used
= 0;
865 /* Try to take a stackshot once at panic time */
866 if (begun_panic_stackshot
) {
869 begun_panic_stackshot
= TRUE
;
871 if (panic_stackshot_buf
== 0) {
872 kdb_printf("No stackshot buffer allocated, skipping...\n");
876 err
= kcdata_memory_static_init(&kc_panic_data
, (mach_vm_address_t
)panic_stackshot_buf
, KCDATA_BUFFER_BEGIN_STACKSHOT
,
877 PANIC_STACKSHOT_BUFSIZE
, KCFLAG_USE_MEMCOPY
);
878 if (err
!= KERN_SUCCESS
) {
879 kdb_printf("Failed to initialize kcdata buffer for panic stackshot, skipping ...\n");
883 kdp_snapshot_preflight(-1, (void *) panic_stackshot_buf
, PANIC_STACKSHOT_BUFSIZE
, (STACKSHOT_GET_GLOBAL_MEM_STATS
| STACKSHOT_SAVE_LOADINFO
| STACKSHOT_KCDATA_FORMAT
|
884 STACKSHOT_ENABLE_BT_FAULTING
| STACKSHOT_ENABLE_UUID_FAULTING
| STACKSHOT_FROM_PANIC
| STACKSHOT_NO_IO_STATS
885 | STACKSHOT_THREAD_WAITINFO
), &kc_panic_data
, 0);
886 err
= do_stackshot(NULL
);
887 bytes_traced
= (int) kdp_stack_snapshot_bytes_traced();
888 if (bytes_traced
> 0 && !err
) {
889 panic_stackshot_len
= bytes_traced
;
890 kdb_printf("Panic stackshot succeeded, length: %u bytes\n", bytes_traced
);
892 bytes_used
= (int) kcdata_memory_get_used_bytes(&kc_panic_data
);
893 if (bytes_used
> 0) {
894 kdb_printf("Panic stackshot incomplete, consumed %u bytes\n", bytes_used
);
896 kdb_printf("Panic stackshot incomplete, consumed %u bytes, error : %d \n", bytes_used
, err
);
900 #endif /* DEVELOPMENT || DEBUG */
906 __unused
const char *message
, uint64_t panic_options
)
909 int cn
= cpu_number();
912 * Issue an I/O port read if one has been requested - this is an event logic
913 * analyzers can use as a trigger point.
915 panic_io_port_read();
917 /* Obtain current frame pointer */
918 __asm__
volatile("movq %%rbp, %0" : "=m" (stackptr
));
920 /* Print backtrace - callee is internally synchronized */
921 if (panic_options
& DEBUGGER_OPTION_INITPROC_PANIC
) {
922 /* Special handling of launchd died panics */
923 print_launchd_info();
925 panic_i386_backtrace(stackptr
, ((panic_double_fault_cpu
== cn
) ? 80: 48), NULL
, FALSE
, NULL
);
928 if (panic_options
& DEBUGGER_OPTION_COPROC_INITIATED_PANIC
) {
929 panic_info
->mph_panic_flags
|= MACOS_PANIC_HEADER_FLAG_COPROC_INITIATED_PANIC
;
932 /* Flush the paniclog */
935 /* Try to take a panic stackshot */
936 RecordPanicStackshot();
942 unsigned long pi_size
= 0;
944 assert(panic_info
!= NULL
);
945 panic_info
->mph_panic_log_len
= PE_get_offset_into_panic_region(debug_buf_ptr
) - panic_info
->mph_panic_log_offset
;
948 * If we've detected that we're on a co-processor system we flush the panic log via the kPEPanicSync
949 * panic callbacks, otherwise we flush via nvram (unless that has been disabled).
951 if (coprocessor_paniclog_flush
) {
952 /* Only need to calculate the CRC for co-processor platforms */
953 panic_info
->mph_crc
= crc32(0L, &panic_info
->mph_version
, (debug_buf_size
- offsetof(struct macos_panic_header
, mph_version
)));
955 PESavePanicInfoAction(debug_buf
, debug_buf_size
);
956 } else if(commit_paniclog_to_nvram
) {
957 assert(debug_buf_size
!= 0);
965 * Now call the compressor
966 * XXX Consider using the WKdm compressor in the
967 * future, rather than just packing - would need to
968 * be co-ordinated with crashreporter, which decodes
969 * this post-restart. The compressor should be
970 * capable of in-place compression.
972 * Don't include the macOS panic header (for co-processor systems only)
974 bufpos
= packA(debug_buf_base
, (unsigned int) (debug_buf_ptr
- debug_buf_base
),
977 * If compression was successful, use the compressed length
979 pi_size
= bufpos
? bufpos
: (unsigned) (debug_buf_ptr
- debug_buf_base
);
982 * The following sequence is a workaround for:
983 * <rdar://problem/5915669> SnowLeopard10A67: AppleEFINVRAM should not invoke
984 * any routines that use floating point (MMX in this case) when saving panic
985 * logs to nvram/flash.
991 * Save panic log to non-volatile store
992 * Panic info handler must truncate data that is
993 * too long for this platform.
994 * This call must save data synchronously,
995 * since we can subsequently halt the system.
997 kprintf("Attempting to commit panic log to NVRAM\n");
998 pi_size
= PESavePanicInfo((unsigned char *)debug_buf_base
,
1003 * Uncompress in-place, to permit examination of
1004 * the panic log by debuggers.
1007 unpackA(debug_buf_base
, bufpos
);
1013 machine_boot_info(char *buf
, __unused vm_size_t size
)
1019 /* Routines for address - symbol translation. Not called unless the "keepsyms"
1020 * boot-arg is supplied.
1024 panic_print_macho_symbol_name(kernel_mach_header_t
*mh
, vm_address_t search
, const char *module_name
)
1026 kernel_nlist_t
*sym
= NULL
;
1027 struct load_command
*cmd
;
1028 kernel_segment_command_t
*orig_ts
= NULL
, *orig_le
= NULL
;
1029 struct symtab_command
*orig_st
= NULL
;
1031 char *strings
, *bestsym
= NULL
;
1032 vm_address_t bestaddr
= 0, diff
, curdiff
;
1034 /* Assume that if it's loaded and linked into the kernel, it's a valid Mach-O */
1036 cmd
= (struct load_command
*) &mh
[1];
1037 for (i
= 0; i
< mh
->ncmds
; i
++) {
1038 if (cmd
->cmd
== LC_SEGMENT_KERNEL
) {
1039 kernel_segment_command_t
*orig_sg
= (kernel_segment_command_t
*) cmd
;
1041 if (strncmp(SEG_TEXT
, orig_sg
->segname
,
1042 sizeof(orig_sg
->segname
)) == 0)
1044 else if (strncmp(SEG_LINKEDIT
, orig_sg
->segname
,
1045 sizeof(orig_sg
->segname
)) == 0)
1047 else if (strncmp("", orig_sg
->segname
,
1048 sizeof(orig_sg
->segname
)) == 0)
1049 orig_ts
= orig_sg
; /* pre-Lion i386 kexts have a single unnamed segment */
1051 else if (cmd
->cmd
== LC_SYMTAB
)
1052 orig_st
= (struct symtab_command
*) cmd
;
1054 cmd
= (struct load_command
*) ((uintptr_t) cmd
+ cmd
->cmdsize
);
1057 if ((orig_ts
== NULL
) || (orig_st
== NULL
) || (orig_le
== NULL
))
1060 if ((search
< orig_ts
->vmaddr
) ||
1061 (search
>= orig_ts
->vmaddr
+ orig_ts
->vmsize
)) {
1062 /* search out of range for this mach header */
1066 sym
= (kernel_nlist_t
*)(uintptr_t)(orig_le
->vmaddr
+ orig_st
->symoff
- orig_le
->fileoff
);
1067 strings
= (char *)(uintptr_t)(orig_le
->vmaddr
+ orig_st
->stroff
- orig_le
->fileoff
);
1070 for (i
= 0; i
< orig_st
->nsyms
; i
++) {
1071 if (sym
[i
].n_type
& N_STAB
) continue;
1073 if (sym
[i
].n_value
<= search
) {
1074 curdiff
= search
- (vm_address_t
)sym
[i
].n_value
;
1075 if (curdiff
< diff
) {
1077 bestaddr
= sym
[i
].n_value
;
1078 bestsym
= strings
+ sym
[i
].n_un
.n_strx
;
1083 if (bestsym
!= NULL
) {
1085 paniclog_append_noflush("%s : %s + 0x%lx", module_name
, bestsym
, (unsigned long)diff
);
1087 paniclog_append_noflush("%s : %s", module_name
, bestsym
);
1094 extern kmod_info_t
* kmod
; /* the list of modules */
1097 panic_print_kmod_symbol_name(vm_address_t search
)
1101 if (gLoadedKextSummaries
== NULL
)
1103 for (i
= 0; i
< gLoadedKextSummaries
->numSummaries
; ++i
) {
1104 OSKextLoadedKextSummary
*summary
= gLoadedKextSummaries
->summaries
+ i
;
1106 if ((search
>= summary
->address
) &&
1107 (search
< (summary
->address
+ summary
->size
)))
1109 kernel_mach_header_t
*header
= (kernel_mach_header_t
*)(uintptr_t) summary
->address
;
1110 if (panic_print_macho_symbol_name(header
, search
, summary
->name
) == 0) {
1111 paniclog_append_noflush("%s + %llu", summary
->name
, (unsigned long)search
- summary
->address
);
1119 panic_print_symbol_name(vm_address_t search
)
1121 /* try searching in the kernel */
1122 if (panic_print_macho_symbol_name(&_mh_execute_header
, search
, "mach_kernel") == 0) {
1123 /* that failed, now try to search for the right kext */
1124 panic_print_kmod_symbol_name(search
);
1128 /* Generate a backtrace, given a frame pointer - this routine
1129 * should walk the stack safely. The trace is appended to the panic log
1130 * and conditionally, to the console. If the trace contains kernel module
1131 * addresses, display the module name, load address and dependencies.
1134 #define DUMPFRAMES 32
1135 #define PBT_TIMEOUT_CYCLES (5 * 1000 * 1000 * 1000ULL)
1137 panic_i386_backtrace(void *_frame
, int nframes
, const char *msg
, boolean_t regdump
, x86_saved_state_t
*regs
)
1139 cframe_t
*frame
= (cframe_t
*)_frame
;
1140 vm_offset_t raddrs
[DUMPFRAMES
];
1143 volatile uint32_t *ppbtcnt
= &pbtcnt
;
1144 uint64_t bt_tsc_timeout
;
1145 boolean_t keepsyms
= FALSE
;
1146 int cn
= cpu_number();
1147 boolean_t old_doprnt_hide_pointers
= doprnt_hide_pointers
;
1150 hw_atomic_add(&pbtcnt
, 1);
1151 /* Spin on print backtrace lock, which serializes output
1152 * Continue anyway if a timeout occurs.
1154 hw_lock_to(&pbtlock
, ~0U);
1158 if (__improbable(doprnt_hide_pointers
== TRUE
)) {
1159 /* If we're called directly, the Debugger() function will not be called,
1160 * so we need to reset the value in here. */
1161 doprnt_hide_pointers
= FALSE
;
1166 PE_parse_boot_argn("keepsyms", &keepsyms
, sizeof (keepsyms
));
1169 paniclog_append_noflush("%s", msg
);
1172 if ((regdump
== TRUE
) && (regs
!= NULL
)) {
1173 x86_saved_state64_t
*ss64p
= saved_state64(regs
);
1174 paniclog_append_noflush(
1175 "RAX: 0x%016llx, RBX: 0x%016llx, RCX: 0x%016llx, RDX: 0x%016llx\n"
1176 "RSP: 0x%016llx, RBP: 0x%016llx, RSI: 0x%016llx, RDI: 0x%016llx\n"
1177 "R8: 0x%016llx, R9: 0x%016llx, R10: 0x%016llx, R11: 0x%016llx\n"
1178 "R12: 0x%016llx, R13: 0x%016llx, R14: 0x%016llx, R15: 0x%016llx\n"
1179 "RFL: 0x%016llx, RIP: 0x%016llx, CS: 0x%016llx, SS: 0x%016llx\n",
1180 ss64p
->rax
, ss64p
->rbx
, ss64p
->rcx
, ss64p
->rdx
,
1181 ss64p
->isf
.rsp
, ss64p
->rbp
, ss64p
->rsi
, ss64p
->rdi
,
1182 ss64p
->r8
, ss64p
->r9
, ss64p
->r10
, ss64p
->r11
,
1183 ss64p
->r12
, ss64p
->r13
, ss64p
->r14
, ss64p
->r15
,
1184 ss64p
->isf
.rflags
, ss64p
->isf
.rip
, ss64p
->isf
.cs
,
1186 PC
= ss64p
->isf
.rip
;
1189 paniclog_append_noflush("Backtrace (CPU %d), "
1190 #if PRINT_ARGS_FROM_STACK_FRAME
1191 "Frame : Return Address (4 potential args on stack)\n", cn
);
1193 "Frame : Return Address\n", cn
);
1196 for (frame_index
= 0; frame_index
< nframes
; frame_index
++) {
1197 vm_offset_t curframep
= (vm_offset_t
) frame
;
1202 if (curframep
& 0x3) {
1203 paniclog_append_noflush("Unaligned frame\n");
1207 if (!kvtophys(curframep
) ||
1208 !kvtophys(curframep
+ sizeof(cframe_t
) - 1)) {
1209 paniclog_append_noflush("No mapping exists for frame pointer\n");
1213 paniclog_append_noflush("%p : 0x%lx ", frame
, frame
->caller
);
1214 if (frame_index
< DUMPFRAMES
)
1215 raddrs
[frame_index
] = frame
->caller
;
1217 #if PRINT_ARGS_FROM_STACK_FRAME
1218 if (kvtophys((vm_offset_t
)&(frame
->args
[3])))
1219 paniclog_append_noflush("(0x%x 0x%x 0x%x 0x%x) ",
1220 frame
->args
[0], frame
->args
[1],
1221 frame
->args
[2], frame
->args
[3]);
1224 /* Display address-symbol translation only if the "keepsyms"
1225 * boot-arg is suppplied, since we unload LINKEDIT otherwise.
1226 * This routine is potentially unsafe; also, function
1227 * boundary identification is unreliable after a strip -x.
1230 panic_print_symbol_name((vm_address_t
)frame
->caller
);
1232 paniclog_append_noflush("\n");
1234 frame
= frame
->prev
;
1237 if (frame_index
>= nframes
)
1238 paniclog_append_noflush("\tBacktrace continues...\n");
1243 paniclog_append_noflush("Backtrace terminated-invalid frame pointer %p\n",frame
);
1246 /* Identify kernel modules in the backtrace and display their
1247 * load addresses and dependencies. This routine should walk
1248 * the kmod list safely.
1251 kmod_panic_dump((vm_offset_t
*)&raddrs
[0], frame_index
);
1254 kmod_panic_dump(&PC
, 1);
1256 panic_display_system_configuration(FALSE
);
1258 doprnt_hide_pointers
= old_doprnt_hide_pointers
;
1260 /* Release print backtrace lock, to permit other callers in the
1261 * event of panics on multiple processors.
1263 hw_lock_unlock(&pbtlock
);
1264 hw_atomic_sub(&pbtcnt
, 1);
1265 /* Wait for other processors to complete output
1266 * Timeout and continue after PBT_TIMEOUT_CYCLES.
1268 bt_tsc_timeout
= rdtsc64() + PBT_TIMEOUT_CYCLES
;
1269 while(*ppbtcnt
&& (rdtsc64() < bt_tsc_timeout
));
1273 debug_copyin(pmap_t p
, uint64_t uaddr
, void *dest
, size_t size
)
1276 char *kvaddr
= dest
;
1279 ppnum_t upn
= pmap_find_phys(p
, uaddr
);
1280 uint64_t phys_src
= ptoa_64(upn
) | (uaddr
& PAGE_MASK
);
1281 uint64_t phys_dest
= kvtophys((vm_offset_t
)kvaddr
);
1282 uint64_t src_rem
= PAGE_SIZE
- (phys_src
& PAGE_MASK
);
1283 uint64_t dst_rem
= PAGE_SIZE
- (phys_dest
& PAGE_MASK
);
1284 size_t cur_size
= (uint32_t) MIN(src_rem
, dst_rem
);
1285 cur_size
= MIN(cur_size
, rem
);
1287 if (upn
&& pmap_valid_page(upn
) && phys_dest
) {
1288 bcopy_phys(phys_src
, phys_dest
, cur_size
);
1300 print_threads_registers(thread_t thread
)
1302 x86_saved_state_t
*savestate
;
1304 savestate
= get_user_regs(thread
);
1305 paniclog_append_noflush(
1306 "\nRAX: 0x%016llx, RBX: 0x%016llx, RCX: 0x%016llx, RDX: 0x%016llx\n"
1307 "RSP: 0x%016llx, RBP: 0x%016llx, RSI: 0x%016llx, RDI: 0x%016llx\n"
1308 "R8: 0x%016llx, R9: 0x%016llx, R10: 0x%016llx, R11: 0x%016llx\n"
1309 "R12: 0x%016llx, R13: 0x%016llx, R14: 0x%016llx, R15: 0x%016llx\n"
1310 "RFL: 0x%016llx, RIP: 0x%016llx, CS: 0x%016llx, SS: 0x%016llx\n\n",
1311 savestate
->ss_64
.rax
, savestate
->ss_64
.rbx
, savestate
->ss_64
.rcx
, savestate
->ss_64
.rdx
,
1312 savestate
->ss_64
.isf
.rsp
, savestate
->ss_64
.rbp
, savestate
->ss_64
.rsi
, savestate
->ss_64
.rdi
,
1313 savestate
->ss_64
.r8
, savestate
->ss_64
.r9
, savestate
->ss_64
.r10
, savestate
->ss_64
.r11
,
1314 savestate
->ss_64
.r12
, savestate
->ss_64
.r13
, savestate
->ss_64
.r14
, savestate
->ss_64
.r15
,
1315 savestate
->ss_64
.isf
.rflags
, savestate
->ss_64
.isf
.rip
, savestate
->ss_64
.isf
.cs
,
1316 savestate
->ss_64
.isf
.ss
);
1320 print_tasks_user_threads(task_t task
)
1322 thread_t thread
= current_thread();
1323 x86_saved_state_t
*savestate
;
1326 const char *cur_marker
= 0;
1329 for (j
= 0, thread
= (thread_t
) queue_first(&task
->threads
); j
< task
->thread_count
;
1330 ++j
, thread
= (thread_t
) queue_next(&thread
->task_threads
)) {
1332 paniclog_append_noflush("Thread %d: %p\n", j
, thread
);
1333 pmap
= get_task_pmap(task
);
1334 savestate
= get_user_regs(thread
);
1335 rbp
= savestate
->ss_64
.rbp
;
1336 paniclog_append_noflush("\t0x%016llx\n", savestate
->ss_64
.isf
.rip
);
1337 print_one_backtrace(pmap
, (vm_offset_t
)rbp
, cur_marker
, TRUE
);
1338 paniclog_append_noflush("\n");
1343 print_thread_num_that_crashed(task_t task
)
1345 thread_t c_thread
= current_thread();
1349 for (j
= 0, thread
= (thread_t
) queue_first(&task
->threads
); j
< task
->thread_count
;
1350 ++j
, thread
= (thread_t
) queue_next(&thread
->task_threads
)) {
1352 if (c_thread
== thread
) {
1353 paniclog_append_noflush("\nThread %d crashed\n", j
);
1359 #define PANICLOG_UUID_BUF_SIZE 256
1361 void print_uuid_info(task_t task
)
1363 uint32_t uuid_info_count
= 0;
1364 mach_vm_address_t uuid_info_addr
= 0;
1365 boolean_t have_map
= (task
->map
!= NULL
) && (ml_validate_nofault((vm_offset_t
)(task
->map
), sizeof(struct _vm_map
)));
1366 boolean_t have_pmap
= have_map
&& (task
->map
->pmap
!= NULL
) && (ml_validate_nofault((vm_offset_t
)(task
->map
->pmap
), sizeof(struct pmap
)));
1367 int task_pid
= pid_from_task(task
);
1368 char uuidbuf
[PANICLOG_UUID_BUF_SIZE
] = {0};
1369 char *uuidbufptr
= uuidbuf
;
1372 if (have_pmap
&& task
->active
&& task_pid
> 0) {
1373 /* Read dyld_all_image_infos struct from task memory to get UUID array count & location */
1374 struct user64_dyld_all_image_infos task_image_infos
;
1375 if (debug_copyin(task
->map
->pmap
, task
->all_image_info_addr
,
1376 &task_image_infos
, sizeof(struct user64_dyld_all_image_infos
))) {
1377 uuid_info_count
= (uint32_t)task_image_infos
.uuidArrayCount
;
1378 uuid_info_addr
= task_image_infos
.uuidArray
;
1381 /* If we get a NULL uuid_info_addr (which can happen when we catch dyld
1382 * in the middle of updating this data structure), we zero the
1383 * uuid_info_count so that we won't even try to save load info for this task
1385 if (!uuid_info_addr
) {
1386 uuid_info_count
= 0;
1390 if (task_pid
> 0 && uuid_info_count
> 0) {
1391 uint32_t uuid_info_size
= sizeof(struct user64_dyld_uuid_info
);
1392 uint32_t uuid_array_size
= uuid_info_count
* uuid_info_size
;
1393 uint32_t uuid_copy_size
= 0;
1394 uint32_t uuid_image_count
= 0;
1395 char *current_uuid_buffer
= NULL
;
1396 /* Copy in the UUID info array. It may be nonresident, in which case just fix up nloadinfos to 0 */
1398 paniclog_append_noflush("\nuuid info:\n");
1399 while (uuid_array_size
) {
1400 if (uuid_array_size
<= PANICLOG_UUID_BUF_SIZE
) {
1401 uuid_copy_size
= uuid_array_size
;
1402 uuid_image_count
= uuid_array_size
/uuid_info_size
;
1404 uuid_image_count
= PANICLOG_UUID_BUF_SIZE
/uuid_info_size
;
1405 uuid_copy_size
= uuid_image_count
* uuid_info_size
;
1407 if (have_pmap
&& !debug_copyin(task
->map
->pmap
, uuid_info_addr
, uuidbufptr
,
1409 paniclog_append_noflush("Error!! Failed to copy UUID info for task %p pid %d\n", task
, task_pid
);
1410 uuid_image_count
= 0;
1414 if (uuid_image_count
> 0) {
1415 current_uuid_buffer
= uuidbufptr
;
1416 for (k
= 0; k
< uuid_image_count
; k
++) {
1417 paniclog_append_noflush(" %#llx", *(uint64_t *)current_uuid_buffer
);
1418 current_uuid_buffer
+= sizeof(uint64_t);
1419 uint8_t *uuid
= (uint8_t *)current_uuid_buffer
;
1420 paniclog_append_noflush("\tuuid = <%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x>\n",
1421 uuid
[0], uuid
[1], uuid
[2], uuid
[3], uuid
[4], uuid
[5], uuid
[6], uuid
[7], uuid
[8],
1422 uuid
[9], uuid
[10], uuid
[11], uuid
[12], uuid
[13], uuid
[14], uuid
[15]);
1423 current_uuid_buffer
+= 16;
1425 bzero(&uuidbuf
, sizeof(uuidbuf
));
1427 uuid_info_addr
+= uuid_copy_size
;
1428 uuid_array_size
-= uuid_copy_size
;
1433 void print_launchd_info(void)
1435 task_t task
= current_task();
1436 thread_t thread
= current_thread();
1437 volatile uint32_t *ppbtcnt
= &pbtcnt
;
1438 uint64_t bt_tsc_timeout
;
1439 int cn
= cpu_number();
1442 hw_atomic_add(&pbtcnt
, 1);
1443 /* Spin on print backtrace lock, which serializes output
1444 * Continue anyway if a timeout occurs.
1446 hw_lock_to(&pbtlock
, ~0U);
1450 print_uuid_info(task
);
1451 print_thread_num_that_crashed(task
);
1452 print_threads_registers(thread
);
1453 print_tasks_user_threads(task
);
1455 panic_display_system_configuration(TRUE
);
1457 /* Release print backtrace lock, to permit other callers in the
1458 * event of panics on multiple processors.
1460 hw_lock_unlock(&pbtlock
);
1461 hw_atomic_sub(&pbtcnt
, 1);
1462 /* Wait for other processors to complete output
1463 * Timeout and continue after PBT_TIMEOUT_CYCLES.
1465 bt_tsc_timeout
= rdtsc64() + PBT_TIMEOUT_CYCLES
;
1466 while(*ppbtcnt
&& (rdtsc64() < bt_tsc_timeout
));