diff --git a/llvm/lib/Support/Unix/Signals.inc b/llvm/lib/Support/Unix/Signals.inc --- a/llvm/lib/Support/Unix/Signals.inc +++ b/llvm/lib/Support/Unix/Signals.inc @@ -62,6 +62,9 @@ #if HAVE_MACH_MACH_H #include #endif +#ifdef __APPLE__ +#include +#endif #if HAVE_LINK_H #include #endif @@ -463,9 +466,9 @@ RegisterHandlers(); } -#if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES && HAVE_LINK_H && \ - (defined(__linux__) || defined(__FreeBSD__) || \ - defined(__FreeBSD_kernel__) || defined(__NetBSD__)) +#if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES +#if HAVE_LINK_H && (defined(__linux__) || defined(__FreeBSD__) || \ + defined(__FreeBSD_kernel__) || defined(__NetBSD__)) struct DlIteratePhdrData { void **StackTrace; int depth; @@ -509,16 +512,50 @@ dl_iterate_phdr(dl_iterate_phdr_cb, &data); return true; } +#elif defined(__APPLE__) && defined(__LP64__) +static bool findModulesAndOffsets(void **StackTrace, int Depth, + const char **Modules, intptr_t *Offsets, + const char *MainExecutableName, + StringSaver &StrPool) { + uint32_t num_imgs = _dyld_image_count(); + for (uint32_t image_index = 0; image_index < num_imgs; image_index++) { + const char *name = _dyld_get_image_name(image_index); + intptr_t slide = _dyld_get_image_vmaddr_slide(image_index); + auto *header = + (const struct mach_header_64 *)_dyld_get_image_header(image_index); + if (header == NULL) + continue; + auto cmd = (const struct load_command *)(&header[1]); + for (uint32_t cmd_num = 0; cmd_num < header->ncmds; ++cmd_num) { + uint32_t base_cmd = cmd->cmd & ~LC_REQ_DYLD; + if (base_cmd == LC_SEGMENT_64) { + auto cmd_seg64 = (const struct segment_command_64 *)cmd; + for (int j = 0; j < Depth; j++) { + if (Modules[j]) + continue; + intptr_t addr = (intptr_t)StackTrace[j]; + if ((intptr_t)cmd_seg64->vmaddr + slide <= addr && + addr < intptr_t(cmd_seg64->vmaddr + cmd_seg64->vmsize + slide)) { + Modules[j] = name; + Offsets[j] = addr - slide; + } + } + } + cmd = (const load_command *)(((const char *)cmd) + (cmd->cmdsize)); + } + } + return true; +} #else -/// This platform does not have dl_iterate_phdr, so we do not yet know how to -/// find all loaded DSOs. +/// We don't yet know how to find all loaded DSOs on this platform. static bool findModulesAndOffsets(void **StackTrace, int Depth, const char **Modules, intptr_t *Offsets, const char *MainExecutableName, StringSaver &StrPool) { return false; } -#endif // defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES && ... +#endif // per-platform findModulesAndOffsets implementations +#endif // defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES #if ENABLE_BACKTRACES && defined(HAVE__UNWIND_BACKTRACE) static int unwindBacktrace(void **StackTrace, int MaxEntries) {