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
This commit is contained in:
Jason Molenda
2022-09-13 15:40:21 -07:00
parent d00b0aab31
commit 92bd2e443e
6 changed files with 265 additions and 181 deletions

View File

@@ -6975,44 +6975,81 @@ ObjectFileMachO::GetCorefileAllImageInfos() {
bool ObjectFileMachO::LoadCoreFileImages(lldb_private::Process &process) {
MachOCorefileAllImageInfos image_infos = GetCorefileAllImageInfos();
Log *log = GetLog(LLDBLog::DynamicLoader);
Status error;
bool found_platform_binary = false;
ModuleList added_modules;
for (const MachOCorefileImageEntry &image : image_infos.all_image_infos) {
ModuleSP module_sp;
for (MachOCorefileImageEntry &image : image_infos.all_image_infos) {
ModuleSP module_sp, local_filesystem_module_sp;
if (!image.filename.empty()) {
Status error;
// If this is a platform binary, it has been loaded (or registered with
// the DynamicLoader to be loaded), we don't need to do any further
// processing. We're not going to call ModulesDidLoad on this in this
// method, so notify==true.
if (process.GetTarget()
.GetDebugger()
.GetPlatformList()
.LoadPlatformBinaryAndSetup(&process, image.load_address,
true /* notify */)) {
LLDB_LOGF(log,
"ObjectFileMachO::%s binary at 0x%" PRIx64
" is a platform binary, has been handled by a Platform plugin.",
__FUNCTION__, image.load_address);
continue;
}
// If this binary is currently executing, we want to force a
// possibly expensive search for the binary and its dSYM.
if (image.currently_executing && image.uuid.IsValid()) {
ModuleSpec module_spec;
module_spec.GetUUID() = image.uuid;
module_spec.GetFileSpec() = FileSpec(image.filename.c_str());
if (image.currently_executing) {
Symbols::DownloadObjectAndSymbolFile(module_spec, error, true);
if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
process.GetTarget().GetOrCreateModule(module_spec, false);
}
Symbols::DownloadObjectAndSymbolFile(module_spec, error, true);
if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) {
module_sp = process.GetTarget().GetOrCreateModule(module_spec, false);
process.GetTarget().GetImages().AppendIfNeeded(module_sp,
false /* notify */);
}
}
// We have an address, that's the best way to discover the binary.
if (!module_sp && image.load_address != LLDB_INVALID_ADDRESS) {
module_sp = DynamicLoader::LoadBinaryWithUUIDAndAddress(
&process, image.filename, image.uuid, image.load_address,
false /* value_is_offset */, image.currently_executing,
false /* notify */);
}
// If we have a slide, we need to find the original binary
// by UUID, then we can apply the slide value.
if (!module_sp && image.uuid.IsValid() &&
image.slide != LLDB_INVALID_ADDRESS) {
module_sp = DynamicLoader::LoadBinaryWithUUIDAndAddress(
&process, image.filename, image.uuid, image.slide,
true /* value_is_offset */, image.currently_executing,
false /* notify */);
}
// Try to find the binary by UUID or filename on the local
// filesystem or in lldb's global module cache.
if (!module_sp) {
Status error;
ModuleSpec module_spec;
if (image.uuid.IsValid())
module_spec.GetUUID() = image.uuid;
if (!image.filename.empty())
module_spec.GetFileSpec() = FileSpec(image.filename.c_str());
module_sp =
process.GetTarget().GetOrCreateModule(module_spec, false, &error);
process.GetTarget().GetImages().AppendIfNeeded(module_sp,
false /* notify */);
} else {
if (image.load_address != LLDB_INVALID_ADDRESS) {
module_sp = DynamicLoader::LoadBinaryWithUUIDAndAddress(
&process, image.uuid, image.load_address,
false /* value_is_offset */, image.currently_executing,
false /* notify */);
} else if (image.slide != LLDB_INVALID_ADDRESS) {
module_sp = DynamicLoader::LoadBinaryWithUUIDAndAddress(
&process, image.uuid, image.slide, true /* value_is_offset */,
image.currently_executing, false /* notify */);
}
}
if (module_sp.get()) {
// Will call ModulesDidLoad with all modules once they've all
// been added to the Target with load addresses. Don't notify
// here, before the load address is set.
// We have a ModuleSP to load in the Target. Load it at the
// correct address/slide and notify/load scripting resources.
if (module_sp) {
added_modules.Append(module_sp, false /* notify */);
// We have a list of segment load address
if (image.segment_load_addresses.size() > 0) {
if (log) {
std::string uuidstr = image.uuid.GetAsString();
@@ -7073,5 +7110,11 @@ bool ObjectFileMachO::LoadCoreFileImages(lldb_private::Process &process) {
process.Flush();
return true;
}
// Return true if the only binary we found was the platform binary,
// and it was loaded outside the scope of this method.
if (found_platform_binary)
return true;
// No binaries.
return false;
}