Loading...
cache_builder/SubCache.cpp dyld-1335 dyld-1231.3
--- dyld/dyld-1335/cache_builder/SubCache.cpp
+++ dyld/dyld-1231.3/cache_builder/SubCache.cpp
@@ -28,7 +28,6 @@
 #include "Chunk.h"
 #include "CodeSigningTypes.h"
 #include "DyldSharedCache.h"
-#include "Header.h"
 #include "SubCache.h"
 #include "JSONWriter.h"
 
@@ -38,10 +37,8 @@
 #include <CommonCrypto/CommonDigest.h>
 #include <CommonCrypto/CommonDigestSPI.h>
 
+using dyld3::GradedArchs;
 using dyld3::MachOFile;
-
-using mach_o::Header;
-using mach_o::Platform;
 
 using error::Error;
 
@@ -362,7 +359,7 @@
     return false;
 }
 
-static bool hasReadOnlyRegion(std::span<Region> regions)
+static bool hasLinkeditRegion(std::span<Region> regions)
 {
     for ( const Region& region : regions ) {
         if ( region.chunks.empty() )
@@ -377,33 +374,6 @@
             case cache_builder::Region::Kind::authConst:
                 break;
             case Region::Kind::readOnly:
-                return true;
-            case cache_builder::Region::Kind::linkedit:
-            case cache_builder::Region::Kind::unmapped:
-            case cache_builder::Region::Kind::dynamicConfig:
-            case cache_builder::Region::Kind::codeSignature:
-            case cache_builder::Region::Kind::numKinds:
-                break;
-        }
-    }
-    return false;
-}
-
-static bool hasLinkeditRegion(std::span<Region> regions)
-{
-    for ( const Region& region : regions ) {
-        if ( region.chunks.empty() )
-            continue;
-        switch ( region.kind ) {
-            case cache_builder::Region::Kind::text:
-            case cache_builder::Region::Kind::tproConst:
-            case cache_builder::Region::Kind::tproAuthConst:
-            case cache_builder::Region::Kind::dataConst:
-            case cache_builder::Region::Kind::data:
-            case cache_builder::Region::Kind::auth:
-            case cache_builder::Region::Kind::authConst:
-            case Region::Kind::readOnly:
-                break;
             case cache_builder::Region::Kind::linkedit:
                 return true;
             case cache_builder::Region::Kind::unmapped:
@@ -416,46 +386,43 @@
     return false;
 }
 
-void SubCache::setSuffix(Platform platform, bool forceDevelopmentSubCacheSuffix, size_t subCacheIndex)
+void SubCache::setSuffix(dyld3::Platform platform, bool forceDevelopmentSubCacheSuffix,
+                         size_t subCacheIndex)
 {
     assert(this->isSubCache() || this->isStubsCache());
     assert(subCacheIndex > 0);
 
     const char* dataSuffix = forceDevelopmentSubCacheSuffix ? ".development.dylddata" : ".dylddata";
     const char* linkeditSuffix = forceDevelopmentSubCacheSuffix ? ".development.dyldlinkedit" : ".dyldlinkedit";
-    const char* readonlySuffix = forceDevelopmentSubCacheSuffix ? ".development.dyldreadonly" : ".dyldreadonly";
     const char* subCacheSuffix = forceDevelopmentSubCacheSuffix ? ".development" : "";
 
-    if ( (platform == Platform::macOS) || platform.isSimulator() ) {
-        // macOS/sims never has a .development suffix
-        this->fileSuffix = "." + json::decimal(subCacheIndex);
-    } else if ( platform == Platform::driverKit ) {
+    if ( platform == dyld3::Platform::macOS ) {
+        // macOS never has a .development suffix
+        this->fileSuffix = "." + dyld3::json::decimal(subCacheIndex);
+    } else if ( platform == dyld3::Platform::driverKit ) {
         // driverKit never has a .development suffix
-        this->fileSuffix = "." + json::decimal(subCacheIndex);
+        this->fileSuffix = "." + dyld3::json::decimal(subCacheIndex);
     } else if ( this->isStubsDevelopmentCache() ) {
         // Dev stubs always have a suffix
-        this->fileSuffix = "." + json::decimal(subCacheIndex) + ".development";
+        this->fileSuffix = "." + dyld3::json::decimal(subCacheIndex) + ".development";
     } else if ( this->isStubsCustomerCache() ) {
         // Customer stubs never have a suffix
-        this->fileSuffix = "." + json::decimal(subCacheIndex);
+        this->fileSuffix = "." + dyld3::json::decimal(subCacheIndex);
     } else if ( hasDataRegion(this->regions) ) {
         // Data only subcaches have their own suffix
-        this->fileSuffix = "." + json::decimal(subCacheIndex) + dataSuffix;
-    } else if ( hasReadOnlyRegion(this->regions) ) {
-        // read-only only subcaches have their own suffix
-        this->fileSuffix = "." + json::decimal(subCacheIndex) + readonlySuffix;
+        this->fileSuffix = "." + dyld3::json::decimal(subCacheIndex) + dataSuffix;
     } else if ( hasLinkeditRegion(this->regions) ) {
         // Linkedit only subcaches have their own suffix
-        this->fileSuffix = "." + json::decimal(subCacheIndex) + linkeditSuffix;
+        this->fileSuffix = "." + dyld3::json::decimal(subCacheIndex) + linkeditSuffix;
     } else {
-        this->fileSuffix = "." + json::decimal(subCacheIndex) + subCacheSuffix;
+        this->fileSuffix = "." + dyld3::json::decimal(subCacheIndex) + subCacheSuffix;
     }
 }
 
 static std::string getCodeSigningIdentifier(const BuilderOptions& options)
 {
     std::string cacheIdentifier = "com.apple.dyld.cache.";
-    cacheIdentifier += options.arch.name();
+    cacheIdentifier += options.archs.name();
     if ( options.dylibsRemovedFromDisk ) {
         switch ( options.kind ) {
             case CacheKind::development:
@@ -743,14 +710,6 @@
     // Note: cdHash is defined as first 20 bytes of hash
     memcpy(this->cdHash, fullCdHash, 20);
 
-    if ( layout.agile ) {
-        // hash of entire code directory (cdHash) uses same hash as each page
-        uint8_t altfullCdHash[CS_HASH_SIZE_SHA256];
-        CCDigest(kCCDigestSHA256, (const uint8_t*)cd256, layout.cd256Size, altfullCdHash);
-        // Note: cdHash is defined as first 20 bytes of hash
-        memcpy(this->agilecdHash, altfullCdHash, 20);
-    }
-
     // Set the UUID string in the subcache
     uuid_unparse_upper(dyldCacheHeader->uuid, this->uuidString);
 }
@@ -853,7 +812,7 @@
                 break;
             case Chunk::Kind::dylibDataDirty:
                 // On arm64e, dataDirty goes in to auth
-                if ( cacheDylib.inputHdr->isArch("arm64e") )
+                if ( cacheDylib.inputMF->isArch("arm64e") )
                     this->addAuthChunk(&segmentInfo);
                 else
                     this->addDataChunk(&segmentInfo);
@@ -875,6 +834,8 @@
                 break;
         }
     }
+
+    this->addLinkeditFromDylib(cacheDylib);
 }
 
 // Linkedit is stored in Chunks in its own array on the dylib.  This adds it to the subCache.
@@ -969,8 +930,7 @@
     return count;
 }
 
-void SubCache::addCacheHeaderChunk(const BuilderOptions& options, const BuilderConfig& config,
-                                   const std::span<CacheDylib> cacheDylibs)
+void SubCache::addCacheHeaderChunk(const BuilderConfig& config, const std::span<CacheDylib> cacheDylibs)
 {
     // calculate size of header info and where first dylib's mach_header should start
     uint64_t numMappings = this->regions.size();
@@ -983,7 +943,7 @@
         startOffset += sizeof(dyld_cache_tpro_mapping_info) * numTPRORegions(config, this, this->subCaches);
     }
 
-    if ( this->needsCacheHeaderImageList(options) ) {
+    if ( this->needsCacheHeaderImageList() ) {
         startOffset += sizeof(dyld_cache_image_info) * cacheDylibs.size();
         startOffset += sizeof(dyld_cache_image_text_info) * cacheDylibs.size();
         for ( const CacheDylib& cacheDylib : cacheDylibs ) {
@@ -1065,7 +1025,7 @@
     addCodeSignatureChunk(this->codeSignature.get());
 }
 
-void SubCache::addObjCOptsHeaderChunk(const BuilderConfig& config, ObjCOptimizer& objcOptimizer)
+void SubCache::addObjCOptsHeaderChunk(ObjCOptimizer& objcOptimizer)
 {
     this->objcOptsHeader = std::make_unique<ObjCOptsHeaderChunk>();
     this->objcOptsHeader->cacheVMSize       = CacheVMSize(objcOptimizer.optsHeaderByteSize);
@@ -1073,7 +1033,7 @@
 
     objcOptimizer.optsHeaderChunk = this->objcOptsHeader.get();
 
-    this->addReadOnlyChunk(config, this->objcOptsHeader.get());
+    this->addLinkeditChunk(this->objcOptsHeader.get());
 }
 
 void SubCache::addObjCHeaderInfoReadOnlyChunk(const BuilderConfig& config, ObjCOptimizer& objcOptimizer)
@@ -1188,7 +1148,7 @@
     addObjCReadWriteChunk(config, this->objcCanonicalProtocols.get());
 }
 
-void SubCache::addObjCIMPCachesChunk(const BuilderConfig& config, ObjCIMPCachesOptimizer& objcIMPCachesOptimizer)
+void SubCache::addObjCIMPCachesChunk(ObjCIMPCachesOptimizer& objcIMPCachesOptimizer)
 {
     this->objcIMPCaches = std::make_unique<ObjCIMPCachesChunk>();
     this->objcIMPCaches->cacheVMSize                        = CacheVMSize(objcIMPCachesOptimizer.impCachesTotalByteSize);
@@ -1196,7 +1156,7 @@
 
     objcIMPCachesOptimizer.impCachesChunk = this->objcIMPCaches.get();
 
-    this->addReadOnlyChunk(config, this->objcIMPCaches.get());
+    this->addLinkeditChunk(this->objcIMPCaches.get());
 }
 
 void SubCache::addObjCCategoriesChunk(const BuilderConfig& config,
@@ -1225,26 +1185,16 @@
 
 void SubCache::addPatchTableChunk(PatchTableOptimizer& patchTableOptimizer)
 {
-    // We can't compute the size yet so just make an empty chunk
+    // We can't compute the size yet.  We need to know how many fixups we have
+    // And yet we have an estimate, so we'll use it
 
     this->patchTable = std::make_unique<PatchTableChunk>();
-    this->patchTable->cacheVMSize       = CacheVMSize(0ULL);
-    this->patchTable->subCacheFileSize  = CacheFileSize(0ULL);
+    this->patchTable->cacheVMSize       = CacheVMSize(patchTableOptimizer.patchTableTotalByteSize);
+    this->patchTable->subCacheFileSize  = CacheFileSize(patchTableOptimizer.patchTableTotalByteSize);
 
     patchTableOptimizer.patchTableChunk = this->patchTable.get();
 
     this->addLinkeditChunk(this->patchTable.get());
-}
-
-void SubCache::addFunctionVariantsChunk(FunctionVariantsOptimizer& optimizer)
-{
-    this->functionVariants                    = std::make_unique<FunctionVariantsPatchTableChunk>();
-    this->functionVariants->cacheVMSize       = CacheVMSize(optimizer.fvInfoTotalByteSize);
-    this->functionVariants->subCacheFileSize  = CacheFileSize(optimizer.fvInfoTotalByteSize);
-
-    optimizer.chunk = this->functionVariants.get();
-
-    this->addLinkeditChunk(this->functionVariants.get());
 }
 
 void SubCache::addCacheDylibsLoaderChunk(PrebuiltLoaderBuilder& builder)
@@ -1286,21 +1236,7 @@
     this->addLinkeditChunk(this->executablesTrie.get());
 }
 
-void SubCache::addPrewarmingDataChunk(const BuilderConfig& config, PrewarmingOptimizer& opt)
-{
-    if ( opt.prewarmingByteSize == 0 )
-        return;
-
-    this->prewarmingChunk = std::make_unique<PrewarmingChunk>(Chunk::Kind::prewarmingData);
-    this->prewarmingChunk->cacheVMSize      = CacheVMSize(opt.prewarmingByteSize);
-    this->prewarmingChunk->subCacheFileSize = CacheFileSize(opt.prewarmingByteSize);
-
-    opt.prewarmingChunk = this->prewarmingChunk.get();
-
-    this->addReadOnlyChunk(config, this->prewarmingChunk.get());
-}
-
-void SubCache::addSwiftOptsHeaderChunk(const BuilderConfig& config, SwiftOptimizer& opt)
+void SubCache::addSwiftOptsHeaderChunk(SwiftProtocolConformanceOptimizer& opt)
 {
     this->swiftOptsHeader = std::make_unique<SwiftOptsHeaderChunk>();
     this->swiftOptsHeader->cacheVMSize      = CacheVMSize(opt.optsHeaderByteSize);
@@ -1308,10 +1244,10 @@
 
     opt.optsHeaderChunk = this->swiftOptsHeader.get();
 
-    this->addReadOnlyChunk(config, this->swiftOptsHeader.get());
-}
-
-void SubCache::addSwiftTypeHashTableChunk(const BuilderConfig& config, SwiftOptimizer& opt)
+    this->addLinkeditChunk(this->swiftOptsHeader.get());
+}
+
+void SubCache::addSwiftTypeHashTableChunk(SwiftProtocolConformanceOptimizer& opt)
 {
     this->swiftTypeHashTable = std::make_unique<SwiftProtocolConformancesHashTableChunk>();
     this->swiftTypeHashTable->cacheVMSize       = CacheVMSize(opt.typeConformancesHashTableSize);
@@ -1319,10 +1255,10 @@
 
     opt.typeConformancesHashTable = this->swiftTypeHashTable.get();
 
-    this->addReadOnlyChunk(config, this->swiftTypeHashTable.get());
-}
-
-void SubCache::addSwiftMetadataHashTableChunk(const BuilderConfig& config, SwiftOptimizer& opt)
+    this->addLinkeditChunk(this->swiftTypeHashTable.get());
+}
+
+void SubCache::addSwiftMetadataHashTableChunk(SwiftProtocolConformanceOptimizer& opt)
 {
     this->swiftMetadataHashTable = std::make_unique<SwiftProtocolConformancesHashTableChunk>();
     this->swiftMetadataHashTable->cacheVMSize       = CacheVMSize(opt.metadataConformancesHashTableSize);
@@ -1330,10 +1266,10 @@
 
     opt.metadataConformancesHashTable = this->swiftMetadataHashTable.get();
 
-    this->addReadOnlyChunk(config, this->swiftMetadataHashTable.get());
-}
-
-void SubCache::addSwiftForeignHashTableChunk(const BuilderConfig& config, SwiftOptimizer& opt)
+    this->addLinkeditChunk(this->swiftMetadataHashTable.get());
+}
+
+void SubCache::addSwiftForeignHashTableChunk(SwiftProtocolConformanceOptimizer& opt)
 {
     this->swiftForeignTypeHashTable = std::make_unique<SwiftProtocolConformancesHashTableChunk>();
     this->swiftForeignTypeHashTable->cacheVMSize        = CacheVMSize(opt.foreignTypeConformancesHashTableSize);
@@ -1341,10 +1277,10 @@
 
     opt.foreignTypeConformancesHashTable = this->swiftForeignTypeHashTable.get();
 
-    this->addReadOnlyChunk(config, this->swiftForeignTypeHashTable.get());
-}
-
-void SubCache::addSwiftPrespecializedMetadataPointerTableChunks(const BuilderConfig& config, SwiftOptimizer& opt)
+    this->addLinkeditChunk(this->swiftForeignTypeHashTable.get());
+}
+
+void SubCache::addSwiftPrespecializedMetadataPointerTableChunks(SwiftProtocolConformanceOptimizer& opt)
 {
     for ( PointerHashTableOptimizerInfo& tableInfo : opt.prespecializedMetadataHashTables ) {
         PointerHashTableChunk* chunk = this->pointerHashTables.emplace_back(std::make_unique<PointerHashTableChunk>()).get();
@@ -1352,7 +1288,7 @@
         chunk->subCacheFileSize  = CacheFileSize(tableInfo.size);
 
         tableInfo.chunk = chunk;
-        this->addReadOnlyChunk(config, chunk);
+        this->addLinkeditChunk(chunk);
     }
 }
 
