|
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
|
@@ -537,6 +541,41 @@ static void ParseOSVersion(llvm::VersionTuple &version, NSString *Key) {
|
537 | 541 | }
|
538 | 542 |
|
539 | 543 | SharedCacheInfo::SharedCacheInfo() {
|
| 544 | +#if defined(SDK_HAS_NEW_DYLD_INTROSPECTION_SPIS) |
| 545 | + if (__builtin_available(macOS 12, *)) { |
| 546 | + if (dyld_process_create_for_current_task) { |
| 547 | + auto dyld_process = dyld_process_create_for_current_task(); |
| 548 | + auto snapshot = |
| 549 | + dyld_process_snapshot_create_for_process(dyld_process, nullptr); |
| 550 | + auto shared_cache = dyld_process_snapshot_get_shared_cache(snapshot); |
| 551 | + assert(dyld_process && snapshot && shared_cache); |
| 552 | + |
| 553 | + dyld_shared_cache_for_each_image(shared_cache, ^(dyld_image_t image) { |
| 554 | + __block uint64_t minVmAddr = UINT64_MAX; |
| 555 | + __block uint64_t maxVmAddr = 0; |
| 556 | + uuid_t uuidStore; |
| 557 | + __block uuid_t *uuid = &uuidStore; |
| 558 | + |
| 559 | + dyld_image_for_each_segment_info(image, ^(const char *segmentName, |
| 560 | + uint64_t vmAddr, |
| 561 | + uint64_t vmSize, int perm) { |
| 562 | + minVmAddr = std::min(minVmAddr, vmAddr); |
| 563 | + maxVmAddr = std::max(maxVmAddr, vmAddr + vmSize); |
| 564 | + dyld_image_copy_uuid(image, uuid); |
| 565 | + }); |
| 566 | + assert(minVmAddr != UINT_MAX); |
| 567 | + assert(maxVmAddr != 0); |
| 568 | + m_images[dyld_image_get_installname(image)] = SharedCacheImageInfo{ |
| 569 | + UUID::fromData(uuid, 16), |
| 570 | + std::make_shared<DataBufferUnowned>((uint8_t *)minVmAddr, |
| 571 | + maxVmAddr - minVmAddr)}; |
| 572 | + }); |
| 573 | + dyld_process_snapshot_dispose(snapshot); |
| 574 | + return; |
| 575 | + } |
| 576 | + } |
| 577 | +#endif |
| 578 | + |
540 | 579 | size_t shared_cache_size;
|
541 | 580 | uint8_t *shared_cache_start =
|
542 | 581 | _dyld_get_shared_cache_range(&shared_cache_size);
|
|
0 commit comments