jasonmolenda created this revision.
jasonmolenda added a reviewer: jingham.
jasonmolenda added a project: LLDB.
Herald added a subscriber: JDevlieghere.
Herald added a project: All.
jasonmolenda requested review of this revision.
Herald added a subscriber: lldb-commits.

There are some Mach-O corefiles that store the UUID of the main binary at a 
list of fixed addresses in low memory, prefixed with the characters 'uuid' 16 
bytes before the 16-byte uuid itself.  This patch adds check in ProcessMachCore 
for this situation if we haven't found more authoritative metadata about the 
binary to load, tries to find the binary for that UUID and loads it in to the 
target with a slide of 0.  It's uncommon, but it would be nice if it was 
handled automatically and it's easy to drop in to ProcessMachCore at this point 
given the work I've been doing recently.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D157756

Files:
  lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
  lldb/source/Plugins/Process/mach-core/ProcessMachCore.h

Index: lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
===================================================================
--- lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
+++ lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
@@ -87,6 +87,8 @@
 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.
Index: lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
===================================================================
--- lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
+++ 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,65 @@
   }
 }
 
+// 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;
+      if (bytes_left > 20) {
+        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 +398,9 @@
     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 
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to