X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/3903760236c30e3b5ace7a4eefac3a269d68957c..b226f5e54a60dc81db17b1260381d7dbfea3cdf1:/pexpert/i386/pe_init.c diff --git a/pexpert/i386/pe_init.c b/pexpert/i386/pe_init.c index 10a9fb24d..49f9caecf 100644 --- a/pexpert/i386/pe_init.c +++ b/pexpert/i386/pe_init.c @@ -49,7 +49,7 @@ /* extern references */ extern void pe_identify_machine(void * args); - +extern int kdb_printf(const char *format, ...) __printflike(1,2); /* private globals */ PE_state_t PE_state; @@ -335,13 +335,23 @@ PE_reboot_on_panic(void) return FALSE; } +void +PE_sync_panic_buffers(void) +{ +} + /* rdar://problem/21244753 */ uint32_t PE_i_can_has_debugger(uint32_t *debug_flags) { +#if DEVELOPMENT || DEBUG + if (debug_flags) { + assert(debug_boot_arg_inited); + } +#endif + #if CONFIG_CSR - if (csr_check(CSR_ALLOW_KERNEL_DEBUGGER) != 0 && - csr_check(CSR_ALLOW_APPLE_INTERNAL) != 0) { + if (csr_check(CSR_ALLOW_KERNEL_DEBUGGER) != 0) { if (debug_flags) *debug_flags = 0; return FALSE; @@ -352,3 +362,70 @@ PE_i_can_has_debugger(uint32_t *debug_flags) } return TRUE; } + +uint32_t +PE_get_offset_into_panic_region(char *location) +{ + assert(panic_info != NULL); + assert(location > (char *) panic_info); + + return (uint32_t) (location - (char *) panic_info); +} + +void +PE_init_panicheader() +{ + bzero(panic_info, offsetof(struct macos_panic_header, mph_data)); + panic_info->mph_panic_log_offset = PE_get_offset_into_panic_region(debug_buf_base); + + panic_info->mph_magic = MACOS_PANIC_MAGIC; + panic_info->mph_version = MACOS_PANIC_HEADER_CURRENT_VERSION; + + return; +} + +/* + * Tries to update the panic header to keep it consistent on nested panics. + * + * NOTE: The purpose of this function is NOT to detect/correct corruption in the panic region, + * it is to update the panic header to make it consistent when we nest panics. + * + * We try to avoid nested panics/asserts on x86 because they are difficult to debug, so log any + * inconsistencies we find. + */ +void +PE_update_panicheader_nestedpanic() +{ + /* If the panic log offset is not set, re-init the panic header */ + if (panic_info->mph_panic_log_offset == 0) { + PE_init_panicheader(); + panic_info->mph_panic_flags |= MACOS_PANIC_HEADER_FLAG_NESTED_PANIC; + return; + } + + panic_info->mph_panic_flags |= MACOS_PANIC_HEADER_FLAG_NESTED_PANIC; + + /* Usually indicative of corruption in the panic region */ + if(!(((panic_info->mph_stackshot_offset == 0) && (panic_info->mph_stackshot_len == 0)) || + ((panic_info->mph_stackshot_offset != 0) && (panic_info->mph_stackshot_len != 0)))) { + kdb_printf("panic_info contains invalid stackshot metadata: mph_stackshot_offset 0x%x mph_stackshot_len 0x%x\n", + panic_info->mph_stackshot_offset, panic_info->mph_stackshot_len); + } + + /* + * macOS panic logs contain nested panic data, if we've already closed the panic log, + * begin the other log. + */ + if ((panic_info->mph_panic_log_len != 0) && (panic_info->mph_other_log_offset == 0)) { + panic_info->mph_other_log_offset = PE_get_offset_into_panic_region(debug_buf_ptr); + + /* Usually indicative of corruption in the panic region */ + if (panic_info->mph_other_log_len != 0) { + kdb_printf("panic_info contains invalid other log metadata (zero offset but non-zero length), length was 0x%x, zeroing value\n", + panic_info->mph_other_log_len); + panic_info->mph_other_log_len = 0; + } + } + + return; +}