From b46ebe7f54fe284028dc5ab38830f2b035dde751 Mon Sep 17 00:00:00 2001 From: Jeremy <51220084+jeremy-rifkin@users.noreply.github.com> Date: Sat, 30 Sep 2023 19:28:35 -0400 Subject: [PATCH] Update libdwarf code to remove fat mach-o bodge and properly handle fat mach-o files --- src/platform/mach-o.hpp | 12 +++--------- src/symbols/symbols_with_libdwarf.cpp | 27 ++++++--------------------- 2 files changed, 9 insertions(+), 30 deletions(-) diff --git a/src/platform/mach-o.hpp b/src/platform/mach-o.hpp index bc2ca24..4b0427e 100644 --- a/src/platform/mach-o.hpp +++ b/src/platform/mach-o.hpp @@ -207,14 +207,9 @@ namespace detail { return is_fat_magic(magic); } - struct fat_info { - uint32_t offset; - uint32_t size; - }; - - // returns offset, file size + // returns index of the appropriate mach-o binary in the universal binary // TODO: Code duplication with macho_get_text_vmaddr_fat - inline fat_info get_fat_macho_information(const std::string& obj_path) { + inline unsigned get_fat_macho_index(const std::string& obj_path) { auto file = raii_wrap(fopen(obj_path.c_str(), "rb"), file_deleter); if(file == nullptr) { throw file_error("Unable to read object file " + obj_path); @@ -240,12 +235,11 @@ namespace detail { arch.cputype == mhp->cputype && static_cast(mhp->cpusubtype & ~CPU_SUBTYPE_MASK) == arch.cpusubtype ) { - return { arch.offset, arch.size }; + return i; } } // 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"); - return { 0, 0 }; } } } diff --git a/src/symbols/symbols_with_libdwarf.cpp b/src/symbols/symbols_with_libdwarf.cpp index 966aa81..f68cc53 100644 --- a/src/symbols/symbols_with_libdwarf.cpp +++ b/src/symbols/symbols_with_libdwarf.cpp @@ -109,30 +109,14 @@ namespace libdwarf { CPPTRACE_FORCE_NO_INLINE_FOR_PROFILING dwarf_resolver(const std::string& object_path) { obj_path = object_path; + // for universal / fat mach-o files + unsigned universal_number = 0; #if IS_APPLE if(directory_exists(obj_path + ".dSYM")) { obj_path += ".dSYM/Contents/Resources/DWARF/" + basename(object_path); } if(macho_is_fat(obj_path)) { - // If the object is fat, we'll copy out the mach-o object we care about - // Awful hack until libdwarf supports fat mach - auto sub_object = get_fat_macho_information(obj_path); - char tmp_template[] = "/tmp/tmp.cpptrace.XXXXXX"; - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wdeprecated-declarations" - VERIFY(mktemp(tmp_template) != nullptr); - #pragma GCC diagnostic pop - std::string tmp_path = tmp_template; - auto file = raii_wrap(fopen(obj_path.c_str(), "rb"), file_deleter); - auto tmp = raii_wrap(fopen(tmp_path.c_str(), "wb"), file_deleter); - VERIFY(file != nullptr); - VERIFY(tmp != nullptr); - std::unique_ptr buffer(new char[sub_object.size]); - VERIFY(fseek(file, sub_object.offset, SEEK_SET) == 0); - VERIFY(fread(buffer.get(), 1, sub_object.size, file) == sub_object.size); - VERIFY(fwrite(buffer.get(), 1, sub_object.size, tmp) == sub_object.size); - obj_path = tmp_path; - tmp_object_path = std::move(tmp_path); + universal_number = get_fat_macho_index(obj_path); } #endif @@ -140,11 +124,12 @@ namespace libdwarf { // dSYM files. We don't utilize the dSYM logic here, we just care about debuglink. std::unique_ptr buffer(new char[CPPTRACE_MAX_PATH]); auto ret = wrap( - dwarf_init_path, + dwarf_init_path_a, obj_path.c_str(), buffer.get(), CPPTRACE_MAX_PATH, DW_GROUPNUMBER_ANY, + universal_number, nullptr, nullptr, &dbg @@ -674,7 +659,7 @@ namespace libdwarf { for(const auto& obj_entry : collate_frames(frames, trace)) { try { const auto& obj_name = obj_entry.first; - optional resolver_object;// = nullopt; + optional resolver_object = nullopt; dwarf_resolver* resolver = nullptr; auto it = resolver_map.find(obj_name); if(it != resolver_map.end()) {