Loading...
cache_builder/CacheDylib.h dyld-1340 /dev/null
--- dyld/dyld-1340/cache_builder/CacheDylib.h
+++ /dev/null
@@ -1,324 +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 CacheDylib_hpp
-#define CacheDylib_hpp
-
-#include "CachePatching.h"
-#include "Chunk.h"
-#include "Diagnostics.h"
-#include "MachOFile.h"
-#include "NewAdjustDylibSegments.h"
-#include "ObjCVisitor.h"
-#include "SectionCoalescer.h"
-#include "SwiftVisitor.h"
-#include "Timer.h"
-#include "Image.h"
-
-#include <list>
-
-namespace cache_builder
-{
-
-struct BuilderConfig;
-struct InputFile;
-struct ObjCIMPCachesOptimizer;
-struct ObjCSelectorOptimizer;
-struct ObjCCategoryOptimizer;
-struct StubOptimizer;
-struct UnmappedSymbolsOptimizer;
-struct FunctionVariantsOptimizer;
-
-// A dylib which will be included in the cache
-struct CacheDylib
-{
-#if BUILDING_CACHE_BUILDER_UNIT_TESTS
-    CacheDylib();
-#else
-    CacheDylib() = delete;
-#endif
-    CacheDylib(InputFile& inputFile);
-    // create a CacheDylib *placeholder* with an install name only and no input mach-o
-    CacheDylib(std::string_view installName);
-    ~CacheDylib() = default;
-
-    CacheDylib(const CacheDylib&) = delete;
-    CacheDylib& operator=(const CacheDylib&) = delete;
-
-    CacheDylib& operator=(CacheDylib&&) = default;
-    CacheDylib(CacheDylib&&) = default;
-
-    // Passes to create a valid CacheDylib from an input file
-    void categorizeSegments(const BuilderConfig& config,
-                            objc_visitor::Visitor& objcVisitor);
-    void categorizeLinkedit(const BuilderConfig& config);
-
-    // Passes to run to add a CacheDylib to a SubCache
-    void copyRawSegments(const BuilderConfig& config, Timer::AggregateTimer& timer);
-    void applySplitSegInfo(Diagnostics& diag, const BuilderOptions& options,
-                           const BuilderConfig& config, Timer::AggregateTimer& timer,
-                           UnmappedSymbolsOptimizer& unmappedSymbolsOptimizer);
-    void updateSymbolTables(Diagnostics& diag, const BuilderConfig& config, Timer::AggregateTimer& timer);
-    std::vector<error::Error> calculateBindTargets(Diagnostics& diag, const BuilderConfig& config, Timer::AggregateTimer& timer,
-                                                   const std::vector<const CacheDylib *>& cacheDylibs,
-                                                   PatchInfo& dylibPatchInfo);
-    void calcuatePatchInfo(Diagnostics& diag, const BuilderConfig& config, Timer::AggregateTimer& timer,
-                           PatchInfo& dylibPatchInfo);
-    void bind(Diagnostics& diag, const BuilderConfig& config, Timer::AggregateTimer& timer,
-              PatchInfo& dylibPatchInfo, FunctionVariantsOptimizer& functionVariantsOptimizer);
-    void updateObjCSelectorReferences(Diagnostics& diag, const BuilderConfig& config, Timer::AggregateTimer& timer,
-                                      ObjCSelectorOptimizer& objcSelectorOptimizer);
-    void convertObjCMethodListsToOffsets(Diagnostics& diag, const BuilderConfig& config, Timer::AggregateTimer& timer,
-                                         const Chunk* selectorStringsChunk);
-    void sortObjCMethodLists(Diagnostics& diag, const BuilderConfig& config, Timer::AggregateTimer& timer,
-                             const Chunk* selectorStringsChunk);
-    void optimizeLoadsFromConstants(const BuilderConfig& config, Timer::AggregateTimer& timer,
-                                    const ObjCStringsChunk* selectorStringsChunk);
-    error::Error emitObjCIMPCaches(const BuilderConfig& config, Timer::AggregateTimer& timer,
-                                   const ObjCIMPCachesOptimizer& objcIMPCachesOptimizer,
-                                   const ObjCStringsChunk* selectorStringsChunk);
-    void optimizeStubs(const BuilderOptions& options, const BuilderConfig& config,
-                       Timer::AggregateTimer& timer, const StubOptimizer& stubOptimizer,
-                       const PatchInfo& dylibPatchInfo);
-    void fipsSign(Timer::AggregateTimer& timer);
-    void addObjcSegments(Diagnostics& diag, Timer::AggregateTimer& timer,
-                         const ObjCHeaderInfoReadOnlyChunk* headerInfoReadOnlyChunk,
-                         const ObjCImageInfoChunk* imageInfoChunk,
-                         const ObjCProtocolHashTableChunk* protocolHashTableChunk,
-                         const ObjCPreAttachedCategoriesChunk* preAttachedCategoriesChunk,
-                         const ObjCHeaderInfoReadWriteChunk* headerInfoReadWriteChunk,
-                         const ObjCCanonicalProtocolsChunk* canonicalProtocolsChunk);
-    // remove all dylib link load commands, except libSystem
-    void removeLinkedDylibs(Diagnostics& diag);
-    void addLinkedDylib(Diagnostics& diag, const CacheDylib& dylib);
-
-    void forEachCacheSection(void (^callback)(std::string_view segmentName,
-                                              std::string_view sectionName,
-                                              uint8_t* sectionBuffer,
-                                              CacheVMAddress sectionVMAddr,
-                                              CacheVMSize sectionVMSize,
-                                              bool& stop));
-
-    struct DependentDylib
-    {
-        enum class Kind
-        {
-            normal,
-            weakLink,
-            reexport,
-            upward
-        };
-
-        Kind              kind  = Kind::normal;
-        const CacheDylib* dylib = nullptr;
-    };
-
-    struct BindTarget
-    {
-        enum class Kind
-        {
-            absolute,
-            inputImage,
-            cacheImage
-        };
-
-        struct Absolute
-        {
-            uint64_t value;
-        };
-
-        struct InputImage
-        {
-            VMOffset            targetRuntimeOffset;
-            const CacheDylib*   targetDylib;
-            bool                isWeakDef;
-            bool                isFunctionVariant;
-            uint16_t            functionVariantTableIndex;
-        };
-
-        struct CacheImage
-        {
-            VMOffset            targetRuntimeOffset;
-            const CacheDylib*   targetDylib;
-            bool                isWeakDef;
-            bool                isFunctionVariant;
-            uint16_t            functionVariantTableIndex;
-        };
-
-        Kind        kind    = Kind::absolute;
-        union
-        {
-            // Just to give a default constructor...
-            uint64_t    unusedRawValue = 0;
-
-            Absolute    absolute;
-            InputImage  inputImage;
-            CacheImage  cacheImage;
-        };
-        uint64_t    addend  = 0;
-        bool        isWeakImport;
-#if DEBUG
-        CString     name;
-#endif
-    };
-
-    // Map from where the GOT is located in the dylib to where its located in the coalesced section
-    // We don't know the final VMAddr yet, but can map from GOTs in the client to the GOT+offset in the final cache
-    typedef std::unordered_map<const InputDylibVMAddress, ChunkPlusOffset, InputDylibVMAddressHash, InputDylibVMAddressEqual> CoalescedGOTsMap;
-
-    typedef std::pair<BindTarget, std::string> BindTargetAndName;
-    enum class SearchMode
-    {
-        onlySelf,
-        selfAndReexports
-    };
-
-    std::optional<BindTargetAndName>    hasExportedSymbol(Diagnostics& diag, const char* symbolName, SearchMode mode) const;
-
-    objc_visitor::Visitor makeCacheObjCVisitor(const BuilderConfig& config,
-                                               const Chunk* selectorStringsChunk,
-                                               const ObjCCanonicalProtocolsChunk* canonicalProtocolsChunk,
-                                               const ObjCPreAttachedCategoriesChunk* categoriesChunk) const;
-
-    metadata_visitor::SwiftVisitor makeCacheSwiftVisitor(const BuilderConfig& config,
-                                                         std::span<metadata_visitor::Segment> extraRegions) const;
-
-    metadata_visitor::Visitor makeCacheVisitor(const BuilderConfig& config) const;
-
-private:
-
-    // Helper method for calculateBindTargets()
-    BindTargetAndName                   resolveSymbol(Diagnostics& diag, int libOrdinal, const char* symbolName, bool weakImport,
-                                                      const std::vector<const CacheDylib*>& cacheDylibs) const;
-    std::optional<BindTargetAndName>    findDyldMagicSymbolAddress(const char* fullSymbolName, std::string_view name) const;
-
-    void calculateBindLocationPatchInfo(Diagnostics& diag, const BuilderConfig& config,
-                                        const BindTarget& bindTarget, uint64_t addend,
-                                        uint32_t bindOrdinal, uint32_t segIndex,
-                                        InputDylibVMAddress fixupVMAddr, dyld3::MachOFile::PointerMetaData pmd,
-                                        CoalescedGOTsMap& coalescedGOTs, CoalescedGOTsMap& coalescedAuthGOTs,
-                                        CoalescedGOTsMap& coalescedAuthPtrs, PatchInfo& dylibPatchInfo);
-
-    void bindLocation(Diagnostics& diag, const BuilderConfig& config,
-                      const BindTarget& bindTarget, uint64_t addend,
-                      uint32_t bindOrdinal, uint32_t segIndex,
-                      dyld3::MachOFile::ChainedFixupPointerOnDisk* fixupLoc,
-                      CacheVMAddress fixupVMAddr, dyld3::MachOFile::PointerMetaData pmd,
-                      CoalescedGOTsMap& coalescedGOTs, CoalescedGOTsMap& coalescedAuthGOTs,
-                      CoalescedGOTsMap& coalescedAuthPtrs, PatchInfo& dylibPatchInfo,
-                      FunctionVariantsOptimizer& functionVariantsOptimizer);
-    void bindWithChainedFixups(Diagnostics& diag, const BuilderConfig& config,
-                               CoalescedGOTsMap& coalescedGOTs, CoalescedGOTsMap& coalescedAuthGOTs,
-                               CoalescedGOTsMap& coalescedAuthPtrs, PatchInfo& dylibPatchInfo,
-                               FunctionVariantsOptimizer& functionVariantsOptimizer);
-    void bindWithOpcodeFixups(Diagnostics& diag, const BuilderConfig& config,
-                              CoalescedGOTsMap& coalescedGOTs, CoalescedGOTsMap& coalescedAuthGOTs,
-                              CoalescedGOTsMap& coalescedAuthPtrs, PatchInfo& dylibPatchInfo,
-                              FunctionVariantsOptimizer& functionVariantsOptimizer);
-
-    void forEachReferenceToASelRef(Diagnostics &diags,
-                                   void (^handler)(uint64_t kind, uint32_t* instrPtr, uint64_t selRefVMAddr)) const;
-
-    // Part of IMP caches
-    error::Error setObjCImpCachesPointers(const BuilderConfig& config,
-                                          const ObjCIMPCachesOptimizer& objcIMPCachesOptimizer,
-                                          const ObjCStringsChunk* selectorStringsChunk);
-
-    // Part of the stub optimization
-    typedef std::unordered_map<CacheVMAddress, CacheVMAddress,
-                               CacheVMAddressHash, CacheVMAddressEqual> OldToNewStubMap;
-    CacheDylib::OldToNewStubMap buildStubMaps(const BuilderConfig& config,
-                                              const StubOptimizer& stubOptimizer,
-                                              const PatchInfo& dylibPatchInfo);
-
-    typedef bool (^CallSiteHandler)(uint8_t callSiteKind, uint64_t callSiteAddr,
-                                    uint64_t stubAddr, uint32_t& instruction);
-    void forEachCallSiteToAStub(Diagnostics& diag, const CallSiteHandler handler);
-
-    typedef std::unordered_map<CacheVMAddress, CacheVMAddress,
-                               CacheVMAddressHash, CacheVMAddressEqual> GOTToTargetMap;
-    GOTToTargetMap getUniquedGOTTargets(const PatchInfo& dylibPatchInfo) const;
-
-#if DEBUG
-    // Helper method to watch a memory location while building the cache.  Called from copyRawSegments().
-    void watchMemory(const DylibSegmentChunk& segment, std::string_view dylibInstallName,
-                     std::string_view dylibSegmentName, uint64_t dylibAddressInSegment) const;
-#endif
-
-
-public:
-    InputFile*                              inputFile               = nullptr;
-    const dyld3::MachOFile*                 inputMF                 = nullptr;
-    const mach_o::Header*                   inputHdr                = nullptr;
-    std::unique_ptr<mach_o::Image>          inputImage              = nullptr;
-    InputDylibVMAddress                     inputLoadAddress;
-    std::string_view                        installName;
-    uint32_t                                cacheIndex;
-    bool                                    needsPatchTable         = true;
-    dyld3::MachOFile*                       cacheMF                 = nullptr;
-    const mach_o::Header*                   cacheHdr                = nullptr;
-    CacheVMAddress                          cacheLoadAddress;
-    std::vector<DylibSegmentChunk>          segments;
-    // This is a list due to iterator invalidation, ie, calculateSubCacheSymbolStrings() deletes
-    // elements and Region holds pointers to them
-    std::list<LinkeditDataChunk>            linkeditChunks;
-    std::vector<DependentDylib>             dependents;
-    // an unmodified list of linked libraries, used for symbol resolution
-    std::vector<DependentDylib>             inputDependents;
-    std::vector<BindTarget>                 bindTargets;
-    std::optional<uint32_t>                 weakBindTargetsStartIndex;
-    std::unique_ptr<DylibSegmentsAdjustor>  adjustor;
-
-    // The final cache won't have split seg, but we need it in multiple places during building.  So keep a copy
-    const uint8_t*                          inputDylibSplitSegStart = nullptr;
-    const uint8_t*                          inputDylibSplitSegEnd   = nullptr;
-
-    // The final cache won't have dyld info, but we need it in multiple places during building.  So keep a copy
-    const uint8_t*                          inputDylibRebaseStart   = nullptr;
-    const uint8_t*                          inputDylibRebaseEnd     = nullptr;
-    const uint8_t*                          inputDylibBindStart     = nullptr;
-    const uint8_t*                          inputDylibBindEnd       = nullptr;
-    const uint8_t*                          inputDylibLazyBindStart = nullptr;
-    const uint8_t*                          inputDylibLazyBindEnd   = nullptr;
-    const uint8_t*                          inputDylibWeakBindStart = nullptr;
-    const uint8_t*                          inputDylibWeakBindEnd   = nullptr;
-
-    // calculateSubCacheSymbolStrings() builds new nlists.  We need to store them here until we can copy them in to the
-    // final cache binary
-    NListChunk                              optimizedSymbols;
-    const SymbolStringsChunk*               subCacheSymbolStrings   = nullptr;
-    std::vector<uint32_t>                   indirectSymbolTable;
-
-    // calculateUniqueGOTs() uniques GOTs across dylibs.  This stores the results for this dylib
-    DylibSectionCoalescer                   optimizedSections;
-
-    // In Universal caches, this dylib will be redirected to use these alternative stubs
-    StubsChunk                              developmentStubs;
-    StubsChunk                              customerStubs;
-};
-static_assert(std::is_move_constructible<CacheDylib>::value, "CacheDylib needs to be move constructible");
-
-} // namespace cache_builder
-
-#endif /* CacheDylib_hpp */