@@ -1549,16 +1485,15 @@
 }
 
 void SubCache::writeCacheHeader(const BuilderOptions& options, const BuilderConfig& config,
-                                const std::span<CacheDylib> cacheDylibs,
-                                uint32_t osVersion, uint32_t altPlatform, uint32_t altOsVersion)
+                                const std::span<CacheDylib> cacheDylibs)
 {
     Chunk& cacheHeaderChunk = *this->cacheHeader.get();
     dyld_cache_header* dyldCacheHeader = (dyld_cache_header*)cacheHeaderChunk.subCacheBuffer;
 
     // "dyld_v1" + spaces + archName(), with enough spaces to pad to 15 bytes
     std::string magic = "dyld_v1";
-    magic.append(15 - magic.length() - strlen(options.arch.name()), ' ');
-    magic.append(options.arch.name());
+    magic.append(15 - magic.length() - strlen(options.archs.name()), ' ');
+    magic.append(options.archs.name());
     assert(magic.length() == 15);
 
     // Num of mappings depends on cache layout.
@@ -1604,14 +1539,12 @@
     dyldCacheHeader->progClosuresSize              = 0; // no longer used
     dyldCacheHeader->progClosuresTrieAddr          = 0; // no longer used
     dyldCacheHeader->progClosuresTrieSize          = 0; // no longer used
-    dyldCacheHeader->platform                      = options.platform.value();
+    dyldCacheHeader->platform                      = (uint8_t)options.platform;
     dyldCacheHeader->formatVersion                 = 0; //dyld3::closure::kFormatVersion;
     dyldCacheHeader->dylibsExpectedOnDisk          = !options.dylibsRemovedFromDisk;
     dyldCacheHeader->simulator                     = options.isSimulator();
     dyldCacheHeader->locallyBuiltCache             = options.isLocallyBuiltCache;
     dyldCacheHeader->builtFromChainedFixups        = false; // no longer used
-    dyldCacheHeader->newFormatTLVs                 = true;
-    dyldCacheHeader->padding                       = 0;
     dyldCacheHeader->sharedRegionStart             = this->subCacheVMAddress.rawValue();
     dyldCacheHeader->sharedRegionSize              = 0;
     dyldCacheHeader->maxSlide                      = 0; // overwritten later in build if the cache supports ASLR
@@ -1629,9 +1562,9 @@
     dyldCacheHeader->programsPBLSetPoolSize        = 0; // set later only on the main cache file
     dyldCacheHeader->programTrieAddr               = 0; // set later only on the main cache file
     dyldCacheHeader->programTrieSize               = 0; // set later only on the main cache file
-    dyldCacheHeader->osVersion                     = osVersion;
-    dyldCacheHeader->altPlatform                   = altPlatform;
-    dyldCacheHeader->altOsVersion                  = altOsVersion;
+    dyldCacheHeader->osVersion                     = 0; // set later only on the main cache file
+    dyldCacheHeader->altPlatform                   = 0; // set later only on the main cache file
+    dyldCacheHeader->altOsVersion                  = 0; // set later only on the main cache file
     dyldCacheHeader->swiftOptsOffset               = 0; // set later only on the main cache file
     dyldCacheHeader->swiftOptsSize                 = 0; // set later only on the main cache file
     dyldCacheHeader->subCacheArrayOffset           = 0;
@@ -1650,8 +1583,6 @@
     dyldCacheHeader->dynamicDataMaxSize            = 0; // set later only on the main cache file
     dyldCacheHeader->tproMappingsOffset            = 0; // set later only on the main cache file
     dyldCacheHeader->tproMappingsCount             = 0; // set later only on the main cache file
-    dyldCacheHeader->prewarmingDataOffset          = 0; // set later only on the main cache file
-    dyldCacheHeader->prewarmingDataSize            = 0; // set later only on the main cache file
 
     // Fill in old mappings
     // And new mappings which also have slide info
@@ -1663,15 +1594,14 @@
 void SubCache::addMainCacheHeaderInfo(const BuilderOptions& options, const BuilderConfig& config,
                                       const std::span<CacheDylib> cacheDylibs,
                                       CacheVMSize totalVMSize, uint64_t maxSlide,
+                                      uint32_t osVersion, uint32_t altPlatform, uint32_t altOsVersion,
                                       CacheVMAddress dyldInCacheUnslidAddr,
                                       CacheVMAddress dyldInCacheEntryUnslidAddr,
                                       const DylibTrieOptimizer& dylibTrieOptimizer,
                                       const ObjCOptimizer& objcOptimizer,
-                                      const SwiftOptimizer& swiftOpt,
+                                      const SwiftProtocolConformanceOptimizer& swiftProtocolConformanceOpt,
                                       const PatchTableOptimizer& patchTableOptimizer,
-                                      const FunctionVariantsOptimizer& functionVariantOptimizer,
-                                      const PrebuiltLoaderBuilder& prebuiltLoaderBuilder,
-                                      const PrewarmingOptimizer& prewarmingOptimizer)
+                                      const PrebuiltLoaderBuilder& prebuiltLoaderBuilder)
 {
     const CacheVMAddress cacheBaseAddress = config.layout.cacheBaseAddress;
 
@@ -1684,13 +1614,13 @@
     dyldCacheHeader->dylibsTrieAddr = dylibTrieOptimizer.dylibsTrieChunk->cacheVMAddress.rawValue();
     dyldCacheHeader->dylibsTrieSize = dylibTrieOptimizer.dylibsTrieChunk->subCacheFileSize.rawValue();
 
-    // Disable objc optimizations from EK shared cache
-    bool emitObjcOpts = !options.platform.isExclaveKit();
-    if ( !objcOptimizer.objcDylibs.empty() && emitObjcOpts ) {
+    if ( !objcOptimizer.objcDylibs.empty() ) {
         dyldCacheHeader->objcOptsOffset = (objcOptimizer.optsHeaderChunk->cacheVMAddress - cacheBaseAddress).rawValue();
         dyldCacheHeader->objcOptsSize   = objcOptimizer.optsHeaderChunk->subCacheFileSize.rawValue();
-
-        const auto& opt = swiftOpt;
+    }
+
+    if ( !objcOptimizer.objcDylibs.empty() ) {
+        const auto& opt = swiftProtocolConformanceOpt;
         dyldCacheHeader->swiftOptsOffset = (opt.optsHeaderChunk->cacheVMAddress - cacheBaseAddress).rawValue();
         dyldCacheHeader->swiftOptsSize   = opt.optsHeaderChunk->subCacheFileSize.rawValue();
     }
@@ -1707,15 +1637,16 @@
     dyldCacheHeader->dyldInCacheMH      = dyldInCacheUnslidAddr.rawValue();
     dyldCacheHeader->dyldInCacheEntry   = dyldInCacheEntryUnslidAddr.rawValue();
 
+    dyldCacheHeader->osVersion      = osVersion;
+    dyldCacheHeader->altPlatform    = altPlatform;
+    dyldCacheHeader->altOsVersion   = altOsVersion;
+
     // record max slide now that final size is established
     dyldCacheHeader->maxSlide           = maxSlide;
 
     // TODO: Build the atlas
     dyldCacheHeader->cacheAtlasOffset              = 0; // set later only on the main cache file
     dyldCacheHeader->cacheAtlasSize                = 0; // set later only on the main cache file
-
-    dyldCacheHeader->functionVariantInfoAddr = functionVariantOptimizer.chunk->cacheVMAddress.rawValue();
-    dyldCacheHeader->functionVariantInfoSize = functionVariantOptimizer.fvInfoTotalByteSize;
 
     // The main cache has offsets to all the caches
     if ( !this->subCaches.empty() ) {
@@ -1755,11 +1686,6 @@
             ++index;
         });
     }
