Skip to content

[lldb][Mach-O] Read dyld_all_image_infos addr from main bin spec LC_NOTE (#127156) #10056

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions lldb/include/lldb/Symbol/ObjectFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,14 @@ 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
/// kernel binary
eBinaryTypeKernel,
/// user process binary, dyld addr
eBinaryTypeUser,
/// user process binary, dyld_all_image_infos addr
eBinaryTypeUserAllImageInfos,
/// standalone binary / firmware
eBinaryTypeStandalone
};

struct LoadableData {
Expand Down
11 changes: 10 additions & 1 deletion lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5625,9 +5625,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
Expand Down Expand Up @@ -5678,6 +5682,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;
Expand All @@ -5695,6 +5700,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 "
Expand Down
45 changes: 37 additions & 8 deletions lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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) {
Expand All @@ -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 "
Expand Down Expand Up @@ -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() {
Expand Down
1 change: 1 addition & 0 deletions lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand Down