Loading...
--- dyld/dyld-1340/common/DyldSharedCache.h
+++ dyld/dyld-960/common/DyldSharedCache.h
@@ -41,90 +41,27 @@
#endif
#include "dyld_cache_format.h"
-#include "Architecture.h"
#include "CachePatching.h"
#include "Diagnostics.h"
#include "MachOAnalyzer.h"
-#include "Header.h"
-
-#if !(BUILDING_LIBDYLD || BUILDING_DYLD)
#include "JSON.h"
-#endif
-
-typedef dyld3::MachOFile::PointerMetaData PointerMetaData;
namespace dyld4 {
class PrebuiltLoader;
struct PrebuiltLoaderSet;
}
-namespace mach_o {
- struct FunctionVariants;
-}
-
namespace objc_opt {
struct objc_opt_t;
}
-namespace objc
-{
-struct HeaderInfoRO;
-struct HeaderInfoRW;
-class SelectorHashTable;
-class ClassHashTable;
-class ProtocolHashTable;
-}
-
struct SwiftOptimizationHeader;
-
-struct VIS_HIDDEN ObjCOptimizationHeader
-{
- uint32_t version;
- uint32_t flags;
- uint64_t headerInfoROCacheOffset;
- uint64_t headerInfoRWCacheOffset;
- uint64_t selectorHashTableCacheOffset;
- uint64_t classHashTableCacheOffset;
- uint64_t protocolHashTableCacheOffset;
- uint64_t relativeMethodSelectorBaseAddressOffset;
-};
-
-// convenience tuple for tracking file by fs/inode
-struct VIS_HIDDEN FileIdTuple
-{
- FileIdTuple() { ::bzero(this, sizeof(FileIdTuple)); }
-#if !TARGET_OS_EXCLAVEKIT
- FileIdTuple(const struct stat&);
- FileIdTuple(const char* path);
- FileIdTuple(uint64_t fsidScalar, uint64_t fsobjidScalar);
- explicit operator bool() const;
- bool operator==(const FileIdTuple& other) const;
- bool getPath(char pathBuff[PATH_MAX]) const;
- uint64_t inode() const;
- uint64_t fsID() const;
-#endif
-
-private:
- void init(const struct stat&);
-
-#if !TARGET_OS_EXCLAVEKIT
- fsid_t fsid; // file system
- fsobj_id_t fsobjid; // inode within filesystem
-#endif // !TARGET_OS_EXCLAVEKIT
-};
class VIS_HIDDEN DyldSharedCache
{
public:
-#if BUILDING_CACHE_BUILDER || BUILDING_CACHE_BUILDER_UNIT_TESTS
- // FIXME: Delete this as its no longer used
- struct FileAlias
- {
- std::string realPath;
- std::string aliasPath;
- };
-
+#if BUILDING_CACHE_BUILDER
enum CodeSigningDigestMode
{
SHA256only = 0,
@@ -142,10 +79,10 @@
{
std::string outputFilePath;
std::string outputMapFilePath;
- mach_o::Architecture arch;
- mach_o::Platform platform;
+ const dyld3::GradedArchs* archs;
+ dyld3::Platform platform;
LocalSymbolsMode localSymbolMode;
- uint64_t cacheConfiguration;
+ bool optimizeStubs;
bool optimizeDyldDlopens;
bool optimizeDyldLaunches;
CodeSigningDigestMode codeSigningDigestMode;
@@ -158,7 +95,7 @@
bool evictLeafDylibsOnOverflow;
std::unordered_map<std::string, unsigned> dylibOrdering;
std::unordered_map<std::string, unsigned> dirtyDataSegmentOrdering;
- json::Node objcOptimizations;
+ dyld3::json::Node objcOptimizations;
std::string loggingPrefix;
// Customer and dev caches share a local symbols file. Only one will get this set to emit the file
std::string localSymbolsPath;
@@ -181,75 +118,62 @@
uint64_t inode; // only recorded if inodesAreSameAsRuntime
};
+ struct CreateResults
+ {
+ std::string errorMessage;
+ std::set<std::string> warnings;
+ std::set<const dyld3::MachOAnalyzer*> evictions;
+ };
+
+
+ struct FileAlias
+ {
+ std::string realPath;
+ std::string aliasPath;
+ };
+
+
+ // This function verifies the set of dylibs that will go into the cache are self contained. That the depend on no dylibs
+ // outset the set. It will call back the loader function to try to find any mising dylibs.
+ static bool verifySelfContained(std::vector<MappedMachO>& dylibsToCache,
+ std::unordered_set<std::string>& badZippered,
+ MappedMachO (^loader)(const std::string& runtimePath, Diagnostics& diag), std::vector<std::pair<DyldSharedCache::MappedMachO, std::set<std::string>>>& excluded);
+
+
+ //
+ // This function is single threaded and creates a shared cache. The cache file is created in-memory.
+ //
+ // Inputs:
+ // options: various per-platform flags
+ // dylibsToCache: a list of dylibs to include in the cache
+ // otherOsDylibs: a list of other OS dylibs and bundle which should have load info added to the cache
+ // osExecutables: a list of main executables which should have closures created in the cache
+ //
+ // Returns:
+ // On success:
+ // cacheContent: start of the allocated cache buffer which must be vm_deallocated after the caller writes out the buffer.
+ // cacheLength: size of the allocated cache buffer
+ // cdHash: hash of the code directory of the code blob of the created cache
+ // warnings: all warning messsages generated during the creation of the cache
+ //
+ // On failure:
+ // cacheContent: nullptr
+ // errorMessage: the string describing why the cache could not be created
+ // warnings: all warning messsages generated before the failure
+ //
+ static CreateResults create(const CreateOptions& options,
+ const dyld3::closure::FileSystem& fileSystem,
+ const std::vector<MappedMachO>& dylibsToCache,
+ const std::vector<MappedMachO>& otherOsDylibs,
+ const std::vector<MappedMachO>& osExecutables);
+
+
//
// Returns a text "map" file as a big string
//
std::string mapFile() const;
-#endif // BUILDING_CACHE_BUILDER || BUILDING_CACHE_BUILDER_UNIT_TESTS
-
-#if !TARGET_OS_EXCLAVEKIT
- //
- // When the dyld cache is mapped from files, there is one region that is dynamically constructed
- //
- class DynamicRegion
- {
- public:
- static DynamicRegion* make(uintptr_t prefAddress=0);
- void free();
-
- void setDyldCacheFileID(FileIdTuple);
- void setOSCryptexPath(const char*);
- void setCachePath(const char*);
- void setReadOnly();
- void setSystemWideFlags(__uint128_t);
- void setProcessorFlags(__uint128_t);
-
- bool validMagic() const;
- uint32_t version() const;
-
- // available in version 0
- bool getDyldCacheFileID(FileIdTuple& ids) const;
-
- // available in version 1
- const char* osCryptexPath() const;
-
- // available in version 2
- const char* cachePath() const;
-
- // available in version 3
- __uint128_t getSystemWideFunctionVariantFlags() const;
- __uint128_t getProcessorFunctionVariantFlags() const;
-
- static size_t size();
-
- private:
- DynamicRegion();
-
- static constexpr const char* sMagic = "dyld_data v3";
-
- // fields in v0
- char _magic[16]; // e.g. "dyld_data v0"
- FileIdTuple _dyldCache; // the inode of the main file for this dyld cache
-
- // fields added in v1
- uint32_t _osCryptexPathOffset;
-
- // fields added in v2
- uint32_t _cachePathOffset;
-
- // fields added in v3
- uint64_t _paddingToAlign;
- __uint128_t _systemWideFunctionVariantFlags; // system wide function-variant flags set in launchd
- __uint128_t _processorFunctionVariantFlags; // arm64 or x86_64 specific function-variant flags
- };
-
-
- //
- // Returns the DynamicRegion of the dyld cache
- //
- const DynamicRegion* dynamicRegion() const;
-#endif // !TARGET_OS_EXCLAVEKIT
+#endif // BUILDING_CACHE_BUILDER
//
@@ -261,14 +185,14 @@
//
// Returns the platform the cache is for
//
- mach_o::Platform platform() const;
+ dyld3::Platform platform() const;
//
// Iterates over each dylib in the cache
//
- void forEachImage(void (^handler)(const mach_o::Header* hdr, const char* installName)) const;
- void forEachDylib(void (^handler)(const mach_o::Header* hdr, const char* installName, uint32_t imageIndex, uint64_t inode, uint64_t mtime, bool& stop)) const;
+ void forEachImage(void (^handler)(const mach_header* mh, const char* installName)) const;
+ void forEachDylib(void (^handler)(const dyld3::MachOAnalyzer* ma, const char* installName, uint32_t imageIndex, uint64_t inode, uint64_t mtime, bool& stop)) const;
//
@@ -278,9 +202,16 @@
//
+ // Is this path (which we know is in the shared cache), overridable
+ //
+ bool isOverridablePath(const char* dylibPath) const;
+
+
+ //
// Path is to a dylib in the cache and this is an optimized cache so that path cannot be overridden
//
bool hasNonOverridablePath(const char* dylibPath) const;
+
//
// Check if this shared cache file contains local symbols info
@@ -296,10 +227,12 @@
//
const bool hasLocalSymbolsInfoFile() const;
- //
- // Get string name for a given cache type
- //
- static const char* getCacheTypeName(uint64_t cacheType);
+
+ //
+ // Get code signature mapped address
+ //
+ uint64_t getCodeSignAddress() const;
+
//
// Searches cache for dylib with specified mach_header
@@ -316,7 +249,6 @@
// Get image entry from index
//
const mach_header* getIndexedImageEntry(uint32_t index, uint64_t& mTime, uint64_t& node) const;
- const mach_header* getIndexedImageEntry(uint32_t index) const;
// iterates over all dylibs and aliases
@@ -325,7 +257,7 @@
//
// If path is a dylib in the cache, return is mach_header
//
- const mach_o::Header* getImageFromPath(const char* dylibPath) const;
+ const dyld3::MachOFile* getImageFromPath(const char* dylibPath) const;
//
// Get image path from index
@@ -342,33 +274,14 @@
//
void forEachImageTextSegment(void (^handler)(uint64_t loadAddressUnslid, uint64_t textSegmentSize, const uuid_t dylibUUID, const char* installName, bool& stop)) const;
- //
- // Returns the dyld_cache_image_text_info[] from the cache header
- //
- std::span<const dyld_cache_image_text_info> textImageSegments() const;
-
- // Get the path from a dyld_cache_image_text_info
- std::string_view imagePath(const dyld_cache_image_text_info& info) const;
//
// Iterates over each of the three regions in the cache
//
void forEachRegion(void (^handler)(const void* content, uint64_t vmAddr, uint64_t size,
uint32_t initProt, uint32_t maxProt, uint64_t flags,
- uint64_t fileOffset,
bool& stopRegion)) const;
-
- //
- // Iterates over each of the TPRO regions in the cache
- //
- void forEachTPRORegion(void (^handler)(const void* content, uint64_t unslidVMAddr, uint64_t vmSize,
- bool& stopRegion)) const;
-
- //
- // Gets a name for the mapping.
- //
- static const char* mappingName(uint32_t maxProt, uint64_t flags);
//
// Iterates over each of the mappings in the cache and all subCaches
@@ -392,22 +305,7 @@
uint32_t numSubCaches() const;
//
- // Returns index of subCache containing the address
- //
- int32_t getSubCacheIndex(const void* addr) const;
-
- //
- // Gets uuid of the subCache
- //
- void getSubCacheUuid(uint8_t index, uint8_t uuid[]) const;
-
- //
- // Returns the vmOffset of the subCache
- //
- uint64_t getSubCacheVmOffset(uint8_t index) const;
-
- //
- // Returns the address of the first dyld_cache_image_info in the cache
+ // Returns the address of the the first dyld_cache_image_info in the cache
//
const dyld_cache_image_info* images() const;
@@ -448,9 +346,9 @@
void forEachLocalSymbolEntry(void (^handler)(uint64_t dylibCacheVMOffset, uint32_t nlistStartIndex, uint32_t nlistCount, bool& stop)) const;
//
- // Returns if an address range is in this cache, and if so if in an immutable area
- //
- bool inCache(const void* addr, size_t length, bool& immutable) const;
+ // Returns if an address range is in this cache, and if so if in a read-only area
+ //
+ bool inCache(const void* addr, size_t length, bool& readOnly) const;
//
// Returns true if a path is an alternate path (symlink)
@@ -473,11 +371,6 @@
// returns the vm size required to map cache
//
uint64_t mappedSize() const;
-
- //
- // Returns the cache PBLS, if one exists
- //
- const dyld4::PrebuiltLoaderSet* dylibsLoaderSet() const;
//
@@ -502,22 +395,6 @@
const dyld4::PrebuiltLoaderSet* findLaunchLoaderSet(const char* executablePath) const;
//
- // searches cache for PrebuiltLoader for program
- //
- const dyld4::PrebuiltLoaderSet* findLaunchLoaderSetWithCDHash(const char* cdHashString) const;
-
-
- //
- // Iterates over each of the prewarming data entries
- //
- void forEachPrewarmingEntry(void (^handler)(const void* content, uint64_t unslidVMAddr, uint64_t vmSize)) const;
-
- //
- // Iterates over function variant pointers in the dyld cache
- //
- void forEachFunctionVariantPatchLocation(void (^handler)(const void* loc, PointerMetaData pmd, const mach_o::FunctionVariants& fvs, const mach_o::Header* dylibHdr, int variantIndex, bool& stop)) const;
-
- //
// searches cache for PrebuiltLoader for program by cdHash
//
bool hasLaunchLoaderSetWithCDHash(const char* cdHashString) const;
@@ -538,19 +415,14 @@
const uint8_t* legacyCacheDataRegionBuffer() const;
//
+ // Returns a pointer to the shared cache optimized Objective-C data structures
+ //
+ const objc_opt::objc_opt_t* objcOpt() const;
+
+ //
// Returns a pointer to the shared cache optimized Objective-C pointer structures
//
const void* objcOptPtrs() const;
-
- bool hasOptimizedObjC() const;
- uint32_t objcOptVersion() const;
- uint32_t objcOptFlags() const;
- const objc::HeaderInfoRO* objcHeaderInfoRO() const;
- const objc::HeaderInfoRW* objcHeaderInfoRW() const;
- const objc::SelectorHashTable* objcSelectorHashTable() const;
- const objc::ClassHashTable* objcClassHashTable() const;
- const objc::ProtocolHashTable* objcProtocolHashTable() const;
- const void* objcRelativeMethodListsBaseAddress() const;
#if !(BUILDING_LIBDYLD || BUILDING_DYLD)
//
@@ -581,38 +453,24 @@
//
bool addressInText(uint64_t cacheOffset, uint32_t* index) const;
- const void* patchTable() const;
-
uint32_t patchInfoVersion() const;
uint32_t patchableExportCount(uint32_t imageIndex) const;
- void forEachPatchableExport(uint32_t imageIndex,
- void (^handler)(uint32_t dylibVMOffsetOfImpl, const char* exportName,
- PatchKind kind)) const;
-#if BUILDING_SHARED_CACHE_UTIL
+ void forEachPatchableExport(uint32_t imageIndex, void (^handler)(uint32_t dylibVMOffsetOfImpl, const char* exportName)) const;
void forEachPatchableUseOfExport(uint32_t imageIndex, uint32_t dylibVMOffsetOfImpl,
void (^handler)(uint32_t userImageIndex, uint32_t userVMOffset,
- dyld3::MachOLoaded::PointerMetaData pmd, uint64_t addend,
- bool isWeakImport)) const;
-#endif
+ dyld3::MachOLoaded::PointerMetaData pmd, uint64_t addend)) const;
// Use this when you have a root of at imageIndex, and are trying to patch a cached dylib at userImageIndex
bool shouldPatchClientOfImage(uint32_t imageIndex, uint32_t userImageIndex) const;
void forEachPatchableUseOfExportInImage(uint32_t imageIndex, uint32_t dylibVMOffsetOfImpl, uint32_t userImageIndex,
- void (^handler)(uint32_t userVMOffset, dyld3::MachOLoaded::PointerMetaData pmd, uint64_t addend,
- bool isWeakImport)) const;
+ void (^handler)(uint32_t userVMOffset, dyld3::MachOLoaded::PointerMetaData pmd, uint64_t addend)) const;
// Note, use this for weak-defs when you just want all uses of an export, regardless of which dylib they are in.
void forEachPatchableUseOfExport(uint32_t imageIndex, uint32_t dylibVMOffsetOfImpl,
void (^handler)(uint64_t cacheVMOffset,
- dyld3::MachOLoaded::PointerMetaData pmd, uint64_t addend,
- bool isWeakImport)) const;
- // Used to walk just the GOT uses of a given export. The above method will walk both regular and GOT uses
- void forEachPatchableGOTUseOfExport(uint32_t imageIndex, uint32_t dylibVMOffsetOfImpl,
- void (^handler)(uint64_t cacheVMOffset,
- dyld3::MachOLoaded::PointerMetaData pmd, uint64_t addend,
- bool isWeakImport)) const;
+ dyld3::MachOLoaded::PointerMetaData pmd, uint64_t addend)) const;
#if !(BUILDING_LIBDYLD || BUILDING_DYLD)
// MRM map file generator
- std::string generateJSONMap(const char* disposition, uuid_t cache_uuid, bool verbose) const;
+ std::string generateJSONMap(const char* disposition) const;
// This generates a JSON representation of deep reverse dependency information in the cache.
// For each dylib, the output will contain the list of all the other dylibs transitively
@@ -637,15 +495,16 @@
dyld3::MachOAnalyzer::VMAddrConverter makeVMAddrConverter(bool contentRebased) const;
#endif
- // Returns true if the given MachO is in the shared cache range.
+ // Returns if the the given MachO is in the shared cache range.
// Returns false if the cache is null.
static bool inDyldCache(const DyldSharedCache* cache, const dyld3::MachOFile* mf);
- static bool inDyldCache(const DyldSharedCache* cache, const mach_o::Header* header);
-
- // Returns ture if the given path is a subCache filepath.
- static bool isSubCachePath(const char* leafName);
#if !(BUILDING_LIBDYLD || BUILDING_DYLD)
+ //
+ // Apply rebases for manually mapped shared cache
+ //
+ void applyCacheRebases() const;
+
// mmap() an shared cache file read/only but laid out like it would be at runtime
static const DyldSharedCache* mapCacheFile(const char* path,
uint64_t baseCacheUnslidAddress,
@@ -653,19 +512,6 @@
static std::vector<const DyldSharedCache*> mapCacheFiles(const char* path);
#endif
-
- //
- // Fixes up the DATA pages in just this subcache file
- // Takes a slide, so that some tools can call this to get unslid VM addresses, while
- // dyld can pass a slide to apply.
- //
- mach_o::Error fixupDataPages(intptr_t slideToApply) const;
- //
- // Fixes up the DATA pages in this cache and all subcaches
- // Takes a slide, so that some tools can call this to get unslid VM addresses, while
- // dyld can pass a slide to apply.
- //
- mach_o::Error fixupAllDataPages(intptr_t slideToApply) const;
dyld_cache_header header;
@@ -686,48 +532,13 @@
void findDependentsRecursively(std::unordered_map<std::string, std::set<std::string>> &transitiveDependents, const std::unordered_map<std::string, std::set<std::string>> &reverseDependencyMap, std::set<std::string> & visited, const std::string &loadPath) const;
void computeTransitiveDependents(std::unordered_map<std::string, std::set<std::string>> & transitiveDependents) const;
#endif
-
- //
- // Returns a pointer to the old shared cache optimized Objective-C data structures
- //
- const objc_opt::objc_opt_t* oldObjcOpt() const;
-
- //
- // Returns a pointer to the new shared cache optimized Objective-C data structures
- //
- const ObjCOptimizationHeader* objcOpts() const;
};
-#if BUILDING_CACHE_BUILDER || BUILDING_CACHE_BUILDER_UNIT_TESTS
-
-// Manages checking newly built caches against baseline builds
-struct BaselineCachesChecker
-{
- BaselineCachesChecker(std::vector<const char*> archs, mach_o::Platform platform);
-
- // Add a baseline cache map to the checker
- mach_o::Error addBaselineMap(std::string_view path);
- mach_o::Error addBaselineMaps(std::string_view dirPath);
- mach_o::Error addNewMap(std::string_view mapString);
- void setFilesFromNewCaches(std::span<const char* const> files);
-
- const std::set<std::string>& unionBaselineDylibs() { return _unionBaselineDylibs; }
-
- std::set<std::string> dylibsMissingFromNewCaches() const;
-
-private:
- // returns if we have a baseline arch for every arch we are building for
- bool allBaselineArchsPresent() const;
-
- std::vector<std::string> _archs;
- mach_o::Platform _platform;
- std::set<std::string> _unionBaselineDylibs;
- std::set<std::string> _dylibsInNewCaches;
- std::unordered_map<std::string, std::vector<std::string>> _baselineDylibs;
- std::unordered_map<std::string, std::set<std::string>> _newDylibs;
-};
-
-#endif // BUILDING_CACHE_BUILDER || BUILDING_CACHE_BUILDER_UNIT_TESTS
+
+
+
+
+
#endif /* DyldSharedCache_h */