+ panic_display_system_configuration(FALSE);
+
+ doprnt_hide_pointers = old_doprnt_hide_pointers;
+
+ /* Release print backtrace lock, to permit other callers in the
+ * event of panics on multiple processors.
+ */
+ hw_lock_unlock(&pbtlock);
+ hw_atomic_sub(&pbtcnt, 1);
+ /* Wait for other processors to complete output
+ * Timeout and continue after PBT_TIMEOUT_CYCLES.
+ */
+ bt_tsc_timeout = rdtsc64() + PBT_TIMEOUT_CYCLES;
+ while(*ppbtcnt && (rdtsc64() < bt_tsc_timeout));
+}
+
+static boolean_t
+debug_copyin(pmap_t p, uint64_t uaddr, void *dest, size_t size)
+{
+ size_t rem = size;
+ char *kvaddr = dest;
+
+ while (rem) {
+ ppnum_t upn = pmap_find_phys(p, uaddr);
+ uint64_t phys_src = ptoa_64(upn) | (uaddr & PAGE_MASK);
+ uint64_t phys_dest = kvtophys((vm_offset_t)kvaddr);
+ uint64_t src_rem = PAGE_SIZE - (phys_src & PAGE_MASK);
+ uint64_t dst_rem = PAGE_SIZE - (phys_dest & PAGE_MASK);
+ size_t cur_size = (uint32_t) MIN(src_rem, dst_rem);
+ cur_size = MIN(cur_size, rem);
+
+ if (upn && pmap_valid_page(upn) && phys_dest) {
+ bcopy_phys(phys_src, phys_dest, cur_size);
+ }
+ else
+ break;
+ uaddr += cur_size;
+ kvaddr += cur_size;
+ rem -= cur_size;
+ }
+ return (rem == 0);
+}
+
+void
+print_threads_registers(thread_t thread)
+{
+ x86_saved_state_t *savestate;
+
+ savestate = get_user_regs(thread);
+ kdb_printf(
+ "\nRAX: 0x%016llx, RBX: 0x%016llx, RCX: 0x%016llx, RDX: 0x%016llx\n"
+ "RSP: 0x%016llx, RBP: 0x%016llx, RSI: 0x%016llx, RDI: 0x%016llx\n"
+ "R8: 0x%016llx, R9: 0x%016llx, R10: 0x%016llx, R11: 0x%016llx\n"
+ "R12: 0x%016llx, R13: 0x%016llx, R14: 0x%016llx, R15: 0x%016llx\n"
+ "RFL: 0x%016llx, RIP: 0x%016llx, CS: 0x%016llx, SS: 0x%016llx\n\n",
+ savestate->ss_64.rax, savestate->ss_64.rbx, savestate->ss_64.rcx, savestate->ss_64.rdx,
+ savestate->ss_64.isf.rsp, savestate->ss_64.rbp, savestate->ss_64.rsi, savestate->ss_64.rdi,
+ savestate->ss_64.r8, savestate->ss_64.r9, savestate->ss_64.r10, savestate->ss_64.r11,
+ savestate->ss_64.r12, savestate->ss_64.r13, savestate->ss_64.r14, savestate->ss_64.r15,
+ savestate->ss_64.isf.rflags, savestate->ss_64.isf.rip, savestate->ss_64.isf.cs,
+ savestate->ss_64.isf.ss);
+}
+
+void
+print_tasks_user_threads(task_t task)
+{
+ thread_t thread = current_thread();
+ x86_saved_state_t *savestate;
+ pmap_t pmap = 0;
+ uint64_t rbp;
+ const char *cur_marker = 0;
+ int j;
+
+ for (j = 0, thread = (thread_t) queue_first(&task->threads); j < task->thread_count;
+ ++j, thread = (thread_t) queue_next(&thread->task_threads)) {
+
+ kdb_printf("Thread %d: %p\n", j, thread);
+ pmap = get_task_pmap(task);
+ savestate = get_user_regs(thread);
+ rbp = savestate->ss_64.rbp;
+ kdb_printf("\t0x%016llx\n", savestate->ss_64.isf.rip);
+ print_one_backtrace(pmap, (vm_offset_t)rbp, cur_marker, TRUE, TRUE);
+ kdb_printf("\n");
+ }
+}
+
+void
+print_thread_num_that_crashed(task_t task)
+{
+ thread_t c_thread = current_thread();
+ thread_t thread;
+ int j;
+
+ for (j = 0, thread = (thread_t) queue_first(&task->threads); j < task->thread_count;
+ ++j, thread = (thread_t) queue_next(&thread->task_threads)) {
+
+ if (c_thread == thread) {
+ kdb_printf("\nThread %d crashed\n", j);
+ break;
+ }
+ }
+}
+
+#define PANICLOG_UUID_BUF_SIZE 256
+
+void print_uuid_info(task_t task)
+{
+ uint32_t uuid_info_count = 0;
+ mach_vm_address_t uuid_info_addr = 0;
+ boolean_t have_map = (task->map != NULL) && (ml_validate_nofault((vm_offset_t)(task->map), sizeof(struct _vm_map)));
+ boolean_t have_pmap = have_map && (task->map->pmap != NULL) && (ml_validate_nofault((vm_offset_t)(task->map->pmap), sizeof(struct pmap)));
+ int task_pid = pid_from_task(task);
+ char uuidbuf[PANICLOG_UUID_BUF_SIZE] = {0};
+ char *uuidbufptr = uuidbuf;
+ uint32_t k;
+
+ if (have_pmap && task->active && task_pid > 0) {
+ /* Read dyld_all_image_infos struct from task memory to get UUID array count & location */
+ struct user64_dyld_all_image_infos task_image_infos;
+ if (debug_copyin(task->map->pmap, task->all_image_info_addr,
+ &task_image_infos, sizeof(struct user64_dyld_all_image_infos))) {
+ uuid_info_count = (uint32_t)task_image_infos.uuidArrayCount;
+ uuid_info_addr = task_image_infos.uuidArray;
+ }