return (NULL != gIOPolledCoreFileVars);
}
+kern_return_t kdp_polled_corefile_error(void)
+{
+ return gIOPolledCoreFileOpenRet;
+}
#if CONFIG_EMBEDDED
/*
* Whenever we start a coredump, make sure the buffers
case KDP_DATA:
err = IOPolledFileWrite(gIOPolledCoreFileVars, data, length, NULL);
if (kIOReturnSuccess != err) {
- kern_coredump_log(NULL, "IOPolledFileWrite(gIOPolledCoreFileVars, 0x%p, 0x%llx, NULL) returned 0x%x\n",
+ kern_coredump_log(NULL, "IOPolledFileWrite(gIOPolledCoreFileVars, %p, 0x%llx, NULL) returned 0x%x\n",
data, length, err);
break;
}
{
if ((ret = (*vars->outproc)(KDP_DATA, NULL, len, buf)) != kIOReturnSuccess)
{
- kern_coredump_log(NULL, "(kdp_core_zoutput) outproc(KDP_DATA, NULL, 0x%x, 0x%p) returned 0x%x\n",
+ kern_coredump_log(NULL, "(kdp_core_zoutput) outproc(KDP_DATA, NULL, 0x%x, %p) returned 0x%x\n",
len, buf, ret);
vars->error = ret;
}
vars->outlen - vars->outremain,
vars->outbuf)) != kIOReturnSuccess)
{
- kern_coredump_log(NULL, "(kdp_core_zoutputbuf) outproc(KDP_DATA, NULL, 0x%x, 0x%p) returned 0x%x\n",
+ kern_coredump_log(NULL, "(kdp_core_zoutputbuf) outproc(KDP_DATA, NULL, 0x%x, %p) returned 0x%x\n",
(vars->outlen - vars->outremain), vars->outbuf, ret);
vars->error = ret;
}
vincr = kdp_core_ramdisk_size;
}
else
-#if defined(__arm64__)
+#if defined(__arm64__) && defined(CONFIG_XNUPOST)
if (vaddr == _COMM_HIGH_PAGE64_BASE_ADDRESS)
{
/* not readable */
if (ppn && pvphysaddr)
{
uint64_t phys = ptoa_64(ppn);
-#if defined(__arm__) || defined(__arm64__)
- if (isphysmem(phys)) *pvphysaddr = phystokv(phys);
-#else
- if (physmap_enclosed(phys)) *pvphysaddr = (uintptr_t)PHYSMAP_PTOV(phys);
-#endif
- else ppn = 0;
+ if (physmap_enclosed(phys)) {
+ *pvphysaddr = phystokv(phys);
+ } else {
+ ppn = 0;
+ }
}
return (ppn);
IOReturn ret;
vm_map_offset_t vcurstart, vcur;
uint64_t vincr = 0;
- vm_map_offset_t debug_start;
- vm_map_offset_t debug_end;
+ vm_map_offset_t debug_start = trunc_page((vm_map_offset_t) debug_buf_base);
+ vm_map_offset_t debug_end = round_page((vm_map_offset_t) (debug_buf_base + debug_buf_size));
+#if defined(XNU_TARGET_OS_BRIDGE)
+ vm_map_offset_t macos_panic_start = trunc_page((vm_map_offset_t) macos_panic_base);
+ vm_map_offset_t macos_panic_end = round_page((vm_map_offset_t) (macos_panic_base + macos_panic_size));
+#endif
+
boolean_t lastvavalid;
#if defined(__arm__) || defined(__arm64__)
vm_page_t m = VM_PAGE_NULL;
#endif
- debug_start = trunc_page((vm_map_offset_t) debug_buf_base);
- debug_end = round_page((vm_map_offset_t) (debug_buf_base + debug_buf_size));
-
#if defined(__x86_64__)
assert(!is_ept_pmap(pmap));
#endif
ppn = VM_PAGE_GET_PHYS_PAGE(m);
break;
}
- m = (vm_page_t)vm_page_queue_next(&m->listq);
- }
- vcur = phystokv(ptoa(ppn));
- if (vcur != vprev)
- {
- ret = callback(vcurstart, vprev, context);
- lastvavalid = FALSE;
+ m = (vm_page_t)vm_page_queue_next(&m->vmp_listq);
}
vincr = PAGE_SIZE_64;
if (ppn == atop(avail_end))
{
vm_object_unlock(&pmap_object_store);
m = VM_PAGE_NULL;
+ // avail_end is not a valid physical address,
+ // so phystokv(avail_end) may not produce the expected result.
+ vcur = phystokv(avail_start) + (avail_end - avail_start);
+ } else {
+ m = (vm_page_t)vm_page_queue_next(&m->vmp_listq);
+ vcur = phystokv(ptoa(ppn));
+ }
+ if (vcur != vprev)
+ {
+ ret = callback(vcurstart, vprev, context);
+ lastvavalid = FALSE;
}
- else
- m = (vm_page_t)vm_page_queue_next(&m->listq);
}
if (m == VM_PAGE_NULL)
ppn = kernel_pmap_present_mapping(vcur, &vincr, NULL);
if (ppn != 0)
{
if (((vcur < debug_start) || (vcur >= debug_end))
- && !(EFI_VALID_PAGE(ppn) ||
- pmap_valid_page(ppn)))
+ && !(EFI_VALID_PAGE(ppn) || pmap_valid_page(ppn))
+#if defined(XNU_TARGET_OS_BRIDGE)
+ // include the macOS panic region if it's mapped
+ && ((vcur < macos_panic_start) || (vcur >= macos_panic_end))
+#endif
+ )
{
/* not something we want */
ppn = 0;
#if defined(__x86_64__)
/* Try to skip by 2MB if possible */
- if (((vcur & PDMASK) == 0) && cpu_64bit) {
+ if ((vcur & PDMASK) == 0) {
pd_entry_t *pde;
pde = pmap_pde(pmap, vcur);
if (0 == pde || ((*pde & INTEL_PTE_VALID) == 0)) {
/* send previous run */
ret = callback(vcurstart, vcur, context);
}
+
+#if KASAN
+ if (ret == KERN_SUCCESS) {
+ ret = kasan_traverse_mappings(callback, context);
+ }
+#endif
+
return (ret);
}
/* Write the file header -- first seek to the beginning of the file */
foffset = 0;
if ((ret = (outvars->outproc)(KDP_SEEK, NULL, sizeof(foffset), &foffset)) != kIOReturnSuccess) {
- kern_coredump_log(NULL, "(kern_dump_update_header) outproc(KDP_SEEK, NULL, %lu, 0x%p) foffset = 0x%llx returned 0x%x\n",
+ kern_coredump_log(NULL, "(kern_dump_update_header) outproc(KDP_SEEK, NULL, %lu, %p) foffset = 0x%llx returned 0x%x\n",
sizeof(foffset), &foffset, foffset, ret);
return ret;
}
if ((ret = (outvars->outproc)(KDP_DATA, NULL, sizeof(kdp_core_header), &kdp_core_header)) != kIOReturnSuccess) {
- kern_coredump_log(NULL, "(kern_dump_update_header) outproc(KDP_DATA, NULL, %lu, 0x%p) returned 0x%x\n",
+ kern_coredump_log(NULL, "(kern_dump_update_header) outproc(KDP_DATA, NULL, %lu, %p) returned 0x%x\n",
sizeof(kdp_core_header), &kdp_core_header, ret);
return ret;
}
int ret;
if ((ret = (outvars->outproc)(KDP_SEEK, NULL, sizeof(next_file_offset), &next_file_offset)) != kIOReturnSuccess) {
- kern_coredump_log(NULL, "(kern_dump_seek_to_next_file) outproc(KDP_SEEK, NULL, %lu, 0x%p) foffset = 0x%llx returned 0x%x\n",
+ kern_coredump_log(NULL, "(kern_dump_seek_to_next_file) outproc(KDP_SEEK, NULL, %lu, %p) foffset = 0x%llx returned 0x%x\n",
sizeof(next_file_offset), &next_file_offset, next_file_offset, ret);
}
assert (existing_log_size <= debug_buf_size);
- if (kd_variant == KERN_DUMP_DISK) {
+ if ((kd_variant == KERN_DUMP_DISK) || (kd_variant == KERN_DUMP_STACKSHOT_DISK)) {
/* Open the file for output */
if ((ret = (*outproc)(KDP_WRQ, NULL, 0, NULL)) != kIOReturnSuccess) {
kern_coredump_log(NULL, "outproc(KDP_WRQ, NULL, 0, NULL) returned 0x%x\n", ret);
bzero(&outvars, sizeof(outvars));
outvars.outproc = outproc;
- if (kd_variant == KERN_DUMP_DISK) {
+ if ((kd_variant == KERN_DUMP_DISK) || (kd_variant == KERN_DUMP_STACKSHOT_DISK)) {
outvars.zoutput = kdp_core_zoutput;
/* Space for file header, panic log, core log */
foffset = (KERN_COREDUMP_HEADERSIZE + existing_log_size + KERN_COREDUMP_MAXDEBUGLOGSIZE +
/* Seek the calculated offset (we'll scrollback later to flush the logs and header) */
if ((ret = (*outproc)(KDP_SEEK, NULL, sizeof(foffset), &foffset)) != kIOReturnSuccess) {
- kern_coredump_log(NULL, "(do_kern_dump seek begin) outproc(KDP_SEEK, NULL, %lu, 0x%p) foffset = 0x%llx returned 0x%x\n",
+ kern_coredump_log(NULL, "(do_kern_dump seek begin) outproc(KDP_SEEK, NULL, %lu, %p) foffset = 0x%llx returned 0x%x\n",
sizeof(foffset), &foffset, foffset, ret);
dump_succeeded = FALSE;
goto exit;
kern_coredump_log(NULL, "%s", (kd_variant == KERN_DUMP_DISK) ? "Writing local cores..." :
"Transmitting kernel state, please wait:\n");
+
+#if defined(__x86_64__)
+ if (((kd_variant == KERN_DUMP_STACKSHOT_DISK) || (kd_variant == KERN_DUMP_DISK)) && ((panic_stackshot_buf != 0) && (panic_stackshot_len != 0))) {
+ uint64_t compressed_stackshot_len = 0;
+
+ if ((ret = kdp_reset_output_vars(&outvars, panic_stackshot_len)) != KERN_SUCCESS) {
+ kern_coredump_log(NULL, "Failed to reset outvars for stackshot with len 0x%zx, returned 0x%x\n", panic_stackshot_len, ret);
+ dump_succeeded = FALSE;
+ } else if ((ret = kdp_core_output(&outvars, panic_stackshot_len, (void *)panic_stackshot_buf)) != KERN_SUCCESS) {
+ kern_coredump_log(NULL, "Failed to write panic stackshot to file, kdp_coreoutput(outvars, %lu, %p) returned 0x%x\n",
+ panic_stackshot_len, (void *) panic_stackshot_buf, ret);
+ dump_succeeded = FALSE;
+ } else if ((ret = kdp_core_output(&outvars, 0, NULL)) != KERN_SUCCESS) {
+ kern_coredump_log(NULL, "Failed to flush stackshot data : kdp_core_output(%p, 0, NULL) returned 0x%x\n", &outvars, ret);
+ dump_succeeded = FALSE;
+ } else if ((ret = kern_dump_record_file(&outvars, "panic_stackshot.kcdata", foffset, &compressed_stackshot_len)) != KERN_SUCCESS) {
+ kern_coredump_log(NULL, "Failed to record panic stackshot in corefile header, kern_dump_record_file returned 0x%x\n", ret);
+ dump_succeeded = FALSE;
+ } else {
+ kern_coredump_log(NULL, "Recorded panic stackshot in corefile at offset 0x%llx, compressed to %llu bytes\n", foffset, compressed_stackshot_len);
+ foffset = roundup((foffset + compressed_stackshot_len), KERN_COREDUMP_BEGIN_FILEBYTES_ALIGN);
+ if ((ret = kern_dump_seek_to_next_file(&outvars, foffset)) != kIOReturnSuccess) {
+ kern_coredump_log(NULL, "Failed to seek to stackshot file offset 0x%llx, kern_dump_seek_to_next_file returned 0x%x\n", foffset, ret);
+ dump_succeeded = FALSE;
+ }
+ }
+ }
+#endif
+
if (kd_variant == KERN_DUMP_DISK) {
/*
* Dump co-processors as well, foffset will be overwritten with the
if (kern_do_coredump(&outvars, FALSE, foffset, &foffset) != 0) {
dump_succeeded = FALSE;
}
- } else {
+ } else if (kd_variant != KERN_DUMP_STACKSHOT_DISK) {
/* Only the kernel */
if (kern_do_coredump(&outvars, TRUE, foffset, &foffset) != 0) {
dump_succeeded = FALSE;
}
if (kd_variant == KERN_DUMP_DISK) {
-#if defined(__x86_64__) && (DEVELOPMENT || DEBUG)
- /* Write the macOS panic stackshot on its own to a separate 'corefile' */
- if (panic_stackshot_buf && panic_stackshot_len) {
- uint64_t compressed_stackshot_len = 0;
-
- /* Seek to the offset of the next 'file' (foffset provided/updated from kern_do_coredump) */
- if ((ret = kern_dump_seek_to_next_file(&outvars, foffset)) != kIOReturnSuccess) {
- kern_coredump_log(NULL, "Failed to seek to stackshot file offset 0x%llx, kern_dump_seek_to_next_file returned 0x%x\n", foffset, ret);
- dump_succeeded = FALSE;
- } else if ((ret = kdp_reset_output_vars(&outvars, panic_stackshot_len)) != KERN_SUCCESS) {
- kern_coredump_log(NULL, "Failed to reset outvars for stackshot with len 0x%zx, returned 0x%x\n", panic_stackshot_len, ret);
- dump_succeeded = FALSE;
- } else if ((ret = kdp_core_output(&outvars, panic_stackshot_len, (void *)panic_stackshot_buf)) != KERN_SUCCESS) {
- kern_coredump_log(NULL, "Failed to write panic stackshot to file, kdp_coreoutput(outvars, %lu, 0x%p) returned 0x%x\n",
- panic_stackshot_len, (void *) panic_stackshot_buf, ret);
- dump_succeeded = FALSE;
- } else if ((ret = kdp_core_output(&outvars, 0, NULL)) != KERN_SUCCESS) {
- kern_coredump_log(NULL, "Failed to flush stackshot data : kdp_core_output(0x%p, 0, NULL) returned 0x%x\n", &outvars, ret);
- dump_succeeded = FALSE;
- } else if ((ret = kern_dump_record_file(&outvars, "panic_stackshot.kcdata", foffset, &compressed_stackshot_len)) != KERN_SUCCESS) {
- kern_coredump_log(NULL, "Failed to record panic stackshot in corefile header, kern_dump_record_file returned 0x%x\n", ret);
- dump_succeeded = FALSE;
- } else {
- kern_coredump_log(NULL, "Recorded panic stackshot in corefile at offset 0x%llx, compressed to %llu bytes\n", foffset, compressed_stackshot_len);
- }
- }
-#endif /* defined(__x86_64__) && (DEVELOPMENT || DEBUG) */
-
/* Write the debug log -- first seek to the end of the corefile header */
foffset = KERN_COREDUMP_HEADERSIZE;
if ((ret = (*outproc)(KDP_SEEK, NULL, sizeof(foffset), &foffset)) != kIOReturnSuccess) {
- kern_coredump_log(NULL, "(do_kern_dump seek logfile) outproc(KDP_SEEK, NULL, %lu, 0x%p) foffset = 0x%llx returned 0x%x\n",
+ kern_coredump_log(NULL, "(do_kern_dump seek logfile) outproc(KDP_SEEK, NULL, %lu, %p) foffset = 0x%llx returned 0x%x\n",
sizeof(foffset), &foffset, foffset, ret);
dump_succeeded = FALSE;
goto exit;
*/
buf = debug_buf_base;
if ((ret = (*outproc)(KDP_DATA, NULL, existing_log_size, buf)) != kIOReturnSuccess) {
- kern_coredump_log(NULL, "(do_kern_dump paniclog) outproc(KDP_DATA, NULL, %lu, 0x%p) returned 0x%x\n",
+ kern_coredump_log(NULL, "(do_kern_dump paniclog) outproc(KDP_DATA, NULL, %lu, %p) returned 0x%x\n",
existing_log_size, buf, ret);
dump_succeeded = FALSE;
goto exit;
/* Write the coredump log */
if ((ret = (*outproc)(KDP_DATA, NULL, new_log_len, buf)) != kIOReturnSuccess) {
- kern_coredump_log(NULL, "(do_kern_dump coredump log) outproc(KDP_DATA, NULL, %lu, 0x%p) returned 0x%x\n",
+ kern_coredump_log(NULL, "(do_kern_dump coredump log) outproc(KDP_DATA, NULL, %lu, %p) returned 0x%x\n",
new_log_len, buf, ret);
dump_succeeded = FALSE;
goto exit;
#if KASAN
kasan_disable();
#endif
- if (kd_variant == KERN_DUMP_DISK) {
+ if ((kd_variant == KERN_DUMP_DISK) || (kd_variant == KERN_DUMP_STACKSHOT_DISK)) {
if (dumped_local) return (0);
if (local_dump_in_progress) return (-1);
local_dump_in_progress = TRUE;
#if CONFIG_EMBEDDED
hwsd_info->xhsdci_status = XHSDCI_STATUS_KERNEL_BUSY;
#endif
- ret = do_kern_dump(&kern_dump_disk_proc, KERN_DUMP_DISK);
+ ret = do_kern_dump(&kern_dump_disk_proc, kd_variant);
if (ret == 0) {
dumped_local = TRUE;
kern_dump_successful = TRUE;
}
#if CONFIG_EMBEDDED
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wmissing-noreturn"
void
panic_spin_shmcon()
{
-#pragma clang diagnostic pop
+ if (hwsd_info == NULL) {
+ kern_coredump_log(NULL, "handshake structure not initialized\n");
+ return;
+ }
+
kern_coredump_log(NULL, "\nPlease go to https://panic.apple.com to report this panic\n");
kern_coredump_log(NULL, "Waiting for hardware shared memory debugger, handshake structure is at virt: %p, phys %p\n",
hwsd_info, (void *)kvtophys((vm_offset_t)hwsd_info));
- assert(hwsd_info != NULL);
hwsd_info->xhsdci_status = XHSDCI_STATUS_KERNEL_READY;
hwsd_info->xhsdci_seq_no = 0;
FlushPoC_DcacheRegion((vm_offset_t) hwsd_info, sizeof(*hwsd_info));
PE_consistent_debug_register(kDbgIdAstrisConnection, kvtophys((vm_offset_t) hwsd_info), sizeof(pmap_paddr_t));
PE_consistent_debug_register(kDbgIdAstrisConnectionVers, CUR_XNU_HWSDCI_STRUCT_VERS, sizeof(uint32_t));
#endif /* CONFIG_EMBEDDED */
-
-#if defined(__x86_64__) && (DEVELOPMENT || DEBUG)
- /* Allocate space in the kernel map for the panic stackshot */
- kr = kmem_alloc(kernel_map, &panic_stackshot_buf, PANIC_STACKSHOT_BUFSIZE, VM_KERN_MEMORY_DIAG);
- assert (KERN_SUCCESS == kr);
-#endif /* defined(__x86_64__) && (DEVELOPMENT || DEBUG) */
}
#endif /* CONFIG_KDP_INTERACTIVE_DEBUGGING */