Loading...
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
/*
 * Copyright (c) 2000-2019 Apple Inc. All rights reserved.
 *
 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
 *
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. The rights granted to you under the License
 * may not be used to create, or enable the creation or redistribution of,
 * unlawful or unlicensed copies of an Apple operating system, or to
 * circumvent, violate, or enable the circumvention or violation of, any
 * terms of an Apple operating system software license agreement.
 *
 * Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this file.
 *
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 *
 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
 */

#ifndef _KERN_DEBUG_H_
#define _KERN_DEBUG_H_

#include <kern/kcdata.h>

#include <sys/cdefs.h>
#include <stdint.h>
#include <stdarg.h>
#include <uuid/uuid.h>
#include <mach/boolean.h>
#include <mach/kern_return.h>
#include <mach/vm_types.h>

#ifndef XNU_KERNEL_PRIVATE
#include <TargetConditionals.h>
#endif

__BEGIN_DECLS

#ifdef __APPLE_API_PRIVATE
#ifdef __APPLE_API_UNSTABLE

struct thread_snapshot {
	uint32_t                snapshot_magic;
	uint32_t                nkern_frames;
	uint32_t                nuser_frames;
	uint64_t                wait_event;
	uint64_t                continuation;
	uint64_t                thread_id;
	uint64_t                user_time;
	uint64_t                system_time;
	int32_t                 state;
	int32_t                 priority;    /*	static priority */
	int32_t                 sched_pri;   /* scheduled (current) priority */
	int32_t                 sched_flags; /* scheduler flags */
	char                    ss_flags;
	char                    ts_qos;      /* effective qos */
	char                    ts_rqos;     /* requested qos */
	char                    ts_rqos_override; /* requested qos override */
	char                    io_tier;
	/*
	 * In microstackshots, the low two bytes are the start of the first async
	 * frame in the thread's user space call stack.  If the call stack lacks
	 * async stack frames, it's `UINT16_MAX`.
	 */
	char                    _reserved[3]; /* pad for 4 byte alignement packing */

	/*
	 * I/O Statistics
	 * XXX: These fields must be together
	 */
	uint64_t                disk_reads_count;
	uint64_t                disk_reads_size;
	uint64_t                disk_writes_count;
	uint64_t                disk_writes_size;
	uint64_t                io_priority_count[STACKSHOT_IO_NUM_PRIORITIES];
	uint64_t                io_priority_size[STACKSHOT_IO_NUM_PRIORITIES];
	uint64_t                paging_count;
	uint64_t                paging_size;
	uint64_t                non_paging_count;
	uint64_t                non_paging_size;
	uint64_t                data_count;
	uint64_t                data_size;
	uint64_t                metadata_count;
	uint64_t                metadata_size;
	/* XXX: I/O Statistics end */

	uint64_t                voucher_identifier; /* obfuscated voucher identifier */
	uint64_t                total_syscalls;
	char                    pth_name[STACKSHOT_MAX_THREAD_NAME_SIZE];
} __attribute__((packed));

/* old, non kcdata format */
struct task_snapshot {
	uint32_t snapshot_magic;
	int32_t pid;
	uint64_t                uniqueid;
	uint64_t                user_time_in_terminated_threads;
	uint64_t                system_time_in_terminated_threads;
	uint8_t                 shared_cache_identifier[16];
	uint64_t                shared_cache_slide;
	uint32_t                nloadinfos;
	int                     suspend_count;
	int                     task_size;      /* pages */
	int                     faults;         /* number of page faults */
	int                     pageins;        /* number of actual pageins */
	int                     cow_faults;     /* number of copy-on-write faults */
	uint32_t                ss_flags;
	/*
	 * In microstackshots, `p_start_sec` is actually the resource coalition ID.
	 */
	uint64_t                p_start_sec;    /* from the bsd proc struct */
	uint64_t                p_start_usec;   /* from the bsd proc struct */

	/*
	 * We restrict ourselves to a statically defined
	 * (current as of 2009) length for the
	 * p_comm string, due to scoping issues (osfmk/bsd and user/kernel
	 * binary compatibility).
	 */
	char                    p_comm[17];
	uint32_t                was_throttled;
	uint32_t                did_throttle;
	uint32_t                latency_qos;
	/*
	 * I/O Statistics
	 * XXX: These fields must be together.
	 */
	uint64_t                disk_reads_count;
	uint64_t                disk_reads_size;
	uint64_t                disk_writes_count;
	uint64_t                disk_writes_size;
	uint64_t                io_priority_count[STACKSHOT_IO_NUM_PRIORITIES];
	uint64_t                io_priority_size[STACKSHOT_IO_NUM_PRIORITIES];
	uint64_t                paging_count;
	uint64_t                paging_size;
	uint64_t                non_paging_count;
	uint64_t                non_paging_size;
	uint64_t                data_count;
	uint64_t                data_size;
	uint64_t                metadata_count;
	uint64_t                metadata_size;
	/* XXX: I/O Statistics end */

	uint32_t                donating_pid_count;
} __attribute__ ((packed));



struct micro_snapshot {
	uint32_t                snapshot_magic;
	uint32_t                ms_cpu;  /* cpu number this snapshot was recorded on */
	uint64_t                ms_time; /* time at sample (seconds) */
	uint64_t                ms_time_microsecs;
	uint8_t                 ms_flags;
	uint16_t                ms_opaque_flags;        /* managed by external entity, e.g. fdrmicrod */
} __attribute__ ((packed));


/*
 * mirrors the dyld_cache_header struct defined in dyld_cache_format.h from dyld source code
 */
