[Lldb-commits] [lldb] d70d5e9 - Get binary UUID from fixed location in special Mach-O corefiles
Jason Molenda via lldb-commits
lldb-commits at lists.llvm.org
Tue Aug 15 14:34:17 PDT 2023
Author: Jason Molenda
Date: 2023-08-15T13:49:57-07:00
New Revision: d70d5e9f6fa2770f9a5e7be4ba6b3512f5424968
URL: https://github.com/llvm/llvm-project/commit/d70d5e9f6fa2770f9a5e7be4ba6b3512f5424968
DIFF: https://github.com/llvm/llvm-project/commit/d70d5e9f6fa2770f9a5e7be4ba6b3512f5424968.diff
LOG: Get binary UUID from fixed location in special Mach-O corefiles
Some Apple firmware environments store the UUID of the main binary
at a fixed address in low memory. Add that list of addresess to
ProcessMachCore to check for a UUID, and try to load it.
Differential Revision: https://reviews.llvm.org/D157756
Added:
Modified:
lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
Removed:
################################################################################
diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
index 9ad6d70e25299d..9859e5982a01df 100644
--- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
+++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
@@ -28,6 +28,7 @@
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/State.h"
+#include "lldb/Utility/UUID.h"
#include "ProcessMachCore.h"
#include "Plugins/Process/Utility/StopInfoMachException.h"
@@ -223,6 +224,66 @@ void ProcessMachCore::CreateMemoryRegions() {
}
}
+// Some corefiles have a UUID stored in a low memory
+// address. We inspect a set list of addresses for
+// the characters 'uuid' and 16 bytes later there will
+// be a uuid_t UUID. If we can find a binary that
+// matches the UUID, it is loaded with no slide in the target.
+bool ProcessMachCore::LoadBinaryViaLowmemUUID() {
+ Log *log(GetLog(LLDBLog::DynamicLoader | LLDBLog::Process));
+ ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
+
+ uint64_t lowmem_uuid_addresses[] = {0x2000204, 0x1000204, 0x1000020, 0x4204,
+ 0x1204, 0x1020, 0x4020, 0xc00,
+ 0xC0, 0};
+
+ for (uint64_t addr : lowmem_uuid_addresses) {
+ const VMRangeToFileOffset::Entry *core_memory_entry =
+ m_core_aranges.FindEntryThatContains(addr);
+ if (core_memory_entry) {
+ const addr_t offset = addr - core_memory_entry->GetRangeBase();
+ const addr_t bytes_left = core_memory_entry->GetRangeEnd() - addr;
+ // (4-bytes 'uuid' + 12 bytes pad for align + 16 bytes uuid_t) == 32 bytes
+ if (bytes_left >= 32) {
+ char strbuf[4];
+ if (core_objfile->CopyData(
+ core_memory_entry->data.GetRangeBase() + offset, 4, &strbuf) &&
+ strncmp("uuid", (char *)&strbuf, 4) == 0) {
+ uuid_t uuid_bytes;
+ if (core_objfile->CopyData(core_memory_entry->data.GetRangeBase() +
+ offset + 16,
+ sizeof(uuid_t), uuid_bytes)) {
+ UUID uuid(uuid_bytes, sizeof(uuid_t));
+ if (uuid.IsValid()) {
+ LLDB_LOGF(log,
+ "ProcessMachCore::LoadBinaryViaLowmemUUID: found "
+ "binary uuid %s at low memory address 0x%" PRIx64,
+ uuid.GetAsString().c_str(), addr);
+ // We have no address specified, only a UUID. Load it at the file
+ // address.
+ const bool value_is_offset = true;
+ const bool force_symbol_search = true;
+ const bool notify = true;
+ const bool set_address_in_target = true;
+ const bool allow_memory_image_last_resort = false;
+ if (DynamicLoader::LoadBinaryWithUUIDAndAddress(
+ this, llvm::StringRef(), uuid, 0, value_is_offset,
+ force_symbol_search, notify, set_address_in_target,
+ allow_memory_image_last_resort)) {
+ m_dyld_plugin_name = DynamicLoaderStatic::GetPluginNameStatic();
+ }
+ // We found metadata saying which binary should be loaded; don't
+ // try an exhaustive search.
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
bool ProcessMachCore::LoadBinariesViaMetadata() {
Log *log(GetLog(LLDBLog::DynamicLoader | LLDBLog::Process));
ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
@@ -338,6 +399,9 @@ bool ProcessMachCore::LoadBinariesViaMetadata() {
m_dyld_plugin_name = DynamicLoaderStatic::GetPluginNameStatic();
}
+ if (!found_binary_spec_in_metadata && LoadBinaryViaLowmemUUID())
+ found_binary_spec_in_metadata = true;
+
// LoadCoreFileImges may have set the dynamic loader, e.g. in
// PlatformDarwinKernel::LoadPlatformBinaryAndSetup().
// If we now have a dynamic loader, save its name so we don't
diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
index 112e674627125b..c8820209e3f383 100644
--- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
+++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
@@ -87,6 +87,8 @@ class ProcessMachCore : public lldb_private::PostMortemProcess {
private:
void CreateMemoryRegions();
+ bool LoadBinaryViaLowmemUUID();
+
/// \return
/// True if any metadata were found indicating the binary that should
/// be loaded, regardless of whether the specified binary could be found.
More information about the lldb-commits
mailing list