[Lldb-commits] [lldb] [lldb][macOS] Index shared cache files by UUID & filename (PR #180874)

Jason Molenda via lldb-commits lldb-commits at lists.llvm.org
Fri Feb 13 13:42:56 PST 2026


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

>From 8e20b05454a651d86e3a2d4197c0c520f0d413ee Mon Sep 17 00:00:00 2001
From: Jason Molenda <jmolenda at apple.com>
Date: Tue, 10 Feb 2026 18:13:46 -0800
Subject: [PATCH 1/8] [lldb][macOS] Index shared cache files by UUID & filename

The shared cache index only had accessors for getting a file from
a shared cache by filename.  In some environments like iOS Simulator,
a filename can be either the actual realpath name of the framework
in an SDK or simulator runtime install location, or rooted on /
like /System/LibraryFrameworks/SwiftUI.framework.  Because the searches
for binaries were by filename, this divergence would be a problem.
However, searching for binaries by the binary's UUID can remove
taht ambiguity.

I changed HostInfoMacOSX's store of SharedCacheImageInfo's to have
a std::vector of all of the SharedCacheImageInfo's in a shared
cache.  Then I create a mapping of filename-to-SharedCacheImageInfo*
and a mapping of UUID-to-SharedCacheImageInfo*, both pointing into
the now-frozen std::vector.  I added a HostInfo::GetSharedCacheImageInfo
method to fetch an entry by shared-cache UUID + file UUID, in addition
to the previous shared-cache UUID + filename.

The filenames are stored as StringRefs  in HostInfoMacOSX, but I
was not convident about the lifetime of the c-strings I was getting
from the libdyld SPI.  I created ConstStrings for them and have the
StringRef's refer to the constant string pool, to sidestep this
problem.

rdar://148939795
---
 lldb/include/lldb/Host/HostInfoBase.h         |  24 +++-
 .../include/lldb/Host/macosx/HostInfoMacOSX.h |   3 +
 .../Host/macosx/objcxx/HostInfoMacOSX.mm      | 106 +++++++++++++++---
 .../MacOSX-DYLD/DynamicLoaderDarwin.cpp       |  25 +++--
 .../Platform/MacOSX/PlatformDarwinDevice.cpp  |  21 ++--
 5 files changed, 139 insertions(+), 40 deletions(-)

diff --git a/lldb/include/lldb/Host/HostInfoBase.h b/lldb/include/lldb/Host/HostInfoBase.h
index bc80e5e62ed39..d6423e602c7fc 100644
--- a/lldb/include/lldb/Host/HostInfoBase.h
+++ b/lldb/include/lldb/Host/HostInfoBase.h
@@ -30,15 +30,17 @@ class FileSpec;
 
 struct SharedCacheImageInfo {
   SharedCacheImageInfo()
-      : m_uuid(), m_extractor_sp(), m_create_data_extractor(nullptr),
-        m_image_baton(nullptr) {}
-  SharedCacheImageInfo(UUID uuid, lldb::DataExtractorSP extractor_sp)
-      : m_uuid(uuid), m_extractor_sp(extractor_sp),
+      : m_filename(), m_uuid(), m_extractor_sp(),
+        m_create_data_extractor(nullptr), m_image_baton(nullptr) {}
+  SharedCacheImageInfo(ConstString filename, UUID uuid,
+                       lldb::DataExtractorSP extractor_sp)
+      : m_filename(filename), m_uuid(uuid), m_extractor_sp(extractor_sp),
         m_create_data_extractor(nullptr), m_image_baton(nullptr) {}
   SharedCacheImageInfo(
-      UUID uuid, lldb::DataExtractorSP (*create_data_extractor)(void *image),
+      ConstString filename, UUID uuid,
+      lldb::DataExtractorSP (*create_data_extractor)(void *image),
       void *image_baton)
-      : m_uuid(uuid), m_extractor_sp(),
+      : m_filename(filename), m_uuid(uuid), m_extractor_sp(),
         m_create_data_extractor(create_data_extractor),
         m_image_baton(image_baton) {}
 
@@ -47,6 +49,7 @@ struct SharedCacheImageInfo {
       m_extractor_sp = m_create_data_extractor(m_image_baton);
     return m_extractor_sp;
   }
+  lldb_private::ConstString GetFilename() const { return m_filename; }
   const UUID &GetUUID() const { return m_uuid; }
   void *GetImageBaton();
   void SetExtractor(lldb::DataExtractorSP extractor_sp) {
@@ -57,6 +60,7 @@ struct SharedCacheImageInfo {
       lldb::DataExtractorSP (*create_data_extractor)(void *image));
 
 private:
+  lldb_private::ConstString m_filename;
   UUID m_uuid;
   lldb::DataExtractorSP m_extractor_sp;
   lldb::DataExtractorSP (*m_create_data_extractor)(void *image);
@@ -198,6 +202,14 @@ class HostInfoBase {
     return {};
   }
 
+  /// Return information about module with UUID \p file_uuid, if it is loaded in
+  /// the current process's address space using shared cache \p sc_uuid.
+  /// The shared cache must have been previously indexed.
+  static SharedCacheImageInfo GetSharedCacheImageInfo(const UUID &file_uuid,
+                                                      const UUID &sc_uuid) {
+    return {};
+  }
+
   /// Scan the files in a shared cache, if the filepath and uuid match
   /// on the debug host.
   /// Returns false if the shared cache filepath did not exist, or uuid
diff --git a/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h b/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h
index c58056cb492b7..d57e5e9dd4a0c 100644
--- a/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h
+++ b/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h
@@ -48,6 +48,9 @@ class HostInfoMacOSX : public HostInfoPosix {
   static SharedCacheImageInfo
   GetSharedCacheImageInfo(llvm::StringRef image_name, const UUID &uuid);
 
+  static SharedCacheImageInfo GetSharedCacheImageInfo(const UUID &file_uuid,
+                                                      const UUID &sc_uuid);
+
   static bool SharedCacheIndexFiles(FileSpec &filepath, UUID &uuid);
 
 protected:
diff --git a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
index d37062b152a00..dfb61d151cbb7 100644
--- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
+++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
@@ -12,6 +12,7 @@
 #include "lldb/Host/Host.h"
 #include "lldb/Host/HostInfo.h"
 #include "lldb/Utility/Args.h"
+#include "lldb/Utility/ConstString.h"
 #include "lldb/Utility/DataBuffer.h"
 #include "lldb/Utility/DataExtractor.h"
 #include "lldb/Utility/LLDBLog.h"
@@ -19,6 +20,7 @@
 #include "lldb/Utility/Timer.h"
 #include "lldb/Utility/VirtualDataExtractor.h"
 
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringMap.h"
@@ -684,14 +686,29 @@ void dyld_shared_cache_for_each_image(dyld_shared_cache_t cache,
 namespace {
 class SharedCacheInfo {
 public:
-  llvm::StringMap<SharedCacheImageInfo> &GetImages() {
-    return m_caches[m_host_uuid];
+  llvm::StringMap<SharedCacheImageInfo *> &GetFilenameToImageInfoMap() {
+    return m_filename_map[m_host_uuid];
+  }
+  llvm::DenseMap<UUID, SharedCacheImageInfo *> &GetUUIDToImageInfoMap() {
+    return m_uuid_map[m_host_uuid];
+  }
+
+  bool
+  GetFilenameToImageInfoMap(llvm::StringMap<SharedCacheImageInfo *> **images,
+                            const UUID &sc_uuid) {
+    if (m_filename_map.contains(sc_uuid)) {
+      *images = &m_filename_map[sc_uuid];
+      return true;
+    }
+    *images = nullptr;
+    return false;
   }
 
-  bool GetImages(llvm::StringMap<SharedCacheImageInfo> **images,
-                 const UUID &uuid) {
-    if (m_caches.find(uuid) != m_caches.end()) {
-      *images = &m_caches[uuid];
+  bool
+  GetUUIDToImageInfoMap(llvm::DenseMap<UUID, SharedCacheImageInfo *> **images,
+                        const UUID &sc_uuid) {
+    if (m_uuid_map.contains(sc_uuid)) {
+      *images = &m_uuid_map[sc_uuid];
       return true;
     }
     *images = nullptr;
@@ -709,7 +726,12 @@ bool GetImages(llvm::StringMap<SharedCacheImageInfo> **images,
   void CreateSharedCacheInfoLLDBsVirtualMemory();
   bool CreateHostSharedCacheImageList();
 
-  std::map<UUID, llvm::StringMap<SharedCacheImageInfo>> m_caches;
+  std::vector<SharedCacheImageInfo> m_file_infos;
+  llvm::SmallDenseMap<UUID, llvm::StringMap<SharedCacheImageInfo *>>
+      m_filename_map;
+  llvm::SmallDenseMap<UUID, llvm::DenseMap<UUID, SharedCacheImageInfo *>>
+      m_uuid_map;
+
   UUID m_host_uuid;
 
   // macOS 26.4 and newer
@@ -735,6 +757,9 @@ bool GetImages(llvm::StringMap<SharedCacheImageInfo> **images,
   _dyld_get_shared_cache_uuid(dsc_uuid);
   m_host_uuid = UUID(dsc_uuid);
 
+  // In macOS 26, a shared cache has around 3500 files.
+  m_file_infos.reserve(4000);
+
   if (ModuleList::GetGlobalModuleListProperties()
           .GetSharedCacheBinaryLoading() &&
       CreateHostSharedCacheImageList())
@@ -866,20 +891,31 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)(
         return;
       UUID image_uuid(uuid_tmp, sizeof(uuid_t));
 
+      // Copy the filename into the const string pool to
+      // ensure lifetime.
+      ConstString installname(dyld_image_get_installname(image));
       Log *log = GetLog(LLDBLog::Modules);
       if (log && log->GetVerbose())
-        LLDB_LOGF(log, "sc file %s image %p", dyld_image_get_installname(image),
+        LLDB_LOGF(log, "sc file %s image %p", installname.GetCString(),
                   (void *)image);
 
       m_dyld_image_retain_4HWTrace(image);
-      m_caches[m_host_uuid][dyld_image_get_installname(image)] =
-          SharedCacheImageInfo(image_uuid, map_shared_cache_binary_segments,
-                               image);
+      m_file_infos.push_back(SharedCacheImageInfo(
+          installname, image_uuid, map_shared_cache_binary_segments, image));
     });
   });
   if (return_failed)
     return false;
 
+  // vector of SharedCacheImageInfos has been fully populated, we can
+  // take pointers to the objects now.
+  size_t file_info_size = m_file_infos.size();
+  for (size_t i = 0; i < file_info_size; i++) {
+    SharedCacheImageInfo *entry = &m_file_infos[i];
+    m_filename_map[m_host_uuid][entry->GetFilename()] = entry;
+    m_uuid_map[m_host_uuid][entry->GetUUID()] = entry;
+  }
+
   return true;
 }
 
@@ -944,7 +980,10 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)(
     lldb::DataBufferSP data_sp = std::make_shared<DataBufferUnowned>(
         (uint8_t *)minVmAddr, maxVmAddr - minVmAddr);
     lldb::DataExtractorSP extractor_sp = std::make_shared<DataExtractor>(data_sp);
-    m_caches[m_host_uuid][dyld_image_get_installname(image)] =
+    // Copy the filename into the const string pool to
+    // ensure lifetime.
+    ConstString installname(dyld_image_get_installname(image));
+    m_caches[m_host_uuid][installname.GetStringRef()] =
         SharedCacheImageInfo{UUID(uuid, 16), extractor_sp};
   });
   return true;
@@ -968,9 +1007,19 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)(
             shared_cache_size - info->textSegmentOffset);
         lldb::DataExtractorSP extractor_sp =
             std::make_shared<DataExtractor>(buffer_sp);
-        m_caches[m_host_uuid][info->path] =
-            SharedCacheImageInfo{UUID(info->dylibUuid, 16), extractor_sp};
+        ConstString filepath(info->path);
+        m_file_infos.push_back(SharedCacheImageInfo(
+            filepath, UUID(info->dylibUuid, 16), extractor_sp));
       });
+
+  // vector of SharedCacheImageInfos has been fully populated, we can
+  // take pointers to the objects now.
+  size_t file_info_size = m_file_infos.size();
+  for (size_t i = 0; i < file_info_size; i++) {
+    SharedCacheImageInfo *entry = &m_file_infos[i];
+    m_filename_map[m_host_uuid][entry->GetFilename()] = entry;
+    m_uuid_map[m_host_uuid][entry->GetUUID()] = entry;
+  }
 }
 
 SharedCacheInfo &GetSharedCacheSingleton() {
@@ -980,15 +1029,36 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)(
 
 SharedCacheImageInfo
 HostInfoMacOSX::GetSharedCacheImageInfo(llvm::StringRef image_name) {
-  return GetSharedCacheSingleton().GetImages().lookup(image_name);
+  SharedCacheImageInfo *entry =
+      GetSharedCacheSingleton().GetFilenameToImageInfoMap().lookup(image_name);
+  if (entry)
+    return *entry;
+  return {};
 }
 
 SharedCacheImageInfo
 HostInfoMacOSX::GetSharedCacheImageInfo(llvm::StringRef image_name,
                                         const UUID &uuid) {
-  llvm::StringMap<SharedCacheImageInfo> *shared_cache_info;
-  if (GetSharedCacheSingleton().GetImages(&shared_cache_info, uuid))
-    return shared_cache_info->lookup(image_name);
+  llvm::StringMap<SharedCacheImageInfo *> *shared_cache_info;
+  if (GetSharedCacheSingleton().GetFilenameToImageInfoMap(&shared_cache_info,
+                                                          uuid)) {
+    SharedCacheImageInfo *entry = shared_cache_info->lookup(image_name);
+    if (entry)
+      return *entry;
+  }
+  return {};
+}
+
+SharedCacheImageInfo
+HostInfoMacOSX::GetSharedCacheImageInfo(const UUID &file_uuid,
+                                        const UUID &sc_uuid) {
+  llvm::DenseMap<UUID, SharedCacheImageInfo *> *shared_cache_info;
+  if (GetSharedCacheSingleton().GetUUIDToImageInfoMap(&shared_cache_info,
+                                                      sc_uuid)) {
+    SharedCacheImageInfo *entry = shared_cache_info->lookup(file_uuid);
+    if (entry)
+      return *entry;
+  }
   return {};
 }
 
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
index 0a8aa51a1469c..8658cba0689be 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
@@ -130,12 +130,13 @@ ModuleSP DynamicLoaderDarwin::FindTargetModuleForImageInfo(
 
   if (!module_sp &&
       HostInfo::GetArchitecture().IsCompatibleMatch(target.GetArchitecture())) {
-    // When debugging on the host, we are most likely using the same shared
-    // cache as our inferior. The dylibs from the shared cache might not
-    // exist on the filesystem, so let's use the images in our own memory
-    // to create the modules.
-    // Check if the requested image is in our shared cache.
+
     SharedCacheImageInfo image_info;
+
+    // If we have a shared cache filepath and UUID, ask HostInfo
+    // if it can provide the SourceCacheImageInfo for the binary
+    // out of that shared cache.  Search by the Module's UUID if
+    // available, else the filepath.
     addr_t sc_base_addr;
     UUID sc_uuid;
     LazyBool using_sc;
@@ -143,12 +144,18 @@ ModuleSP DynamicLoaderDarwin::FindTargetModuleForImageInfo(
     FileSpec sc_path;
     if (GetSharedCacheInformation(sc_base_addr, sc_uuid, using_sc, private_sc,
                                   sc_path) &&
-        sc_uuid)
-      image_info = HostInfo::GetSharedCacheImageInfo(
-          module_spec.GetFileSpec().GetPath(), sc_uuid);
-    else
+        sc_uuid) {
+      if (module_spec.GetUUID())
+        image_info =
+            HostInfo::GetSharedCacheImageInfo(module_spec.GetUUID(), sc_uuid);
+      else
+        image_info = HostInfo::GetSharedCacheImageInfo(
+            module_spec.GetFileSpec().GetPath(), sc_uuid);
+    } else {
+      // Fall back to looking lldb's own shared cache by filename
       image_info = HostInfo::GetSharedCacheImageInfo(
           module_spec.GetFileSpec().GetPath());
+    };
 
     // If we found it and it has the correct UUID, let's proceed with
     // creating a module from the memory contents.
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp
index 59d2f9ed9d856..ab12ada1fdf43 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp
@@ -314,11 +314,11 @@ lldb_private::Status PlatformDarwinDevice::GetSharedModuleWithLocalCache(
   Status err;
 
   if (CheckLocalSharedCache()) {
-    // When debugging on the host, we are most likely using the same shared
-    // cache as our inferior. The dylibs from the shared cache might not
-    // exist on the filesystem, so let's use the images in our own memory
-    // to create the modules.
 
+    // If we have a shared cache filepath and UUID, ask HostInfo
+    // if it can provide the SourceCacheImageInfo for the binary
+    // out of that shared cache.  Search by the Module's UUID if
+    // available, else the filepath.
     SharedCacheImageInfo image_info;
     if (process && process->GetDynamicLoader()) {
       addr_t sc_base_addr;
@@ -326,11 +326,18 @@ lldb_private::Status PlatformDarwinDevice::GetSharedModuleWithLocalCache(
       LazyBool using_sc, private_sc;
       FileSpec sc_path;
       if (process->GetDynamicLoader()->GetSharedCacheInformation(
-              sc_base_addr, sc_uuid, using_sc, private_sc, sc_path))
-        image_info = HostInfo::GetSharedCacheImageInfo(
-            module_spec.GetFileSpec().GetPath(), sc_uuid);
+              sc_base_addr, sc_uuid, using_sc, private_sc, sc_path)) {
+        if (module_spec.GetUUID()) {
+          image_info =
+              HostInfo::GetSharedCacheImageInfo(module_spec.GetUUID(), sc_uuid);
+        } else {
+          image_info = HostInfo::GetSharedCacheImageInfo(
+              module_spec.GetFileSpec().GetPath(), sc_uuid);
+        }
+      }
     }
 
+    // Fall back to looking for the file in lldb's own shared cache.
     if (!image_info.GetUUID())
       image_info = HostInfo::GetSharedCacheImageInfo(
           module_spec.GetFileSpec().GetPath());

>From f313ebc8d290ef19038fe11e7d59f3c4c2607bb0 Mon Sep 17 00:00:00 2001
From: Jason Molenda <jmolenda at apple.com>
Date: Wed, 11 Feb 2026 12:13:13 -0800
Subject: [PATCH 2/8] remove extra semicolon

---
 .../Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp   | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
index 8658cba0689be..19455838e988b 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
@@ -155,7 +155,7 @@ ModuleSP DynamicLoaderDarwin::FindTargetModuleForImageInfo(
       // Fall back to looking lldb's own shared cache by filename
       image_info = HostInfo::GetSharedCacheImageInfo(
           module_spec.GetFileSpec().GetPath());
-    };
+    }
 
     // If we found it and it has the correct UUID, let's proceed with
     // creating a module from the memory contents.

>From 7536b6a10131034dbb232469d102dc147a2f15ad Mon Sep 17 00:00:00 2001
From: Jason Molenda <github-mail at molenda.com>
Date: Thu, 12 Feb 2026 14:06:55 -0800
Subject: [PATCH 3/8] Update lldb/include/lldb/Host/HostInfoBase.h

Co-authored-by: Jonas Devlieghere <jonas at devlieghere.com>
---
 lldb/include/lldb/Host/HostInfoBase.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/include/lldb/Host/HostInfoBase.h b/lldb/include/lldb/Host/HostInfoBase.h
index d6423e602c7fc..9110d38e9709f 100644
--- a/lldb/include/lldb/Host/HostInfoBase.h
+++ b/lldb/include/lldb/Host/HostInfoBase.h
@@ -60,7 +60,7 @@ struct SharedCacheImageInfo {
       lldb::DataExtractorSP (*create_data_extractor)(void *image));
 
 private:
-  lldb_private::ConstString m_filename;
+  ConstString m_filename;
   UUID m_uuid;
   lldb::DataExtractorSP m_extractor_sp;
   lldb::DataExtractorSP (*m_create_data_extractor)(void *image);

>From a24c8db9b0041a34a6979dbadaac4fcad2dac2ac Mon Sep 17 00:00:00 2001
From: Jason Molenda <github-mail at molenda.com>
Date: Fri, 13 Feb 2026 11:06:37 -0800
Subject: [PATCH 4/8] Update lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm

Co-authored-by: Jonas Devlieghere <jonas at devlieghere.com>
---
 lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
index dfb61d151cbb7..ba9e941013393 100644
--- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
+++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
@@ -907,7 +907,7 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)(
   if (return_failed)
     return false;
 
-  // vector of SharedCacheImageInfos has been fully populated, we can
+  // Vector of SharedCacheImageInfos has been fully populated, we can
   // take pointers to the objects now.
   size_t file_info_size = m_file_infos.size();
   for (size_t i = 0; i < file_info_size; i++) {

>From 8e76f92a055263e1b232c124ee7702c94088d535 Mon Sep 17 00:00:00 2001
From: Jason Molenda <github-mail at molenda.com>
Date: Fri, 13 Feb 2026 11:06:49 -0800
Subject: [PATCH 5/8] Update lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm

Co-authored-by: Jonas Devlieghere <jonas at devlieghere.com>
---
 lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
index ba9e941013393..21299a0c1d159 100644
--- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
+++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
@@ -1029,9 +1029,7 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)(
 
 SharedCacheImageInfo
 HostInfoMacOSX::GetSharedCacheImageInfo(llvm::StringRef image_name) {
-  SharedCacheImageInfo *entry =
-      GetSharedCacheSingleton().GetFilenameToImageInfoMap().lookup(image_name);
-  if (entry)
+  if (SharedCacheImageInfo *entry = GetSharedCacheSingleton().GetFilenameToImageInfoMap().lookup(image_name))
     return *entry;
   return {};
 }

>From 329a97c39abb040687e620ce69398976524d380f Mon Sep 17 00:00:00 2001
From: Jason Molenda <github-mail at molenda.com>
Date: Fri, 13 Feb 2026 11:07:22 -0800
Subject: [PATCH 6/8] Update lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm

Co-authored-by: Jonas Devlieghere <jonas at devlieghere.com>
---
 lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
index 21299a0c1d159..8e511dd864ea0 100644
--- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
+++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
@@ -1040,8 +1040,7 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)(
   llvm::StringMap<SharedCacheImageInfo *> *shared_cache_info;
   if (GetSharedCacheSingleton().GetFilenameToImageInfoMap(&shared_cache_info,
                                                           uuid)) {
-    SharedCacheImageInfo *entry = shared_cache_info->lookup(image_name);
-    if (entry)
+    if (SharedCacheImageInfo *entry = shared_cache_info->lookup(image_name))
       return *entry;
   }
   return {};

>From 4e2c9578667c0872db6e075af65a1e513e3573b3 Mon Sep 17 00:00:00 2001
From: Jason Molenda <github-mail at molenda.com>
Date: Fri, 13 Feb 2026 11:07:34 -0800
Subject: [PATCH 7/8] Update lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm

Co-authored-by: Jonas Devlieghere <jonas at devlieghere.com>
---
 lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
index 8e511dd864ea0..247e7dfd18078 100644
--- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
+++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
@@ -1052,8 +1052,7 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)(
   llvm::DenseMap<UUID, SharedCacheImageInfo *> *shared_cache_info;
   if (GetSharedCacheSingleton().GetUUIDToImageInfoMap(&shared_cache_info,
                                                       sc_uuid)) {
-    SharedCacheImageInfo *entry = shared_cache_info->lookup(file_uuid);
-    if (entry)
+    if (SharedCacheImageInfo *entry = shared_cache_info->lookup(file_uuid))
       return *entry;
   }
   return {};

>From c39e0a2a1fbcb9b64ff8522a3c5fc95b4f916b13 Mon Sep 17 00:00:00 2001
From: Jason Molenda <jmolenda at apple.com>
Date: Fri, 13 Feb 2026 13:40:45 -0800
Subject: [PATCH 8/8] Address Jonas' feedback points.

Also, fix a mistake in HostInfoMacOSX where it would never
use a shared cache other than lldb's own shared cache.

Change the HostInfo::GetSharedCacheImageInfo calls to
accept a ModuleSpec instead of having versions that take
a filename or UUID.  The HostInfoMacOSX method is a good
place to check for either one based on which is available.
---
 lldb/include/lldb/Host/HostInfoBase.h         | 15 +---
 .../include/lldb/Host/macosx/HostInfoMacOSX.h |  8 +-
 .../Host/macosx/objcxx/HostInfoMacOSX.mm      | 82 +++++++++----------
 .../MacOSX-DYLD/DynamicLoaderDarwin.cpp       | 10 +--
 .../Platform/MacOSX/PlatformDarwinDevice.cpp  | 11 +--
 .../SymbolLocatorDebugSymbols.cpp             |  8 +-
 .../ObjectFile/MachO/TestObjectFileMachO.cpp  | 10 ++-
 7 files changed, 60 insertions(+), 84 deletions(-)

diff --git a/lldb/include/lldb/Host/HostInfoBase.h b/lldb/include/lldb/Host/HostInfoBase.h
index 9110d38e9709f..0c6bf4c4b0983 100644
--- a/lldb/include/lldb/Host/HostInfoBase.h
+++ b/lldb/include/lldb/Host/HostInfoBase.h
@@ -187,25 +187,16 @@ class HostInfoBase {
     return llvm::errorCodeToError(llvm::errc::no_such_file_or_directory);
   }
 
-  /// Return information about module \p image_name if it is loaded in
+  /// Return information about module \p spec if it is loaded in
   /// the current process's address space.
-  static SharedCacheImageInfo
-  GetSharedCacheImageInfo(llvm::StringRef image_name) {
-    return {};
-  }
-
-  /// Return information about module \p image_name if it is loaded in
-  /// the current process's address space using shared cache \p uuid.
-  /// The shared cache UUID must have been previously indexed.
-  static SharedCacheImageInfo
-  GetSharedCacheImageInfo(llvm::StringRef image_name, const UUID &uuid) {
+  static SharedCacheImageInfo GetSharedCacheImageInfo(const ModuleSpec &spec) {
     return {};
   }
 
   /// Return information about module with UUID \p file_uuid, if it is loaded in
   /// the current process's address space using shared cache \p sc_uuid.
   /// The shared cache must have been previously indexed.
-  static SharedCacheImageInfo GetSharedCacheImageInfo(const UUID &file_uuid,
+  static SharedCacheImageInfo GetSharedCacheImageInfo(const ModuleSpec &spec,
                                                       const UUID &sc_uuid) {
     return {};
   }
diff --git a/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h b/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h
index d57e5e9dd4a0c..7ec8c8d852cf6 100644
--- a/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h
+++ b/lldb/include/lldb/Host/macosx/HostInfoMacOSX.h
@@ -42,13 +42,9 @@ class HostInfoMacOSX : public HostInfoPosix {
                                                      llvm::StringRef tool);
 
   /// Shared cache utilities
-  static SharedCacheImageInfo
-  GetSharedCacheImageInfo(llvm::StringRef image_name);
+  static SharedCacheImageInfo GetSharedCacheImageInfo(const ModuleSpec &spec);
 
-  static SharedCacheImageInfo
-  GetSharedCacheImageInfo(llvm::StringRef image_name, const UUID &uuid);
-
-  static SharedCacheImageInfo GetSharedCacheImageInfo(const UUID &file_uuid,
+  static SharedCacheImageInfo GetSharedCacheImageInfo(const ModuleSpec &spec,
                                                       const UUID &sc_uuid);
 
   static bool SharedCacheIndexFiles(FileSpec &filepath, UUID &uuid);
diff --git a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
index 247e7dfd18078..05e094e60c440 100644
--- a/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
+++ b/lldb/source/Host/macosx/objcxx/HostInfoMacOSX.mm
@@ -686,33 +686,26 @@ void dyld_shared_cache_for_each_image(dyld_shared_cache_t cache,
 namespace {
 class SharedCacheInfo {
 public:
-  llvm::StringMap<SharedCacheImageInfo *> &GetFilenameToImageInfoMap() {
+  llvm::DenseMap<ConstString, SharedCacheImageInfo *> &
+  GetHostSCFilenameToImageInfoMap() {
     return m_filename_map[m_host_uuid];
   }
-  llvm::DenseMap<UUID, SharedCacheImageInfo *> &GetUUIDToImageInfoMap() {
+  llvm::DenseMap<UUID, SharedCacheImageInfo *> &GetHostSCUUIDToImageInfoMap() {
     return m_uuid_map[m_host_uuid];
   }
 
-  bool
-  GetFilenameToImageInfoMap(llvm::StringMap<SharedCacheImageInfo *> **images,
-                            const UUID &sc_uuid) {
-    if (m_filename_map.contains(sc_uuid)) {
-      *images = &m_filename_map[sc_uuid];
-      return true;
-    }
-    *images = nullptr;
-    return false;
+  llvm::DenseMap<ConstString, SharedCacheImageInfo *> *
+  GetFilenameToImageInfoMap(const UUID &sc_uuid) {
+    if (m_filename_map.contains(sc_uuid))
+      return &m_filename_map[sc_uuid];
+    return nullptr;
   }
 
-  bool
-  GetUUIDToImageInfoMap(llvm::DenseMap<UUID, SharedCacheImageInfo *> **images,
-                        const UUID &sc_uuid) {
-    if (m_uuid_map.contains(sc_uuid)) {
-      *images = &m_uuid_map[sc_uuid];
-      return true;
-    }
-    *images = nullptr;
-    return false;
+  llvm::DenseMap<UUID, SharedCacheImageInfo *> *
+  GetUUIDToImageInfoMap(const UUID &sc_uuid) {
+    if (m_uuid_map.contains(sc_uuid))
+      return &m_uuid_map[sc_uuid];
+    return nullptr;
   }
 
   /// Given the UUID and filepath to a shared cache on the local debug host
@@ -727,7 +720,7 @@ void dyld_shared_cache_for_each_image(dyld_shared_cache_t cache,
   bool CreateHostSharedCacheImageList();
 
   std::vector<SharedCacheImageInfo> m_file_infos;
-  llvm::SmallDenseMap<UUID, llvm::StringMap<SharedCacheImageInfo *>>
+  llvm::SmallDenseMap<UUID, llvm::DenseMap<ConstString, SharedCacheImageInfo *>>
       m_filename_map;
   llvm::SmallDenseMap<UUID, llvm::DenseMap<UUID, SharedCacheImageInfo *>>
       m_uuid_map;
@@ -1012,7 +1005,7 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)(
             filepath, UUID(info->dylibUuid, 16), extractor_sp));
       });
 
-  // vector of SharedCacheImageInfos has been fully populated, we can
+  // std::vector of SharedCacheImageInfos has been fully populated, we can
   // take pointers to the objects now.
   size_t file_info_size = m_file_infos.size();
   for (size_t i = 0; i < file_info_size; i++) {
@@ -1028,33 +1021,36 @@ static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)(
 }
 
 SharedCacheImageInfo
-HostInfoMacOSX::GetSharedCacheImageInfo(llvm::StringRef image_name) {
-  if (SharedCacheImageInfo *entry = GetSharedCacheSingleton().GetFilenameToImageInfoMap().lookup(image_name))
+HostInfoMacOSX::GetSharedCacheImageInfo(const ModuleSpec &spec) {
+  SharedCacheImageInfo *entry = nullptr;
+  if (spec.GetUUID())
+    entry = GetSharedCacheSingleton().GetHostSCUUIDToImageInfoMap().lookup(
+        spec.GetUUID());
+  else
+    entry = GetSharedCacheSingleton().GetHostSCFilenameToImageInfoMap().lookup(
+        spec.GetFileSpec().GetPathAsConstString());
+  if (entry)
     return *entry;
   return {};
 }
 
 SharedCacheImageInfo
-HostInfoMacOSX::GetSharedCacheImageInfo(llvm::StringRef image_name,
-                                        const UUID &uuid) {
-  llvm::StringMap<SharedCacheImageInfo *> *shared_cache_info;
-  if (GetSharedCacheSingleton().GetFilenameToImageInfoMap(&shared_cache_info,
-                                                          uuid)) {
-    if (SharedCacheImageInfo *entry = shared_cache_info->lookup(image_name))
-      return *entry;
-  }
-  return {};
-}
-
-SharedCacheImageInfo
-HostInfoMacOSX::GetSharedCacheImageInfo(const UUID &file_uuid,
+HostInfoMacOSX::GetSharedCacheImageInfo(const ModuleSpec &spec,
                                         const UUID &sc_uuid) {
-  llvm::DenseMap<UUID, SharedCacheImageInfo *> *shared_cache_info;
-  if (GetSharedCacheSingleton().GetUUIDToImageInfoMap(&shared_cache_info,
-                                                      sc_uuid)) {
-    if (SharedCacheImageInfo *entry = shared_cache_info->lookup(file_uuid))
-      return *entry;
-  }
+  llvm::DenseMap<UUID, SharedCacheImageInfo *> *uuid_to_fileinfos =
+      GetSharedCacheSingleton().GetUUIDToImageInfoMap(sc_uuid);
+  llvm::DenseMap<ConstString, SharedCacheImageInfo *> *filename_to_fileinfos =
+      GetSharedCacheSingleton().GetFilenameToImageInfoMap(sc_uuid);
+
+  SharedCacheImageInfo *entry = nullptr;
+  if (uuid_to_fileinfos && spec.GetUUID())
+    entry = uuid_to_fileinfos->lookup(spec.GetUUID());
+  else if (filename_to_fileinfos)
+    entry = filename_to_fileinfos->lookup(
+        spec.GetFileSpec().GetPathAsConstString());
+
+  if (entry)
+    return *entry;
   return {};
 }
 
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
index 19455838e988b..f70a08de3c5ee 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp
@@ -145,16 +145,10 @@ ModuleSP DynamicLoaderDarwin::FindTargetModuleForImageInfo(
     if (GetSharedCacheInformation(sc_base_addr, sc_uuid, using_sc, private_sc,
                                   sc_path) &&
         sc_uuid) {
-      if (module_spec.GetUUID())
-        image_info =
-            HostInfo::GetSharedCacheImageInfo(module_spec.GetUUID(), sc_uuid);
-      else
-        image_info = HostInfo::GetSharedCacheImageInfo(
-            module_spec.GetFileSpec().GetPath(), sc_uuid);
+      image_info = HostInfo::GetSharedCacheImageInfo(module_spec, sc_uuid);
     } else {
       // Fall back to looking lldb's own shared cache by filename
-      image_info = HostInfo::GetSharedCacheImageInfo(
-          module_spec.GetFileSpec().GetPath());
+      image_info = HostInfo::GetSharedCacheImageInfo(module_spec);
     }
 
     // If we found it and it has the correct UUID, let's proceed with
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp
index ab12ada1fdf43..890ad300b3e36 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwinDevice.cpp
@@ -327,20 +327,13 @@ lldb_private::Status PlatformDarwinDevice::GetSharedModuleWithLocalCache(
       FileSpec sc_path;
       if (process->GetDynamicLoader()->GetSharedCacheInformation(
               sc_base_addr, sc_uuid, using_sc, private_sc, sc_path)) {
-        if (module_spec.GetUUID()) {
-          image_info =
-              HostInfo::GetSharedCacheImageInfo(module_spec.GetUUID(), sc_uuid);
-        } else {
-          image_info = HostInfo::GetSharedCacheImageInfo(
-              module_spec.GetFileSpec().GetPath(), sc_uuid);
-        }
+        image_info = HostInfo::GetSharedCacheImageInfo(module_spec, sc_uuid);
       }
     }
 
     // Fall back to looking for the file in lldb's own shared cache.
     if (!image_info.GetUUID())
-      image_info = HostInfo::GetSharedCacheImageInfo(
-          module_spec.GetFileSpec().GetPath());
+      image_info = HostInfo::GetSharedCacheImageInfo(module_spec);
 
     // If we found it and it has the correct UUID, let's proceed with
     // creating a module from the memory contents.
diff --git a/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.cpp b/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.cpp
index f4b572c9e88ac..8597dff457c39 100644
--- a/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.cpp
+++ b/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.cpp
@@ -203,8 +203,8 @@ std::optional<ModuleSpec> SymbolLocatorDebugSymbols::LocateExecutableObjectFile(
 
           // Check if the requested image is in our shared cache.
           if (!success) {
-            SharedCacheImageInfo image_info = HostInfo::GetSharedCacheImageInfo(
-                module_spec.GetFileSpec().GetPath());
+            SharedCacheImageInfo image_info =
+                HostInfo::GetSharedCacheImageInfo(module_spec);
 
             // If we found it and it has the correct UUID, let's proceed with
             // creating a module from the memory contents.
@@ -646,8 +646,8 @@ static int LocateMacOSXFilesUsingDebugSymbols(const ModuleSpec &module_spec,
 
           // Check if the requested image is in our shared cache.
           if (!success) {
-            SharedCacheImageInfo image_info = HostInfo::GetSharedCacheImageInfo(
-                module_spec.GetFileSpec().GetPath());
+            SharedCacheImageInfo image_info =
+                HostInfo::GetSharedCacheImageInfo(module_spec);
 
             // If we found it and it has the correct UUID, let's proceed with
             // creating a module from the memory contents.
diff --git a/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp b/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp
index 5b516fc2582f5..a761b55983edf 100644
--- a/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp
+++ b/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp
@@ -12,8 +12,10 @@
 #include "TestingSupport/SubsystemRAII.h"
 #include "TestingSupport/TestUtilities.h"
 #include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
 #include "lldb/Host/FileSystem.h"
 #include "lldb/Host/HostInfo.h"
+#include "lldb/Utility/FileSpec.h"
 #include "lldb/lldb-defines.h"
 #include "gtest/gtest.h"
 
@@ -37,8 +39,10 @@ TEST_F(ObjectFileMachOTest, ModuleFromSharedCacheInfo) {
 
   Platform::SetHostPlatform(PlatformRemoteMacOSX::CreateInstance(true, &arch));
 
+  ModuleSpec mod_spec;
+  mod_spec.GetFileSpec() = FileSpec("/usr/lib/libobjc.A.dylib");
   SharedCacheImageInfo image_info =
-      HostInfo::GetSharedCacheImageInfo("/usr/lib/libobjc.A.dylib");
+      HostInfo::GetSharedCacheImageInfo(mod_spec);
   EXPECT_TRUE(image_info.GetUUID());
   EXPECT_TRUE(image_info.GetExtractor());
 
@@ -85,8 +89,10 @@ TEST_F(ObjectFileMachOTest, ModuleFromSharedCacheInfo) {
 }
 
 TEST_F(ObjectFileMachOTest, IndirectSymbolsInTheSharedCache) {
+  ModuleSpec mod_spec;
+  mod_spec.GetFileSpec() = FileSpec("/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit");
   SharedCacheImageInfo image_info = HostInfo::GetSharedCacheImageInfo(
-      "/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit");
+      mod_spec);
   ModuleSpec spec(FileSpec(), UUID(), image_info.GetExtractor());
   lldb::ModuleSP module = std::make_shared<Module>(spec);
 



More information about the lldb-commits mailing list