struct _dyld_cache_header {
	char        magic[16];                          // e.g. "dyld_v0    i386"
	uint32_t    mappingOffset;      // file offset to first dyld_cache_mapping_info
	uint32_t    mappingCount;       // number of dyld_cache_mapping_info entries
	uint32_t    imagesOffset;       // file offset to first dyld_cache_image_info
	uint32_t    imagesCount;        // number of dyld_cache_image_info entries
	uint64_t    dyldBaseAddress;    // base address of dyld when cache was built
	uint64_t    codeSignatureOffset;// file offset of code signature blob
	uint64_t    codeSignatureSize;  // size of code signature blob (zero means to end of file)
	uint64_t    slideInfoOffset;    // file offset of kernel slid info
	uint64_t    slideInfoSize;      // size of kernel slid info
	uint64_t    localSymbolsOffset; // file offset of where local symbols are stored
	uint64_t    localSymbolsSize;   // size of local symbols information
	uint8_t     uuid[16];           // unique value for each shared cache file
	uint64_t    cacheType;          // 0 for development, 1 for production
	uint32_t    branchPoolsOffset;  // file offset to table of uint64_t pool addresses
	uint32_t    branchPoolsCount;   // number of uint64_t entries
	uint64_t    accelerateInfoAddr; // (unslid) address of optimization info
	uint64_t    accelerateInfoSize; // size of optimization info
	uint64_t    imagesTextOffset;   // file offset to first dyld_cache_image_text_info
	uint64_t    imagesTextCount;    // number of dyld_cache_image_text_info entries
	uint64_t    dylibsImageGroupAddr;// (unslid) address of ImageGroup for dylibs in this cache
	uint64_t    dylibsImageGroupSize;// size of ImageGroup for dylibs in this cache
	uint64_t    otherImageGroupAddr;// (unslid) address of ImageGroup for other OS dylibs
	uint64_t    otherImageGroupSize;// size of oImageGroup for other OS dylibs
	uint64_t    progClosuresAddr;   // (unslid) address of list of program launch closures
	uint64_t    progClosuresSize;   // size of list of program launch closures
	uint64_t    progClosuresTrieAddr;// (unslid) address of trie of indexes into program launch closures
	uint64_t    progClosuresTrieSize;// size of trie of indexes into program launch closures
	uint32_t    platform;           // platform number (macOS=1, etc)
	uint32_t    formatVersion        : 8,// dyld3::closure::kFormatVersion
	    dylibsExpectedOnDisk : 1,      // dyld should expect the dylib exists on disk and to compare inode/mtime to see if cache is valid
	    simulator            : 1,      // for simulator of specified platform
	    locallyBuiltCache    : 1,      // 0 for B&I built cache, 1 for locally built cache
	    padding              : 21;     // TBD
};

/*
 * mirrors the dyld_cache_image_text_info struct defined in dyld_cache_format.h from dyld source code
 */
struct _dyld_cache_image_text_info {
	uuid_t      uuid;
	uint64_t    loadAddress;        // unslid address of start of __TEXT
	uint32_t    textSegmentSize;
	uint32_t    pathOffset;         // offset from start of cache file
};


enum micro_snapshot_flags {
	kInterruptRecord        = 0x1,
	kTimerArmingRecord      = 0x2,
	kUserMode               = 0x4, /* interrupted usermode, or armed by usermode */
	kIORecord               = 0x8,
	kPMIRecord              = 0x10,
	kMACFRecord             = 0x20, /* armed by MACF policy */
};

/*
 * Flags used in the following assortment of snapshots.
 */
enum generic_snapshot_flags {
	kUser64_p               = 0x1, /* Userspace uses 64 bit pointers */
	kKernel64_p             = 0x2  /* The kernel uses 64 bit pointers */
};

#define VM_PRESSURE_TIME_WINDOW 5 /* seconds */

__options_decl(stackshot_flags_t, uint64_t, {
	STACKSHOT_GET_DQ                           = 0x01,
	STACKSHOT_SAVE_LOADINFO                    = 0x02,
	STACKSHOT_GET_GLOBAL_MEM_STATS             = 0x04,
	STACKSHOT_SAVE_KEXT_LOADINFO               = 0x08,
	/*
	 * 0x10, 0x20, 0x40 and 0x80 are reserved.
	 *
	 * See microstackshot_flags_t whose members used to be part of this
	 * declaration.
	 */
	STACKSHOT_ACTIVE_KERNEL_THREADS_ONLY       = 0x100,
	STACKSHOT_GET_BOOT_PROFILE                 = 0x200,
	STACKSHOT_DO_COMPRESS                      = 0x400,
	STACKSHOT_SAVE_IMP_DONATION_PIDS           = 0x2000,
	STACKSHOT_SAVE_IN_KERNEL_BUFFER            = 0x4000,
	STACKSHOT_RETRIEVE_EXISTING_BUFFER         = 0x8000,
	STACKSHOT_KCDATA_FORMAT                    = 0x10000,
	STACKSHOT_ENABLE_BT_FAULTING               = 0x20000,
	STACKSHOT_COLLECT_DELTA_SNAPSHOT           = 0x40000,
	/* Include the layout of the system shared cache */
	STACKSHOT_COLLECT_SHAREDCACHE_LAYOUT       = 0x80000,
	/*
	 * Kernel consumers of stackshot (via stack_snapshot_from_kernel) can ask
	 * that we try to take the stackshot lock, and fail if we don't get it.
	 */
	STACKSHOT_TRYLOCK                          = 0x100000,
	STACKSHOT_ENABLE_UUID_FAULTING             = 0x200000,
	STACKSHOT_FROM_PANIC                       = 0x400000,
	STACKSHOT_NO_IO_STATS                      = 0x800000,
	/* Report owners of and pointers to kernel objects that threads are blocked on */
	STACKSHOT_THREAD_WAITINFO                  = 0x1000000,
	STACKSHOT_THREAD_GROUP                     = 0x2000000,
	STACKSHOT_SAVE_JETSAM_COALITIONS           = 0x4000000,
	STACKSHOT_INSTRS_CYCLES                    = 0x8000000,
	STACKSHOT_ASID                             = 0x10000000,
	STACKSHOT_PAGE_TABLES                      = 0x20000000,
	STACKSHOT_DISABLE_LATENCY_INFO             = 0x40000000,
	STACKSHOT_SAVE_DYLD_COMPACTINFO            = 0x80000000,
	STACKSHOT_INCLUDE_DRIVER_THREADS_IN_KERNEL = 0x100000000,
}); // Note: Add any new flags to kcdata.py (stackshot_in_flags)

