Loading...
common/ProcessAtlas.cpp dyld-1340 dyld-1125.5
--- dyld/dyld-1340/common/ProcessAtlas.cpp
+++ dyld/dyld-1125.5/common/ProcessAtlas.cpp
@@ -26,7 +26,6 @@
 
 #if !TARGET_OS_EXCLAVEKIT
 
-#include <span>
 #include <atomic>
 #include <cstring>
 #include <Block.h>
@@ -50,27 +49,24 @@
 #include "dyld_process_info_internal.h" // For dyld_all_image_infos_{32,64}
 
 #include "Defines.h"
-#include "Header.h"
 #include "DyldSharedCache.h"
+#include "MachOFile.h"
 #include "PVLEInt64.h"
+#include "MachOFile.h"
 #include "MachOLoaded.h"
 #include "ProcessAtlas.h"
-#include "Utilities.h"
-#include "SafeVMPrimitives.h"
+#include "Utils.h"
 
 #include "CRC32c.h"
 #include "UUID.h"
-#include "Bitmap.h"
 
 using lsl::CRC32c;
 using lsl::Allocator;
 using lsl::emitPVLEUInt64;
 using lsl::readPVLEUInt64;
-using lsl::Bitmap;
 
 using dyld3::FatFile;
-
-using mach_o::Header;
+using dyld3::MachOFile;
 // TODO: forEach shared cache needs to filter out subcaches and skip them
 
 // The allocations made by a snapshot need to last for the life of a spanshot. In libdyld that is under the caller control
@@ -80,10 +76,8 @@
 #if BUILDING_DYLD
 #define _transactionalAllocator _ephemeralAllocator
 #else
-#define _transactionalAllocator MemoryManager::memoryManager().defaultAllocator()
+#define _transactionalAllocator Allocator::defaultAllocator()
 #endif
