|
35 | 35 | #include <CoreFoundation/CoreFoundation.h>
|
36 | 36 | #include <Foundation/Foundation.h>
|
37 | 37 | #include <mach-o/dyld.h>
|
| 38 | +#if __has_include(<mach-o/dyld_introspection.h>) |
| 39 | +#include <mach-o/dyld_introspection.h> |
| 40 | +#define SDK_HAS_NEW_DYLD_INTROSPECTION_SPIS |
| 41 | +#endif |
38 | 42 | #include <objc/objc-auto.h>
|
39 | 43 |
|
40 | 44 | // These are needed when compiling on systems
|
@@ -525,6 +529,41 @@ static void ParseOSVersion(llvm::VersionTuple &version, NSString *Key) {
|
525 | 529 | }
|
526 | 530 |
|
527 | 531 | SharedCacheInfo::SharedCacheInfo() {
|
| 532 | +#if defined(SDK_HAS_NEW_DYLD_INTROSPECTION_SPIS) |
| 533 | + if (__builtin_available(macOS 12, *)) { |
| 534 | + if (dyld_process_create_for_current_task) { |
| 535 | + auto dyld_process = dyld_process_create_for_current_task(); |
| 536 | + auto snapshot = |
| 537 | + dyld_process_snapshot_create_for_process(dyld_process, nullptr); |
| 538 | + auto shared_cache = dyld_process_snapshot_get_shared_cache(snapshot); |
| 539 | + assert(dyld_process && snapshot && shared_cache); |
| 540 | + |
| 541 | + dyld_shared_cache_for_each_image(shared_cache, ^(dyld_image_t image) { |
| 542 | + __block uint64_t minVmAddr = UINT64_MAX; |
| 543 | + __block uint64_t maxVmAddr = 0; |
| 544 | + uuid_t uuidStore; |
| 545 | + __block uuid_t *uuid = &uuidStore; |
| 546 | + |
| 547 | + dyld_image_for_each_segment_info(image, ^(const char *segmentName, |
| 548 | + uint64_t vmAddr, |
| 549 | + uint64_t vmSize, int perm) { |
| 550 | + minVmAddr = std::min(minVmAddr, vmAddr); |
| 551 | + maxVmAddr = std::max(maxVmAddr, vmAddr + vmSize); |
| 552 | + dyld_image_copy_uuid(image, uuid); |
| 553 | + }); |
| 554 | + assert(minVmAddr != UINT_MAX); |
| 555 | + assert(maxVmAddr != 0); |
| 556 | + m_images[dyld_image_get_installname(image)] = SharedCacheImageInfo{ |
| 557 | + UUID::fromData(uuid, 16), |
| 558 | + std::make_shared<DataBufferUnowned>((uint8_t *)minVmAddr, |
| 559 | + maxVmAddr - minVmAddr)}; |
| 560 | + }); |
| 561 | + dyld_process_snapshot_dispose(snapshot); |
| 562 | + return; |
| 563 | + } |
| 564 | + } |
| 565 | +#endif |
| 566 | + |
528 | 567 | size_t shared_cache_size;
|
529 | 568 | uint8_t *shared_cache_start =
|
530 | 569 | _dyld_get_shared_cache_range(&shared_cache_size);
|
|
0 commit comments