__options_decl(microstackshot_flags_t, uint32_t, {
	STACKSHOT_GET_MICROSTACKSHOT               = 0x10,
	STACKSHOT_GLOBAL_MICROSTACKSHOT_ENABLE     = 0x20,
	STACKSHOT_GLOBAL_MICROSTACKSHOT_DISABLE    = 0x40,
	STACKSHOT_SET_MICROSTACKSHOT_MARK          = 0x80,
});

#define STACKSHOT_THREAD_SNAPSHOT_MAGIC     0xfeedface
#define STACKSHOT_TASK_SNAPSHOT_MAGIC       0xdecafbad
#define STACKSHOT_MEM_AND_IO_SNAPSHOT_MAGIC 0xbfcabcde
#define STACKSHOT_MICRO_SNAPSHOT_MAGIC      0x31c54011

#define STACKSHOT_PAGETABLES_MASK_ALL           ~0

#define KF_SERIAL_OVRD (0x2)
#define KF_PMAPV_OVRD (0x4)
#define KF_MATV_OVRD (0x8)
#define KF_STACKSHOT_OVRD (0x10)
#define KF_COMPRSV_OVRD (0x20)
#define KF_INTERRUPT_MASKED_DEBUG_OVRD (0x40)
#define KF_TRAPTRACE_OVRD (0x80)
#define KF_IOTRACE_OVRD (0x100)
#define KF_INTERRUPT_MASKED_DEBUG_STACKSHOT_OVRD (0x200)
#define KF_SCHED_HYGIENE_DEBUG_PMC_OVRD (0x400)
#define KF_RW_LOCK_DEBUG_OVRD (0x800)
#define KF_MADVISE_FREE_DEBUG_OVRD (0x1000)
#define KF_DISABLE_FP_POPC_ON_PGFLT (0x2000)
#define KF_IO_TIMEOUT_OVRD (0x8000)

boolean_t kern_feature_override(uint32_t fmask);

__options_decl(eph_panic_flags_t, uint64_t, {
	EMBEDDED_PANIC_HEADER_FLAG_COREDUMP_COMPLETE              = 0x01,                               /* INFO: coredump completed */
	EMBEDDED_PANIC_HEADER_FLAG_STACKSHOT_SUCCEEDED            = 0x02,                               /* INFO: stackshot completed */
	EMBEDDED_PANIC_HEADER_FLAG_STACKSHOT_FAILED_DEBUGGERSYNC  = 0x04,                               /* ERROR: stackshot failed to sync with external debugger */
	EMBEDDED_PANIC_HEADER_FLAG_STACKSHOT_FAILED_ERROR         = 0x08,                               /* ERROR: stackshot failed */
	EMBEDDED_PANIC_HEADER_FLAG_STACKSHOT_FAILED_INCOMPLETE    = 0x10,                               /* ERROR: stackshot is partially complete */
	EMBEDDED_PANIC_HEADER_FLAG_STACKSHOT_FAILED_NESTED        = 0x20,                               /* ERROR: stackshot caused a nested panic */
	EMBEDDED_PANIC_HEADER_FLAG_NESTED_PANIC                   = 0x40,                               /* ERROR: panic handler encountered a panic */
	EMBEDDED_PANIC_HEADER_FLAG_BUTTON_RESET_PANIC             = 0x80,                               /* INFO: force-reset panic: user held power button to force shutdown */
	EMBEDDED_PANIC_HEADER_FLAG_COPROC_INITIATED_PANIC         = 0x100,                              /* INFO: panic was triggered by a companion processor (not Xnu) */
	EMBEDDED_PANIC_HEADER_FLAG_COREDUMP_FAILED                = 0x200,                              /* ERROR: coredump failed to complete */
	EMBEDDED_PANIC_HEADER_FLAG_COMPRESS_FAILED                = 0x400,                              /* ERROR: stackshot failed to compress */
	EMBEDDED_PANIC_HEADER_FLAG_STACKSHOT_DATA_COMPRESSED      = 0x800,                              /* INFO: stackshot data is compressed */
	EMBEDDED_PANIC_HEADER_FLAG_ENCRYPTED_COREDUMP_SKIPPED     = 0x1000,                             /* ERROR: coredump policy requires encryption, but encryptions is not initialized or available */
	EMBEDDED_PANIC_HEADER_FLAG_KERNEL_COREDUMP_SKIPPED_EXCLUDE_REGIONS_UNAVAILABLE   = 0x2000,      /* ERROR: coredump region exclusion list is not available */
	EMBEDDED_PANIC_HEADER_FLAG_COREFILE_UNLINKED              = 0x4000,                             /* ERROR: coredump output file is not linked */
	EMBEDDED_PANIC_HEADER_FLAG_INCOHERENT_PANICLOG            = 0x8000                              /* ERROR: paniclog integrity check failed (a warning to consumer code i.e. DumpPanic) */
});

#define EMBEDDED_PANIC_HEADER_CURRENT_VERSION 4
#define EMBEDDED_PANIC_MAGIC 0x46554E4B /* FUNK */
#define EMBEDDED_PANIC_HEADER_OSVERSION_LEN 32

/*
 * Any updates to this header should be also updated in astris as it can not
 * grab this header from the SDK.
 *
 * NOTE: DO NOT REMOVE OR CHANGE THE MEANING OF ANY FIELDS FROM THIS STRUCTURE.
 *       Any modifications should add new fields at the end, bump the version number
 *       and be done alongside astris and DumpPanic changes.
 */
struct embedded_panic_header {
	uint32_t eph_magic;                /* EMBEDDED_PANIC_MAGIC if valid */
	uint32_t eph_crc;                  /* CRC of everything following the ph_crc in the header and the contents */
	uint32_t eph_version;              /* embedded_panic_header version */
	eph_panic_flags_t eph_panic_flags; /* Flags indicating any state or relevant details */
	uint32_t eph_panic_log_offset;     /* Offset of the beginning of the panic log from the beginning of the header */
	uint32_t eph_panic_log_len;        /* length of the panic log */
	uint32_t eph_stackshot_offset;     /* Offset of the beginning of the panic stackshot from the beginning of the header */
	uint32_t eph_stackshot_len;        /* length of the panic stackshot (0 if not valid ) */
	uint32_t eph_other_log_offset;     /* Offset of the other log (any logging subsequent to the stackshot) from the beginning of the header */
	uint32_t eph_other_log_len;        /* length of the other log */
	union {
		struct {
			uint64_t eph_x86_power_state:8,
			    eph_x86_efi_boot_state:8,
			    eph_x86_system_state:8,
			    eph_x86_unused_bits:40;
		}; // anonymous struct to group the bitfields together.
		uint64_t eph_x86_do_not_use; /* Used for offsetof/sizeof when parsing header */
	};
	char eph_os_version[EMBEDDED_PANIC_HEADER_OSVERSION_LEN];
	char eph_macos_version[EMBEDDED_PANIC_HEADER_OSVERSION_LEN];
	uuid_string_t eph_bootsessionuuid_string;                      /* boot session UUID */
	uint64_t eph_roots_installed;                                  /* bitmap indicating which roots are installed on this system */
} __attribute__((packed));


#define MACOS_PANIC_HEADER_CURRENT_VERSION 3
#define MACOS_PANIC_MAGIC 0x44454544 /* DEED */

__options_decl(mph_panic_flags_t, uint64_t, {
	MACOS_PANIC_HEADER_FLAG_NESTED_PANIC                   = 0x01,                                /* ERROR: panic handler encountered a panic */
	MACOS_PANIC_HEADER_FLAG_COPROC_INITIATED_PANIC         = 0x02,                                /* INFO: panic was triggered by a companion processor (not Xnu) */
	MACOS_PANIC_HEADER_FLAG_STACKSHOT_SUCCEEDED            = 0x04,                                /* INFO: stackshot completed */
	MACOS_PANIC_HEADER_FLAG_STACKSHOT_DATA_COMPRESSED      = 0x08,                                /* INFO: stackshot data is compressed */
	MACOS_PANIC_HEADER_FLAG_STACKSHOT_FAILED_DEBUGGERSYNC  = 0x10,                                /* ERROR: stackshot failed to sync with external debugger */
	MACOS_PANIC_HEADER_FLAG_STACKSHOT_FAILED_ERROR         = 0x20,                                /* ERROR: stackshot failed */
	MACOS_PANIC_HEADER_FLAG_STACKSHOT_FAILED_INCOMPLETE    = 0x40,                                /* ERROR: stackshot is partially complete */
	MACOS_PANIC_HEADER_FLAG_STACKSHOT_FAILED_NESTED        = 0x80,                                /* ERROR: stackshot caused a nested panic */
	MACOS_PANIC_HEADER_FLAG_COREDUMP_COMPLETE              = 0x100,                               /* INFO: coredump completed */
	MACOS_PANIC_HEADER_FLAG_COREDUMP_FAILED                = 0x200,                               /* ERROR: coredump failed to complete */
	MACOS_PANIC_HEADER_FLAG_STACKSHOT_KERNEL_ONLY          = 0x400,                               /* ERROR: stackshot contains only kernel data (e.g. due to space limitations) */
	MACOS_PANIC_HEADER_FLAG_STACKSHOT_FAILED_COMPRESS      = 0x800,                               /* ERROR: stackshot failed to compress */
	MACOS_PANIC_HEADER_FLAG_ENCRYPTED_COREDUMP_SKIPPED     = 0x1000,                              /* ERROR: coredump policy requires encryption, but encryptions is not initialized or available */
	MACOS_PANIC_HEADER_FLAG_KERNEL_COREDUMP_SKIPPED_EXCLUDE_REGIONS_UNAVAILABLE     = 0x2000,     /* ERROR: coredump region exclusion list is not available */
	MACOS_PANIC_HEADER_FLAG_COREFILE_UNLINKED              = 0x4000,                              /* ERROR: coredump output file is not linked */
	MACOS_PANIC_HEADER_FLAG_INCOHERENT_PANICLOG            = 0x8000                               /* ERROR: paniclog integrity check failed (a warning to consumer code i.e. DumpPanic) */
});

struct macos_panic_header {
	uint32_t mph_magic;                   /* MACOS_PANIC_MAGIC if valid */
	uint32_t mph_crc;                     /* CRC of everything following mph_crc in the header and the contents */
	uint32_t mph_version;                 /* macos_panic_header version */
	uint32_t mph_padding;                 /* unused */
	mph_panic_flags_t mph_panic_flags;    /* Flags indicating any state or relevant details */
	uint32_t mph_panic_log_offset;        /* Offset of the panic log from the beginning of the header */
	uint32_t mph_panic_log_len;           /* length of the panic log */
	uint32_t mph_stackshot_offset;        /* Offset of the panic stackshot from the beginning of the header */
	uint32_t mph_stackshot_len;           /* length of the panic stackshot */
	uint32_t mph_other_log_offset;        /* Offset of the other log (any logging subsequent to the stackshot) from the beginning of the header */
	uint32_t mph_other_log_len;           /* length of the other log */
	uint64_t mph_roots_installed;         /* bitmap indicating which roots are installed on this system */
	char     mph_data[];                  /* panic data -- DO NOT ACCESS THIS FIELD DIRECTLY. Use the offsets above relative to the beginning of the header */
} __attribute__((packed));

/*
 * Any change to the below structure should mirror the structure defined in MacEFIFirmware
 * (and vice versa)
 */

struct efi_aurr_panic_header {
	uint32_t efi_aurr_magic;
	uint32_t efi_aurr_crc;
	uint32_t efi_aurr_version;
	uint32_t efi_aurr_reset_cause;
	uint32_t efi_aurr_reset_log_offset;
	uint32_t efi_aurr_reset_log_len;
	char efi_aurr_panic_data[];
} __attribute__((packed));

/*
 * EXTENDED_/DEBUG_BUF_SIZE can't grow without updates to SMC and iBoot to store larger panic logs on co-processor systems
 */
#define EXTENDED_DEBUG_BUF_SIZE 0x0013ff80

#define EFI_AURR_PANIC_STRING_MAX_LEN 112
#define EFI_AURR_EXTENDED_LOG_SIZE (EXTENDED_DEBUG_BUF_SIZE - sizeof(struct efi_aurr_panic_header) - EFI_AURR_PANIC_STRING_MAX_LEN)

struct efi_aurr_extended_panic_log {
	char efi_aurr_extended_log_buf[EFI_AURR_EXTENDED_LOG_SIZE];
	uint32_t efi_aurr_log_tail; /* Circular buffer indices */
	uint32_t efi_aurr_log_head; /* ditto.. */
} __attribute__((packed));

#endif /* __APPLE_API_UNSTABLE */
#endif /* __APPLE_API_PRIVATE */

/*
 * If non-zero, this physical address had an ECC error that led to a panic.
 */
extern uint64_t ecc_panic_physical_address;

#ifdef KERNEL

__abortlike __printflike(1, 2)
extern void panic(const char *string, ...);

#endif /* KERNEL */

#ifdef KERNEL_PRIVATE
#if DEBUG
#ifndef DKPR
#define DKPR 1
#endif
#endif

#if DKPR
/*
 * For the DEBUG kernel, support the following:
 *	sysctl -w debug.kprint_syscall=<syscall_mask>
 *	sysctl -w debug.kprint_syscall_process=<p_comm>
 * <syscall_mask> should be an OR of the masks below
 * for UNIX, MACH, MDEP, or IPC. This debugging aid
 * assumes the task/process is locked/wired and will
 * not go away during evaluation. If no process is
 * specified, all processes will be traced
 */
extern int debug_kprint_syscall;
extern int debug_kprint_current_process(const char **namep);
#define DEBUG_KPRINT_SYSCALL_PREDICATE_INTERNAL(mask, namep)                    \
	( (debug_kprint_syscall & (mask)) && debug_kprint_current_process(namep) )
#define DEBUG_KPRINT_SYSCALL_MASK(mask, fmt, args...)   do {                    \
	        const char *dks_name = NULL;                                                                    \
	        if (DEBUG_KPRINT_SYSCALL_PREDICATE_INTERNAL(mask, &dks_name)) { \
	                kprintf("[%s%s%p]" fmt, dks_name ? dks_name : "",                       \
	                                dks_name ? "@" : "", current_thread(), args);                   \
	        }                                                                                                                               \
	} while (0)
#else /* !DEBUG */
#define DEBUG_KPRINT_SYSCALL_PREDICATE_INTERNAL(mask, namep) (0)
#define DEBUG_KPRINT_SYSCALL_MASK(mask, fmt, args...) do { } while (0) /* kprintf(fmt, args) */
#endif /* !DEBUG */

enum {
	DEBUG_KPRINT_SYSCALL_UNIX_MASK = 1 << 0,
	DEBUG_KPRINT_SYSCALL_MACH_MASK = 1 << 1,
	DEBUG_KPRINT_SYSCALL_MDEP_MASK = 1 << 2,
	DEBUG_KPRINT_SYSCALL_IPC_MASK  = 1 << 3
};

#define DEBUG_KPRINT_SYSCALL_PREDICATE(mask)                            \
	DEBUG_KPRINT_SYSCALL_PREDICATE_INTERNAL(mask, NULL)
#define DEBUG_KPRINT_SYSCALL_UNIX(fmt, args...)                         \
	DEBUG_KPRINT_SYSCALL_MASK(DEBUG_KPRINT_SYSCALL_UNIX_MASK,fmt,args)
#define DEBUG_KPRINT_SYSCALL_MACH(fmt, args...)                         \
	DEBUG_KPRINT_SYSCALL_MASK(DEBUG_KPRINT_SYSCALL_MACH_MASK,fmt,args)
#define DEBUG_KPRINT_SYSCALL_MDEP(fmt, args...)                         \
	DEBUG_KPRINT_SYSCALL_MASK(DEBUG_KPRINT_SYSCALL_MDEP_MASK,fmt,args)
#define DEBUG_KPRINT_SYSCALL_IPC(fmt, args...)                          \
	DEBUG_KPRINT_SYSCALL_MASK(DEBUG_KPRINT_SYSCALL_IPC_MASK,fmt,args)