-
-    if ( prewarmingOptimizer.prewarmingChunk != nullptr ) {
-        dyldCacheHeader->prewarmingDataOffset = (prewarmingOptimizer.prewarmingChunk->cacheVMAddress - cacheBaseAddress).rawValue();
-        dyldCacheHeader->prewarmingDataSize   = prewarmingOptimizer.prewarmingChunk->subCacheFileSize.rawValue();
-    }
 }
 
 void SubCache::addSymbolsCacheHeaderInfo(const UnmappedSymbolsOptimizer& optimizer)
@@ -1786,7 +1712,7 @@
                                        const BuilderConfig& config,
                                        const std::span<CacheDylib> cacheDylibs)
 {
-    if ( !this->needsCacheHeaderImageList(options) )
+    if ( !this->needsCacheHeaderImageList() )
         return;
 
     Chunk&             cacheHeaderChunk   = *this->cacheHeader.get();
@@ -1812,7 +1738,7 @@
 
     // write text image array and image names pool at same time
     for ( const CacheDylib& cacheDylib : cacheDylibs ) {
-        cacheDylib.inputHdr->getUuid(textImages->uuid);
+        cacheDylib.inputMF->getUuid(textImages->uuid);
         textImages->loadAddress     = cacheDylib.cacheLoadAddress.rawValue();
         textImages->textSegmentSize = (uint32_t)cacheDylib.segments.front().cacheVMSize.rawValue();
         textImages->pathOffset      = stringOffset;
@@ -1920,17 +1846,16 @@
     return this->kind == Kind::stubsCustomer;
 }
 
-bool SubCache::needsCacheHeaderImageList(const BuilderOptions& options) const
+bool SubCache::needsCacheHeaderImageList() const
 {
     // Symbols and stubs files don't need an image list
+    // We'd like to not add the image list to subcaches, only the main cache, but Rosetta needs
+    // the image list on subCaches.
     switch ( this->kind ) {
         case Kind::mainDevelopment:
         case Kind::mainCustomer:
+        case Kind::subUniversal:
             return true;
-        case Kind::subUniversal:
-            // We'd like to not add the image list to subcaches, only the main cache, but Rosetta needs
-            // the image list on subCaches.
-            return options.arch.sameCpu(mach_o::Architecture::x86_64);
         case Kind::stubsDevelopment:
         case Kind::stubsCustomer:
         case Kind::symbols: