[Lldb-commits] [lldb] [lldb][Mach-O] Read dyld_all_image_infos addr from `main bin spec` LC_NOTE (PR #127156)

Jason Molenda via lldb-commits lldb-commits at lists.llvm.org
Tue Feb 18 11:46:07 PST 2025


https://github.com/jasonmolenda updated https://github.com/llvm/llvm-project/pull/127156

>From 0a6558940403814ffa2bf6c265bc0e9267eef855 Mon Sep 17 00:00:00 2001
From: Jason Molenda <jmolenda at apple.com>
Date: Thu, 13 Feb 2025 18:20:28 -0800
Subject: [PATCH 1/2] [lldb][Mach-O] Read dyld_all_image_infos addr from `main
 bin spec` LC_NOTE

Mach-O corefiles have LC_NOTE metadata, one LC_NOTE that lldb
recognizes is `main bin spec` which can specify that this is a
kernel corefile, userland corefile, or firmware/standalone corefile.
With a userland corefile, the LC_NOTE would specify the virtual
address of the dyld binary's Mach-O header.  lldb would create a
Module from that in-memory binary, find the `dyld_all_image_infos`
object in dyld's DATA segment, and use that object to find all of
the binaries present in the corefile.

ProcessMachCore takes the metadata from this LC_NOTE and passes the
address to the DynamicLoader plugin via its `GetImageInfoAddress()`
method, so the DynamicLoader can find all of the binaries and load
them in the Target at their correct virtual addresses.

We have a corefile creator who would prefer to specify the address
of `dyld_all_image_infos` directly, instead of specifying the address
of dyld and parsing that to find the object.  DynamicLoaderMacOSX,
the DynamicLoader plugin being used here, will accept either a
dyld virtual address or a `dyld_all_image_infos` virtual address
from ProcessMachCore, and do the correct thing with either value.

lldb's process save-core mach-o corefile reader will continue to
specify the virtual address of the dyld binary.

rdar://144322688
---
 lldb/include/lldb/Symbol/ObjectFile.h         |  9 ++--
 .../ObjectFile/Mach-O/ObjectFileMachO.cpp     | 10 ++++-
 .../Process/mach-core/ProcessMachCore.cpp     | 45 +++++++++++++++----
 .../Process/mach-core/ProcessMachCore.h       |  1 +
 4 files changed, 53 insertions(+), 12 deletions(-)

diff --git a/lldb/include/lldb/Symbol/ObjectFile.h b/lldb/include/lldb/Symbol/ObjectFile.h
index d89314d44bf67..8873209eeece6 100644
--- a/lldb/include/lldb/Symbol/ObjectFile.h
+++ b/lldb/include/lldb/Symbol/ObjectFile.h
@@ -81,9 +81,12 @@ class ObjectFile : public std::enable_shared_from_this<ObjectFile>,
   enum BinaryType {
     eBinaryTypeInvalid = 0,
     eBinaryTypeUnknown,
-    eBinaryTypeKernel,    /// kernel binary
-    eBinaryTypeUser,      /// user process binary
-    eBinaryTypeStandalone /// standalone binary / firmware
+    eBinaryTypeKernel,            /// kernel binary
+    eBinaryTypeUser,              /// user process binary,
+                                  /// dyld addr
+    eBinaryTypeUserAllImageInfos, /// user process binary,
+                                  /// dyld_all_image_infos addr
+    eBinaryTypeStandalone         /// standalone binary / firmware
   };
 
   struct LoadableData {
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index 4e356a7c8f5d9..8cf6ed268f3b8 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -5599,9 +5599,13 @@ bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &value,
       // struct main_bin_spec
       // {
       //     uint32_t version;       // currently 2
-      //     uint32_t type;          // 0 == unspecified, 1 == kernel,
+      //     uint32_t type;          // 0 == unspecified,
+      //                             // 1 == kernel
       //                             // 2 == user process,
+      //                                     dyld mach-o binary addr
       //                             // 3 == standalone binary
+      //                             // 4 == user process,
+      //                             //      dyld_all_image_infos addr
       //     uint64_t address;       // UINT64_MAX if address not specified
       //     uint64_t slide;         // slide, UINT64_MAX if unspecified
       //                             // 0 if no slide needs to be applied to
@@ -5669,6 +5673,10 @@ bool ObjectFileMachO::GetCorefileMainBinaryInfo(addr_t &value,
             type = eBinaryTypeStandalone;
             typestr = "standalone";
             break;
+          case 4:
+            type = eBinaryTypeUserAllImageInfos;
+            typestr = "userland dyld_all_image_infos";
+            break;
           }
           LLDB_LOGF(log,
                     "LC_NOTE 'main bin spec' found, version %d type %d "
diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
index eef9bd4a175ec..281f3a0db8f69 100644
--- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
+++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
@@ -114,6 +114,7 @@ ProcessMachCore::ProcessMachCore(lldb::TargetSP target_sp,
     : PostMortemProcess(target_sp, listener_sp, core_file), m_core_aranges(),
       m_core_range_infos(), m_core_module_sp(),
       m_dyld_addr(LLDB_INVALID_ADDRESS),
+      m_dyld_all_image_infos_addr(LLDB_INVALID_ADDRESS),
       m_mach_kernel_addr(LLDB_INVALID_ADDRESS) {}
 
 // Destructor
@@ -320,6 +321,9 @@ bool ProcessMachCore::LoadBinariesViaMetadata() {
     } else if (type == ObjectFile::eBinaryTypeUser) {
       m_dyld_addr = objfile_binary_value;
       m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
+    } else if (type == ObjectFile::eBinaryTypeUserAllImageInfos) {
+      m_dyld_all_image_infos_addr = objfile_binary_value;
+      m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
     } else {
       const bool force_symbol_search = true;
       const bool notify = true;
@@ -466,6 +470,7 @@ void ProcessMachCore::LoadBinariesViaExhaustiveSearch() {
   addr_t saved_user_dyld_addr = m_dyld_addr;
   m_mach_kernel_addr = LLDB_INVALID_ADDRESS;
   m_dyld_addr = LLDB_INVALID_ADDRESS;
+  m_dyld_all_image_infos_addr = LLDB_INVALID_ADDRESS;
 
   addr_t better_kernel_address =
       DynamicLoaderDarwinKernel::SearchForDarwinKernel(this);
@@ -507,6 +512,12 @@ void ProcessMachCore::LoadBinariesAndSetDYLD() {
                   "image at 0x%" PRIx64,
                   __FUNCTION__, m_dyld_addr);
         m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
+      } else if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS) {
+        LLDB_LOGF(log,
+                  "ProcessMachCore::%s: Using user process dyld "
+                  "dyld_all_image_infos at 0x%" PRIx64,
+                  __FUNCTION__, m_dyld_all_image_infos_addr);
+        m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
       }
     } else {
       if (m_dyld_addr != LLDB_INVALID_ADDRESS) {
@@ -515,6 +526,11 @@ void ProcessMachCore::LoadBinariesAndSetDYLD() {
                   "image at 0x%" PRIx64,
                   __FUNCTION__, m_dyld_addr);
         m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
+      } else if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS) {
+        LLDB_LOGF(log,
+                  "ProcessMachCore::%s: Using user process dyld "
+                  "dyld_all_image_infos at 0x%" PRIx64,
+                  __FUNCTION__, m_dyld_all_image_infos_addr);
       } else if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
         LLDB_LOGF(log,
                   "ProcessMachCore::%s: Using kernel "
@@ -763,19 +779,32 @@ void ProcessMachCore::Initialize() {
 }
 
 addr_t ProcessMachCore::GetImageInfoAddress() {
-  // If we found both a user-process dyld and a kernel binary, we need to
-  // decide which to prefer.
+  // The DynamicLoader plugin will call back in to this Process
+  // method to find the virtual address of one of these:
+  //   1. The xnu mach kernel binary Mach-O header
+  //   2. The dyld binary Mach-O header
+  //   3. dyld's dyld_all_image_infos object
+  //
+  //  DynamicLoaderMacOSX will accept either the dyld Mach-O header
+  //  address or the dyld_all_image_infos interchangably, no need
+  //  to distinguish between them.  It disambiguates by the Mach-O
+  //  file magic number at the start.
   if (GetCorefilePreference() == eKernelCorefile) {
-    if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS) {
+    if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS)
       return m_mach_kernel_addr;
-    }
-    return m_dyld_addr;
+    if (m_dyld_addr != LLDB_INVALID_ADDRESS)
+      return m_dyld_addr;
   } else {
-    if (m_dyld_addr != LLDB_INVALID_ADDRESS) {
+    if (m_dyld_addr != LLDB_INVALID_ADDRESS)
       return m_dyld_addr;
-    }
-    return m_mach_kernel_addr;
+    if (m_mach_kernel_addr != LLDB_INVALID_ADDRESS)
+      return m_mach_kernel_addr;
   }
+
+  // m_dyld_addr and m_mach_kernel_addr both
+  // invalid, return m_dyld_all_image_infos_addr
+  // in case it has a useful value.
+  return m_dyld_all_image_infos_addr;
 }
 
 lldb_private::ObjectFile *ProcessMachCore::GetCoreObjectFile() {
diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
index 8996ae116614b..6ba9f2354edf9 100644
--- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
+++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
@@ -131,6 +131,7 @@ class ProcessMachCore : public lldb_private::PostMortemProcess {
   VMRangeToPermissions m_core_range_infos;
   lldb::ModuleSP m_core_module_sp;
   lldb::addr_t m_dyld_addr;
+  lldb::addr_t m_dyld_all_image_infos_addr;
   lldb::addr_t m_mach_kernel_addr;
   llvm::StringRef m_dyld_plugin_name;
 };

>From 11384154451c75afc99a272e61c4e869d605a11e Mon Sep 17 00:00:00 2001
From: Jason Molenda <github-mail at molenda.com>
Date: Tue, 18 Feb 2025 11:45:55 -0800
Subject: [PATCH 2/2] Update lldb/include/lldb/Symbol/ObjectFile.h

Co-authored-by: Jonas Devlieghere <jonas at devlieghere.com>
---
 lldb/include/lldb/Symbol/ObjectFile.h | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/lldb/include/lldb/Symbol/ObjectFile.h b/lldb/include/lldb/Symbol/ObjectFile.h
index 8873209eeece6..a91590ad47981 100644
--- a/lldb/include/lldb/Symbol/ObjectFile.h
+++ b/lldb/include/lldb/Symbol/ObjectFile.h
@@ -81,12 +81,14 @@ class ObjectFile : public std::enable_shared_from_this<ObjectFile>,
   enum BinaryType {
     eBinaryTypeInvalid = 0,
     eBinaryTypeUnknown,
-    eBinaryTypeKernel,            /// kernel binary
-    eBinaryTypeUser,              /// user process binary,
-                                  /// dyld addr
-    eBinaryTypeUserAllImageInfos, /// user process binary,
-                                  /// dyld_all_image_infos addr
-    eBinaryTypeStandalone         /// standalone binary / firmware
+    /// kernel binary
+    eBinaryTypeKernel, 
+    /// user process binary, dyld addr
+    eBinaryTypeUser,        
+    /// user process binary, dyld_all_image_infos addr
+    eBinaryTypeUserAllImageInfos, 
+    /// standalone binary / firmware
+    eBinaryTypeStandalone         
   };
 
   struct LoadableData {



More information about the lldb-commits mailing list