1/*
2 * Copyright (c) 2000-2019 Apple 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#ifndef _KERN_DEBUG_H_
30#define _KERN_DEBUG_H_
31
32#include <kern/kcdata.h>
33
34#include <sys/cdefs.h>
35#include <stdint.h>
36#include <stdarg.h>
37#include <uuid/uuid.h>
38#include <mach/boolean.h>
39#include <mach/kern_return.h>
40#include <mach/vm_types.h>
41
42#ifndef XNU_KERNEL_PRIVATE
43#include <TargetConditionals.h>
44#endif
45
46__BEGIN_DECLS
47
48#ifdef __APPLE_API_PRIVATE
49#ifdef __APPLE_API_UNSTABLE
50
51struct thread_snapshot {
52 uint32_t snapshot_magic;
53 uint32_t nkern_frames;
54 uint32_t nuser_frames;
55 uint64_t wait_event;
56 uint64_t continuation;
57 uint64_t thread_id;
58 uint64_t user_time;
59 uint64_t system_time;
60 int32_t state;
61 int32_t priority; /* static priority */
62 int32_t sched_pri; /* scheduled (current) priority */
63 int32_t sched_flags; /* scheduler flags */
64 char ss_flags;
65 char ts_qos; /* effective qos */
66 char ts_rqos; /* requested qos */
67 char ts_rqos_override; /* requested qos override */
68 char io_tier;
69 /*
70 * In microstackshots, the low two bytes are the start of the first async
71 * frame in the thread's user space call stack. If the call stack lacks
72 * async stack frames, it's `UINT16_MAX`.
73 */
74 char _reserved[3]; /* pad for 4 byte alignement packing */
75
76 /*
77 * I/O Statistics
78 * XXX: These fields must be together
79 */
80 uint64_t disk_reads_count;
81 uint64_t disk_reads_size;
82 uint64_t disk_writes_count;
83 uint64_t disk_writes_size;
84 uint64_t io_priority_count[STACKSHOT_IO_NUM_PRIORITIES];
85 uint64_t io_priority_size[STACKSHOT_IO_NUM_PRIORITIES];
86 uint64_t paging_count;
87 uint64_t paging_size;
88 uint64_t non_paging_count;
89 uint64_t non_paging_size;
90 uint64_t data_count;
91 uint64_t data_size;
92 uint64_t metadata_count;
93 uint64_t metadata_size;
94 /* XXX: I/O Statistics end */
95
96 uint64_t voucher_identifier; /* obfuscated voucher identifier */
97 uint64_t total_syscalls;
98 char pth_name[STACKSHOT_MAX_THREAD_NAME_SIZE];
99} __attribute__((packed));
100
101/* old, non kcdata format */
102struct task_snapshot {
103 uint32_t snapshot_magic;
104 int32_t pid;
105 uint64_t uniqueid;
106 uint64_t user_time_in_terminated_threads;
107 uint64_t system_time_in_terminated_threads;
108 uint8_t shared_cache_identifier[16];
109 uint64_t shared_cache_slide;
110 uint32_t nloadinfos;
111 int suspend_count;
112 int task_size; /* pages */
113 int faults; /* number of page faults */
114 int pageins; /* number of actual pageins */
115 int cow_faults; /* number of copy-on-write faults */
116 uint32_t ss_flags;
117 /*
118 * In microstackshots, `p_start_sec` is actually the resource coalition ID
119 * that this thread belongs to.
120 */
121 uint64_t p_start_sec; /* from the bsd proc struct */
122 /*
123 * In microstackshots, `p_stat_usec` is actually the resource coalition ID
124 * that this thread is doing work on behalf of.
125 */
126 uint64_t p_start_usec; /* from the bsd proc struct */
127
128 /*
129 * We restrict ourselves to a statically defined
130 * (current as of 2009) length for the
131 * p_comm string, due to scoping issues (osfmk/bsd and user/kernel
132 * binary compatibility).
133 */
134 char p_comm[17];
135 uint32_t was_throttled;
136 uint32_t did_throttle;
137 uint32_t latency_qos;
138 /*
139 * I/O Statistics
140 * XXX: These fields must be together.
141 */
142 uint64_t disk_reads_count;
143 uint64_t disk_reads_size;
144 uint64_t disk_writes_count;
145 uint64_t disk_writes_size;
146 uint64_t io_priority_count[STACKSHOT_IO_NUM_PRIORITIES];
147 uint64_t io_priority_size[STACKSHOT_IO_NUM_PRIORITIES];
148 uint64_t paging_count;
149 uint64_t paging_size;
150 uint64_t non_paging_count;
151 uint64_t non_paging_size;
152 uint64_t data_count;
153 uint64_t data_size;
154 uint64_t metadata_count;
155 uint64_t metadata_size;
156 /* XXX: I/O Statistics end */
157
158 uint32_t donating_pid_count;
159} __attribute__ ((packed));
160
161
162
163struct micro_snapshot {
164 uint32_t snapshot_magic;
165 uint32_t ms_cpu; /* cpu number this snapshot was recorded on */
166 uint64_t ms_time; /* time at sample (seconds) */
167 uint64_t ms_time_microsecs;
168 uint8_t ms_flags;
169 uint16_t ms_opaque_flags; /* managed by external entity, e.g. fdrmicrod */
170} __attribute__ ((packed));
171
172
173/*
174 * mirrors the dyld_cache_header struct defined in dyld_cache_format.h from dyld source code
175 */
176struct _dyld_cache_header {
177 char magic[16]; // e.g. "dyld_v0 i386"
178 uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info
179 uint32_t mappingCount; // number of dyld_cache_mapping_info entries
180 uint32_t imagesOffset; // file offset to first dyld_cache_image_info
181 uint32_t imagesCount; // number of dyld_cache_image_info entries
182 uint64_t dyldBaseAddress; // base address of dyld when cache was built
183 uint64_t codeSignatureOffset;// file offset of code signature blob
184 uint64_t codeSignatureSize; // size of code signature blob (zero means to end of file)
185 uint64_t slideInfoOffset; // file offset of kernel slid info
186 uint64_t slideInfoSize; // size of kernel slid info
187 uint64_t localSymbolsOffset; // file offset of where local symbols are stored
188 uint64_t localSymbolsSize; // size of local symbols information
189 uint8_t uuid[16]; // unique value for each shared cache file
190 uint64_t cacheType; // 0 for development, 1 for production
191 uint32_t branchPoolsOffset; // file offset to table of uint64_t pool addresses
192 uint32_t branchPoolsCount; // number of uint64_t entries
193 uint64_t accelerateInfoAddr; // (unslid) address of optimization info
194 uint64_t accelerateInfoSize; // size of optimization info
195 uint64_t imagesTextOffset; // file offset to first dyld_cache_image_text_info
196 uint64_t imagesTextCount; // number of dyld_cache_image_text_info entries
197 uint64_t dylibsImageGroupAddr;// (unslid) address of ImageGroup for dylibs in this cache
198 uint64_t dylibsImageGroupSize;// size of ImageGroup for dylibs in this cache
199 uint64_t otherImageGroupAddr;// (unslid) address of ImageGroup for other OS dylibs
200 uint64_t otherImageGroupSize;// size of oImageGroup for other OS dylibs
201 uint64_t progClosuresAddr; // (unslid) address of list of program launch closures
202 uint64_t progClosuresSize; // size of list of program launch closures
203 uint64_t progClosuresTrieAddr;// (unslid) address of trie of indexes into program launch closures
204 uint64_t progClosuresTrieSize;// size of trie of indexes into program launch closures
205 uint32_t platform; // platform number (macOS=1, etc)
206 uint32_t formatVersion : 8,// dyld3::closure::kFormatVersion
207 dylibsExpectedOnDisk : 1, // dyld should expect the dylib exists on disk and to compare inode/mtime to see if cache is valid
208 simulator : 1, // for simulator of specified platform
209 locallyBuiltCache : 1, // 0 for B&I built cache, 1 for locally built cache
210 padding : 21; // TBD
211};
212
213/*
214 * mirrors the dyld_cache_image_text_info struct defined in dyld_cache_format.h from dyld source code
215 */
216struct _dyld_cache_image_text_info {
217 uuid_t uuid;
218 uint64_t loadAddress; // unslid address of start of __TEXT
219 uint32_t textSegmentSize;
220 uint32_t pathOffset; // offset from start of cache file
221};
222
223
224enum micro_snapshot_flags {
225 kInterruptRecord = 0x1,
226 kTimerArmingRecord = 0x2,
227 kUserMode = 0x4, /* interrupted usermode, or armed by usermode */
228 kIORecord = 0x8,
229 kPMIRecord = 0x10,
230 kMACFRecord = 0x20, /* armed by MACF policy */
231};
232
233/*
234 * Flags used in the following assortment of snapshots.
235 */
236enum generic_snapshot_flags {
237 kUser64_p = 0x1, /* Userspace uses 64 bit pointers */
238 kKernel64_p = 0x2 /* The kernel uses 64 bit pointers */
239};
240
241#define VM_PRESSURE_TIME_WINDOW 5 /* seconds */
242
243__options_decl(stackshot_flags_t, uint64_t, {
244 STACKSHOT_GET_DQ = 0x01,
245 STACKSHOT_SAVE_LOADINFO = 0x02,
246 STACKSHOT_GET_GLOBAL_MEM_STATS = 0x04,
247 STACKSHOT_SAVE_KEXT_LOADINFO = 0x08,
248 /*
249 * 0x10, 0x20, 0x40 and 0x80 are reserved.
250 *
251 * See microstackshot_flags_t whose members used to be part of this
252 * declaration.
253 */
254 STACKSHOT_ACTIVE_KERNEL_THREADS_ONLY = 0x100,
255 STACKSHOT_GET_BOOT_PROFILE = 0x200,
256 STACKSHOT_DO_COMPRESS = 0x400,
257 STACKSHOT_SAVE_IMP_DONATION_PIDS = 0x2000,
258 STACKSHOT_SAVE_IN_KERNEL_BUFFER = 0x4000,
259 STACKSHOT_RETRIEVE_EXISTING_BUFFER = 0x8000,
260 STACKSHOT_KCDATA_FORMAT = 0x10000,
261 STACKSHOT_ENABLE_BT_FAULTING = 0x20000,
262 STACKSHOT_COLLECT_DELTA_SNAPSHOT = 0x40000,
263 /* Include the layout of the system shared cache */
264 STACKSHOT_COLLECT_SHAREDCACHE_LAYOUT = 0x80000,
265 /*
266 * Kernel consumers of stackshot (via stack_snapshot_from_kernel) can ask
267 * that we try to take the stackshot lock, and fail if we don't get it.
268 */
269 STACKSHOT_TRYLOCK = 0x100000,
270 STACKSHOT_ENABLE_UUID_FAULTING = 0x200000,
271 STACKSHOT_FROM_PANIC = 0x400000,
272 STACKSHOT_NO_IO_STATS = 0x800000,
273 /* Report owners of and pointers to kernel objects that threads are blocked on */
274 STACKSHOT_THREAD_WAITINFO = 0x1000000,
275 STACKSHOT_THREAD_GROUP = 0x2000000,
276 STACKSHOT_SAVE_JETSAM_COALITIONS = 0x4000000,
277 STACKSHOT_INSTRS_CYCLES = 0x8000000,
278 STACKSHOT_ASID = 0x10000000,
279 STACKSHOT_PAGE_TABLES = 0x20000000,
280 STACKSHOT_DISABLE_LATENCY_INFO = 0x40000000,
281 STACKSHOT_SAVE_DYLD_COMPACTINFO = 0x80000000,
282 STACKSHOT_INCLUDE_DRIVER_THREADS_IN_KERNEL = 0x100000000,
283 /* Include Exclave stacks in Stackshot - currently unused/on-by-default */
284 STACKSHOT_EXCLAVES = 0x200000000,
285 /* Skip Exclaves stack collection */
286 STACKSHOT_SKIP_EXCLAVES = 0x400000000,
287}); // Note: Add any new flags to kcdata.py (stackshot_in_flags)
288
289__options_decl(microstackshot_flags_t, uint32_t, {
290 STACKSHOT_GET_MICROSTACKSHOT = 0x10,
291 STACKSHOT_GLOBAL_MICROSTACKSHOT_ENABLE = 0x20,
292 STACKSHOT_GLOBAL_MICROSTACKSHOT_DISABLE = 0x40,
293 STACKSHOT_SET_MICROSTACKSHOT_MARK = 0x80,
294});
295
296#define STACKSHOT_THREAD_SNAPSHOT_MAGIC 0xfeedface
297#define STACKSHOT_TASK_SNAPSHOT_MAGIC 0xdecafbad
298#define STACKSHOT_MEM_AND_IO_SNAPSHOT_MAGIC 0xbfcabcde
299#define STACKSHOT_MICRO_SNAPSHOT_MAGIC 0x31c54011
300
301#define STACKSHOT_PAGETABLES_MASK_ALL ~0
302
303__options_closed_decl(kf_override_flag_t, uint32_t, {
304 KF_SERIAL_OVRD = 0x2,
305 KF_PMAPV_OVRD = 0x4,
306 KF_MATV_OVRD = 0x8,
307 KF_STACKSHOT_OVRD = 0x10,
308 KF_COMPRSV_OVRD = 0x20,
309 KF_INTERRUPT_MASKED_DEBUG_OVRD = 0x40,
310 KF_TRAPTRACE_OVRD = 0x80,
311 KF_IOTRACE_OVRD = 0x100,
312 KF_INTERRUPT_MASKED_DEBUG_STACKSHOT_OVRD = 0x200,
313 KF_SCHED_HYGIENE_DEBUG_PMC_OVRD = 0x400,
314 KF_RW_LOCK_DEBUG_OVRD = 0x800,
315 KF_MADVISE_FREE_DEBUG_OVRD = 0x1000,
316 KF_DISABLE_FP_POPC_ON_PGFLT = 0x2000,
317 KF_DISABLE_PROD_TRC_VALIDATION = 0x4000,
318 KF_IO_TIMEOUT_OVRD = 0x8000,
319 KF_PREEMPTION_DISABLED_DEBUG_OVRD = 0x10000,
320});
321
322boolean_t kern_feature_override(kf_override_flag_t fmask);
323
324__options_decl(eph_panic_flags_t, uint64_t, {
325 EMBEDDED_PANIC_HEADER_FLAG_COREDUMP_COMPLETE = 0x01, /* INFO: coredump completed */
326 EMBEDDED_PANIC_HEADER_FLAG_STACKSHOT_SUCCEEDED = 0x02, /* INFO: stackshot completed */
327 EMBEDDED_PANIC_HEADER_FLAG_STACKSHOT_FAILED_DEBUGGERSYNC = 0x04, /* ERROR: stackshot failed to sync with external debugger */
328 EMBEDDED_PANIC_HEADER_FLAG_STACKSHOT_FAILED_ERROR = 0x08, /* ERROR: stackshot failed */
329 EMBEDDED_PANIC_HEADER_FLAG_STACKSHOT_FAILED_INCOMPLETE = 0x10, /* ERROR: stackshot is partially complete */
330 EMBEDDED_PANIC_HEADER_FLAG_STACKSHOT_FAILED_NESTED = 0x20, /* ERROR: stackshot caused a nested panic */
331 EMBEDDED_PANIC_HEADER_FLAG_NESTED_PANIC = 0x40, /* ERROR: panic handler encountered a panic */
332 EMBEDDED_PANIC_HEADER_FLAG_BUTTON_RESET_PANIC = 0x80, /* INFO: force-reset panic: user held power button to force shutdown */
333 EMBEDDED_PANIC_HEADER_FLAG_COPROC_INITIATED_PANIC = 0x100, /* INFO: panic was triggered by a companion processor (not Xnu) */
334 EMBEDDED_PANIC_HEADER_FLAG_COREDUMP_FAILED = 0x200, /* ERROR: coredump failed to complete */
335 EMBEDDED_PANIC_HEADER_FLAG_COMPRESS_FAILED = 0x400, /* ERROR: stackshot failed to compress */
336 EMBEDDED_PANIC_HEADER_FLAG_STACKSHOT_DATA_COMPRESSED = 0x800, /* INFO: stackshot data is compressed */
337 EMBEDDED_PANIC_HEADER_FLAG_ENCRYPTED_COREDUMP_SKIPPED = 0x1000, /* ERROR: coredump policy requires encryption, but encryptions is not initialized or available */
338 EMBEDDED_PANIC_HEADER_FLAG_KERNEL_COREDUMP_SKIPPED_EXCLUDE_REGIONS_UNAVAILABLE = 0x2000, /* ERROR: coredump region exclusion list is not available */
339 EMBEDDED_PANIC_HEADER_FLAG_COREFILE_UNLINKED = 0x4000, /* ERROR: coredump output file is not linked */
340 EMBEDDED_PANIC_HEADER_FLAG_INCOHERENT_PANICLOG = 0x8000, /* ERROR: paniclog integrity check failed (a warning to consumer code i.e. DumpPanic) */
341 EMBEDDED_PANIC_HEADER_FLAG_EXCLAVE_PANIC = 0x10000, /* INFO: panic originated from exclaves */
342});
343
344#define EMBEDDED_PANIC_HEADER_CURRENT_VERSION 5
345#define EMBEDDED_PANIC_MAGIC 0x46554E4B /* FUNK */
346#define EMBEDDED_PANIC_HEADER_OSVERSION_LEN 32
347
348/*
349 * Any updates to this header should be also updated in astris as it can not
350 * grab this header from the SDK.
351 *
352 * NOTE: DO NOT REMOVE OR CHANGE THE MEANING OF ANY FIELDS FROM THIS STRUCTURE.
353 * Any modifications should add new fields at the end, bump the version number
354 * and be done alongside astris and DumpPanic changes.
355 */
356struct embedded_panic_header {
357 uint32_t eph_magic; /* EMBEDDED_PANIC_MAGIC if valid */
358 uint32_t eph_crc; /* CRC of everything following the ph_crc in the header and the contents */
359 uint32_t eph_version; /* embedded_panic_header version */
360 eph_panic_flags_t eph_panic_flags; /* Flags indicating any state or relevant details */
361 uint32_t eph_panic_log_offset; /* Offset of the beginning of the panic log from the beginning of the header */
362 uint32_t eph_panic_log_len; /* length of the panic log */
363 uint32_t eph_stackshot_offset; /* Offset of the beginning of the panic stackshot from the beginning of the header */
364 uint32_t eph_stackshot_len; /* length of the panic stackshot (0 if not valid ) */
365 uint32_t eph_other_log_offset; /* Offset of the other log (any logging subsequent to the stackshot) from the beginning of the header */
366 uint32_t eph_other_log_len; /* length of the other log */
367 union {
368 struct {
369 uint64_t eph_x86_power_state:8,
370 eph_x86_efi_boot_state:8,
371 eph_x86_system_state:8,
372 eph_x86_unused_bits:40;
373 }; // anonymous struct to group the bitfields together.
374 uint64_t eph_x86_do_not_use; /* Used for offsetof/sizeof when parsing header */
375 } __attribute__((packed));
376 char eph_os_version[EMBEDDED_PANIC_HEADER_OSVERSION_LEN];
377 char eph_macos_version[EMBEDDED_PANIC_HEADER_OSVERSION_LEN];
378 uuid_string_t eph_bootsessionuuid_string; /* boot session UUID */
379 uint64_t eph_roots_installed; /* bitmap indicating which roots are installed on this system */
380 uint32_t eph_ext_paniclog_offset;
381 uint32_t eph_ext_paniclog_len;
382} __attribute__((packed));
383
384
385#define MACOS_PANIC_HEADER_CURRENT_VERSION 3
386#define MACOS_PANIC_MAGIC 0x44454544 /* DEED */
387
388__options_decl(mph_panic_flags_t, uint64_t, {
389 MACOS_PANIC_HEADER_FLAG_NESTED_PANIC = 0x01, /* ERROR: panic handler encountered a panic */
390 MACOS_PANIC_HEADER_FLAG_COPROC_INITIATED_PANIC = 0x02, /* INFO: panic was triggered by a companion processor (not Xnu) */
391 MACOS_PANIC_HEADER_FLAG_STACKSHOT_SUCCEEDED = 0x04, /* INFO: stackshot completed */
392 MACOS_PANIC_HEADER_FLAG_STACKSHOT_DATA_COMPRESSED = 0x08, /* INFO: stackshot data is compressed */
393 MACOS_PANIC_HEADER_FLAG_STACKSHOT_FAILED_DEBUGGERSYNC = 0x10, /* ERROR: stackshot failed to sync with external debugger */
394 MACOS_PANIC_HEADER_FLAG_STACKSHOT_FAILED_ERROR = 0x20, /* ERROR: stackshot failed */
395 MACOS_PANIC_HEADER_FLAG_STACKSHOT_FAILED_INCOMPLETE = 0x40, /* ERROR: stackshot is partially complete */
396 MACOS_PANIC_HEADER_FLAG_STACKSHOT_FAILED_NESTED = 0x80, /* ERROR: stackshot caused a nested panic */
397 MACOS_PANIC_HEADER_FLAG_COREDUMP_COMPLETE = 0x100, /* INFO: coredump completed */
398 MACOS_PANIC_HEADER_FLAG_COREDUMP_FAILED = 0x200, /* ERROR: coredump failed to complete */
399 MACOS_PANIC_HEADER_FLAG_STACKSHOT_KERNEL_ONLY = 0x400, /* ERROR: stackshot contains only kernel data (e.g. due to space limitations) */
400 MACOS_PANIC_HEADER_FLAG_STACKSHOT_FAILED_COMPRESS = 0x800, /* ERROR: stackshot failed to compress */
401 MACOS_PANIC_HEADER_FLAG_ENCRYPTED_COREDUMP_SKIPPED = 0x1000, /* ERROR: coredump policy requires encryption, but encryptions is not initialized or available */
402 MACOS_PANIC_HEADER_FLAG_KERNEL_COREDUMP_SKIPPED_EXCLUDE_REGIONS_UNAVAILABLE = 0x2000, /* ERROR: coredump region exclusion list is not available */
403 MACOS_PANIC_HEADER_FLAG_COREFILE_UNLINKED = 0x4000, /* ERROR: coredump output file is not linked */
404 MACOS_PANIC_HEADER_FLAG_INCOHERENT_PANICLOG = 0x8000 /* ERROR: paniclog integrity check failed (a warning to consumer code i.e. DumpPanic) */
405});
406
407struct macos_panic_header {
408 uint32_t mph_magic; /* MACOS_PANIC_MAGIC if valid */
409 uint32_t mph_crc; /* CRC of everything following mph_crc in the header and the contents */
410 uint32_t mph_version; /* macos_panic_header version */
411 uint32_t mph_padding; /* unused */
412 mph_panic_flags_t mph_panic_flags; /* Flags indicating any state or relevant details */
413 uint32_t mph_panic_log_offset; /* Offset of the panic log from the beginning of the header */
414 uint32_t mph_panic_log_len; /* length of the panic log */
415 uint32_t mph_stackshot_offset; /* Offset of the panic stackshot from the beginning of the header */
416 uint32_t mph_stackshot_len; /* length of the panic stackshot */
417 uint32_t mph_other_log_offset; /* Offset of the other log (any logging subsequent to the stackshot) from the beginning of the header */
418 uint32_t mph_other_log_len; /* length of the other log */
419 uint64_t mph_roots_installed; /* bitmap indicating which roots are installed on this system */
420 char mph_data[]; /* panic data -- DO NOT ACCESS THIS FIELD DIRECTLY. Use the offsets above relative to the beginning of the header */
421} __attribute__((packed));
422
423/*
424 * Any change to the below structure should mirror the structure defined in MacEFIFirmware
425 * (and vice versa)
426 */
427
428struct efi_aurr_panic_header {
429 uint32_t efi_aurr_magic;
430 uint32_t efi_aurr_crc;
431 uint32_t efi_aurr_version;
432 uint32_t efi_aurr_reset_cause;
433 uint32_t efi_aurr_reset_log_offset;
434 uint32_t efi_aurr_reset_log_len;
435 char efi_aurr_panic_data[];
436} __attribute__((packed));
437
438/*
439 * EXTENDED_/DEBUG_BUF_SIZE can't grow without updates to SMC and iBoot to store larger panic logs on co-processor systems
440 */
441#define EXTENDED_DEBUG_BUF_SIZE 0x0013ff80
442
443#define EFI_AURR_PANIC_STRING_MAX_LEN 112
444#define EFI_AURR_EXTENDED_LOG_SIZE (EXTENDED_DEBUG_BUF_SIZE - sizeof(struct efi_aurr_panic_header) - EFI_AURR_PANIC_STRING_MAX_LEN)
445
446struct efi_aurr_extended_panic_log {
447 char efi_aurr_extended_log_buf[EFI_AURR_EXTENDED_LOG_SIZE];
448 uint32_t efi_aurr_log_tail; /* Circular buffer indices */
449 uint32_t efi_aurr_log_head; /* ditto.. */
450} __attribute__((packed));
451
452#endif /* __APPLE_API_UNSTABLE */
453#endif /* __APPLE_API_PRIVATE */
454
455/*
456 * If non-zero, this physical address had an ECC error that led to a panic.
457 */
458extern uint64_t ecc_panic_physical_address;
459
460#ifdef KERNEL
461
462__abortlike __printflike(1, 2)
463extern void panic(const char *string, ...);
464
465#endif /* KERNEL */
466
467#ifdef KERNEL_PRIVATE
468#if DEBUG
469#ifndef DKPR
470#define DKPR 1
471#endif
472#endif
473
474#if DKPR
475/*
476 * For the DEBUG kernel, support the following:
477 * sysctl -w debug.kprint_syscall=<syscall_mask>
478 * sysctl -w debug.kprint_syscall_process=<p_comm>
479 * <syscall_mask> should be an OR of the masks below
480 * for UNIX, MACH, MDEP, or IPC. This debugging aid
481 * assumes the task/process is locked/wired and will
482 * not go away during evaluation. If no process is
483 * specified, all processes will be traced
484 */
485extern int debug_kprint_syscall;
486extern int debug_kprint_current_process(const char **namep);
487#define DEBUG_KPRINT_SYSCALL_PREDICATE_INTERNAL(mask, namep) \
488 ( (debug_kprint_syscall & (mask)) && debug_kprint_current_process(namep) )
489#define DEBUG_KPRINT_SYSCALL_MASK(mask, fmt, args...) do { \
490 const char *dks_name = NULL; \
491 if (DEBUG_KPRINT_SYSCALL_PREDICATE_INTERNAL(mask, &dks_name)) { \
492 kprintf("[%s%s%p]" fmt, dks_name ? dks_name : "", \
493 dks_name ? "@" : "", current_thread(), args); \
494 } \
495 } while (0)
496#else /* !DEBUG */
497#define DEBUG_KPRINT_SYSCALL_PREDICATE_INTERNAL(mask, namep) (0)
498#define DEBUG_KPRINT_SYSCALL_MASK(mask, fmt, args...) do { } while (0) /* kprintf(fmt, args) */
499#endif /* !DEBUG */
500
501enum {
502 DEBUG_KPRINT_SYSCALL_UNIX_MASK = 1 << 0,
503 DEBUG_KPRINT_SYSCALL_MACH_MASK = 1 << 1,
504 DEBUG_KPRINT_SYSCALL_MDEP_MASK = 1 << 2,
505 DEBUG_KPRINT_SYSCALL_IPC_MASK = 1 << 3
506};
507
508#define DEBUG_KPRINT_SYSCALL_PREDICATE(mask) \
509 DEBUG_KPRINT_SYSCALL_PREDICATE_INTERNAL(mask, NULL)
510#define DEBUG_KPRINT_SYSCALL_UNIX(fmt, args...) \
511 DEBUG_KPRINT_SYSCALL_MASK(DEBUG_KPRINT_SYSCALL_UNIX_MASK,fmt,args)
512#define DEBUG_KPRINT_SYSCALL_MACH(fmt, args...) \
513 DEBUG_KPRINT_SYSCALL_MASK(DEBUG_KPRINT_SYSCALL_MACH_MASK,fmt,args)
514#define DEBUG_KPRINT_SYSCALL_MDEP(fmt, args...) \
515 DEBUG_KPRINT_SYSCALL_MASK(DEBUG_KPRINT_SYSCALL_MDEP_MASK,fmt,args)
516#define DEBUG_KPRINT_SYSCALL_IPC(fmt, args...) \
517 DEBUG_KPRINT_SYSCALL_MASK(DEBUG_KPRINT_SYSCALL_IPC_MASK,fmt,args)
518
519/* Debug boot-args */
520#define DB_HALT 0x1
521//#define DB_PRT 0x2 -- obsolete
522#define DB_NMI 0x4
523#define DB_KPRT 0x8
524#define DB_KDB 0x10
525#define DB_ARP 0x40
526#define DB_KDP_BP_DIS 0x80
527//#define DB_LOG_PI_SCRN 0x100 -- obsolete
528#define DB_KDP_GETC_ENA 0x200
529
530#define DB_KERN_DUMP_ON_PANIC 0x400 /* Trigger core dump on panic*/
531#define DB_KERN_DUMP_ON_NMI 0x800 /* Trigger core dump on NMI */
532#define DB_DBG_POST_CORE 0x1000 /*Wait in debugger after NMI core */
533#define DB_PANICLOG_DUMP 0x2000 /* Send paniclog on panic,not core*/
534#define DB_REBOOT_POST_CORE 0x4000 /* Attempt to reboot after
535 * post-panic crashdump/paniclog
536 * dump.
537 */
538#define DB_NMI_BTN_ENA 0x8000 /* Enable button to directly trigger NMI */
539/* 0x10000 was DB_PRT_KDEBUG (kprintf kdebug events), feature removed */
540#define DB_DISABLE_LOCAL_CORE 0x20000 /* ignore local kernel core dump support */
541#define DB_DISABLE_GZIP_CORE 0x40000 /* don't gzip kernel core dumps */
542#define DB_DISABLE_CROSS_PANIC 0x80000 /* x86 only - don't trigger cross panics. Only
543 * necessary to enable x86 kernel debugging on
544 * configs with a dev-fused co-processor running
545 * release bridgeOS.
546 */
547#define DB_REBOOT_ALWAYS 0x100000 /* Don't wait for debugger connection */
548#define DB_DISABLE_STACKSHOT_TO_DISK 0x200000 /* Disable writing stackshot to local disk */
549#define DB_DEBUG_IP_INIT 0x400000 /* iBoot specific: Allow globally enabling debug IPs during init */
550#define DB_SOC_HALT_ENABLE 0x800000 /* iBoot specific: Enable SoC Halt during init */
551
552/*
553 * Values for a 64-bit mask that's passed to the debugger.
554 */
555#define DEBUGGER_OPTION_NONE 0x0ULL
556#define DEBUGGER_OPTION_PANICLOGANDREBOOT 0x1ULL /* capture a panic log and then reboot immediately */
557#define DEBUGGER_OPTION_INITPROC_PANIC 0x20ULL
558#define DEBUGGER_OPTION_COPROC_INITIATED_PANIC 0x40ULL /* panic initiated by a co-processor */
559#define DEBUGGER_OPTION_SKIP_LOCAL_COREDUMP 0x80ULL /* don't try to save local coredumps for this panic */
560#define DEBUGGER_OPTION_ATTEMPTCOREDUMPANDREBOOT 0x100ULL /* attempt to save coredump. always reboot */
561#define DEBUGGER_INTERNAL_OPTION_THREAD_BACKTRACE 0x200ULL /* backtrace the specified thread in the paniclog (x86 only) */
562#define DEBUGGER_OPTION_PRINT_CPU_USAGE_PANICLOG 0x400ULL /* print extra CPU usage data in the panic log */
563#define DEBUGGER_OPTION_SKIP_PANICEND_CALLOUTS 0x800ULL /* (bridgeOS) skip the kPEPanicEnd callouts -- don't wait for x86 to finish sending panic data */
564#define DEBUGGER_OPTION_SYNC_ON_PANIC_UNSAFE 0x1000ULL /* sync() early in Panic - Can add unbounded delay, may be unsafe for some panic scenarios. Intended for userspace, watchdogs and RTBuddy panics */
565
566#define DEBUGGER_INTERNAL_OPTIONS_MASK (DEBUGGER_INTERNAL_OPTION_THREAD_BACKTRACE)
567
568#define __STRINGIFY(x) #x
569#define LINE_NUMBER(x) __STRINGIFY(x)
570#ifdef __FILE_NAME__
571#define PANIC_LOCATION __FILE_NAME__ ":" LINE_NUMBER(__LINE__)
572#else
573#define PANIC_LOCATION __FILE__ ":" LINE_NUMBER(__LINE__)
574#define __FILE_NAME__ __FILE__
575#endif
576
577/* Macros for XNU platform stalls
578 * The "location" macros specify points where we can stall or panic
579 * The "action" macros specify the action to take at these points.
580 * The default action is to stall. */
581#if (DEVELOPMENT || DEBUG)
582#define PLATFORM_STALL_XNU_DISABLE (0)
583#define PLATFORM_STALL_XNU_LOCATION_ARM_INIT (0x1ULL << 0)
584#define PLATFORM_STALL_XNU_LOCATION_KERNEL_BOOTSTRAP (0x1ULL << 1)
585#define PLATFORM_STALL_XNU_LOCATION_BSD_INIT (0x1ULL << 2)
586#define PLATFORM_STALL_XNU_ACTION_PANIC (0x1ULL << 7)
587
588extern uint64_t xnu_platform_stall_value;
589
590void platform_stall_panic_or_spin(uint32_t req);
591
592#endif
593
594#if XNU_KERNEL_PRIVATE
595#define panic(ex, ...) ({ \
596 __asm__("" ::: "memory"); \
597 (panic)(ex " @%s:%d", ## __VA_ARGS__, __FILE_NAME__, __LINE__); \
598})
599#else
600#define panic(ex, ...) ({ \
601 __asm__("" ::: "memory"); \
602 (panic)(#ex " @%s:%d", ## __VA_ARGS__, __FILE_NAME__, __LINE__); \
603})
604#endif
605#define panic_plain(ex, ...) (panic)(ex, ## __VA_ARGS__)
606
607struct task;
608struct thread;
609struct proc;
610
611__abortlike __printflike(4, 5)
612void panic_with_options(unsigned int reason, void *ctx,
613 uint64_t debugger_options_mask, const char *str, ...);
614void Debugger(const char * message);
615void populate_model_name(char *);
616
617boolean_t panic_validate_ptr(void *ptr, vm_size_t size, const char *what);
618
619boolean_t panic_get_thread_proc_task(struct thread *thread, struct task **task, struct proc **proc);
620
621#define PANIC_VALIDATE_PTR(expr) \
622 panic_validate_ptr(expr, sizeof(*(expr)), #expr)
623
624
625#if defined(__arm__) || defined(__arm64__)
626/* Note that producer_name and buf should never be de-allocated as we reference these during panic */
627void register_additional_panic_data_buffer(const char *producer_name, void *buf, int len);
628#endif
629
630unsigned panic_active(void);
631
632#endif /* KERNEL_PRIVATE */
633
634#if XNU_KERNEL_PRIVATE
635
636#if defined (__x86_64__)
637struct thread;
638
639__abortlike __printflike(5, 6)
640void panic_with_thread_context(unsigned int reason, void *ctx,
641 uint64_t debugger_options_mask, struct thread* th, const char *str, ...);
642#endif
643
644/* limit the max size to a reasonable length */
645#define ADDITIONAL_PANIC_DATA_BUFFER_MAX_LEN 64
646
647struct additional_panic_data_buffer {
648 const char *producer_name;
649 void *buf;
650 int len;
651};
652
653extern struct additional_panic_data_buffer *panic_data_buffers;
654
655boolean_t oslog_is_safe(void);
656boolean_t debug_mode_active(void);
657boolean_t stackshot_active(void);
658void panic_stackshot_reset_state(void);
659
660/*
661 * @function stack_snapshot_from_kernel
662 *
663 * @abstract Stackshot function for kernel consumers who have their own buffer.
664 *
665 * @param pid the PID to be traced or -1 for the whole system
666 * @param buf a pointer to the buffer where the stackshot should be written
667 * @param size the size of the buffer
668 * @param flags flags to be passed to the stackshot
669 * @param delta_since_timestamp start time for delta period
670 * @param pagetable_mask if pagetable dumping is set in flags, the mask of page table levels to dump
671 * @bytes_traced a pointer to be filled with the length of the stackshot
672 *
673 */
674kern_return_t
675stack_snapshot_from_kernel(int pid, void *buf, uint32_t size, uint64_t flags,
676 uint64_t delta_since_timestamp, uint32_t pagetable_mask, unsigned *bytes_traced);
677
678/*
679 * Returns whether on device corefiles are enabled based on the build
680 * and boot configuration.
681 */
682boolean_t on_device_corefile_enabled(void);
683
684/*
685 * Returns whether panic stackshot to disk is enabled based on the build
686 * and boot configuration.
687 */
688boolean_t panic_stackshot_to_disk_enabled(void);
689
690#if defined(__x86_64__)
691extern char debug_buf[];
692extern boolean_t coprocessor_paniclog_flush;
693extern boolean_t extended_debug_log_enabled;
694#endif /* defined(__x86_64__) */
695
696extern char *debug_buf_base;
697
698#if defined(XNU_TARGET_OS_BRIDGE)
699extern uint64_t macos_panic_base;
700extern unsigned int macos_panic_size;
701#endif /* defined(XNU_TARGET_OS_BRIDGE) */
702
703extern char kernel_uuid_string[];
704extern char panic_disk_error_description[];
705extern size_t panic_disk_error_description_size;
706
707extern unsigned char *kernel_uuid;
708extern unsigned int debug_boot_arg;
709extern int verbose_panic_flow_logging;
710
711extern boolean_t kernelcache_uuid_valid;
712extern uuid_t kernelcache_uuid;
713extern uuid_string_t kernelcache_uuid_string;
714
715extern boolean_t pageablekc_uuid_valid;
716extern uuid_t pageablekc_uuid;
717extern uuid_string_t pageablekc_uuid_string;
718
719extern boolean_t auxkc_uuid_valid;
720extern uuid_t auxkc_uuid;
721extern uuid_string_t auxkc_uuid_string;
722
723extern boolean_t doprnt_hide_pointers;
724
725extern unsigned int halt_in_debugger; /* pending halt in debugger after boot */
726extern unsigned int current_debugger;
727#define NO_CUR_DB 0x0
728#define KDP_CUR_DB 0x1
729
730extern unsigned int active_debugger;
731extern unsigned int kernel_debugger_entry_count;
732
733extern unsigned int panicDebugging;
734
735extern const char *debugger_panic_str;
736
737extern char *debug_buf_ptr;
738extern unsigned int debug_buf_size;
739
740extern void debug_log_init(void);
741extern void debug_putc(char);
742extern boolean_t debug_is_current_cpu_in_panic_state(void);
743
744/*
745 * Initialize the physical carveout requested with the `phys_carveout_mb`
746 * boot-arg. This should only be called at kernel startup, when physically
747 * contiguous pages are plentiful.
748 */
749extern void phys_carveout_init(void);
750
751/*
752 * Check whether a kernel virtual address points within the physical carveout.
753 */
754extern boolean_t debug_is_in_phys_carveout(vm_map_offset_t va);
755
756/*
757 * Check whether the physical carveout should be included in a coredump.
758 */
759extern boolean_t debug_can_coredump_phys_carveout(void);
760
761extern vm_offset_t phys_carveout;
762extern uintptr_t phys_carveout_pa;
763extern size_t phys_carveout_size;
764
765extern boolean_t kernel_debugging_restricted(void);
766
767#if defined (__x86_64__)
768extern void extended_debug_log_init(void);
769
770int packA(char *inbuf, uint32_t length, uint32_t buflen);
771void unpackA(char *inbuf, uint32_t length);
772
773#define PANIC_STACKSHOT_BUFSIZE (1024 * 1024)
774
775extern uintptr_t panic_stackshot_buf;
776extern size_t panic_stackshot_buf_len;
777
778extern size_t panic_stackshot_len;
779#endif /* defined (__x86_64__) */
780
781void SavePanicInfo(const char *message, void *panic_data, uint64_t panic_options);
782void paniclog_flush(void);
783void panic_display_zalloc(void); /* in zalloc.c */
784void panic_display_kernel_aslr(void);
785void panic_display_hibb(void);
786void panic_display_model_name(void);
787void panic_display_kernel_uuid(void);
788void panic_display_process_name(void);
789void panic_print_symbol_name(vm_address_t search);
790#if CONFIG_ECC_LOGGING
791void panic_display_ecc_errors(void);
792#endif /* CONFIG_ECC_LOGGING */
793void panic_display_compressor_stats(void);
794
795/*
796 * @var not_in_kdp
797 *
798 * @abstract True if we're in normal kernel operation, False if we're in a
799 * single-core debugger context.
800 */
801extern unsigned int not_in_kdp;
802
803#define DEBUGGER_NO_CPU -1
804
805typedef enum {
806 DBOP_NONE,
807 DBOP_STACKSHOT,
808 DBOP_RESET_PGO_COUNTERS,
809 DBOP_PANIC,
810 DBOP_DEBUGGER,
811 DBOP_BREAKPOINT,
812} debugger_op;
813
814__printflike(3, 0)
815kern_return_t DebuggerTrapWithState(debugger_op db_op, const char *db_message, const char *db_panic_str, va_list *db_panic_args,
816 uint64_t db_panic_options, void *db_panic_data_ptr, boolean_t db_proceed_on_sync_failure, unsigned long db_panic_caller);
817void handle_debugger_trap(unsigned int exception, unsigned int code, unsigned int subcode, void *state);
818
819void DebuggerWithContext(unsigned int reason, void *ctx, const char *message, uint64_t debugger_options_mask, unsigned long debugger_caller);
820
821const char *sysctl_debug_get_preoslog(size_t *size);
822void sysctl_debug_free_preoslog(void);
823
824#if DEBUG || DEVELOPMENT
825/* leak pointer scan definitions */
826
827enum{
828 kInstanceFlagAddress = 0x01UL,
829 kInstanceFlagReferenced = 0x02UL,
830 kInstanceFlags = 0x03UL
831};
832
833#define INSTANCE_GET(x) ((x) & ~kInstanceFlags)
834#define INSTANCE_PUT(x) ((x) ^ ~kInstanceFlags)
835
836typedef void (^leak_site_proc)(uint32_t siteCount, uint32_t elem_size, uint32_t btref);
837
838extern kern_return_t
839zone_leaks(const char * zoneName, uint32_t nameLen, leak_site_proc proc);
840
841extern void
842zone_leaks_scan(uintptr_t * instances, uint32_t count, uint32_t zoneSize, uint32_t * found);
843
844/* panic testing hooks */
845
846#define PANIC_TEST_CASE_DISABLED 0
847#define PANIC_TEST_CASE_RECURPANIC_ENTRY 0x2 // recursive panic at panic entrypoint, before panic data structures are initialized
848#define PANIC_TEST_CASE_RECURPANIC_PRELOG 0x4 // recursive panic prior to paniclog being written
849#define PANIC_TEST_CASE_RECURPANIC_POSTLOG 0x8 // recursive panic after paniclog has been written
850#define PANIC_TEST_CASE_RECURPANIC_POSTCORE 0x10 // recursive panic after corefile has been written
851#define PANIC_TEST_CASE_COREFILE_IO_ERR 0x20 // single IO error in the corefile write path
852extern unsigned int panic_test_case;
853
854#define PANIC_TEST_FAILURE_MODE_BADPTR 0x1 // dereference a bad pointer
855#define PANIC_TEST_FAILURE_MODE_SPIN 0x2 // spin until watchdog kicks in
856#define PANIC_TEST_FAILURE_MODE_PANIC 0x4 // explicit panic
857extern unsigned int panic_test_failure_mode; // panic failure mode
858
859extern unsigned int panic_test_action_count; // test parameter, depends on test case
860
861#endif /* DEBUG || DEVELOPMENT */
862
863/*
864 * A callback that reads or writes data from a given offset into the corefile. It is understood that this
865 * callback should only be used from within the context where it is given. It should never be stored and
866 * reused later on.
867 */
868typedef kern_return_t (*IOCoreFileAccessCallback)(void *context, boolean_t write, uint64_t offset, int length, void *buffer);
869
870/*
871 * A callback that receives temporary file-system access to the kernel corefile
872 *
873 * Parameters:
874 * - access: A function to call for reading/writing the kernel corefile.
875 * - access_context: The context that should be passed to the 'access' function.
876 * - recipient_context: The recipient-specific context. Can be anything.
877 */
878typedef kern_return_t (*IOCoreFileAccessRecipient)(IOCoreFileAccessCallback access, void *access_context, void *recipient_context);
879
880/*
881 * Provides safe and temporary file-system access to the kernel corefile to the given recipient callback.
882 * It does so by opening the kernel corefile, then calling the 'recipient' callback, passing it an IOCoreFileAccessCallback
883 * function that it can use to read/write data, then closing the kernel corefile as soon as the recipient returns.
884 *
885 * Parameters:
886 * - recipient: A function to call, providing it access to the kernel corefile.
887 * - recipient_context: Recipient-specific context. Can be anything.
888 */
889extern kern_return_t
890IOProvideCoreFileAccess(IOCoreFileAccessRecipient recipient, void *recipient_context);
891
892struct kdp_core_encryption_key_descriptor {
893 uint64_t kcekd_format;
894 uint16_t kcekd_size;
895 void * kcekd_key;
896};
897
898/*
899 * Registers a new kernel (and co-processor) coredump encryption key. The key format should be one of the
900 * supported "next" key formats in mach_debug_types.h. The recipient context pointer should point to a kdp_core_encryption_key_descriptor
901 * structure.
902 *
903 * Note that the given key pointer should be allocated using `kmem_alloc(kernel_map, <pointer>, <size>, VM_KERN_MEMORY_DIAG)`
904 *
905 * Note that upon successful completion, this function will adopt the given public key pointer
906 * and the caller should NOT release it.
907 */
908kern_return_t kdp_core_handle_new_encryption_key(IOCoreFileAccessCallback access_data, void *access_context, void *recipient_context);
909
910/*
911 * Enum of allowed values for the 'lbr_support' boot-arg
912 */
913typedef enum {
914 LBR_ENABLED_NONE,
915 LBR_ENABLED_USERMODE,
916 LBR_ENABLED_KERNELMODE,
917 LBR_ENABLED_ALLMODES
918} lbr_modes_t;
919
920extern lbr_modes_t last_branch_enabled_modes;
921
922/* Exclaves stackshot tests support */
923#define STACKSHOT_EXCLAVES_TESTING ((DEVELOPMENT || DEBUG) && CONFIG_EXCLAVES)
924
925#endif /* XNU_KERNEL_PRIVATE */
926
927__END_DECLS
928
929#endif /* _KERN_DEBUG_H_ */
930