diff --git a/src/binary/mach-o.hpp b/src/binary/mach-o.hpp index 13b1e27..2a02f5c 100644 --- a/src/binary/mach-o.hpp +++ b/src/binary/mach-o.hpp @@ -26,6 +26,7 @@ #include #include #include +#include namespace cpptrace { namespace detail { @@ -176,7 +177,7 @@ namespace detail { } } // somehow no __TEXT section was found... - PANIC("Couldn't find __TEXT section while parsing Mach-O object"); + throw std::runtime_error("Couldn't find __TEXT section while parsing Mach-O object"); return 0; } @@ -410,7 +411,7 @@ namespace detail { if(allow_arch_mismatch) { return; } else { - PANIC("Mach-O file cpu type and subtype do not match current machine " + object_path); + throw std::runtime_error("Mach-O file cpu type and subtype do not match current machine " + object_path); } } cputype = header.cputype; @@ -441,34 +442,64 @@ namespace detail { if(should_swap()) { swap_fat_header(&header, NX_UnknownByteOrder); } - thread_local static struct LP(mach_header)* mhp = _NSGetMachExecuteHeader(); + // thread_local static struct LP(mach_header)* mhp = _NSGetMachExecuteHeader(); + // off_t arch_offset = (off_t)header_size; + // for(std::size_t i = 0; i < header.nfat_arch; i++) { + // fat_arch arch = load_bytes(file, arch_offset); + // if(should_swap()) { + // swap_fat_arch(&arch, 1, NX_UnknownByteOrder); + // } + // off_t mach_header_offset = (off_t)arch.offset; + // arch_offset += arch_size; + // std::uint32_t magic = load_bytes(file, mach_header_offset); + // std::cerr<<"xxx: "<cputype<(mhp->cpusubtype & ~CPU_SUBTYPE_MASK)<cputype && + // static_cast(mhp->cpusubtype & ~CPU_SUBTYPE_MASK) == arch.cpusubtype + // ) { + // load_base = mach_header_offset; + // fat_index = i; + // if(is_magic_64(magic)) { + // load_mach<64>(true); + // } else { + // load_mach<32>(true); + // } + // return; + // } + // } + std::vector fat_arches; + fat_arches.reserve(header.nfat_arch); off_t arch_offset = (off_t)header_size; for(std::size_t i = 0; i < header.nfat_arch; i++) { fat_arch arch = load_bytes(file, arch_offset); if(should_swap()) { swap_fat_arch(&arch, 1, NX_UnknownByteOrder); } - off_t mach_header_offset = (off_t)arch.offset; + fat_arches.push_back(arch); arch_offset += arch_size; + } + thread_local static struct LP(mach_header)* mhp = _NSGetMachExecuteHeader(); + fat_arch* best = NXFindBestFatArch( + mhp->cputype, + mhp->cpusubtype, + fat_arches.data(), + header.nfat_arch + ); + if(best) { + off_t mach_header_offset = (off_t)best->offset; std::uint32_t magic = load_bytes(file, mach_header_offset); - std::cerr<<"xxx: "<cputype<(mhp->cpusubtype & ~CPU_SUBTYPE_MASK)<cputype && - static_cast(mhp->cpusubtype & ~CPU_SUBTYPE_MASK) == arch.cpusubtype - ) { - load_base = mach_header_offset; - fat_index = i; - if(is_magic_64(magic)) { - load_mach<64>(true); - } else { - load_mach<32>(true); - } - return; + load_base = mach_header_offset; + fat_index = best - fat_arches.data(); + if(is_magic_64(magic)) { + load_mach<64>(true); + } else { + load_mach<32>(true); } + return; } // If this is reached... something went wrong. The cpu we're on wasn't found. - PANIC("Couldn't find appropriate architecture in fat Mach-O"); + throw std::runtime_error("Couldn't find appropriate architecture in fat Mach-O"); } template