[Lldb-commits] [lldb] r299612 - Some old mach-o core files have an LC_IDENT load command

Jason Molenda via lldb-commits lldb-commits at lists.llvm.org
Wed Apr 5 18:50:12 PDT 2017


Author: jmolenda
Date: Wed Apr  5 20:50:11 2017
New Revision: 299612

URL: http://llvm.org/viewvc/llvm-project?rev=299612&view=rev
Log:
Some old mach-o core files have an LC_IDENT load command 
and there's a string in there that can be helpful in locating
the kernel binary.  Use it.
<rdar://problem/31444711> 

Modified:
    lldb/trunk/include/lldb/Symbol/ObjectFile.h
    lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
    lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
    lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp

Modified: lldb/trunk/include/lldb/Symbol/ObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ObjectFile.h?rev=299612&r1=299611&r2=299612&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ObjectFile.h (original)
+++ lldb/trunk/include/lldb/Symbol/ObjectFile.h Wed Apr  5 20:50:11 2017
@@ -563,6 +563,19 @@ public:
 
   virtual uint32_t GetNumThreadContexts() { return 0; }
 
+  //------------------------------------------------------------------
+  /// Some object files may have an identifier string embedded in them,
+  /// e.g. in a Mach-O core file using the LC_IDENT load command (which 
+  /// is obsolete, but can still be found in some old files)
+  ///
+  /// @return
+  ///     Returns the identifier string if one exists, else an empty
+  ///     string.
+  //------------------------------------------------------------------
+  virtual std::string GetIdentifierString () { 
+      return std::string(); 
+  }
+
   virtual lldb::RegisterContextSP
   GetThreadContextAtIndex(uint32_t idx, lldb_private::Thread &thread) {
     return lldb::RegisterContextSP();

Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=299612&r1=299611&r2=299612&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Wed Apr  5 20:50:11 2017
@@ -5353,6 +5353,37 @@ uint32_t ObjectFileMachO::GetNumThreadCo
   return m_thread_context_offsets.GetSize();
 }
 
+// The LC_IDENT load command has been obsoleted for a very
+// long time and it should not occur in Mach-O files.  But
+// if it is there, it may contain a hint about where to find
+// the main binary in a core file, so we'll use it.
+std::string ObjectFileMachO::GetIdentifierString() {
+  std::string result;
+  ModuleSP module_sp(GetModule());
+  if (module_sp) {
+    std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
+    lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
+    for (uint32_t i = 0; i < m_header.ncmds; ++i) {
+      const uint32_t cmd_offset = offset;
+      struct ident_command ident_command;
+      if (m_data.GetU32(&offset, &ident_command, 2) == NULL)
+        break;
+      if (ident_command.cmd == LC_IDENT && ident_command.cmdsize != 0) {
+        char *buf = (char *)malloc (ident_command.cmdsize);
+        if (buf != nullptr 
+            && m_data.CopyData (offset, ident_command.cmdsize, buf) == ident_command.cmdsize) {
+          buf[ident_command.cmdsize - 1] = '\0';
+          result = buf;
+        }
+        if (buf)
+          free (buf);
+      }
+      offset = cmd_offset + ident_command.cmdsize;
+    }
+  }
+  return result;
+}
+
 lldb::RegisterContextSP
 ObjectFileMachO::GetThreadContextAtIndex(uint32_t idx,
                                          lldb_private::Thread &thread) {

Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h?rev=299612&r1=299611&r2=299612&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h Wed Apr  5 20:50:11 2017
@@ -111,6 +111,8 @@ public:
 
   uint32_t GetNumThreadContexts() override;
 
+  std::string GetIdentifierString() override;
+
   lldb::RegisterContextSP
   GetThreadContextAtIndex(uint32_t idx, lldb_private::Thread &thread) override;
 

Modified: lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp?rev=299612&r1=299611&r2=299612&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp (original)
+++ lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp Wed Apr  5 20:50:11 2017
@@ -291,8 +291,42 @@ Error ProcessMachCore::DoLoadCore() {
     m_core_range_infos.Sort();
   }
 
-  if (m_dyld_addr == LLDB_INVALID_ADDRESS ||
-      m_mach_kernel_addr == LLDB_INVALID_ADDRESS) {
+
+  bool found_main_binary_definitively = false;
+
+  // This checks for the presence of an LC_IDENT string in a core file;
+  // LC_IDENT is very obsolete and should not be used in new code, but
+  // if the load command is present, let's use the contents.
+  std::string corefile_identifier = core_objfile->GetIdentifierString();
+  if (corefile_identifier.find("Darwin Kernel") != std::string::npos) {
+      UUID uuid;
+      addr_t addr = LLDB_INVALID_ADDRESS;
+      if (corefile_identifier.find("UUID=") != std::string::npos) {
+          size_t p = corefile_identifier.find("UUID=") + strlen("UUID=");
+          std::string uuid_str = corefile_identifier.substr(p, 36);
+          uuid.SetFromCString(uuid_str.c_str());
+      }
+      if (corefile_identifier.find("stext=") != std::string::npos) {
+          size_t p = corefile_identifier.find("stext=") + strlen("stext=");
+          if (corefile_identifier[p] == '0' && corefile_identifier[p + 1] == 'x') {
+              errno = 0;
+              addr = ::strtoul(corefile_identifier.c_str() + p, NULL, 16);
+              if (errno != 0 || addr == 0)
+                  addr = LLDB_INVALID_ADDRESS;
+          }
+      }
+      if (uuid.IsValid() && addr != LLDB_INVALID_ADDRESS) {
+          m_mach_kernel_addr = addr;
+          found_main_binary_definitively = true;
+          if (log)
+            log->Printf("ProcessMachCore::DoLoadCore: Using the kernel address 0x%" PRIx64
+                        "from LC_IDENT string '%s'", addr, corefile_identifier.c_str());
+      }
+  }
+
+  if (found_main_binary_definitively == false &&
+      (m_dyld_addr == LLDB_INVALID_ADDRESS ||
+      m_mach_kernel_addr == LLDB_INVALID_ADDRESS)) {
     // We need to locate the main executable in the memory ranges
     // we have in the core file.  We need to search for both a user-process dyld
     // binary
@@ -317,7 +351,8 @@ Error ProcessMachCore::DoLoadCore() {
     }
   }
 
-  if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
+  if (found_main_binary_definitively == false 
+       && m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
     // In the case of multiple kernel images found in the core file via
     // exhaustive
     // search, we may not pick the correct one.  See if the




More information about the lldb-commits mailing list