================
@@ -649,30 +653,228 @@ static bool ResolveAndVerifyCandidateSupportDir(FileSpec 
&path) {
     dyld_shared_cache_dylib_text_info;
 }
 
-extern "C" int dyld_shared_cache_iterate_text(
+// All available on at least macOS 12
+extern "C" {
+int dyld_shared_cache_iterate_text(
     const uuid_t cacheUuid,
     void (^callback)(const dyld_shared_cache_dylib_text_info *info));
-extern "C" uint8_t *_dyld_get_shared_cache_range(size_t *length);
-extern "C" bool _dyld_get_shared_cache_uuid(uuid_t uuid);
+uint8_t *_dyld_get_shared_cache_range(size_t *length);
+bool _dyld_get_shared_cache_uuid(uuid_t uuid);
+bool dyld_image_for_each_segment_info(void *image,
+                                      void (^)(const char *segmentName,
+                                               uint64_t vmAddr, uint64_t 
vmSize,
+                                               int perm));
+const char *dyld_shared_cache_file_path(void);
+bool dyld_shared_cache_for_file(const char *filePath,
+                                void (^block)(void *cache));
+void dyld_shared_cache_copy_uuid(void *cache, uuid_t *uuid);
+uint64_t dyld_shared_cache_get_base_address(void *cache);
+void dyld_shared_cache_for_each_image(void *cache, void (^block)(void *image));
+bool dyld_image_copy_uuid(void *cache, uuid_t *uuid);
+const char *dyld_image_get_installname(void *image);
+const char *dyld_image_get_file_path(void *image);
+}
 
 namespace {
 class SharedCacheInfo {
 public:
-  const UUID &GetUUID() const { return m_uuid; }
-  const llvm::StringMap<SharedCacheImageInfo> &GetImages() const {
-    return m_images;
+  llvm::StringMap<SharedCacheImageInfo> &GetImages() {
+    return m_caches[m_host_uuid];
   }
 
   SharedCacheInfo();
 
 private:
   bool CreateSharedCacheInfoWithInstrospectionSPIs();
+  void CreateSharedCacheInfoLLDBsVirtualMemory();
+  bool CreateHostSharedCacheImageList();
+
+  // Given the UUID and filepath to a shared cache on the local debug host
+  // system, open it and add all of the binary images to m_caches.
+  bool CreateSharedCacheImageList(UUID uuid, std::string filepath);
 
-  llvm::StringMap<SharedCacheImageInfo> m_images;
-  UUID m_uuid;
+  std::map<UUID, llvm::StringMap<SharedCacheImageInfo>> m_caches;
+  UUID m_host_uuid;
+
+  // macOS 26.4 and newer
+  void (*m_dyld_image_retain_4HWTrace)(void *image);
+  void (*m_dyld_image_release_4HWTrace)(void *image);
+  dispatch_data_t (*m_dyld_image_segment_data_4HWTrace)(
+      void *image, const char *segmentName);
 };
+
+} // namespace
+
+SharedCacheInfo::SharedCacheInfo() {
+  // macOS 26.4 and newer
+  m_dyld_image_retain_4HWTrace =
+      (void (*)(void *))dlsym(RTLD_DEFAULT, "dyld_image_retain_4HWTrace");
+  m_dyld_image_release_4HWTrace =
+      (void (*)(void *))dlsym(RTLD_DEFAULT, "dyld_image_release_4HWTrace");
+  m_dyld_image_segment_data_4HWTrace =
+      (dispatch_data_t(*)(void *image, const char *segmentName))dlsym(
+          RTLD_DEFAULT, "dyld_image_segment_data_4HWTrace");
+
+  uuid_t dsc_uuid;
+  _dyld_get_shared_cache_uuid(dsc_uuid);
+  m_host_uuid = UUID(dsc_uuid);
+
+  if (ModuleList::GetGlobalModuleListProperties()
+          .GetSharedCacheSegmentLoads() &&
+      CreateHostSharedCacheImageList())
+    return;
+
+  if (CreateSharedCacheInfoWithInstrospectionSPIs())
+    return;
+
+  CreateSharedCacheInfoLLDBsVirtualMemory();
 }
 
+struct segment {
+  std::string name;
+  uint64_t vmaddr;
+  size_t vmsize;
+
+  // Mapped into lldb's own address space via libdispatch:
+  const void *data;
+  size_t size;
+};
+
+static DataExtractorSP map_shared_cache_binary_segments(void *image) {
+  // dyld_image_segment_data_4HWTrace can't be called on
+  // multiple threads simultaneously.
+  static std::mutex g_mutex;
+  std::lock_guard<std::mutex> guard(g_mutex);
+
+  static dispatch_data_t (*g_dyld_image_segment_data_4HWTrace)(
+      void *image, const char *segmentName);
+  static std::once_flag g_once_flag;
+  std::call_once(g_once_flag, [&]() {
+    g_dyld_image_segment_data_4HWTrace =
+        (dispatch_data_t(*)(void *, const char *))dlsym(
+            RTLD_DEFAULT, "dyld_image_segment_data_4HWTrace");
+  });
+  if (!g_dyld_image_segment_data_4HWTrace)
+    return {};
+
+  __block std::vector<segment> segments;
+  __block void *image_copy = image;
+  dyld_image_for_each_segment_info(
+      image,
+      ^(const char *segmentName, uint64_t vmAddr, uint64_t vmSize, int perm) {
+        segment seg;
+        seg.name = segmentName;
+        seg.vmaddr = vmAddr;
+        seg.vmsize = vmSize;
+
+        dispatch_data_t data_from_libdyld =
+            g_dyld_image_segment_data_4HWTrace(image_copy, segmentName);
+        (void)dispatch_data_create_map(data_from_libdyld, &seg.data, 
&seg.size);
+
+        segments.push_back(seg);
+      });
+
+  if (!segments.size())
+    return {};
+
+  Log *log = GetLog(LLDBLog::Modules);
+  for (segment seg : segments) {
+    if (log && log->GetVerbose())
+      LLDB_LOGF(
+          log,
+          "image %p %s vmaddr 0x%llx vmsize 0x%zx mapped to lldb vm addr %p",
+          image, seg.name.c_str(), seg.vmaddr, seg.vmsize, seg.data);
+  }
----------------
JDevlieghere wrote:

If you're going to check log, let's do it outside the loop. I suspect the 
compiler will be smart enough to generate the equivalent code, but it's still 
nice as a human to see it too. 

https://github.com/llvm/llvm-project/pull/179881
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to