================
@@ -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