[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