Loading...
--- dyld/dyld-1340/cache_builder/SubCache.h
+++ /dev/null
@@ -1,348 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
-*
-* Copyright (c) 2017 Apple Inc. All rights reserved.
-*
-* @APPLE_LICENSE_HEADER_START@
-*
-* This file contains Original Code and/or Modifications of Original Code
-* as defined in and that are subject to the Apple Public Source License
-* Version 2.0 (the 'License'). You may not use this file except in
-* compliance with the License. Please obtain a copy of the License at
-* http://www.opensource.apple.com/apsl/ and read it before using this
-* file.
-*
-* The Original Code and all software distributed under the License are
-* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
-* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
-* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
-* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
-* Please see the License for the specific language governing rights and
-* limitations under the License.
-*
-* @APPLE_LICENSE_HEADER_END@
-*/
-
-#ifndef SubCache_hpp
-#define SubCache_hpp
-
-#include "Defines.h"
-#include "Chunk.h"
-#include "MachOFile.h"
-#include "Optimizers.h"
-#include "Platform.h"
-#include "Types.h"
-
-#include <uuid/uuid.h>
-#include <vector>
-
-namespace cache_builder
-{
-
-struct BuilderOptions;
-
-struct Region
-{
- // Note the order of this enum is the order in the final cache binary.
- // It is sorted to try keep page tables to a minimum, ie, keeping similar regions adjacent
- enum class Kind : uint32_t
- {
- text,
-
- // Rosetta expects __DATA_CONST after __TEXT, as we currently sort using this enum
- dataConst,
-
- // Put TPRO const before data as we want it to be adjacent to the DATA_DIRTY which it at the start of data
- tproConst,
-
- data,
-
- // Put TPRO auth const before auth as we want it to be adjacent to the DATA_DIRTY which it at the start of auth
- tproAuthConst,
-
- auth,
-
- // FIXME: Move this to be after DATA_CONST to reduce page tables
- // Needs rdar://96315050
- authConst,
-
- readOnly,
- linkedit,
- unmapped,
- dynamicConfig,
- codeSignature,
-
- numKinds
- };
-
- Region(Kind kind) : kind(kind) { }
-
- uint32_t initProt() const;
- uint32_t maxProt() const;
- bool canContainAuthPointers() const;
- bool needsSharedCacheMapping() const;
- bool needsSharedCacheReserveAddressSpace() const;
-
- bool needsRegionPadding(const Region& next) const;
-
- Kind kind;
-
- // The chunks from dylibs, optimzations, etc, which make up this Region
- std::vector<Chunk*> chunks;
-
- std::list<AlignChunk> alignmentChunks;
-
- CacheFileOffset subCacheFileOffset;
- CacheFileSize subCacheFileSize;
- CacheVMAddress subCacheVMAddress;
- CacheVMSize subCacheVMSize;
- uint8_t* subCacheBuffer = nullptr;
-};
-
-struct SubCache
-{
-private:
- enum class Kind
- {
- mainDevelopment,
- stubsDevelopment,
-
- mainCustomer,
- stubsCustomer,
-
- // If we aren't the main cache, or a stubs cache, then the remainder is a universal "sub" cache
- // which is typically TEXT/DATA/LINKEDIT
- subUniversal,
-
- symbols
- };
-
- SubCache(Kind kind);
-
-public:
- SubCache() = delete;
- ~SubCache() = default;
- SubCache(const SubCache&) = delete;
- SubCache& operator=(const SubCache&) = delete;
- SubCache(SubCache&&) = default;
- SubCache& operator=(SubCache&&) = default;
-
- // Helper methods to build the various kinds of subCache
- static SubCache makeMainCache(const BuilderOptions& options, bool isDevelopment);
- static SubCache makeSubCache(const BuilderOptions& options);
- static SubCache makeStubsCache(const BuilderOptions& options, bool isDevelopment);
- static SubCache makeSymbolsCache();
-
- // These methods are called by computeSubCaches() to add Chunk's to the subCache
- void addDylib(const BuilderConfig& config, CacheDylib& cacheDylib);
- void addLinkeditFromDylib(CacheDylib& cacheDylib);
- void addCacheHeaderChunk(const BuilderOptions& options, const BuilderConfig& config,
- const std::span<CacheDylib> cacheDylibs);
- void addObjCHeaderInfoReadWriteChunk(const BuilderConfig& config, ObjCOptimizer& objcOptimizer);
- void addCodeSignatureChunk();
- void addObjCOptsHeaderChunk(const BuilderConfig& config, ObjCOptimizer& objcOptimizer);
- void addObjCHeaderInfoReadOnlyChunk(const BuilderConfig& config, ObjCOptimizer& objcOptimizer);
- void addObjCImageInfoChunk(const BuilderConfig& config, ObjCOptimizer& objcOptimizer);
- void addObjCSelectorStringsChunk(const BuilderConfig& config, ObjCSelectorOptimizer& objCSelectorOptimizer);
- void addObjCSelectorHashTableChunk(const BuilderConfig& config, ObjCSelectorOptimizer& objCSelectorOptimizer);
- void addObjCClassNameStringsChunk(const BuilderConfig& config, ObjCClassOptimizer& objcClassOptimizer);
- void addObjCClassHashTableChunk(const BuilderConfig& config, ObjCClassOptimizer& objcClassOptimizer);
- void addObjCProtocolNameStringsChunk(const BuilderConfig& config, ObjCProtocolOptimizer& objcProtocolOptimizer);
- void addObjCProtocolHashTableChunk(const BuilderConfig& config, ObjCProtocolOptimizer& objcProtocolOptimizer);
- void addObjCProtocolSwiftDemangledNamesChunk(const BuilderConfig& config, ObjCProtocolOptimizer& objcProtocolOptimizer);
- void addObjCCanonicalProtocolsChunk(const BuilderConfig& config,
- ObjCProtocolOptimizer& objcProtocolOptimizer);
- void addObjCCategoriesChunk(const BuilderConfig& config,
- ObjCCategoryOptimizer& objcCategoryOptimizer);
- void addObjCIMPCachesChunk(const BuilderConfig& config, ObjCIMPCachesOptimizer& objcIMPCachesOptimizer);
- void addCacheTrieChunk(DylibTrieOptimizer& dylibTrieOptimizer);
- void addPatchTableChunk(PatchTableOptimizer& patchTableOptimizer);
- void addFunctionVariantsChunk(FunctionVariantsOptimizer& optimizer);
- void addCacheDylibsLoaderChunk(PrebuiltLoaderBuilder& builder);
- void addExecutableLoaderChunk(PrebuiltLoaderBuilder& builder);
- void addExecutablesTrieChunk(PrebuiltLoaderBuilder& builder);
- void addSwiftOptsHeaderChunk(const BuilderConfig& config, SwiftOptimizer& opt);
- void addSwiftTypeHashTableChunk(const BuilderConfig& config, SwiftOptimizer& opt);
- void addSwiftMetadataHashTableChunk(const BuilderConfig& config, SwiftOptimizer& opt);
- void addSwiftForeignHashTableChunk(const BuilderConfig& config, SwiftOptimizer& opt);
- void addSwiftPrespecializedMetadataPointerTableChunks(const BuilderConfig& config, SwiftOptimizer& opt);
- void addPrewarmingDataChunk(const BuilderConfig& config, PrewarmingOptimizer& opt);
- void addUnmappedSymbols(const BuilderConfig& config, UnmappedSymbolsOptimizer& opt);
- void addDynamicConfigChunk();
- void addSlideInfoChunks();
- void removeEmptyRegions();
-
- // When "kind == sub", sets the suffix on this subCache
- // This has to be done after creating things like stubs sub caches, which might move the indices
- void setSuffix(mach_o::Platform platform, bool forceDevelopmentSubCacheSuffix,
- size_t subCacheIndex);
-
- void setCodeSignatureSize(const BuilderOptions& options, const BuilderConfig& config,
- CacheFileSize estimatedSize);
-
- error::Error computeSlideInfo(const BuilderConfig& config);
-
- // Emits a dyld_cache_header for this subCache
- void writeCacheHeader(const BuilderOptions& options, const BuilderConfig& config,
- const std::span<CacheDylib> cacheDylibs,
- uint32_t osVersion, uint32_t altPlatform, uint32_t altOsVersion);
-
- // Adds any additional fields which are set only on the main subCache(s)
- void addMainCacheHeaderInfo(const BuilderOptions& options, const BuilderConfig& config,
- const std::span<CacheDylib> cacheDylibs,
- CacheVMSize totalVMSize, uint64_t maxSlide,
- CacheVMAddress dyldInCacheUnslidAddr,
- CacheVMAddress dyldInCacheEntryUnslidAddr,
- const DylibTrieOptimizer& dylibTrieOptimizer,
- const ObjCOptimizer& objcOpt,
- const SwiftOptimizer& swiftOpt,
- const PatchTableOptimizer& patchTableOptimizer,
- const FunctionVariantsOptimizer& functionVariantOptimizer,
- const PrebuiltLoaderBuilder& prebuiltLoaderBuilder,
- const PrewarmingOptimizer& prewarmingOptimizer);
-
- // Adds any additional fields which are set only on the .symbols subCache
- void addSymbolsCacheHeaderInfo(const UnmappedSymbolsOptimizer& unmappedSymbolsOptimizer);
-
- void codeSign(Diagnostics& diag, const BuilderOptions& options, const BuilderConfig& config);
-
- bool isMainCache() const;
- bool isMainDevelopmentCache() const;
- bool isMainCustomerCache() const;
- bool isSubCache() const;
- bool isStubsCache() const;
- bool isStubsDevelopmentCache() const;
- bool isStubsCustomerCache() const;
- bool isSymbolsCache() const;
-
- void addStubsChunk(Chunk* chunk);
-
- bool shouldKeepCache(bool keepDevelopmentCaches, bool keepCustomerCaches) const;
-
- // Note this is for x86_64 only, and works out where the TPRO "regions" are inside the DATA region
- static void forEachTPRORegionInData(SubCache* mainSubCache, std::span<SubCache*> subCaches,
- void (^callback)(Region& region, const Chunk* firstChunk, const Chunk* lastChunk));
-
- // Adds the given chunk to the given region
- void addTextChunk(Chunk* chunk);
- void addDataChunk(Chunk* chunk);
- void addTPROConstChunk(const BuilderConfig& config, Chunk* chunk);
- void addDataConstChunk(Chunk* chunk);
- void addAuthChunk(Chunk* chunk);
- void addAuthConstChunk(Chunk* chunk);
- void addReadOnlyChunk(const BuilderConfig& config, Chunk* chunk);
- void addLinkeditChunk(Chunk* chunk);
- void addUnmappedChunk(Chunk* chunk);
- void addCodeSignatureChunk(Chunk* chunk);
- void addObjCReadWriteChunk(const BuilderConfig& config, Chunk* chunk);
-
-#if BUILDING_CACHE_BUILDER_UNIT_TESTS
- // We need everything public to write tests
-public:
-#else
-private:
-#endif
-
- // Returns true if the cache header on this subCache needs an image list
- // The symbols cache and stubs caches, for example, don't need this
- bool needsCacheHeaderImageList(const BuilderOptions& options) const;
-
- // Add image info to the subCache header, if it needs it
- void addCacheHeaderImageInfo(const BuilderOptions& options,
- const BuilderConfig& config,
- const std::span<CacheDylib> cacheDylibs);
-
- static uint64_t getCacheType(const BuilderOptions& options);
- uint32_t getCacheSubType() const;
- void writeCacheHeaderMappings();
-
- static error::Error convertChainsToVMAddresses(const BuilderConfig& config, Region& region);
- static error::Error computeSlideInfoV1(const BuilderConfig& config,
- SlideInfoChunk* slideChunk,
- Region& region);
- static error::Error computeSlideInfoV2(const BuilderConfig& config,
- SlideInfoChunk* slideChunk,
- Region& region);
- static error::Error computeSlideInfoV3(const BuilderConfig& config,
- SlideInfoChunk* slideChunk,
- Region& region);
- static error::Error computeSlideInfoV5(const BuilderConfig& config,
- SlideInfoChunk* slideChunk,
- Region& region);
- static error::Error computeSlideInfoForRegion(const BuilderConfig& config,
- SlideInfoChunk* slideChunk,
- Region& region);
-
-public:
- Kind kind;
- std::vector<Region> regions;
-
- // This buffer is vm_allocated (or points to a file on disk). Either way, the builder
- // creates it but doesn't destroy it. Its ownership will move out to the calling code via
- // getResults(), and the caller will deallocate/unmap as needed
- uint8_t* buffer = nullptr;
- uint64_t bufferSize = 0;
- CacheVMAddress subCacheVMAddress;
- uint8_t cdHash[20];
- uint8_t agilecdHash[20]; // if using agile signatures, this is the sha256
- uuid_string_t uuidString;
- std::string fileSuffix;
-
- // Some Chunk instances are owned by the SubCache. Eg, it owns its own header
- std::unique_ptr<CacheHeaderChunk> cacheHeader;
- std::unique_ptr<SlideInfoChunk> tproConstSlideInfo;
- std::unique_ptr<SlideInfoChunk> dataSlideInfo;
- std::unique_ptr<SlideInfoChunk> dataConstSlideInfo;
- std::unique_ptr<SlideInfoChunk> tproAuthConstSlideInfo;
- std::unique_ptr<SlideInfoChunk> authSlideInfo;
- std::unique_ptr<SlideInfoChunk> authConstSlideInfo;
- std::unique_ptr<CodeSignatureChunk> codeSignature;
- std::unique_ptr<ObjCOptsHeaderChunk> objcOptsHeader;
- std::unique_ptr<ObjCHeaderInfoReadOnlyChunk> objcHeaderInfoRO;
- std::unique_ptr<ObjCHeaderInfoReadWriteChunk> objcHeaderInfoRW;
- std::unique_ptr<ObjCImageInfoChunk> objcImageInfo;
- std::unique_ptr<ObjCStringsChunk> objcSelectorStrings;
- std::unique_ptr<ObjCSelectorHashTableChunk> objcSelectorsHashTable;
- std::unique_ptr<ObjCStringsChunk> objcClassNameStrings;
- std::unique_ptr<ObjCClassHashTableChunk> objcClassesHashTable;
- std::unique_ptr<ObjCStringsChunk> objcProtocolNameStrings;
- std::unique_ptr<ObjCProtocolHashTableChunk> objcProtocolsHashTable;
- std::unique_ptr<ObjCCanonicalProtocolsChunk> objcCanonicalProtocols;
- std::unique_ptr<ObjCPreAttachedCategoriesChunk> objcCategories;
- std::unique_ptr<ObjCStringsChunk> objcSwiftDemangledNameStrings;
- std::unique_ptr<ObjCIMPCachesChunk> objcIMPCaches;
- std::unique_ptr<SwiftOptsHeaderChunk> swiftOptsHeader;
- std::unique_ptr<SwiftProtocolConformancesHashTableChunk> swiftTypeHashTable;
- std::unique_ptr<SwiftProtocolConformancesHashTableChunk> swiftMetadataHashTable;
- std::unique_ptr<SwiftProtocolConformancesHashTableChunk> swiftForeignTypeHashTable;
- std::unique_ptr<CacheTrieChunk> cacheDylibsTrie;
- std::unique_ptr<PatchTableChunk> patchTable;
- std::unique_ptr<FunctionVariantsPatchTableChunk> functionVariants;
- std::unique_ptr<DynamicConfigChunk> dynamicConfig;
- std::unique_ptr<PrebuiltLoaderChunk> cacheDylibsLoaders;
- std::unique_ptr<PrebuiltLoaderChunk> executableLoaders;
- std::unique_ptr<CacheTrieChunk> executablesTrie;
- std::unique_ptr<SymbolStringsChunk> optimizedSymbolStrings;
- std::vector<std::unique_ptr<PointerHashTableChunk>> pointerHashTables;
- std::unique_ptr<PrewarmingChunk> prewarmingChunk;
-
- // Each subCache has its own Linkedit so needs its own optimizer
- SymbolStringsOptimizer symbolStringsOptimizer;
-
- // Each subCache can have its own uniqued GOTs
- UniquedGOTsOptimizer uniquedGOTsOptimizer;
-
- // FIXME: Should these be zero-sized Chunk's instead?
- uint64_t rosettaReadOnlyAddr = 0;
- uint64_t rosettaReadOnlySize = 0;
- uint64_t rosettaReadWriteAddr = 0;
- uint64_t rosettaReadWriteSize = 0;
-
- // The following is only used depending on the kind field
-
- // Main sub caches have a list of the other sub caches (indices are in to the builder subCaches array)
- std::vector<SubCache*> subCaches;
-};
-
-} // namespace cache_builder
-
-#endif /* SubCache_hpp */