X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/fe8ab488e9161c46dd9885d58fc52996dc0249ff..e8c3f78193f1895ea514044358b93b1add9322f3:/libkern/gen/OSDebug.cpp?ds=sidebyside diff --git a/libkern/gen/OSDebug.cpp b/libkern/gen/OSDebug.cpp index 7cb847108..cbcdd5728 100644 --- a/libkern/gen/OSDebug.cpp +++ b/libkern/gen/OSDebug.cpp @@ -43,16 +43,25 @@ #include #include + extern int etext; __BEGIN_DECLS // From osmfk/kern/thread.h but considered to be private extern vm_offset_t min_valid_stack_address(void); extern vm_offset_t max_valid_stack_address(void); +// From osfmk/kern/printf.c +extern boolean_t doprnt_hide_pointers; + // From osfmk/kmod.c extern void kmod_dump_log(vm_offset_t *addr, unsigned int cnt, boolean_t doUnslide); extern addr64_t kvtophys(vm_offset_t va); +#if __arm__ +extern int copyinframe(vm_address_t fp, char *frame); +#elif defined(__arm64__) +extern int copyinframe(vm_address_t fp, char *frame, boolean_t is64bit); +#endif __END_DECLS @@ -93,7 +102,7 @@ void OSReportWithBacktrace(const char *str, ...) { char buf[128]; - void *bt[9]; + void *bt[9] = {}; const unsigned cnt = sizeof(bt) / sizeof(bt[0]); va_list listp; @@ -106,12 +115,15 @@ OSReportWithBacktrace(const char *str, ...) lck_mtx_lock(sOSReportLock); { + boolean_t old_doprnt_hide_pointers = doprnt_hide_pointers; + doprnt_hide_pointers = FALSE; printf("%s\nBacktrace 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n", buf, (unsigned long) VM_KERNEL_UNSLIDE(bt[2]), (unsigned long) VM_KERNEL_UNSLIDE(bt[3]), (unsigned long) VM_KERNEL_UNSLIDE(bt[4]), (unsigned long) VM_KERNEL_UNSLIDE(bt[5]), (unsigned long) VM_KERNEL_UNSLIDE(bt[6]), (unsigned long) VM_KERNEL_UNSLIDE(bt[7]), (unsigned long) VM_KERNEL_UNSLIDE(bt[8])); kmod_dump_log((vm_offset_t *) &bt[2], cnt - 2, TRUE); + doprnt_hide_pointers = old_doprnt_hide_pointers; } lck_mtx_unlock(sOSReportLock); } @@ -166,6 +178,7 @@ OSPrintBacktrace(void) unsigned OSBacktrace(void **bt, unsigned maxAddrs) { unsigned frame; + if (!current_thread()) return 0; #if __x86_64__ #define SANE_x86_64_FRAME_SIZE (kernel_stack_size >> 1) @@ -210,6 +223,42 @@ pad: for ( ; frame_index < maxAddrs; frame_index++) bt[frame_index] = (void *) 0; +#elif __arm__ || __arm64__ + uint32_t i = 0; + uintptr_t frameb[2]; + uintptr_t fp = 0; + + // get the current frame pointer for this thread +#if defined(__arm__) +#define OSBacktraceFrameAlignOK(x) (((x) & 0x3) == 0) + __asm__ volatile("mov %0,r7" : "=r" (fp)); +#elif defined(__arm64__) +#define OSBacktraceFrameAlignOK(x) (((x) & 0xf) == 0) + __asm__ volatile("mov %0, fp" : "=r" (fp)); +#else +#error Unknown architecture. +#endif + + // now crawl up the stack recording the link value of each frame + do { + // check bounds + if ((fp == 0) || (!OSBacktraceFrameAlignOK(fp)) || (fp > VM_MAX_KERNEL_ADDRESS) || (fp < VM_MIN_KERNEL_AND_KEXT_ADDRESS)) { + break; + } + // safely read frame +#ifdef __arm64__ + if (copyinframe(fp, (char*)frameb, TRUE) != 0) { +#else + if (copyinframe(fp, (char*)frameb) != 0) { +#endif + break; + } + + // No need to use copyin as this is always a kernel address, see check above + bt[i] = (void*)frameb[1]; // link register + fp = frameb[0]; + } while (++i < maxAddrs); + frame= i; #else #error arch #endif