[Lldb-commits] [lldb] [lldb][Mach-O] Read dyld_all_image_infos addr from `main bin spec` LC_NOTE (PR #127156)
Jason Molenda via lldb-commits
lldb-commits at lists.llvm.org
Tue Feb 18 11:46:07 PST 2025
https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/127156
>From 0a6558940403814ffa2bf6c265bc0e9267eef855 Mon Sep 17 00:00:00 2001
From: Jason Molenda <jmolenda at apple.com>
Date: Thu, 13 Feb 2025 18:20:28 -0800
Subject: [PATCH 1/2] [lldb][Mach-O] Read dyld_all_image_infos addr from `main
bin spec` LC_NOTE
Mach-O corefiles have LC_NOTE metadata, one LC_NOTE that lldb
recognizes is `main bin spec` which can specify that this is a
kernel corefile, userland corefile, or firmware/standalone corefile.
With a userland corefile, the LC_NOTE would specify the virtual
address of the dyld binary's Mach-O header. lldb would create a
Module from that in-memory binary, find the `dyld_all_image_infos`
object in dyld's DATA segment, and use that object to find all of
the binaries present in the corefile.
ProcessMachCore takes the metadata from this LC_NOTE and passes the
address to the DynamicLoader plugin via its `GetImageInfoAddress()`
method, so the DynamicLoader can find all of the binaries and load
them in the Target at their correct virtual addresses.
We have a corefile creator who would prefer to specify the address
of `dyld_all_image_infos` directly, instead of specifying the address
of dyld and parsing that to find the object. DynamicLoaderMacOSX,
the DynamicLoader plugin being used here, will accept either a
dyld virtual address or a `dyld_all_image_infos` virtual address
from ProcessMachCore, and do the correct thing with either value.
lldb's process save-core mach-o corefile reader will continue to
specify the virtual address of the dyld binary.
rdar://144322688
---
lldb/include/lldb/Symbol/ObjectFile.h | 9 ++--
.../ObjectFile/Mach-O/ObjectFileMachO.cpp | 10 ++++-
.../Process/mach-core/ProcessMachCore.cpp | 45 +++++++++++++++----
.../Process/mach-core/ProcessMachCore.h | 1 +
4 files changed, 53 insertions(+), 12 deletions(-)
diff --git a/lldb/include/lldb/Symbol/ObjectFile.h b/lldb/include/lldb/Symbol/ObjectFile.h
index d89314d44bf67..8873209eeece6 100644
--- a/lldb/include/lldb/Symbol/ObjectFile.h
+++ b/lldb/include/lldb/Symbol/ObjectFile.h
@@ -81,9 +81,12 @@ class ObjectFile : public std::enable_shared_from_this<ObjectFile>,
enum BinaryType {
eBinaryTypeInvalid = 0,
eBinaryTypeUnknown,
- eBinaryTypeKernel, /// kernel binary
- eBinaryTypeUser, /// user process binary
- eBinaryTypeStandalone /// standalone binary / firmware
+ eBinaryTypeKernel, /// kernel binary
+ eBinaryTypeUser, /// user process binary,
+ /// dyld addr
+ eBinaryTypeUserAllImageInfos, /// user process binary,
+ /// dyld_all_image_infos addr
+ eBinaryTypeStandalone /// standalone binary / firmware
};
struct LoadableData {
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index 4e356a7c8f5d9..8cf6ed268f3b8 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
@@ -5669,6 +5673,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;
};
>From 11384154451c75afc99a272e61c4e869d605a11e Mon Sep 17 00:00:00 2001
From: Jason Molenda <github-mail at molenda.com>
Date: Tue, 18 Feb 2025 11:45:55 -0800
Subject: [PATCH 2/2] Update lldb/include/lldb/Symbol/ObjectFile.h
Co-authored-by: Jonas Devlieghere <jonas at devlieghere.com>
---
lldb/include/lldb/Symbol/ObjectFile.h | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/lldb/include/lldb/Symbol/ObjectFile.h b/lldb/include/lldb/Symbol/ObjectFile.h
index 8873209eeece6..a91590ad47981 100644
--- a/lldb/include/lldb/Symbol/ObjectFile.h
+++ b/lldb/include/lldb/Symbol/ObjectFile.h
@@ -81,12 +81,14 @@ class ObjectFile : public std::enable_shared_from_this<ObjectFile>,
enum BinaryType {
eBinaryTypeInvalid = 0,
eBinaryTypeUnknown,
- eBinaryTypeKernel, /// kernel binary
- eBinaryTypeUser, /// user process binary,
- /// dyld addr
- eBinaryTypeUserAllImageInfos, /// user process binary,
- /// dyld_all_image_infos addr
- 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 {
More information about the lldb-commits
mailing list