diff --git a/lldb/include/lldb/Symbol/ObjectFile.h b/lldb/include/lldb/Symbol/ObjectFile.h index d89314d44bf67..874926da2ceb7 100644 --- a/lldb/include/lldb/Symbol/ObjectFile.h +++ b/lldb/include/lldb/Symbol/ObjectFile.h @@ -81,9 +81,14 @@ class ObjectFile : public std::enable_shared_from_this, enum BinaryType { eBinaryTypeInvalid = 0, eBinaryTypeUnknown, - eBinaryTypeKernel, /// kernel binary - eBinaryTypeUser, /// user process binary - eBinaryTypeStandalone /// standalone binary / firmware + /// kernel binary + eBinaryTypeKernel, + /// user process binary, dyld addr + eBinaryTypeUser, + /// user process binary, dyld_all_image_infos addr + eBinaryTypeUserAllImageInfos, + /// standalone binary / firmware + eBinaryTypeStandalone }; struct LoadableData { diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp index 4e356a7c8f5d9..a19322ff1e263 100644 --- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp +++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp @@ -5599,9 +5599,13 @@ bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &value, // struct main_bin_spec // { // uint32_t version; // currently 2 - // uint32_t type; // 0 == unspecified, 1 == kernel, + // uint32_t type; // 0 == unspecified, + // // 1 == kernel // // 2 == user process, + // dyld mach-o binary addr // // 3 == standalone binary + // // 4 == user process, + // // dyld_all_image_infos addr // uint64_t address; // UINT64_MAX if address not specified // uint64_t slide; // slide, UINT64_MAX if unspecified // // 0 if no slide needs to be applied to @@ -5652,6 +5656,7 @@ bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &value, // convert the "main bin spec" type into our // ObjectFile::BinaryType enum const char *typestr = "unrecognized type"; + type = eBinaryTypeInvalid; switch (binspec_type) { case 0: type = eBinaryTypeUnknown; @@ -5669,6 +5674,10 @@ bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &value, type = eBinaryTypeStandalone; typestr = "standalone"; break; + case 4: + type = eBinaryTypeUserAllImageInfos; + typestr = "userland dyld_all_image_infos"; + break; } LLDB_LOGF(log, "LC_NOTE 'main bin spec' found, version %d type %d " diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp index eef9bd4a175ec..281f3a0db8f69 100644 --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp @@ -114,6 +114,7 @@ ProcessMachCore::ProcessMachCore(lldb::TargetSP target_sp, : PostMortemProcess(target_sp, listener_sp, core_file), m_core_aranges(), m_core_range_infos(), m_core_module_sp(), m_dyld_addr(LLDB_INVALID_ADDRESS), + m_dyld_all_image_infos_addr(LLDB_INVALID_ADDRESS), m_mach_kernel_addr(LLDB_INVALID_ADDRESS) {} // Destructor @@ -320,6 +321,9 @@ bool ProcessMachCore::LoadBinariesViaMetadata() { } else if (type == ObjectFile::eBinaryTypeUser) { m_dyld_addr = objfile_binary_value; m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic(); + } else if (type == ObjectFile::eBinaryTypeUserAllImageInfos) { + m_dyld_all_image_infos_addr = objfile_binary_value; + m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic(); } else { const bool force_symbol_search = true; const bool notify = true; @@ -466,6 +470,7 @@ void ProcessMachCore::LoadBinariesViaExhaustiveSearch() { addr_t saved_user_dyld_addr = m_dyld_addr; m_mach_kernel_addr = LLDB_INVALID_ADDRESS; m_dyld_addr = LLDB_INVALID_ADDRESS; + m_dyld_all_image_infos_addr = LLDB_INVALID_ADDRESS; addr_t better_kernel_address = DynamicLoaderDarwinKernel::SearchForDarwinKernel(this); @@ -507,6 +512,12 @@ void ProcessMachCore::LoadBinariesAndSetDYLD() { "image at 0x%" PRIx64, __FUNCTION__, m_dyld_addr); m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic(); + } else if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS) { + LLDB_LOGF(log, + "ProcessMachCore::%s: Using user process dyld " + "dyld_all_image_infos at 0x%" PRIx64, + __FUNCTION__, m_dyld_all_image_infos_addr); + m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic(); } } else { if (m_dyld_addr != LLDB_INVALID_ADDRESS) { @@ -515,6 +526,11 @@ void ProcessMachCore::LoadBinariesAndSetDYLD() { "image at 0x%" PRIx64, __FUNCTION__, m_dyld_addr); m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic(); + } else if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS) { + LLDB_LOGF(log, + "ProcessMachCore::%s: Using user process dyld " + "dyld_all_image_infos at 0x%" PRIx64, + __FUNCTION__, m_dyld_all_image_infos_addr); } else if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) { LLDB_LOGF(log, "ProcessMachCore::%s: Using kernel " @@ -763,19 +779,32 @@ void ProcessMachCore::Initialize() { } addr_t ProcessMachCore::GetImageInfoAddress() { - // If we found both a user-process dyld and a kernel binary, we need to - // decide which to prefer. + // The DynamicLoader plugin will call back in to this Process + // method to find the virtual address of one of these: + // 1. The xnu mach kernel binary Mach-O header + // 2. The dyld binary Mach-O header + // 3. dyld's dyld_all_image_infos object + // + // DynamicLoaderMacOSX will accept either the dyld Mach-O header + // address or the dyld_all_image_infos interchangably, no need + // to distinguish between them. It disambiguates by the Mach-O + // file magic number at the start. if (GetCorefilePreference() == eKernelCorefile) { - if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) { + if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) return m_mach_kernel_addr; - } - return m_dyld_addr; + if (m_dyld_addr != LLDB_INVALID_ADDRESS) + return m_dyld_addr; } else { - if (m_dyld_addr != LLDB_INVALID_ADDRESS) { + if (m_dyld_addr != LLDB_INVALID_ADDRESS) return m_dyld_addr; - } - return m_mach_kernel_addr; + if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) + return m_mach_kernel_addr; } + + // m_dyld_addr and m_mach_kernel_addr both + // invalid, return m_dyld_all_image_infos_addr + // in case it has a useful value. + return m_dyld_all_image_infos_addr; } lldb_private::ObjectFile *ProcessMachCore::GetCoreObjectFile() { diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h index 8996ae116614b..6ba9f2354edf9 100644 --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h @@ -131,6 +131,7 @@ class ProcessMachCore : public lldb_private::PostMortemProcess { VMRangeToPermissions m_core_range_infos; lldb::ModuleSP m_core_module_sp; lldb::addr_t m_dyld_addr; + lldb::addr_t m_dyld_all_image_infos_addr; lldb::addr_t m_mach_kernel_addr; llvm::StringRef m_dyld_plugin_name; };