-
-#define BLEND_KERN_RETURN_LOCATION(kr, loc) (kr) = ((kr & 0x00ffffff) | loc<<24);
 
 namespace {
 static const size_t kCachePeekSize = 0x4000;
@@ -102,7 +96,7 @@
 
 static void getCacheInfo(const dyld_cache_header *cache, uint64_t &headerSize, bool& splitCache) {
     // If we have sub caches, then the cache header itself tells us how much space we need to cover all caches
-    if ( cache->mappingOffset >= offsetof(dyld_cache_header, subCacheArrayCount) ) {
+    if ( cache->mappingOffset >= __offsetof(dyld_cache_header, subCacheArrayCount) ) {
         // New style cache
         headerSize = cache->subCacheArrayOffset + (sizeof(dyld_subcache_entry)*cache->subCacheArrayCount);
         splitCache = true;
@@ -127,6 +121,56 @@
 
 namespace dyld4 {
 namespace Atlas {
+
+Bitmap::Bitmap(Allocator& allocator, size_t size)
+    : _size(size), _bitmap(UniquePtr<std::byte>((std::byte*)allocator.malloc((size+7)/8))) {}
+
+Bitmap::Bitmap(Allocator& allocator, std::span<std::byte>& data) {
+    _size = (size_t)readPVLEUInt64(data);
+    const size_t byteSize = (_size+7)/8;
+    _bitmap = UniquePtr<std::byte>((std::byte*)allocator.malloc(byteSize));
+    _bitmap.withUnsafe([&](std::byte* bitmap) {
+        std::copy(&data[0], &data[byteSize], &bitmap[0]);
+    });
+    data = data.last(data.size()-byteSize);
+}
+
+Bitmap::Bitmap(Bitmap&& other) {
+    swap(other);
+}
+
+Bitmap& Bitmap::operator=(Bitmap&& other) {
+    swap(other);
+    return *this;
+}
+
+void Bitmap::setBit(size_t bit) {
+    contract(bit < _size);
+    _bitmap.withUnsafe([&](std::byte* bitmap) {
+        std::byte* byte = &bitmap[bit/8];
+        (*byte) |= (std::byte)(1<<(bit%8));
+    });
+}
+
+void Bitmap::emit(Vector<std::byte>& data) const {
+    emitPVLEUInt64(_size, data);
+    const size_t byteSize = (_size+7)/8;
+    _bitmap.withUnsafe([&](std::byte* bitmap) {
+        std::copy(&bitmap[0], &bitmap[byteSize], std::back_inserter(data));
+    });
+}
+
+size_t Bitmap::size() const {
+    return _size;
+}
+
+bool Bitmap::checkBit(size_t bit) const {
+    contract(bit < _size);
+    return ((std::byte)0 != _bitmap.withUnsafe([&](std::byte* bitmap) {
+        std::byte* byte = &bitmap[bit/8];
+        return ((*byte) & (std::byte)(1<<(bit%8)));
+    }));
+}
 
 #pragma mark -
 #pragma mark Mappers
@@ -165,7 +209,7 @@
 #endif
 }
 
-SharedPtr<Mapper> Mapper::mapperForSharedCache(Allocator& _ephemeralAllocator, FileRecord& file, SafePointer baseAddress) {
+SharedPtr<Mapper> Mapper::mapperForSharedCache(Allocator& _ephemeralAllocator, FileRecord& file, const void* baseAddress) {
     bool        useLocalCache   = false;
     size_t      length          = 0;
     uint64_t    slide     = 0;
@@ -203,7 +247,7 @@
     }
     if (!baseAddress) {
         // No base address passed in, treat as unslid
-        baseAddress = onDiskCacheHeader->sharedRegionStart;
+        baseAddress = (void*)onDiskCacheHeader->sharedRegionStart;
     }
     slide = (uint64_t)baseAddress-(uint64_t)onDiskCacheHeader->sharedRegionStart;
     uint64_t headerSize = 0;
@@ -251,7 +295,7 @@
         auto subCaches = (dyld_subcache_entry*)&onDiskHeaderBytes[onDiskCacheHeader->subCacheArrayOffset];
         for (auto i = 0; i < onDiskCacheHeader->subCacheArrayCount; ++i) {
             char subCachePath[PATH_MAX];
-            if (onDiskCacheHeader->mappingOffset <= offsetof(dyld_cache_header, cacheSubType)) {
+            if (onDiskCacheHeader->mappingOffset <= __offsetof(dyld_cache_header, cacheSubType)) {
                 snprintf(&subCachePath[0], sizeof(subCachePath), "%s.%u", file.getPath(), i+1);
             } else {
                 char basePath[PATH_MAX];
@@ -277,7 +321,7 @@
 
             auto onDiskSubcacheUUID = UUID(subCache->uuid);
             uint8_t uuidBuf[16];
-            if (onDiskCacheHeader->mappingOffset <= offsetof(dyld_cache_header, cacheSubType))  {
+            if (onDiskCacheHeader->mappingOffset <= __offsetof(dyld_cache_header, cacheSubType))  {
                 auto subCacheArray = (dyld_subcache_entry_v1*)&onDiskHeaderBytes[onDiskCacheHeader->subCacheArrayOffset];
                 memcpy(uuidBuf, subCacheArray[i].uuid, 16);
             } else {
@@ -361,7 +405,7 @@
     return { _transactionalAllocator.makeShared<Mapper>(_transactionalAllocator, mappings), baseAddress };
 }
 
-SharedPtr<Mapper> Mapper::mapperForMachO(Allocator& _ephemeralAllocator, FileRecord& file, const UUID& uuid, const SafePointer baseAddress) {
+SharedPtr<Mapper> Mapper::mapperForMachO(Allocator& _ephemeralAllocator, FileRecord& file, const UUID& uuid, const void* baseAddress) {
     const char* filePath = file.getPath();
     // open filePath
     int fd = dyld3::open(filePath, O_RDONLY, 0);
@@ -377,21 +421,21 @@
     }
 
     // mmap whole file temporarily
-    void* tempMapping = ::mmap(nullptr, (size_t)sb.st_size, PROT_READ, MAP_FILE | MAP_PRIVATE | MAP_RESILIENT_CODESIGN, fd, 0);
+    void* tempMapping = ::mmap(nullptr, (size_t)sb.st_size, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
     if ( tempMapping == MAP_FAILED ) {
         ::close(fd);
         return nullptr;
     }
 
     // if fat file, pick matching slice
-    __block const Header*    mf         = nullptr;
+    __block const MachOFile*    mf         = nullptr;
     const FatFile*              ff         = FatFile::isFatFile(tempMapping);
     __block uint64_t            fileOffset = 0;
     if (ff) {
         uint64_t                fileLength = sb.st_size;
         Diagnostics             diag;
         ff->forEachSlice(diag, fileLength, ^(uint32_t sliceCpuType, uint32_t sliceCpuSubType, const void *sliceStart, uint64_t sliceSize, bool &stop) {
-            auto slice = (Header*)sliceStart;
+            auto slice = (MachOFile*)sliceStart;
             uuid_t sliceUUIDRaw;
             slice->getUuid(sliceUUIDRaw);
             auto sliceUUID = UUID(sliceUUIDRaw);
@@ -405,7 +449,7 @@
         diag.clearError();
     }
     if (!mf) {
-        auto slice =  Header::isMachO({(uint8_t*)tempMapping, (size_t)sb.st_size});
+        auto slice =  MachOFile::isMachO(tempMapping);
         if (slice) {
             uuid_t sliceUUID;
             slice->getUuid(sliceUUID);
@@ -421,16 +465,16 @@
     }
     __block Vector<Mapper::Mapping> mappings(_transactionalAllocator);
     __block uint64_t slide = 0;
-    mf->forEachSegment(^(const Header::SegmentInfo &info, bool &stop) {
-        if ( info.segmentName == "__TEXT" ) {
-            slide = (uint64_t)baseAddress - info.vmaddr;
+    mf->forEachSegment(^(const MachOFile::SegmentInfo &info, bool &stop) {
+        if (strncmp(info.segName, "__TEXT", 16) == 0) {
+            slide = (uint64_t)baseAddress - info.vmAddr;
         }
 //        fprintf(stderr, "Mapping\n");
 //        fprintf(stderr, "fd\tAddress\tFile Offset\tSize\n");
 //        fprintf(stderr, "%u\t0x%llx\t0x%llx\t%llu\n", fd, info.vmAddr + slide, info.fileOffset + fileOffset, info.vmSize);
         mappings.emplace_back((Mapper::Mapping) {
-            .address = info.vmaddr + slide,
-            .size = info.vmsize,
+            .address = info.vmAddr + slide,
+            .size = info.vmSize,
             .offset = info.fileOffset + fileOffset,
             .fd = fd
         });
@@ -458,46 +502,46 @@
     }
 }
 
-std::pair<SafePointer,bool> Mapper::map(const SafePointer addr, uint64_t size) const {
+std::pair<void*,bool> Mapper::map(const void* addr, uint64_t size) const {
     if (_flatMapping) {
         uint64_t offset = (uint64_t)addr-(uint64_t)baseAddress();
-        return {(uint64_t)((uintptr_t)_flatMapping+offset),false};
+        return {(void*)((uintptr_t)_flatMapping+offset),false};
     }
     if (_mappings.size() == 0) {
         // No mappings means we are an identity mapper
-        return { addr, false };
+        return { (void*)addr, false };
     }
     for (const auto& mapping : _mappings) {
         if (((uint64_t)addr >= mapping.address) && ((uint64_t)addr < (mapping.address + mapping.size))) {
             if (mapping.fd == -1) {
-                return {(((uint64_t)addr-mapping.address)+mapping.offset), false};
+                return {(void*)(((uint64_t)addr-mapping.address)+mapping.offset), false};
             }
             assert(((uint64_t)addr + size) <= mapping.address + mapping.size);
-            uint64_t offset = (uint64_t)addr - mapping.address + mapping.offset;
+            off_t offset = (off_t)addr - mapping.address + mapping.offset;
             // Handle unaligned mmap
             void* newMapping = nullptr;
             size_t extraBytes = 0;
-            uint64_t roundedOffset = offset & (-1*PAGE_SIZE);
+            off_t roundedOffset = offset & (-1*PAGE_SIZE);
             extraBytes = (size_t)offset - (size_t)roundedOffset;
             newMapping = mmap(nullptr, (size_t)size+extraBytes, PROT_READ, MAP_FILE | MAP_PRIVATE, mapping.fd, roundedOffset);
-            if (newMapping == MAP_FAILED) {
+            if (newMapping == (void*)-1) {
 //                fprintf(stderr, "mmap failed: %s (%d)\n", strerror(errno), errno);
-                return { SafePointer(), false};
-            }
-            return {(uint64_t)((uintptr_t)newMapping+extraBytes),true};
-        }
-    }
-    return {SafePointer(), false};
-}
-
-void Mapper::unmap(const SafePointer addr, uint64_t size) const {
-    void* roundedAddr = (void*)((intptr_t)(uint64_t)addr & (-1*PAGE_SIZE));
-    size_t extraBytes = (uintptr_t)(uint64_t)addr - (uintptr_t)roundedAddr;
+                return {(void*)1, false};
+            }
+            return {(void*)((uintptr_t)newMapping+extraBytes),true};
+        }
+    }
+    return {(void*)-1, false};
+}
+
+void Mapper::unmap(const void* addr, uint64_t size) const {
+    void* roundedAddr = (void*)((intptr_t)addr & (-1*PAGE_SIZE));
+    size_t extraBytes = (uintptr_t)addr - (uintptr_t)roundedAddr;
     munmap(roundedAddr, (size_t)size+extraBytes);
 }
 
-const SafePointer Mapper::baseAddress() const {
-    return _mappings[0].address;
+const void* Mapper::baseAddress() const {
+    return (const void*)_mappings[0].address;
 }
 
 const uint64_t Mapper::size() const {
@@ -545,25 +589,25 @@
 
 #if BUILDING_DYLD
 Image::Image(RuntimeState* state, Allocator& ephemeralAllocator, SharedPtr<Mapper>& mapper, const Loader* ldr)
-    :   _ephemeralAllocator(ephemeralAllocator), _mapper(mapper), _rebasedAddress((uint64_t)ldr->loadAddress(*state)) {
+    :   _ephemeralAllocator(ephemeralAllocator), _mapper(mapper), _rebasedAddress((void*)ldr->loadAddress(*state)) {
         auto fileID = ldr->fileID(*state);
         if (fileID.inode() &&  fileID.device()) {
             _file = state->fileManager.fileRecordForFileID(ldr->fileID(*state));
             if ( _file.volume().empty() ) {
-                _file = state->fileManager.fileRecordForPath(ephemeralAllocator, ldr->path(*state));
+                _file = state->fileManager.fileRecordForPath(ephemeralAllocator, ldr->path());
             }
         } else {
-            _file = state->fileManager.fileRecordForPath(ephemeralAllocator, ldr->path(*state));
+            _file = state->fileManager.fileRecordForPath(ephemeralAllocator, ldr->path());
         }
     }
 #endif
-Image::Image(Allocator& ephemeralAllocator, FileRecord&& file, SharedPtr<Mapper>& mapper, const SafePointer mh)
-    : _ephemeralAllocator(ephemeralAllocator), _file(std::move(file)), _mapper(mapper), _rebasedAddress(mh) {}
-Image::Image(Allocator& ephemeralAllocator, FileRecord&& file, SharedPtr<Mapper>& mapper, const SafePointer mh, const UUID& uuid)
-    :  _ephemeralAllocator(ephemeralAllocator), _file(std::move(file)), _mapper(mapper), _uuid(uuid), _rebasedAddress(mh) {}
-
-Image::Image(Allocator& ephemeralAllocator, SharedPtr<Mapper>& mapper, SafePointer baseAddress, uint64_t cacheSlide, SharedCache* sharedCache)
-    : _ephemeralAllocator(ephemeralAllocator), _mapper(mapper), _sharedCacheSlide(cacheSlide), _rebasedAddress(((uint64_t)baseAddress+cacheSlide)), _sharedCache(sharedCache) {}
+Image::Image(Allocator& ephemeralAllocator, FileRecord&& file, SharedPtr<Mapper>& mapper, const struct mach_header* mh)
+    : _ephemeralAllocator(ephemeralAllocator), _file(std::move(file)), _mapper(mapper), _rebasedAddress((void*)mh) {}
+Image::Image(Allocator& ephemeralAllocator, FileRecord&& file, SharedPtr<Mapper>& mapper, const struct mach_header* mh, const UUID& uuid)
+    :  _ephemeralAllocator(ephemeralAllocator), _file(std::move(file)), _mapper(mapper), _uuid(uuid), _rebasedAddress((void*)mh) {}
+
+Image::Image(Allocator& ephemeralAllocator, SharedPtr<Mapper>& mapper, void* baseAddress, uint64_t cacheSlide, SharedCache* sharedCache)
+    : _ephemeralAllocator(ephemeralAllocator), _mapper(mapper), _sharedCacheSlide(cacheSlide), _rebasedAddress((void*)((uint64_t)baseAddress+cacheSlide)), _sharedCache(sharedCache) {}
 
 Image::Image(Image&& other) : _ephemeralAllocator(other._ephemeralAllocator) {
     swap(other);
@@ -600,7 +644,7 @@
         return nullptr;
     }
     if (!_ml) {
-        SafePointer slidML = rebasedAddress();
+        void* slidML = (void*)rebasedAddress();
         // Note, using 4k here as we might be an arm64e process inspecting an x86_64 image, which uses 4k pages
         if (!_mapper && !_mapperFailed) {
             _mapper = Mapper::mapperForMachO(_transactionalAllocator, _file, _uuid, _rebasedAddress);
@@ -610,10 +654,6 @@
             return nullptr;
         }
         _ml = _mapper->map<MachOLoaded>(slidML, 4096);
-        if (!_ml) {
-           _mapperFailed = true;
-           return nullptr;
-        }
         size_t size = _ml->sizeofcmds;
         if ( _ml->magic == MH_MAGIC_64 ) {
             size += sizeof(mach_header_64);
@@ -622,10 +662,6 @@
         }
         if (size > 4096) {
             _ml = _mapper->map<MachOLoaded>(slidML, size);
-            if (!_ml) {
-               _mapperFailed = true;
-               return nullptr;
-            }
         }
     }
     // This is a bit of a mess. With compact info this will be unified, but for now we use a lot of hacky abstactions here to deal with
@@ -636,7 +672,7 @@
 const UUID& Image::uuid() const {
     if (!_uuidLoaded) {
         uuid_t fileUUID;
-        const Header* mh = (Header*)ml();
+        const MachOLoaded* mh = ml();
         if (mh && mh->hasMachOMagic()) {
             if (mh->getUuid(fileUUID))
                 _uuid = UUID(fileUUID);
@@ -646,7 +682,7 @@
     return _uuid;
 }
 
-SafePointer Image::rebasedAddress() const {
+uint64_t Image::rebasedAddress() const {
     return (uint64_t)_rebasedAddress;
 }
 
@@ -654,7 +690,7 @@
 const char* Image::installname() const {
     if (!_installnameLoaded) {
         if (ml()) {
-            _installname = ((const Header*)ml())->installName();
+            _installname = ml()->installName();
         }
         _installnameLoaded = true;
     }
@@ -674,7 +710,7 @@
 }
 
 uint64_t Image::sharedCacheVMOffset() const {
-    return (uint64_t)_rebasedAddress - (uint64_t)sharedCache()->rebasedAddress();
+    return (uint64_t)_rebasedAddress - sharedCache()->rebasedAddress();
 }
 
 uint32_t Image::pointerSize() {
@@ -684,34 +720,34 @@
 
 bool Image::forEachSegment(void (^block)(const char* segmentName, uint64_t vmAddr, uint64_t vmSize, int perm)) {
     if (!ml()) { return false; }
-    __block uint64_t slide = (uint64_t)_rebasedAddress - ((const Header*)ml())->preferredLoadAddress();
-    ((const Header*)ml())->forEachSegment(^(const Header::SegmentInfo &info, bool &stop) {
+    __block uint64_t slide = (uint64_t)_rebasedAddress - ml()->preferredLoadAddress();
+    ml()->forEachSegment(^(const MachOLoaded::SegmentInfo &info, bool &stop) {
         uint64_t vmAddr = 0x0;
         if ( _sharedCacheSlide.has_value() ) {
-            vmAddr = info.vmaddr + _sharedCacheSlide.value();
+            vmAddr = info.vmAddr + _sharedCacheSlide.value();
         } else {
             if ( ml()->isMainExecutable() ) {
-                if ( info.segmentName.starts_with("__PAGEZERO") )
+                if ( strncmp(info.segName, "__PAGEZERO", 10) == 0 )
                     return;
             }
-            vmAddr = info.vmaddr + slide;
-        }
-        block(info.segmentName.data(), vmAddr, info.vmsize, info.initProt);
+            vmAddr = info.vmAddr + slide;
+        }
+        block(info.segName, vmAddr, info.vmSize, info.protections);
     });
     return true;
 }
 
 bool Image::forEachSection(void (^block)(const char* segmentName, const char* sectionName, uint64_t vmAddr, uint64_t vmSize)) {
     if (!ml()) { return false; }
-    __block uint64_t slide = (uint64_t)_rebasedAddress - ((const Header*)ml())->preferredLoadAddress();
-    ((const Header*)ml())->forEachSection(^(const Header::SectionInfo &info, bool &stop) {
+    __block uint64_t slide = (uint64_t)_rebasedAddress - ml()->preferredLoadAddress();
+    ml()->forEachSection(^(const MachOLoaded::SectionInfo &info, bool malformedSectionRange, bool &stop) {
         uint64_t sectAddr = 0x0;
         if ( _sharedCacheSlide.has_value() ) {
-            sectAddr = info.address + _sharedCacheSlide.value();
+            sectAddr = info.sectAddr + _sharedCacheSlide.value();
         } else {
-            sectAddr = info.address + slide;
-        }
-        block(info.segmentName.data(), info.sectionName.data(), sectAddr, info.size);
+            sectAddr = info.sectAddr + slide;
+        }
+        block(info.segInfo.segName, info.sectName, sectAddr, info.sectSize);
     });
     return true;
 }
@@ -719,23 +755,23 @@
 bool Image::contentForSegment(const char* segmentName, void (^contentReader)(const void* content, uint64_t vmAddr, uint64_t vmSize)) {
     if (!ml()) { return false; }
     __block bool result = false;
-    __block uint64_t slide = (uint64_t)_rebasedAddress - ((const Header*)ml())->preferredLoadAddress();
-    ((const Header*)ml())->forEachSegment(^(const Header::SegmentInfo &info, bool &stop) {
-        if ( segmentName != info.segmentName ) { return; }
+    __block uint64_t slide = (uint64_t)_rebasedAddress - ml()->preferredLoadAddress();
+    ml()->forEachSegment(^(const MachOLoaded::SegmentInfo &info, bool &stop) {
+        if (strcmp(segmentName, info.segName) != 0) { return; }
         uint64_t vmAddr = 0;
         if ( _sharedCacheSlide.has_value() ) {
-            vmAddr = info.vmaddr + _sharedCacheSlide.value();
+            vmAddr = info.vmAddr + _sharedCacheSlide.value();
         } else {
             if ( ml()->isMainExecutable() ) {
-                if ( info.segmentName.starts_with("__PAGEZERO") )
+                if ( strncmp(info.segName, "__PAGEZERO", 10) == 0 )
                     return;
             }
-            vmAddr = info.vmaddr + slide;
-        }
-
-        if (info.vmsize) {
-            auto content = _mapper->map<uint8_t>(vmAddr, info.vmsize);
-            contentReader((void*)&*content, vmAddr, info.vmsize);
+            vmAddr = info.vmAddr + slide;
+        }
+
+        if (info.vmSize) {
+            auto content = _mapper->map<uint8_t>((void*)(vmAddr), info.vmSize);
+            contentReader((void*)&*content, vmAddr, info.vmSize);
         } else {
             contentReader(nullptr, vmAddr, 0);
         }
@@ -748,19 +784,19 @@
 bool Image::contentForSection(const char* segmentName, const char* sectionName,
                               void (^contentReader)(const void* content, uint64_t vmAddr, uint64_t vmSize)) {
     __block bool result = false;
-    __block uint64_t slide = (uint64_t)_rebasedAddress - ((const Header*)ml())->preferredLoadAddress();
-    ((const Header*)ml())->forEachSection(^(const Header::SectionInfo &info, bool &stop) {
-        if ( segmentName != info.segmentName ) { return; }
-        if ( sectionName != info.sectionName ) { return; }
+    __block uint64_t slide = (uint64_t)_rebasedAddress - ml()->preferredLoadAddress();
+    ml()->forEachSection(^(const MachOLoaded::SectionInfo &info, bool malformedRange, bool &stop) {
+        if (strcmp(segmentName, info.segInfo.segName) != 0) { return; }
+        if (strcmp(sectionName, info.sectName) != 0) { return; }
         uint64_t sectAddr = 0;
         if ( _sharedCacheSlide.has_value() ) {
-            sectAddr = info.address + _sharedCacheSlide.value();
+            sectAddr = info.sectAddr + _sharedCacheSlide.value();
         } else {
-            sectAddr = info.address + slide;
-        }
-        if (info.size) {
-            auto content = _mapper->map<uint8_t>(sectAddr, info.size);
-            contentReader((void*)&*content, sectAddr, info.size);
+            sectAddr = info.sectAddr + slide;
+        }
+        if (info.sectSize) {
+            auto content = _mapper->map<uint8_t>((void*)(sectAddr), info.sectSize);
+            contentReader((void*)&*content, sectAddr, info.sectSize);
         } else {
             contentReader(nullptr, sectAddr, 0);
         }
@@ -775,12 +811,12 @@
 
 SharedCacheLocals::SharedCacheLocals(SharedPtr<Mapper>& M, bool use64BitDylibOffsets)
     : _mapper(M), _use64BitDylibOffsets(use64BitDylibOffsets) {
-    auto header = _mapper->map<dyld_cache_header>(0ULL, sizeof(dyld_cache_header));
+    auto header = _mapper->map<dyld_cache_header>((void*)0, sizeof(dyld_cache_header));
 
     // Map in the whole locals buffer.
     // TODO: Once we have the symbols in their own file, simplify this to just map the whole file
     // and not do the header and locals separately
-    _locals = _mapper->map<uint8_t>(header->localSymbolsOffset, header->localSymbolsSize);
+    _locals = _mapper->map<uint8_t>((void*)header->localSymbolsOffset, header->localSymbolsSize);
 }
 
 const dyld_cache_local_symbols_info* SharedCacheLocals::localInfo() const {
@@ -799,7 +835,7 @@
                                 uint64_t rebasedAddress, bool splitCache)
 {
     // If we have sub caches, then the cache header itself tells us how much space we need to cover all caches
-    if (header->mappingOffset >= offsetof(dyld_cache_header, subCacheArrayCount) ) {
+    if (header->mappingOffset >= __offsetof(dyld_cache_header, subCacheArrayCount) ) {
         return header->sharedRegionSize;
     } else {
         auto headerBytes = (uint8_t*)&*header;
@@ -813,19 +849,19 @@
         if (splitCache) {
             for (auto i = 0; i < header->subCacheArrayCount; ++i) {
                 uint64_t subCacheOffset = 0;
-                if (header->mappingOffset <= offsetof(dyld_cache_header, cacheSubType) ) {
+                if (header->mappingOffset <= __offsetof(dyld_cache_header, cacheSubType) ) {
                     auto subCaches = (dyld_subcache_entry_v1*)&headerBytes[header->subCacheArrayOffset];
                     subCacheOffset = subCaches[i].cacheVMOffset;
                 } else {
                     auto subCaches = (dyld_subcache_entry*)&headerBytes[header->subCacheArrayOffset];
                     subCacheOffset = subCaches[i].cacheVMOffset;
                 }
-                auto subCacheHeader = mapper->map<dyld_cache_header>(subCacheOffset + rebasedAddress, PAGE_SIZE);
+                auto subCacheHeader = mapper->map<dyld_cache_header>((void*)(subCacheOffset + rebasedAddress), PAGE_SIZE);
                 uint64_t subCacheHeaderSize = 0;
                 bool splitCacheUnused;
                 getCacheInfo(&*subCacheHeader, subCacheHeaderSize, splitCacheUnused);
                 if (subCacheHeaderSize > PAGE_SIZE) {
-                    subCacheHeader = mapper->map<dyld_cache_header>(subCacheOffset + rebasedAddress, subCacheHeaderSize);
+                    subCacheHeader = mapper->map<dyld_cache_header>((void*)(subCacheOffset + rebasedAddress), subCacheHeaderSize);
                 }
                 auto subCacheHeaderBytes = (uint8_t*)&*subCacheHeader;
                 auto subCacheMappings = (dyld_cache_mapping_and_slide_info*)&subCacheHeaderBytes[subCacheHeader->mappingWithSlideOffset];
@@ -840,20 +876,20 @@
     }
 }
 
-SharedCache::SharedCache(Allocator& ephemeralAllocator, FileRecord&& file, SharedPtr<Mapper>& mapper, SafePointer rebasedAddress, bool P)
+SharedCache::SharedCache(Allocator& ephemeralAllocator, FileRecord&& file, SharedPtr<Mapper>& mapper, uint64_t rebasedAddress, bool P)
     : _ephemeralAllocator(ephemeralAllocator), _file(std::move(file)), _mapper(mapper),  _rebasedAddress(rebasedAddress), _private(P)
 {
     assert(_mapper);
-    _header = _mapper->map<dyld_cache_header>(_rebasedAddress, PAGE_SIZE);
+    _header = _mapper->map<dyld_cache_header>((void*)_rebasedAddress, PAGE_SIZE);
     uint64_t headerSize = 0;
     bool splitCache = false;
     getCacheInfo(&*_header, headerSize, splitCache);
     if (headerSize > PAGE_SIZE) {
-        _header = _mapper->map<dyld_cache_header>(_rebasedAddress, headerSize);
+        _header = _mapper->map<dyld_cache_header>((void*)_rebasedAddress, headerSize);
     }
     _uuid = UUID(&_header->uuid[0]);
-    _slide = (uint64_t)_rebasedAddress -  _header->sharedRegionStart;
-    _size = cacheMappedSize(_header, _mapper, (uint64_t)rebasedAddress, splitCache);
+    _slide = _rebasedAddress -  _header->sharedRegionStart;
+    _size = cacheMappedSize(_header, _mapper, rebasedAddress, splitCache);
 }
 
 
@@ -867,7 +903,6 @@
         "/private/preboot/Cryptexes/OS/System/DriverKit/System/Library/dyld/",
         "/System/Cryptexes/OS/System/Library/Caches/com.apple.dyld/",
         "/System/Cryptexes/OS/System/Library/dyld/",
-        "/System/Cryptexes/ExclaveOS/System/ExclaveKit/System/Library/dyld/",
         "/System/Volumes/Preboot/Cryptexes/Incoming/OS/System/Library/dyld/",
         "/System/Volumes/Preboot/Cryptexes/Incoming/OS/System/DriverKit/System/Library/dyld/",
         "/private/preboot/Cryptexes/Incoming/OS/System/Library/Caches/com.apple.dyld/",
@@ -876,7 +911,6 @@
         "/System/Cryptexes/Incoming/OS/System/Library/dyld/",
         "/System/Library/Caches/com.apple.dyld/",
         "/System/DriverKit/System/Library/dyld/",
-        "/System/ExclaveKit/System/Library/dyld/",
         "/System/Library/dyld/"
     };
 
@@ -943,7 +977,7 @@
 
 UniquePtr<SharedCache> SharedCache::createForFileRecord(Allocator& _ephemeralAllocator, FileRecord&& file) {
     auto uuid = UUID();
-    auto fileMapper = Mapper::mapperForSharedCache(_ephemeralAllocator, file, 0ULL);
+    auto fileMapper = Mapper::mapperForSharedCache(_ephemeralAllocator, file, 0);
     if (!fileMapper) { return nullptr; }
     return _transactionalAllocator.makeUnique<SharedCache>(_ephemeralAllocator, std::move(file), fileMapper, (uint64_t)fileMapper->baseAddress(), true);
 }
@@ -953,7 +987,7 @@
     return _uuid;
 }
 
-SafePointer SharedCache::rebasedAddress() const {
+uint64_t SharedCache::rebasedAddress() const {
     return _rebasedAddress;
 }
 
@@ -976,7 +1010,7 @@
     if (splitCache) {
         auto headerBytes = (std::byte*)&*_header;
         char subCachePath[PATH_MAX];
-        if (_header->mappingOffset <= offsetof(dyld_cache_header, cacheSubType)) {
+        if (_header->mappingOffset <= __offsetof(dyld_cache_header, cacheSubType)) {
             for (auto i = 0; i < _header->subCacheArrayCount; ++i) {
                 snprintf(&subCachePath[0], sizeof(subCachePath), "%s.%u", _file.getPath(), i+1);
                 block(subCachePath);
@@ -988,7 +1022,7 @@
                 block(subCachePath);
             }
         }
-        if ( (_header->mappingOffset >= offsetof(dyld_cache_header, symbolFileUUID)) && !uuid_is_null(_header->symbolFileUUID) ) {
+        if ( (_header->mappingOffset >= __offsetof(dyld_cache_header, symbolFileUUID)) && !uuid_is_null(_header->symbolFileUUID) ) {
             strlcpy(&subCachePath[0], _file.getPath(), PATH_MAX);
             // On new caches, the locals come from a new subCache file
             if (strstr(subCachePath, ".development") != nullptr) {
@@ -1012,7 +1046,7 @@
     auto headerBytes = (uint8_t*)&*_header;
     auto images = std::span((const dyld_cache_image_text_info*)&headerBytes[_header->imagesTextOffset], (size_t)_header->imagesTextCount);
     for (auto i : images) {
-        auto image = Image(_ephemeralAllocator, _mapper, i.loadAddress, _slide, this);
+        auto image = Image(_ephemeralAllocator, _mapper,  (void*)(i.loadAddress), _slide, this);
         block(&image);
     }
 }
@@ -1020,7 +1054,7 @@
 void SharedCache::withImageForIndex(uint32_t idx, void (^block)(Image* image)) {
     auto headerBytes = (uint8_t*)&*_header;
     auto images = std::span((const dyld_cache_image_text_info*)&headerBytes[_header->imagesTextOffset], (size_t)_header->imagesTextCount);
-    auto image = Image(_ephemeralAllocator, _mapper, images[idx].loadAddress, _slide, this);
+    auto image = Image(_ephemeralAllocator, _mapper,  (void*)(images[idx].loadAddress), _slide, this);
     block(&image);
 }
 
@@ -1031,7 +1065,7 @@
     // Where it is depends on the cache header
     char localSymbolsCachePath[PATH_MAX];
     strlcpy(&localSymbolsCachePath[0], _file.getPath(), PATH_MAX);
-    bool useSymbolsFile = (_header->mappingOffset >= offsetof(dyld_cache_header, symbolFileUUID));
+    bool useSymbolsFile = (_header->mappingOffset >= __offsetof(dyld_cache_header, symbolFileUUID));
     if ( useSymbolsFile ) {
         if ( uuid_is_null(_header->symbolFileUUID) )
             return nullptr;
@@ -1082,7 +1116,7 @@
     for(auto i = 0; i < _header->mappingCount; ++i) {
         //    _slide = _baseAddress -  _header->sharedRegionStart;
         auto mapping = (dyld_cache_mapping_info*)&subCacheHeaderBytes[subCacheHeader->mappingOffset+(i*sizeof(dyld_cache_mapping_info))];
-        auto mappingBytes = _mapper->map<uint8_t>(mapping->address - _slide, mapping->size);
+        auto mappingBytes = _mapper->map<uint8_t>((void*)(mapping->address - _slide), mapping->size);
         kern_return_t r = vm_copy(mach_task_self(), (vm_address_t)&*mappingBytes, (vm_size_t)mapping->size, (vm_address_t)(mappedSubCache+mapping->fileOffset));
         if ( r != KERN_SUCCESS ) {
             result = false;
@@ -1108,18 +1142,18 @@
     if (splitCache) {
         for (auto i = 0; i < _header->subCacheArrayCount; ++i) {
             uint64_t subCacheOffset = 0;
-            if (_header->mappingOffset <= offsetof(dyld_cache_header, cacheSubType) ) {
+            if (_header->mappingOffset <= __offsetof(dyld_cache_header, cacheSubType) ) {
                 auto subCaches = (dyld_subcache_entry_v1*)&headerBytes[_header->subCacheArrayOffset];
                 subCacheOffset = subCaches[i].cacheVMOffset;
             } else {
                 auto subCaches = (dyld_subcache_entry*)&headerBytes[_header->subCacheArrayOffset];
                 subCacheOffset = subCaches[i].cacheVMOffset;
             }
-            auto subCacheHeader = _mapper->map<dyld_cache_header>((uint64_t)rebasedAddress() + subCacheOffset, PAGE_SIZE);
+            auto subCacheHeader = _mapper->map<dyld_cache_header>((void*)(rebasedAddress() + subCacheOffset), PAGE_SIZE);
             uint64_t subCacheHeaderSize = subCacheHeader->mappingOffset+subCacheHeader->mappingCount*sizeof(dyld_cache_mapping_info);
             getCacheInfo(&*_header, headerSize, splitCache);
             if (subCacheHeaderSize > PAGE_SIZE) {
-                subCacheHeader = _mapper->map<dyld_cache_header>((uint64_t)rebasedAddress() + subCacheOffset, subCacheHeaderSize);
+                subCacheHeader = _mapper->map<dyld_cache_header>((void*)(rebasedAddress() + subCacheOffset), subCacheHeaderSize);
             }
 //            printf("Subcache Offset: %lx\n", (uintptr_t)&headerBytes[subCacheOffset]);
 //            printf("subCacheHeader: %lx\n", (uintptr_t)&*subCacheHeader);
@@ -1195,8 +1229,6 @@
     pid_t   pid;
     *kr = pid_for_task(_task, &pid);
     if ( *kr != KERN_SUCCESS ) {
-        BLEND_KERN_RETURN_LOCATION(*kr, 0xea);
-        *kr |= 0xeb000000UL;
         return nullptr;
     }
 
@@ -1204,7 +1236,6 @@
     mach_msg_type_number_t count = MACH_TASK_BASIC_INFO_COUNT;
     *kr = task_info(_task, MACH_TASK_BASIC_INFO, (task_info_t)&ti, &count);
     if ( *kr != KERN_SUCCESS ) {
-        BLEND_KERN_RETURN_LOCATION(*kr, 0xe9);
         return nullptr;
     }
 
@@ -1228,14 +1259,13 @@
             mach_vm_size_t readSize = 0;
             *kr = mach_vm_read_overwrite(_task, address, size, (mach_vm_address_t)&unsafeBytes[0], &readSize);
             if ( *kr != KERN_SUCCESS ) {
-                BLEND_KERN_RETURN_LOCATION(*kr, 0xe8);
                 return;
             }
-            auto mh = Header::isMachO({(const uint8_t*)unsafeBytes, (size_t)readSize});
-            if (!mh) {
+            auto mf = MachOFile::isMachO((const void*)unsafeBytes);
+            if (!mf) {
                 return;
             }
-            if ( mh->isMainExecutable() ) {
+            if ( mf->filetype == MH_EXECUTE ) {
                 int len = proc_regionfilename(pid, address, executablePath, PATH_MAX);
                 if ( len != 0 ) {
                     executablePath[len] = '\0';
@@ -1243,11 +1273,11 @@
                 SharedPtr<Mapper> mapper = nullptr;
                 auto file = _fileManager.fileRecordForPath(_transactionalAllocator, executablePath);
                 uuid_t rawUUID;
-                mh->getUuid(rawUUID);
+                mf->getUuid(rawUUID);
                 auto uuid = UUID(rawUUID);
-                result->addImage(Image(_transactionalAllocator, std::move(file), mapper, (uint64_t)address, uuid));
+                result->addImage(Image(_transactionalAllocator, std::move(file), mapper, (const mach_header*)address, uuid));
                 foundMainExecutable = true;
-            } else if ( mh->isDylinker() ) {
+            } else if ( mf->filetype == MH_DYLINKER ) {
                 int len = proc_regionfilename(pid, address, executablePath, PATH_MAX);
                 if ( len != 0 ) {
                     executablePath[len] = '\0';
@@ -1255,9 +1285,9 @@
                 SharedPtr<Mapper> mapper = nullptr;
                 auto file = _fileManager.fileRecordForPath(_transactionalAllocator, executablePath);
                 uuid_t rawUUID;
-                mh->getUuid(rawUUID);
+                mf->getUuid(rawUUID);
                 auto uuid = UUID(rawUUID);
-                result->addImage(Image(_transactionalAllocator, std::move(file), mapper, (uint64_t)address, uuid));
+                result->addImage(Image(_transactionalAllocator, std::move(file), mapper, (const mach_header*)address, uuid));
                 foundDyld = true;
             }
         });
@@ -1289,55 +1319,48 @@
     task_dyld_info_data_t task_dyld_info;
     *kr = task_info(_task, TASK_DYLD_INFO, (task_info_t)&task_dyld_info, &count);
     if ( *kr != KERN_SUCCESS ) {
-        BLEND_KERN_RETURN_LOCATION(*kr, 0xef);
         return nullptr;
     }
     //The kernel will return MACH_VM_MIN_ADDRESS for an executable that has not had dyld loaded
     if (task_dyld_info.all_image_info_addr == MACH_VM_MIN_ADDRESS) {
-        BLEND_KERN_RETURN_LOCATION(*kr, 0xee);
         return nullptr;
     }
-    uint64_t failedAddress = 0;
+    uint8_t remoteBuffer[16*1024];
+    mach_vm_size_t readSize = 0;
     while (1) {
         // Using mach_vm_read_overwrite because this is part of dyld. If the file is removed or the codesignature is invalid
         // then the system is broken beyond recovery anyway
-        auto taskInfoBuffer = SafeRemoteBuffer(_task, task_dyld_info.all_image_info_addr, task_dyld_info.all_image_info_size, kr);
+        *kr = mach_vm_read_overwrite(_task, task_dyld_info.all_image_info_addr, task_dyld_info.all_image_info_size,
+                                     (mach_vm_address_t)&remoteBuffer[0], &readSize);
         if (*kr != KERN_SUCCESS) {
-            BLEND_KERN_RETURN_LOCATION(*kr, 0xed);
             // If we cannot read the all image info this is game over
             return nullptr;
         }
         uint64_t compactInfoAddress;
         uint64_t compactInfoSize;
         if (task_dyld_info.all_image_info_format == TASK_DYLD_ALL_IMAGE_INFO_32 ) {
-            const dyld_all_image_infos_32* info = (const dyld_all_image_infos_32*)&taskInfoBuffer.data()[0];
+            const dyld_all_image_infos_32* info = (const dyld_all_image_infos_32*)&remoteBuffer[0];
             compactInfoAddress              = info->compact_dyld_image_info_addr;
             compactInfoSize                 = info->compact_dyld_image_info_size;
         } else {
-            const dyld_all_image_infos_64* info = (const dyld_all_image_infos_64*)&taskInfoBuffer.data()[0];
+            const dyld_all_image_infos_64* info = (const dyld_all_image_infos_64*)&remoteBuffer[0];
             compactInfoAddress              = info->compact_dyld_image_info_addr;
             compactInfoSize                 = info->compact_dyld_image_info_size;
         }
         if (compactInfoSize == 0) {
             return synthesizeSnapshot(kr);
         }
-        
-        auto compactInfoBuffer = SafeRemoteBuffer(_task, compactInfoAddress,compactInfoSize, kr);
+        auto compactInfo = UniquePtr<std::byte>((std::byte*)_transactionalAllocator.malloc((size_t)compactInfoSize));
+        *kr = mach_vm_read_overwrite(_task, compactInfoAddress, compactInfoSize, (mach_vm_address_t)&*compactInfo, &readSize);
         if (*kr != KERN_SUCCESS) {
-            BLEND_KERN_RETURN_LOCATION(*kr, 0xec);
-            if (compactInfoAddress == failedAddress) {
-                // We tried the same address twice and it failed both times, this is not a simple mutation issue, give up and reutrn an error
-                return nullptr;
-            }
-            failedAddress = compactInfoAddress;
             // The read failed, chances are the process mutated the compact info, retry
             continue;
         }
-        UniquePtr<ProcessSnapshot> result = _transactionalAllocator.makeUnique<ProcessSnapshot>(_ephemeralAllocator, _fileManager, false, compactInfoBuffer.data());
+        std::span<std::byte> data = std::span<std::byte>(&*compactInfo, (size_t)compactInfoSize);
+        UniquePtr<ProcessSnapshot> result = _transactionalAllocator.makeUnique<ProcessSnapshot>(_ephemeralAllocator, _fileManager, false, data);
         if (!result->valid()) {
             // Something blew up we don't know what
             *kr = KERN_FAILURE;
-            BLEND_KERN_RETURN_LOCATION(*kr, 0xeb);
             return nullptr;
         }
         return result;
@@ -1575,46 +1598,14 @@
     :   _ephemeralAllocator(ephemeralAllocator), _fileManager(fileManager), _images(_transactionalAllocator),
         _identityMapper(_transactionalAllocator.makeShared<Mapper>(_transactionalAllocator)), _useIdentityMapper(useIdentityMapper) {}
 
-#if BUILDING_LIBDYLD && !TARGET_OS_DRIVERKIT && !TARGET_OS_EXCLAVEKIT
-// This function is a private interface between libdyld and Dyld.framework and implemented in Swift
-// there is no header
-extern "C" const bool unwrapCompactInfo(void* _Nonnull buffer, uint64_t* _Nonnull size);
-#endif /* BUILDING_LIBDYLD && !TARGET_OS_DRIVERKIT && !TARGET_OS_EXCLAVEKIT */
-
 ProcessSnapshot::ProcessSnapshot(Allocator& ephemeralAllocator, FileManager& fileManager, bool useIdentityMapper, const std::span<std::byte> data)
     :   _ephemeralAllocator(ephemeralAllocator), _fileManager(fileManager), _images(_transactionalAllocator),
         _identityMapper(_transactionalAllocator.makeShared<Mapper>(_transactionalAllocator)), _useIdentityMapper(useIdentityMapper) {
         Serializer serializer(*this);
-        bool deserializedSucceeed = serializer.deserialize(data);
-#if BUILDING_LIBDYLD && !TARGET_OS_DRIVERKIT && !TARGET_OS_EXCLAVEKIT
-        static dispatch_once_t onceToken;
-        static __typeof__(unwrapCompactInfo) *unwrapCompactInfoPtr = nullptr;
-        if (!deserializedSucceeed) {
-            // If we failed we try to load the unwrap function
-            dispatch_once(&onceToken, ^{
-                // We attempt a dlopen() here since the unwrapCompactInfo is not in the build yet, and this is a temporary compatibility hack
-                void* dyldFrameworkHandle = dlopen("/System/Library/PrivateFrameworks/Dyld.framework/Dyld", RTLD_NOW);
-                unwrapCompactInfoPtr = (__typeof__(unwrapCompactInfo)*)dlsym(dyldFrameworkHandle, "unwrapCompactInfo");
-            });
-        }
-        // Only try the fallback if we managed to load the unwrap function
-        if (unwrapCompactInfoPtr && !deserializedSucceeed) {
-            std::byte* unwrappedData = (std::byte*)_transactionalAllocator.malloc(data.size());
-            std::copy(data.begin(), data.end(), unwrappedData);
-            uint64_t unwrappedSize = data.size();
-            if (unwrapCompactInfoPtr((void*)unwrappedData, &unwrappedSize)) {
-                std::span<std::byte> unwrappedSpan = std::span<std::byte>(unwrappedData, (size_t)unwrappedSize);
-                deserializedSucceeed = serializer.deserialize(unwrappedSpan);
-            }
-            free((void*)unwrappedData);
-        }
-#endif /* BUILDING_LIBDYLD && !TARGET_OS_DRIVERKIT && !TARGET_OS_EXCLAVEKIT */
-        if (!deserializedSucceeed) {
+        if (!serializer.deserialize(data)) {
             // Deerialization failed, reset the snapshot and mark invalid
             _images.clear();
-            if (_bitmap) {
-                _bitmap->clear();
-            }
+            _bitmap             = nullptr;
             _sharedCache        = nullptr;
             _platform           = 0;
             _initialImageCount  = 0;
@@ -1671,7 +1662,7 @@
     uint64_t address    = ~0ULL;
     auto i              = other._images.begin();
     if (i != other._images.end()) {
-        address = (uint64_t)(*i)->rebasedAddress();
+        address = (*i)->rebasedAddress();
     }
 
     for (auto& image : _images) {
@@ -1683,7 +1674,7 @@
                 address = ~0ULL;
                 break;
             }
-            address = (uint64_t)(*i)->rebasedAddress();
+            address = (*i)->rebasedAddress();
         }
         if (image->rebasedAddress() != address) {
             block(&*image);
@@ -1700,7 +1691,7 @@
 }
 
 #if BUILDING_DYLD
-void ProcessSnapshot::addImages(RuntimeState* state, Vector<ConstAuthLoader>& loaders) {
+void ProcessSnapshot::addImages(RuntimeState* state, const std::span<const Loader*>& loaders) {
     for (auto& ldr : loaders) {
         if (_sharedCache && ldr->dylibInDyldCache) {
             _bitmap->setBit(ldr->ref.index);
@@ -1730,7 +1721,7 @@
 
 void ProcessSnapshot::addSharedCacheImage(const struct mach_header* mh) {
     assert(mh->flags & MH_DYLIB_IN_CACHE);
-    auto header = (dyld_cache_header*)(uint64_t)_sharedCache->rebasedAddress();
+    auto header = (dyld_cache_header*)_sharedCache->rebasedAddress();
     auto headerBytes = (uint8_t*)header;
     auto slide = (uint64_t)header - header->sharedRegionStart;
     auto images = std::span((const dyld_cache_image_text_info*)&headerBytes[header->imagesTextOffset], (size_t)header->imagesTextCount);
@@ -1784,7 +1775,7 @@
         if (!name) {
             name = "<unknown>";
         }
-        fprintf(stderr, "0x%llx %s %s\n",  (uint64_t)image->rebasedAddress(), uuidStr, name);
+        fprintf(stderr, "0x%llx %s %s\n",  image->rebasedAddress(), uuidStr, name);
     });
 }
 
@@ -1897,37 +1888,22 @@
     }
 }
 
-bool ProcessSnapshot::Serializer::readMappedFileInfo(std::span<std::byte>& data, uint64_t& rebasedAddress, UUID& uuid, FileRecord& file) {
-    uint64_t flags = 0;
-    if (!readPVLEUInt64(data, flags)
-        || !readPVLEUInt64(data, rebasedAddress)) {
-        return false;
-    }
+void ProcessSnapshot::Serializer::readMappedFileInfo(std::span<std::byte>& data, uint64_t& rebasedAddress, UUID& uuid, FileRecord& file) {
+    uint64_t flags = readPVLEUInt64(data);
+    rebasedAddress = readPVLEUInt64(data);
     if (flags & kMappedFileFlagsHasUUID) {
-        if (data.size() < 16) {
-            return false;
-        }
         uuid = UUID(&data[0]);
         data = data.last(data.size()-16);
     }
     if (flags & kMappedFileFlagsHasFileID) {
-        uint64_t volumeIndex = 0;
-        uint64_t objectID = 0;
-        if (!readPVLEUInt64(data, volumeIndex)
-            || !readPVLEUInt64(data, objectID)
-            || volumeIndex >= _volumeUUIDs.size()) {
-            return false;
-        }
+        uint64_t volumeIndex = readPVLEUInt64(data);
+        uint64_t objectID = readPVLEUInt64(data);
         file = _fileManager.fileRecordForVolumeUUIDAndObjID(_volumeUUIDs[(size_t)volumeIndex], objectID);
     }
     if (flags & kMappedFileFlagsHasFilePath) {
-        uint64_t pathOffset = 0;
-        if (!readPVLEUInt64(data, pathOffset) || pathOffset >= _stringTableBuffer.size()) {
-            return false;
-        }
+        uint64_t pathOffset = readPVLEUInt64(data);
         file = _fileManager.fileRecordForPath(_ephemeralAllocator, &_stringTableBuffer[(size_t)pathOffset]);
     }
-    return true;
 }
 
 Vector<std::byte> ProcessSnapshot::Serializer::serialize() {
@@ -1999,18 +1975,16 @@
     emitPVLEUInt64(_stringTableBuffer.size(), result);
     std::copy((std::byte*)_stringTableBuffer.begin(), (std::byte*)_stringTableBuffer.end(), std::back_inserter(result));
     if (_processFlags & kProcessFlagsHasSharedCache) {
-        uint64_t address = (uint64_t)_sharedCache->rebasedAddress()/((_processFlags & kProcessFlagsHas16kPages) ? 16384 : 4096);
+        uint64_t address = _sharedCache->rebasedAddress()/((_processFlags & kProcessFlagsHas16kPages) ? 16384 : 4096);
         emitMappedFileInfo(address, _sharedCache->uuid(), _sharedCache->file(), result);
-        emitPVLEUInt64(_bitmap->size(), result);
-        if (_bitmap->size() > 0)
-            emit(_bitmap->bytes(), result);
+        _bitmap->emit(result);
     }
 
     emitPVLEUInt64(_images.size(), result);
     uint64_t lastAddress = 0;
     for (const auto& image : _images) {
-        uint64_t address = ((uint64_t)image->rebasedAddress()-lastAddress)/((_processFlags & kProcessFlagsHas16kPages) ? 16384 : 4096);
-        lastAddress = (uint64_t)image->rebasedAddress();
+        uint64_t address = (image->rebasedAddress()-lastAddress)/((_processFlags & kProcessFlagsHas16kPages) ? 16384 : 4096);
+        lastAddress = image->rebasedAddress();
         emitMappedFileInfo(address, image->uuid(), image->file(), result);
     }
     while(result.size()%16 != 0) {
@@ -2024,10 +1998,6 @@
 
 bool ProcessSnapshot::Serializer::deserialize(const std::span<std::byte> data) {
     auto i = data;
-    if (i.size() < 36) {
-        // Ensure data is at least large enough to read the header
-        return false;
-    }
     // Confirm magic
     _magic              = read<uint32_t>(i);
     _version            = read<uint32_t>(i);
@@ -2049,27 +2019,17 @@
     if (_crc32c != checksumer) {
         return false;
     }
-    uint64_t volumeUUIDCount = 0;
-    if (!readPVLEUInt64(i, _processFlags)
-        || !readPVLEUInt64(i, _platform)
-        || !readPVLEUInt64(i, _initialImageCount)
-        || !readPVLEUInt64(i, _dyldState)
-        || !readPVLEUInt64(i, volumeUUIDCount)) {
-        return false;
-    }
-    if (i.size() < volumeUUIDCount*16) {
-        return false;
-    }
+    _processFlags           = readPVLEUInt64(i);
+    _platform               = readPVLEUInt64(i);
+    _initialImageCount      = readPVLEUInt64(i);
+    _dyldState              = readPVLEUInt64(i);
+    auto volumeUUIDCount    = readPVLEUInt64(i);
     for (auto j = 0; j < volumeUUIDCount; ++j) {
         UUID volumeUUID(&i[j*16]);
         _volumeUUIDs.push_back(volumeUUID);
     }
     i = i.last((size_t)(i.size()-(16*volumeUUIDCount)));
-    uint64_t stringTableSize = 0;
-    if (!readPVLEUInt64(i, stringTableSize)
-        || i.size() < stringTableSize) {
-        return false;
-    }
+    auto stringTableSize    = readPVLEUInt64(i);
     _stringTableBuffer.reserve((size_t)stringTableSize);
     std::copy((uint8_t*)&i[0], (uint8_t*)&i[(size_t)stringTableSize], std::back_inserter(_stringTableBuffer));
     i = i.last((size_t)(i.size()-stringTableSize));
@@ -2078,9 +2038,8 @@
         uint64_t rebasedAddress;
         UUID uuid;
         FileRecord file;
-        if ( !readMappedFileInfo(i, rebasedAddress, uuid, file) )
-            return false;
-        rebasedAddress = rebasedAddress * ((_processFlags & kProcessFlagsHas16kPages) ? kPageSize16K : kPageSize4K);
+        readMappedFileInfo(i, rebasedAddress, uuid, file);
+        rebasedAddress = rebasedAddress * ((_processFlags & kProcessFlagsHas16kPages) ? 16384 : 4096);
         SharedPtr<Mapper> mapper = nullptr;
         if (_processSnapshot._useIdentityMapper) {
             mapper = _processSnapshot.identityMapper();
@@ -2088,34 +2047,24 @@
 #if BUILDING_DYLD || BUILDING_UNIT_TESTS
             mapper = _transactionalAllocator.makeShared<Mapper>(_transactionalAllocator);
 #else
-            mapper = Mapper::mapperForSharedCache(_transactionalAllocator, file, rebasedAddress);
+            mapper = Mapper::mapperForSharedCache(_transactionalAllocator, file, (void*)rebasedAddress);
 #endif
         }
         if (!mapper) {
             return false;
         }
-        _sharedCache = _transactionalAllocator.makeUnique<SharedCache>(_transactionalAllocator, std::move(file), mapper,
+
+        _sharedCache = _transactionalAllocator.makeUnique<SharedCache>(_ephemeralAllocator, std::move(file), mapper,
                                                                        rebasedAddress, _processFlags & kProcessFlagsHasPrivateCache);
-        uint64_t encodedSize = 0;
-        if (!readPVLEUInt64(i, encodedSize)) {
-            return false;
-        }
-        _bitmap = _transactionalAllocator.makeUnique<Bitmap>(_transactionalAllocator, (size_t)encodedSize, i);
-        if (_bitmap->size() == 0) {
-            return false;
-        }
-    }
-    uint64_t imageCount = 0;
-    if (!readPVLEUInt64(i, imageCount)) {
-        return false;
-    }
+        _bitmap = _transactionalAllocator.makeUnique<Bitmap>(_transactionalAllocator, i);
+    }
+    auto imageCount = readPVLEUInt64(i);
     uint64_t lastAddress = 0;
     for (auto j = 0; j < imageCount; ++j) {
         uint64_t rebasedAddress;
         UUID uuid;
         FileRecord file;
-        if ( !readMappedFileInfo(i, rebasedAddress, uuid, file) )
-            return false;
+        readMappedFileInfo(i, rebasedAddress, uuid, file);
         rebasedAddress = (rebasedAddress * ((_processFlags & kProcessFlagsHas16kPages) ? 16384 : 4096)) + lastAddress;
         lastAddress = rebasedAddress;
         SharedPtr<Mapper> mapper = nullptr;
@@ -2127,7 +2076,7 @@
             mapper = _transactionalAllocator.makeShared<Mapper>(_transactionalAllocator);
         }
 #endif
-        auto image = Image(_transactionalAllocator, std::move(file), mapper, (uint64_t)rebasedAddress, uuid);
+        auto image = Image(_ephemeralAllocator, std::move(file), mapper, (const struct mach_header*)rebasedAddress, uuid);
         _images.insert(_transactionalAllocator.makeUnique<Image>(std::move(image)));
     }
     return true;
@@ -2136,4 +2085,3 @@
 };
 };
 #endif // !TARGET_OS_EXCLAVEKIT
-