Skip to content

Commit 92bd2e4

Browse files
committed
Add mach-o corefile support for platform binaries
Add support for recognizing a platform binary in the ObjectFileMachO method that parses the "load binary" LC_NOTEs in a corefile. A bit of reorganization to ProcessMachCore::DoLoadCore to separate all of the unrelated things being done in that method into their own separate methods, as well as small fixes to improve the handling of a corefile with multiple kernel images in the corefile. Differential Revision: https://reviews.llvm.org/D133680 rdar://98754861
1 parent d00b0aa commit 92bd2e4

File tree

6 files changed

+271
-187
lines changed

6 files changed

+271
-187
lines changed

lldb/include/lldb/Target/DynamicLoader.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,13 @@ class DynamicLoader : public PluginInterface {
226226
/// \param[in] process
227227
/// The process to add this binary to.
228228
///
229+
/// \param[in] name
230+
/// Name of the binary, if available. If this method cannot find a
231+
/// matching binary on the debug host, it may create a memory module
232+
/// out of live memory, and the provided name will be used. If an
233+
/// empty StringRef is provided, a name will be constructed for the module
234+
/// based on the address it is loaded at.
235+
///
229236
/// \param[in] uuid
230237
/// UUID of the binary to be loaded. UUID may be empty, and if a
231238
/// load address is supplied, will read the binary from memory, get
@@ -251,10 +258,9 @@ class DynamicLoader : public PluginInterface {
251258
///
252259
/// \return
253260
/// Returns a shared pointer for the Module that has been added.
254-
static lldb::ModuleSP
255-
LoadBinaryWithUUIDAndAddress(Process *process, UUID uuid, lldb::addr_t value,
256-
bool value_is_offset, bool force_symbol_search,
257-
bool notify);
261+
static lldb::ModuleSP LoadBinaryWithUUIDAndAddress(
262+
Process *process, llvm::StringRef name, UUID uuid, lldb::addr_t value,
263+
bool value_is_offset, bool force_symbol_search, bool notify);
258264

259265
/// Get information about the shared cache for a process, if possible.
260266
///

lldb/source/Core/DynamicLoader.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -175,17 +175,19 @@ ModuleSP DynamicLoader::LoadModuleAtAddress(const FileSpec &file,
175175
return nullptr;
176176
}
177177

178-
static ModuleSP ReadUnnamedMemoryModule(Process *process, addr_t addr) {
178+
static ModuleSP ReadUnnamedMemoryModule(Process *process, addr_t addr,
179+
llvm::StringRef name) {
179180
char namebuf[80];
180-
snprintf(namebuf, sizeof(namebuf), "memory-image-0x%" PRIx64, addr);
181-
return process->ReadModuleFromMemory(FileSpec(namebuf), addr);
181+
if (name.empty()) {
182+
snprintf(namebuf, sizeof(namebuf), "memory-image-0x%" PRIx64, addr);
183+
name = namebuf;
184+
}
185+
return process->ReadModuleFromMemory(FileSpec(name), addr);
182186
}
183187

184-
ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(Process *process,
185-
UUID uuid, addr_t value,
186-
bool value_is_offset,
187-
bool force_symbol_search,
188-
bool notify) {
188+
ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(
189+
Process *process, llvm::StringRef name, UUID uuid, addr_t value,
190+
bool value_is_offset, bool force_symbol_search, bool notify) {
189191
ModuleSP memory_module_sp;
190192
ModuleSP module_sp;
191193
PlatformSP platform_sp = process->GetTarget().GetPlatform();
@@ -195,7 +197,7 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(Process *process,
195197
module_spec.GetUUID() = uuid;
196198

197199
if (!uuid.IsValid() && !value_is_offset) {
198-
memory_module_sp = ReadUnnamedMemoryModule(process, value);
200+
memory_module_sp = ReadUnnamedMemoryModule(process, value, name);
199201

200202
if (memory_module_sp)
201203
uuid = memory_module_sp->GetUUID();
@@ -223,7 +225,7 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress(Process *process,
223225
// read it out of memory.
224226
if (!module_sp.get() && value != LLDB_INVALID_ADDRESS && !value_is_offset) {
225227
if (!memory_module_sp)
226-
memory_module_sp = ReadUnnamedMemoryModule(process, value);
228+
memory_module_sp = ReadUnnamedMemoryModule(process, value, name);
227229
if (memory_module_sp)
228230
module_sp = memory_module_sp;
229231
}

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

Lines changed: 68 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6975,44 +6975,81 @@ ObjectFileMachO::GetCorefileAllImageInfos() {
69756975
bool ObjectFileMachO::LoadCoreFileImages(lldb_private::Process &process) {
69766976
MachOCorefileAllImageInfos image_infos = GetCorefileAllImageInfos();
69776977
Log *log = GetLog(LLDBLog::DynamicLoader);
6978+
Status error;
69786979

6980+
bool found_platform_binary = false;
69796981
ModuleList added_modules;
6980-
for (const MachOCorefileImageEntry &image : image_infos.all_image_infos) {
6981-
ModuleSP module_sp;
6982+
for (MachOCorefileImageEntry &image : image_infos.all_image_infos) {
6983+
ModuleSP module_sp, local_filesystem_module_sp;
6984+
6985+
// If this is a platform binary, it has been loaded (or registered with
6986+
// the DynamicLoader to be loaded), we don't need to do any further
6987+
// processing. We're not going to call ModulesDidLoad on this in this
6988+
// method, so notify==true.
6989+
if (process.GetTarget()
6990+
.GetDebugger()
6991+
.GetPlatformList()
6992+
.LoadPlatformBinaryAndSetup(&process, image.load_address,
6993+
true /* notify */)) {
6994+
LLDB_LOGF(log,
6995+
"ObjectFileMachO::%s binary at 0x%" PRIx64
6996+
" is a platform binary, has been handled by a Platform plugin.",
6997+
__FUNCTION__, image.load_address);
6998+
continue;
6999+
}
69827000

6983-
if (!image.filename.empty()) {
6984-
Status error;
7001+
// If this binary is currently executing, we want to force a
7002+
// possibly expensive search for the binary and its dSYM.
7003+
if (image.currently_executing && image.uuid.IsValid()) {
69857004
ModuleSpec module_spec;
69867005
module_spec.GetUUID() = image.uuid;
6987-
module_spec.GetFileSpec() = FileSpec(image.filename.c_str());
6988-
if (image.currently_executing) {
6989-
Symbols::DownloadObjectAndSymbolFile(module_spec, error, true);
6990-
if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
6991-
process.GetTarget().GetOrCreateModule(module_spec, false);
6992-
}
7006+
Symbols::DownloadObjectAndSymbolFile(module_spec, error, true);
7007+
if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
7008+
module_sp = process.GetTarget().GetOrCreateModule(module_spec, false);
7009+
process.GetTarget().GetImages().AppendIfNeeded(module_sp,
7010+
false /* notify */);
69937011
}
7012+
}
7013+
7014+
// We have an address, that's the best way to discover the binary.
7015+
if (!module_sp && image.load_address != LLDB_INVALID_ADDRESS) {
7016+
module_sp = DynamicLoader::LoadBinaryWithUUIDAndAddress(
7017+
&process, image.filename, image.uuid, image.load_address,
7018+
false /* value_is_offset */, image.currently_executing,
7019+
false /* notify */);
7020+
}
7021+
7022+
// If we have a slide, we need to find the original binary
7023+
// by UUID, then we can apply the slide value.
7024+
if (!module_sp && image.uuid.IsValid() &&
7025+
image.slide != LLDB_INVALID_ADDRESS) {
7026+
module_sp = DynamicLoader::LoadBinaryWithUUIDAndAddress(
7027+
&process, image.filename, image.uuid, image.slide,
7028+
true /* value_is_offset */, image.currently_executing,
7029+
false /* notify */);
7030+
}
7031+
7032+
// Try to find the binary by UUID or filename on the local
7033+
// filesystem or in lldb's global module cache.
7034+
if (!module_sp) {
7035+
Status error;
7036+
ModuleSpec module_spec;
7037+
if (image.uuid.IsValid())
7038+
module_spec.GetUUID() = image.uuid;
7039+
if (!image.filename.empty())
7040+
module_spec.GetFileSpec() = FileSpec(image.filename.c_str());
69947041
module_sp =
69957042
process.GetTarget().GetOrCreateModule(module_spec, false, &error);
69967043
process.GetTarget().GetImages().AppendIfNeeded(module_sp,
69977044
false /* notify */);
6998-
} else {
6999-
if (image.load_address != LLDB_INVALID_ADDRESS) {
7000-
module_sp = DynamicLoader::LoadBinaryWithUUIDAndAddress(
7001-
&process, image.uuid, image.load_address,
7002-
false /* value_is_offset */, image.currently_executing,
7003-
false /* notify */);
7004-
} else if (image.slide != LLDB_INVALID_ADDRESS) {
7005-
module_sp = DynamicLoader::LoadBinaryWithUUIDAndAddress(
7006-
&process, image.uuid, image.slide, true /* value_is_offset */,
7007-
image.currently_executing, false /* notify */);
7008-
}
70097045
}
70107046

7011-
if (module_sp.get()) {
7012-
// Will call ModulesDidLoad with all modules once they've all
7013-
// been added to the Target with load addresses. Don't notify
7014-
// here, before the load address is set.
7047+
// We have a ModuleSP to load in the Target. Load it at the
7048+
// correct address/slide and notify/load scripting resources.
7049+
if (module_sp) {
70157050
added_modules.Append(module_sp, false /* notify */);
7051+
7052+
// We have a list of segment load address
70167053
if (image.segment_load_addresses.size() > 0) {
70177054
if (log) {
70187055
std::string uuidstr = image.uuid.GetAsString();
@@ -7073,5 +7110,11 @@ bool ObjectFileMachO::LoadCoreFileImages(lldb_private::Process &process) {
70737110
process.Flush();
70747111
return true;
70757112
}
7113+
// Return true if the only binary we found was the platform binary,
7114+
// and it was loaded outside the scope of this method.
7115+
if (found_platform_binary)
7116+
return true;
7117+
7118+
// No binaries.
70767119
return false;
70777120
}

lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,7 @@ Status ProcessGDBRemote::DoConnectRemote(llvm::StringRef remote_url) {
575575
const bool force_symbol_search = true;
576576
const bool notify = true;
577577
DynamicLoader::LoadBinaryWithUUIDAndAddress(
578-
this, standalone_uuid, standalone_value,
578+
this, llvm::StringRef(), standalone_uuid, standalone_value,
579579
standalone_value_is_offset, force_symbol_search, notify);
580580
}
581581
}
@@ -607,7 +607,8 @@ Status ProcessGDBRemote::DoConnectRemote(llvm::StringRef remote_url) {
607607
const bool force_symbol_search = true;
608608
// Second manually load this binary into the Target.
609609
DynamicLoader::LoadBinaryWithUUIDAndAddress(
610-
this, uuid, addr, value_is_slide, force_symbol_search, notify);
610+
this, llvm::StringRef(), uuid, addr, value_is_slide,
611+
force_symbol_search, notify);
611612
}
612613
}
613614

0 commit comments

Comments
 (0)