/* Debug boot-args */
#define DB_HALT         0x1
//#define DB_PRT          0x2 -- obsolete
#define DB_NMI          0x4
#define DB_KPRT         0x8
#define DB_KDB          0x10
#define DB_ARP          0x40
#define DB_KDP_BP_DIS   0x80
//#define DB_LOG_PI_SCRN  0x100 -- obsolete
#define DB_KDP_GETC_ENA 0x200

#define DB_KERN_DUMP_ON_PANIC           0x400 /* Trigger core dump on panic*/
#define DB_KERN_DUMP_ON_NMI             0x800 /* Trigger core dump on NMI */
#define DB_DBG_POST_CORE                0x1000 /*Wait in debugger after NMI core */
#define DB_PANICLOG_DUMP                0x2000 /* Send paniclog on panic,not core*/
#define DB_REBOOT_POST_CORE             0x4000 /* Attempt to reboot after
	                                        * post-panic crashdump/paniclog
	                                        * dump.
	                                        */
#define DB_NMI_BTN_ENA          0x8000  /* Enable button to directly trigger NMI */
/* 0x10000 was DB_PRT_KDEBUG (kprintf kdebug events), feature removed */
#define DB_DISABLE_LOCAL_CORE   0x20000 /* ignore local kernel core dump support */
#define DB_DISABLE_GZIP_CORE    0x40000 /* don't gzip kernel core dumps */
#define DB_DISABLE_CROSS_PANIC  0x80000 /* x86 only - don't trigger cross panics. Only
	                                 * necessary to enable x86 kernel debugging on
	                                 * configs with a dev-fused co-processor running
	                                 * release bridgeOS.
	                                 */
#define DB_REBOOT_ALWAYS        0x100000 /* Don't wait for debugger connection */
#define DB_DISABLE_STACKSHOT_TO_DISK 0x200000 /* Disable writing stackshot to local disk */

/*
 * Values for a 64-bit mask that's passed to the debugger.
 */
#define DEBUGGER_OPTION_NONE                        0x0ULL
#define DEBUGGER_OPTION_PANICLOGANDREBOOT           0x1ULL /* capture a panic log and then reboot immediately */
#define DEBUGGER_OPTION_INITPROC_PANIC              0x20ULL
#define DEBUGGER_OPTION_COPROC_INITIATED_PANIC      0x40ULL /* panic initiated by a co-processor */
#define DEBUGGER_OPTION_SKIP_LOCAL_COREDUMP         0x80ULL /* don't try to save local coredumps for this panic */
#define DEBUGGER_OPTION_ATTEMPTCOREDUMPANDREBOOT    0x100ULL /* attempt to save coredump. always reboot */
#define DEBUGGER_INTERNAL_OPTION_THREAD_BACKTRACE   0x200ULL /* backtrace the specified thread in the paniclog (x86 only) */
#define DEBUGGER_OPTION_PRINT_CPU_USAGE_PANICLOG    0x400ULL /* print extra CPU usage data in the panic log */
#define DEBUGGER_OPTION_SKIP_PANICEND_CALLOUTS      0x800ULL /* (bridgeOS) skip the kPEPanicEnd callouts -- don't wait for x86 to finish sending panic data */

#define DEBUGGER_INTERNAL_OPTIONS_MASK              (DEBUGGER_INTERNAL_OPTION_THREAD_BACKTRACE)

#define __STRINGIFY(x) #x
#define LINE_NUMBER(x) __STRINGIFY(x)
#ifdef __FILE_NAME__
#define PANIC_LOCATION __FILE_NAME__ ":" LINE_NUMBER(__LINE__)
#else
#define PANIC_LOCATION __FILE__ ":" LINE_NUMBER(__LINE__)
#define __FILE_NAME__ __FILE__
#endif

/* Macros for XNU platform stalls
 *  The "location" macros specify points where we can stall or panic
 *  The "action" macros specify the action to take at these points.
 *  The default action is to stall. */
#if (DEVELOPMENT || DEBUG)
#define PLATFORM_STALL_XNU_DISABLE                              (0)
#define PLATFORM_STALL_XNU_LOCATION_ARM_INIT                    (0x1ULL << 0)
#define PLATFORM_STALL_XNU_LOCATION_KERNEL_BOOTSTRAP            (0x1ULL << 1)
#define PLATFORM_STALL_XNU_LOCATION_BSD_INIT                    (0x1ULL << 2)
#define PLATFORM_STALL_XNU_ACTION_PANIC                         (0x1ULL << 7)

extern uint64_t xnu_platform_stall_value;

void platform_stall_panic_or_spin(uint32_t req);

#endif

#if XNU_KERNEL_PRIVATE
#define panic(ex, ...)  ({ \
	__asm__("" ::: "memory"); \
	(panic)(ex " @%s:%d", ## __VA_ARGS__, __FILE_NAME__, __LINE__); \
})
#else
#define panic(ex, ...)  ({ \
	__asm__("" ::: "memory"); \
	(panic)(#ex " @%s:%d", ## __VA_ARGS__, __FILE_NAME__, __LINE__); \
})
#endif
#define panic_plain(ex, ...)  (panic)(ex, ## __VA_ARGS__)

struct task;
struct thread;
struct proc;

__abortlike __printflike(4, 5)
void panic_with_options(unsigned int reason, void *ctx,
    uint64_t debugger_options_mask, const char *str, ...);
void Debugger(const char * message);
void populate_model_name(char *);

boolean_t panic_validate_ptr(void *ptr, vm_size_t size, const char *what);

boolean_t panic_get_thread_proc_task(struct thread *thread, struct task **task, struct proc **proc);

