Skip to content

Commit ee80f49

Browse files
committed
[lldb][Mach-O] Read dyld_all_image_infos addr from main bin spec LC_NOTE (llvm#127156)
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 (cherry picked from commit 1f5edb1)
1 parent 2f72f06 commit ee80f49

File tree

4 files changed

+56
-12
lines changed

4 files changed

+56
-12
lines changed

lldb/include/lldb/Symbol/ObjectFile.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,14 @@ class ObjectFile : public std::enable_shared_from_this<ObjectFile>,
8181
enum BinaryType {
8282
eBinaryTypeInvalid = 0,
8383
eBinaryTypeUnknown,
84-
eBinaryTypeKernel, /// kernel binary
85-
eBinaryTypeUser, /// user process binary
86-
eBinaryTypeStandalone /// standalone binary / firmware
84+
/// kernel binary
85+
eBinaryTypeKernel,
86+
/// user process binary, dyld addr
87+
eBinaryTypeUser,
88+
/// user process binary, dyld_all_image_infos addr
89+
eBinaryTypeUserAllImageInfos,
90+
/// standalone binary / firmware
91+
eBinaryTypeStandalone
8792
};
8893

8994
struct LoadableData {

lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5625,9 +5625,13 @@ bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &value,
56255625
// struct main_bin_spec
56265626
// {
56275627
// uint32_t version; // currently 2
5628-
// uint32_t type; // 0 == unspecified, 1 == kernel,
5628+
// uint32_t type; // 0 == unspecified,
5629+
// // 1 == kernel
56295630
// // 2 == user process,
5631+
// dyld mach-o binary addr
56305632
// // 3 == standalone binary
5633+
// // 4 == user process,
5634+
// // dyld_all_image_infos addr
56315635
// uint64_t address; // UINT64_MAX if address not specified
56325636
// uint64_t slide; // slide, UINT64_MAX if unspecified
56335637
// // 0 if no slide needs to be applied to
@@ -5678,6 +5682,7 @@ bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &value,
56785682
// convert the "main bin spec" type into our
56795683
// ObjectFile::BinaryType enum
56805684
const char *typestr = "unrecognized type";
5685+
type = eBinaryTypeInvalid;
56815686
switch (binspec_type) {
56825687
case 0:
56835688
type = eBinaryTypeUnknown;
@@ -5695,6 +5700,10 @@ bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &value,
56955700
type = eBinaryTypeStandalone;
56965701
typestr = "standalone";
56975702
break;
5703+
case 4:
5704+
type = eBinaryTypeUserAllImageInfos;
5705+
typestr = "userland dyld_all_image_infos";
5706+
break;
56985707
}
56995708
LLDB_LOGF(log,
57005709
"LC_NOTE 'main bin spec' found, version %d type %d "

lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ ProcessMachCore::ProcessMachCore(lldb::TargetSP target_sp,
114114
: PostMortemProcess(target_sp, listener_sp, core_file), m_core_aranges(),
115115
m_core_range_infos(), m_core_module_sp(),
116116
m_dyld_addr(LLDB_INVALID_ADDRESS),
117+
m_dyld_all_image_infos_addr(LLDB_INVALID_ADDRESS),
117118
m_mach_kernel_addr(LLDB_INVALID_ADDRESS) {}
118119

119120
// Destructor
@@ -320,6 +321,9 @@ bool ProcessMachCore::LoadBinariesViaMetadata() {
320321
} else if (type == ObjectFile::eBinaryTypeUser) {
321322
m_dyld_addr = objfile_binary_value;
322323
m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
324+
} else if (type == ObjectFile::eBinaryTypeUserAllImageInfos) {
325+
m_dyld_all_image_infos_addr = objfile_binary_value;
326+
m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
323327
} else {
324328
const bool force_symbol_search = true;
325329
const bool notify = true;
@@ -466,6 +470,7 @@ void ProcessMachCore::LoadBinariesViaExhaustiveSearch() {
466470
addr_t saved_user_dyld_addr = m_dyld_addr;
467471
m_mach_kernel_addr = LLDB_INVALID_ADDRESS;
468472
m_dyld_addr = LLDB_INVALID_ADDRESS;
473+
m_dyld_all_image_infos_addr = LLDB_INVALID_ADDRESS;
469474

470475
addr_t better_kernel_address =
471476
DynamicLoaderDarwinKernel::SearchForDarwinKernel(this);
@@ -507,6 +512,12 @@ void ProcessMachCore::LoadBinariesAndSetDYLD() {
507512
"image at 0x%" PRIx64,
508513
__FUNCTION__, m_dyld_addr);
509514
m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
515+
} else if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS) {
516+
LLDB_LOGF(log,
517+
"ProcessMachCore::%s: Using user process dyld "
518+
"dyld_all_image_infos at 0x%" PRIx64,
519+
__FUNCTION__, m_dyld_all_image_infos_addr);
520+
m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
510521
}
511522
} else {
512523
if (m_dyld_addr != LLDB_INVALID_ADDRESS) {
@@ -515,6 +526,11 @@ void ProcessMachCore::LoadBinariesAndSetDYLD() {
515526
"image at 0x%" PRIx64,
516527
__FUNCTION__, m_dyld_addr);
517528
m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
529+
} else if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS) {
530+
LLDB_LOGF(log,
531+
"ProcessMachCore::%s: Using user process dyld "
532+
"dyld_all_image_infos at 0x%" PRIx64,
533+
__FUNCTION__, m_dyld_all_image_infos_addr);
518534
} else if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
519535
LLDB_LOGF(log,
520536
"ProcessMachCore::%s: Using kernel "
@@ -763,19 +779,32 @@ void ProcessMachCore::Initialize() {
763779
}
764780

765781
addr_t ProcessMachCore::GetImageInfoAddress() {
766-
// If we found both a user-process dyld and a kernel binary, we need to
767-
// decide which to prefer.
782+
// The DynamicLoader plugin will call back in to this Process
783+
// method to find the virtual address of one of these:
784+
// 1. The xnu mach kernel binary Mach-O header
785+
// 2. The dyld binary Mach-O header
786+
// 3. dyld's dyld_all_image_infos object
787+
//
788+
// DynamicLoaderMacOSX will accept either the dyld Mach-O header
789+
// address or the dyld_all_image_infos interchangably, no need
790+
// to distinguish between them. It disambiguates by the Mach-O
791+
// file magic number at the start.
768792
if (GetCorefilePreference() == eKernelCorefile) {
769-
if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
793+
if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS)
770794
return m_mach_kernel_addr;
771-
}
772-
return m_dyld_addr;
795+
if (m_dyld_addr != LLDB_INVALID_ADDRESS)
796+
return m_dyld_addr;
773797
} else {
774-
if (m_dyld_addr != LLDB_INVALID_ADDRESS) {
798+
if (m_dyld_addr != LLDB_INVALID_ADDRESS)
775799
return m_dyld_addr;
776-
}
777-
return m_mach_kernel_addr;
800+
if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS)
801+
return m_mach_kernel_addr;
778802
}
803+
804+
// m_dyld_addr and m_mach_kernel_addr both
805+
// invalid, return m_dyld_all_image_infos_addr
806+
// in case it has a useful value.
807+
return m_dyld_all_image_infos_addr;
779808
}
780809

781810
lldb_private::ObjectFile *ProcessMachCore::GetCoreObjectFile() {

lldb/source/Plugins/Process/mach-core/ProcessMachCore.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ class ProcessMachCore : public lldb_private::PostMortemProcess {
131131
VMRangeToPermissions m_core_range_infos;
132132
lldb::ModuleSP m_core_module_sp;
133133
lldb::addr_t m_dyld_addr;
134+
lldb::addr_t m_dyld_all_image_infos_addr;
134135
lldb::addr_t m_mach_kernel_addr;
135136
llvm::StringRef m_dyld_plugin_name;
136137
};

0 commit comments

Comments
 (0)