#define PANIC_VALIDATE_PTR(expr) \
	panic_validate_ptr(expr, sizeof(*(expr)), #expr)


#if defined(__arm__) || defined(__arm64__)
/* Note that producer_name and buf should never be de-allocated as we reference these during panic */
void register_additional_panic_data_buffer(const char *producer_name, void *buf, int len);
#endif

unsigned panic_active(void);

#endif  /* KERNEL_PRIVATE */

#if XNU_KERNEL_PRIVATE

#if defined (__x86_64__)
struct thread;

__abortlike __printflike(5, 6)
void panic_with_thread_context(unsigned int reason, void *ctx,
    uint64_t debugger_options_mask, struct thread* th, const char *str, ...);
#endif

/* limit the max size to a reasonable length */
#define ADDITIONAL_PANIC_DATA_BUFFER_MAX_LEN 64

struct additional_panic_data_buffer {
	const char *producer_name;
	void *buf;
	int len;
};

extern struct additional_panic_data_buffer *panic_data_buffers;

boolean_t oslog_is_safe(void);
boolean_t debug_mode_active(void);
boolean_t stackshot_active(void);
void panic_stackshot_reset_state(void);

/*
 * @function stack_snapshot_from_kernel
 *
 * @abstract Stackshot function for kernel consumers who have their own buffer.
 *
 * @param pid     the PID to be traced or -1 for the whole system
 * @param buf     a pointer to the buffer where the stackshot should be written
 * @param size    the size of the buffer
 * @param flags   flags to be passed to the stackshot
 * @param delta_since_timestamp start time for delta period
 * @param pagetable_mask if pagetable dumping is set in flags, the mask of page table levels to dump
 * @bytes_traced  a pointer to be filled with the length of the stackshot
 *
 */
kern_return_t
stack_snapshot_from_kernel(int pid, void *buf, uint32_t size, uint64_t flags,
    uint64_t delta_since_timestamp, uint32_t pagetable_mask, unsigned *bytes_traced);

/*
 * Returns whether on device corefiles are enabled based on the build
 * and boot configuration.
 */
boolean_t on_device_corefile_enabled(void);

/*
 * Returns whether panic stackshot to disk is enabled based on the build
 * and boot configuration.
 */
boolean_t panic_stackshot_to_disk_enabled(void);

#if defined(__x86_64__)
extern char debug_buf[];
extern boolean_t coprocessor_paniclog_flush;
extern boolean_t extended_debug_log_enabled;
#endif /* defined(__x86_64__) */

extern char     *debug_buf_base;

#if defined(XNU_TARGET_OS_BRIDGE)
extern uint64_t macos_panic_base;
extern unsigned int macos_panic_size;
#endif /* defined(XNU_TARGET_OS_BRIDGE) */

extern char     kernel_uuid_string[];
extern char     panic_disk_error_description[];
extern size_t   panic_disk_error_description_size;

extern unsigned char    *kernel_uuid;
extern unsigned int     debug_boot_arg;
extern int     verbose_panic_flow_logging;

extern boolean_t kernelcache_uuid_valid;
extern uuid_t kernelcache_uuid;
extern uuid_string_t kernelcache_uuid_string;

extern boolean_t pageablekc_uuid_valid;
extern uuid_t pageablekc_uuid;
extern uuid_string_t pageablekc_uuid_string;

extern boolean_t auxkc_uuid_valid;
extern uuid_t auxkc_uuid;
extern uuid_string_t auxkc_uuid_string;

extern boolean_t        doprnt_hide_pointers;

extern unsigned int     halt_in_debugger; /* pending halt in debugger after boot */
extern unsigned int     current_debugger;
#define NO_CUR_DB       0x0
#define KDP_CUR_DB      0x1

extern unsigned int     active_debugger;
extern unsigned int     kernel_debugger_entry_count;

extern unsigned int     panicDebugging;

extern const char       *debugger_panic_str;

extern char *debug_buf_ptr;
extern unsigned int debug_buf_size;

extern void debug_log_init(void);
extern void debug_putc(char);
extern boolean_t debug_is_current_cpu_in_panic_state(void);

/*
 * Initialize the physical carveout requested with the `phys_carveout_mb`
 * boot-arg.  This should only be called at kernel startup, when physically
 * contiguous pages are plentiful.
 */
extern void phys_carveout_init(void);

/*
 * Check whether a kernel virtual address points within the physical carveout.
 */
extern boolean_t debug_is_in_phys_carveout(vm_map_offset_t va);

/*
 * Check whether the physical carveout should be included in a coredump.
 */
extern boolean_t debug_can_coredump_phys_carveout(void);

extern vm_offset_t phys_carveout;
extern uintptr_t phys_carveout_pa;
extern size_t phys_carveout_size;

extern boolean_t kernel_debugging_restricted(void);

#if defined (__x86_64__)
extern void extended_debug_log_init(void);

int     packA(char *inbuf, uint32_t length, uint32_t buflen);
void    unpackA(char *inbuf, uint32_t length);

#define PANIC_STACKSHOT_BUFSIZE (1024 * 1024)

extern uintptr_t panic_stackshot_buf;
extern size_t panic_stackshot_buf_len;

extern size_t panic_stackshot_len;
#endif /* defined (__x86_64__) */

void    SavePanicInfo(const char *message, void *panic_data, uint64_t panic_options);
void    paniclog_flush(void);
void    panic_display_zalloc(void); /* in zalloc.c */
void    panic_display_kernel_aslr(void);
void    panic_display_hibb(void);
void    panic_display_model_name(void);
void    panic_display_kernel_uuid(void);
void    panic_display_process_name(void);
void    panic_print_symbol_name(vm_address_t search);
#if CONFIG_ECC_LOGGING
void    panic_display_ecc_errors(void);
#endif /* CONFIG_ECC_LOGGING */
void panic_display_compressor_stats(void);

/*
 * @var not_in_kdp
 *
 * @abstract True if we're in normal kernel operation, False if we're in a
 * single-core debugger context.
 */
extern unsigned int not_in_kdp;

#define DEBUGGER_NO_CPU -1

typedef enum {
	DBOP_NONE,
	DBOP_STACKSHOT,
	DBOP_RESET_PGO_COUNTERS,
	DBOP_PANIC,
	DBOP_DEBUGGER,
	DBOP_BREAKPOINT,
} debugger_op;

__printflike(3, 0)
kern_return_t DebuggerTrapWithState(debugger_op db_op, const char *db_message, const char *db_panic_str, va_list *db_panic_args,
    uint64_t db_panic_options, void *db_panic_data_ptr, boolean_t db_proceed_on_sync_failure, unsigned long db_panic_caller);
void handle_debugger_trap(unsigned int exception, unsigned int code, unsigned int subcode, void *state);

void DebuggerWithContext(unsigned int reason, void *ctx, const char *message, uint64_t debugger_options_mask, unsigned long debugger_caller);

const char *sysctl_debug_get_preoslog(size_t *size);
void sysctl_debug_free_preoslog(void);

#if DEBUG || DEVELOPMENT
/* leak pointer scan definitions */

enum{
	kInstanceFlagAddress    = 0x01UL,
	kInstanceFlagReferenced = 0x02UL,
	kInstanceFlags          = 0x03UL
};

#define INSTANCE_GET(x) ((x) & ~kInstanceFlags)
#define INSTANCE_PUT(x) ((x) ^ ~kInstanceFlags)

typedef void (^leak_site_proc)(uint32_t siteCount, uint32_t elem_size, uint32_t btref);

extern kern_return_t
zone_leaks(const char * zoneName, uint32_t nameLen, leak_site_proc proc);

extern void
zone_leaks_scan(uintptr_t * instances, uint32_t count, uint32_t zoneSize, uint32_t * found);

/* panic testing hooks */

#define PANIC_TEST_CASE_DISABLED                    0
#define PANIC_TEST_CASE_RECURPANIC_ENTRY            0x2    // recursive panic at panic entrypoint, before panic data structures are initialized
#define PANIC_TEST_CASE_RECURPANIC_PRELOG           0x4    // recursive panic prior to paniclog being written
#define PANIC_TEST_CASE_RECURPANIC_POSTLOG          0x8    // recursive panic after paniclog has been written
#define PANIC_TEST_CASE_RECURPANIC_POSTCORE         0x10   // recursive panic after corefile has been written
#define PANIC_TEST_CASE_COREFILE_IO_ERR             0x20   // single IO error in the corefile write path
extern unsigned int    panic_test_case;

#define PANIC_TEST_FAILURE_MODE_BADPTR 0x1                 // dereference a bad pointer
#define PANIC_TEST_FAILURE_MODE_SPIN   0x2                 // spin until watchdog kicks in
#define PANIC_TEST_FAILURE_MODE_PANIC  0x4                 // explicit panic
extern unsigned int    panic_test_failure_mode;    // panic failure mode

extern unsigned int    panic_test_action_count;    // test parameter, depends on test case

#endif  /* DEBUG || DEVELOPMENT */

/*
 * A callback that reads or writes data from a given offset into the corefile. It is understood that this
 * callback should only be used from within the context where it is given. It should never be stored and
 * reused later on.
 */
typedef kern_return_t (*IOCoreFileAccessCallback)(void *context, boolean_t write, uint64_t offset, int length, void *buffer);

/*
 * A callback that receives temporary file-system access to the kernel corefile
 *
 * Parameters:
 *  - access:            A function to call for reading/writing the kernel corefile.
 *  - access_context:    The context that should be passed to the 'access' function.
 *  - recipient_context: The recipient-specific context. Can be anything.
 */
typedef kern_return_t (*IOCoreFileAccessRecipient)(IOCoreFileAccessCallback access, void *access_context, void *recipient_context);

/*
 * Provides safe and temporary file-system access to the kernel corefile to the given recipient callback.
 * It does so by opening the kernel corefile, then calling the 'recipient' callback, passing it an IOCoreFileAccessCallback
 * function that it can use to read/write data, then closing the kernel corefile as soon as the recipient returns.
 *
 * Parameters:
 *  - recipient:         A function to call, providing it access to the kernel corefile.
 *  - recipient_context: Recipient-specific context. Can be anything.
 */
extern kern_return_t
IOProvideCoreFileAccess(IOCoreFileAccessRecipient recipient, void *recipient_context);

struct kdp_core_encryption_key_descriptor {
	uint64_t kcekd_format;
	uint16_t kcekd_size;
	void *   kcekd_key;
};

/*
 * Registers a new kernel (and co-processor) coredump encryption key. The key format should be one of the
 * supported "next" key formats in mach_debug_types.h. The recipient context pointer should point to a kdp_core_encryption_key_descriptor
 * structure.
 *
 * Note that the given key pointer should be allocated using `kmem_alloc(kernel_map, <pointer>, <size>, VM_KERN_MEMORY_DIAG)`
 *
 * Note that upon successful completion, this function will adopt the given public key pointer
 * and the caller should NOT release it.
 */
kern_return_t kdp_core_handle_new_encryption_key(IOCoreFileAccessCallback access_data, void *access_context, void *recipient_context);

/*
 * Enum of allowed values for the 'lbr_support' boot-arg
 */
typedef enum {
	LBR_ENABLED_NONE,
	LBR_ENABLED_USERMODE,
	LBR_ENABLED_KERNELMODE,
	LBR_ENABLED_ALLMODES
} lbr_modes_t;

extern lbr_modes_t last_branch_enabled_modes;

#endif  /* XNU_KERNEL_PRIVATE */

__END_DECLS

#endif  /* _KERN_DEBUG_H_ */