Loading...
--- dyld/dyld-1042.1/common/DyldSharedCache.cpp
+++ dyld/dyld-1235.2/common/DyldSharedCache.cpp
@@ -22,6 +22,9 @@
* @APPLE_LICENSE_HEADER_END@
*/
+#include <TargetConditionals.h>
+
+#if !TARGET_OS_EXCLAVEKIT
#include <dirent.h>
#include <sys/errno.h>
@@ -36,13 +39,14 @@
#include <unistd.h>
#include <dlfcn.h>
+#include "OptimizerSwift.h"
+
#if BUILDING_CACHE_BUILDER
#include <set>
#include <string>
#include <vector>
#include <unordered_map>
#include <unordered_set>
-// #include "SharedCacheBuilder.h"
#include "FileUtils.h"
#endif
@@ -279,6 +283,66 @@
}
}
+void DyldSharedCache::forEachTPRORegion(void (^handler)(const void* content, uint64_t unslidVMAddr, uint64_t vmSize,
+ bool& stopRegion)) const
+{
+ if ( header.mappingOffset <= __offsetof(dyld_cache_header, tproMappingsCount) )
+ return;
+
+ uint64_t baseAddress = this->unslidLoadAddress();
+
+ const dyld_cache_tpro_mapping_info* mappings = (const dyld_cache_tpro_mapping_info*)((char*)this + header.tproMappingsOffset);
+ const dyld_cache_tpro_mapping_info* mappingsEnd = &mappings[header.tproMappingsCount];
+ for (const dyld_cache_tpro_mapping_info* m = mappings; m < mappingsEnd; ++m) {
+ bool stop = false;
+ uint64_t offsetInCache = m->unslidAddress - baseAddress;
+ handler((char*)this + (long)offsetInCache, m->unslidAddress, m->size, stop);
+ if ( stop )
+ return;
+ }
+}
+
+const char* DyldSharedCache::mappingName(uint32_t maxProt, uint64_t flags)
+{
+ const char* mappingName = "";
+ if ( maxProt & VM_PROT_EXECUTE ) {
+ if ( flags & DYLD_CACHE_MAPPING_TEXT_STUBS ) {
+ mappingName = "__TEXT_STUBS";
+ } else {
+ mappingName = "__TEXT";
+ }
+ } else if ( maxProt & VM_PROT_WRITE ) {
+ if ( flags & DYLD_CACHE_MAPPING_AUTH_DATA ) {
+ if ( flags & DYLD_CACHE_MAPPING_DIRTY_DATA )
+ mappingName = "__AUTH_DIRTY";
+ else if ( flags & DYLD_CACHE_MAPPING_CONST_TPRO_DATA )
+ mappingName = "__AUTH_TPRO_CONST";
+ else if ( flags & DYLD_CACHE_MAPPING_CONST_DATA )
+ mappingName = "__AUTH_CONST";
+ else
+ mappingName = "__AUTH";
+ } else {
+ if ( flags & DYLD_CACHE_MAPPING_DIRTY_DATA )
+ mappingName = "__DATA_DIRTY";
+ else if ( flags & DYLD_CACHE_MAPPING_CONST_TPRO_DATA )
+ mappingName = "__TPRO_CONST";
+ else if ( flags & DYLD_CACHE_MAPPING_CONST_DATA )
+ mappingName = "__DATA_CONST";
+ else
+ mappingName = "__DATA";
+ }
+ }
+ else if ( maxProt & VM_PROT_READ ) {
+ if ( flags & DYLD_CACHE_READ_ONLY_DATA )
+ mappingName = "__READ_ONLY";
+ else
+ mappingName = "__LINKEDIT";
+ } else {
+ mappingName = "*unknown*";
+ }
+ return mappingName;
+}
+
void DyldSharedCache::forEachRange(void (^handler)(const char* mappingName,
uint64_t unslidVMAddr, uint64_t vmSize,
uint32_t cacheFileIndex, uint64_t fileOffset,
@@ -290,35 +354,7 @@
forEachCache(^(const DyldSharedCache *cache, bool& stopCache) {
cache->forEachRegion(^(const void *content, uint64_t unslidVMAddr, uint64_t size,
uint32_t initProt, uint32_t maxProt, uint64_t flags, bool& stopRegion) {
- const char* mappingName = "";
- if ( maxProt & VM_PROT_EXECUTE ) {
- if ( flags & DYLD_CACHE_MAPPING_TEXT_STUBS ) {
- mappingName = "__TEXT_STUBS";
- } else {
- mappingName = "__TEXT";
- }
- } else if ( maxProt & VM_PROT_WRITE ) {
- if ( flags & DYLD_CACHE_MAPPING_AUTH_DATA ) {
- if ( flags & DYLD_CACHE_MAPPING_DIRTY_DATA )
- mappingName = "__AUTH_DIRTY";
- else if ( flags & DYLD_CACHE_MAPPING_CONST_DATA )
- mappingName = "__AUTH_CONST";
- else
- mappingName = "__AUTH";
- } else {
- if ( flags & DYLD_CACHE_MAPPING_DIRTY_DATA )
- mappingName = "__DATA_DIRTY";
- else if ( flags & DYLD_CACHE_MAPPING_CONST_DATA )
- mappingName = "__DATA_CONST";
- else
- mappingName = "__DATA";
- }
- }
- else if ( maxProt & VM_PROT_READ ) {
- mappingName = "__LINKEDIT";
- } else {
- mappingName = "*unknown*";
- }
+ const char* mappingName = DyldSharedCache::mappingName(maxProt, flags);
uint64_t fileOffset = (uint8_t*)content - (uint8_t*)cache;
bool stop = false;
handler(mappingName, unslidVMAddr, size, cacheFileIndex, fileOffset, initProt, maxProt, stop);
@@ -352,7 +388,7 @@
return;
for (uint32_t i = 0; i != header.subCacheArrayCount; ++i) {
- const DyldSharedCache* cache = (const DyldSharedCache*)((uint8_t*)this + this->getSubCacheVmOffset(i));
+ const DyldSharedCache* cache = (const DyldSharedCache*)((uintptr_t)this + this->getSubCacheVmOffset(i));
handler(cache, stop);
if ( stop )
return;
@@ -386,25 +422,25 @@
void DyldSharedCache::getSubCacheUuid(uint8_t index, uint8_t uuid[]) const {
if (header.mappingOffset <= __offsetof(dyld_cache_header, cacheSubType) ) {
- const dyld_subcache_entry_v1* subCacheEntries = (dyld_subcache_entry_v1*)((uint8_t*)this + header.subCacheArrayOffset);
+ const dyld_subcache_entry_v1* subCacheEntries = (dyld_subcache_entry_v1*)((uintptr_t)this + header.subCacheArrayOffset);
memcpy(uuid, subCacheEntries[index].uuid, 16);
} else {
- const dyld_subcache_entry* subCacheEntries = (dyld_subcache_entry*)((uint8_t*)this + header.subCacheArrayOffset);
+ const dyld_subcache_entry* subCacheEntries = (dyld_subcache_entry*)((uintptr_t)this + header.subCacheArrayOffset);
memcpy(uuid, subCacheEntries[index].uuid, 16);
}
}
uint64_t DyldSharedCache::getSubCacheVmOffset(uint8_t index) const {
if (header.mappingOffset <= __offsetof(dyld_cache_header, cacheSubType) ) {
- const dyld_subcache_entry_v1* subCacheEntries = (dyld_subcache_entry_v1*)((uint8_t*)this + header.subCacheArrayOffset);
+ const dyld_subcache_entry_v1* subCacheEntries = (dyld_subcache_entry_v1*)((uintptr_t)this + header.subCacheArrayOffset);
return subCacheEntries[index].cacheVMOffset;
} else {
- const dyld_subcache_entry* subCacheEntries = (dyld_subcache_entry*)((uint8_t*)this + header.subCacheArrayOffset);
+ const dyld_subcache_entry* subCacheEntries = (dyld_subcache_entry*)((uintptr_t)this + header.subCacheArrayOffset);
return subCacheEntries[index].cacheVMOffset;
}
}
-bool DyldSharedCache::inCache(const void* addr, size_t length, bool& readOnly) const
+bool DyldSharedCache::inCache(const void* addr, size_t length, bool& immutable) const
{
// quick out if before start of cache
if ( addr < this )
@@ -414,22 +450,19 @@
uintptr_t slide = (uintptr_t)this - (uintptr_t)(mappings[0].address);
uintptr_t unslidStart = (uintptr_t)addr - slide;
- // quick out if after end of cache
- const dyld_cache_mapping_info* lastMapping = &mappings[header.mappingCount - 1];
- if ( unslidStart > (lastMapping->address + lastMapping->size) )
- return false;
-
- // walk cache regions
- const dyld_cache_mapping_info* mappingsEnd = &mappings[header.mappingCount];
- uintptr_t unslidEnd = unslidStart + length;
- for (const dyld_cache_mapping_info* m=mappings; m < mappingsEnd; ++m) {
- if ( (unslidStart >= m->address) && (unslidEnd < (m->address+m->size)) ) {
- readOnly = ((m->initProt & VM_PROT_WRITE) == 0);
- return true;
- }
- }
-
- return false;
+ // walk cache ranges
+ __block bool found = false;
+ auto inRange = ^(const char* mappingName, uint64_t unslidVMAddr, uint64_t vmSize, uint32_t cacheFileIndex,
+ uint64_t fileOffset, uint32_t initProt, uint32_t maxProt, bool& stopRange) {
+ if ( (unslidVMAddr <= unslidStart) && ((unslidStart+length) < (unslidVMAddr+vmSize)) ) {
+ found = true;
+ immutable = ((maxProt & VM_PROT_WRITE) == 0);
+ stopRange = true;
+ }
+ };
+ this->forEachRange(inRange, nullptr);
+
+ return found;
}
bool DyldSharedCache::isAlias(const char* path) const {
@@ -542,7 +575,7 @@
// check for cache without local symbols info
if (!this->hasLocalSymbolsInfo())
return nullptr;
- const auto localInfo = (dyld_cache_local_symbols_info*)((uint8_t*)this + header.localSymbolsOffset);
+ const auto localInfo = (dyld_cache_local_symbols_info*)((uintptr_t)this + header.localSymbolsOffset);
return getLocalNlistEntries(localInfo);
}
@@ -551,7 +584,7 @@
// check for cache without local symbols info
if (!this->hasLocalSymbolsInfo())
return 0;
- const auto localInfo = (dyld_cache_local_symbols_info*)((uint8_t*)this + header.localSymbolsOffset);
+ const auto localInfo = (dyld_cache_local_symbols_info*)((uintptr_t)this + header.localSymbolsOffset);
return localInfo->nlistCount;
}
@@ -565,7 +598,7 @@
// check for cache without local symbols info
if (!this->hasLocalSymbolsInfo())
return nullptr;
- const auto localInfo = (dyld_cache_local_symbols_info*)((uint8_t*)this + header.localSymbolsOffset);
+ const auto localInfo = (dyld_cache_local_symbols_info*)((uintptr_t)this + header.localSymbolsOffset);
return getLocalStrings(localInfo);
}
@@ -574,7 +607,7 @@
// check for cache without local symbols info
if (!this->hasLocalSymbolsInfo())
return 0;
- const auto localInfo = (dyld_cache_local_symbols_info*)((uint8_t*)this + header.localSymbolsOffset);
+ const auto localInfo = (dyld_cache_local_symbols_info*)((uintptr_t)this + header.localSymbolsOffset);
return localInfo->stringsSize;
}
@@ -584,7 +617,7 @@
const dyld_cache_mapping_info* mappings = (dyld_cache_mapping_info*)((char*)this + header.mappingOffset);
uint32_t dyldCacheImageIndex;
if ( hasImagePath(dylibPath, dyldCacheImageIndex) )
- return (dyld3::MachOFile*)((uint8_t*)this + dylibs[dyldCacheImageIndex].address - mappings[0].address);
+ return (dyld3::MachOFile*)((uintptr_t)this + dylibs[dyldCacheImageIndex].address - mappings[0].address);
return nullptr;
}
@@ -593,7 +626,7 @@
// check for cache without local symbols info
if (!this->hasLocalSymbolsInfo())
return;
- const auto localInfo = (dyld_cache_local_symbols_info*)((uint8_t*)this + header.localSymbolsOffset);
+ const auto localInfo = (dyld_cache_local_symbols_info*)((uintptr_t)this + header.localSymbolsOffset);
if ( header.mappingOffset >= __offsetof(dyld_cache_header, symbolFileUUID) ) {
// On new caches, the dylibOffset is 64-bits, and is a VM offset
@@ -618,10 +651,10 @@
const mach_header* DyldSharedCache::getIndexedImageEntry(uint32_t index, uint64_t& mTime, uint64_t& inode) const
{
const dyld_cache_image_info* dylibs = images();
- const dyld_cache_mapping_info* mappings = (dyld_cache_mapping_info*)((char*)this + header.mappingOffset);
+ const dyld_cache_mapping_info* mappings = (dyld_cache_mapping_info*)((uintptr_t)this + header.mappingOffset);
mTime = dylibs[index].modTime;
inode = dylibs[index].inode;
- return (mach_header*)((uint8_t*)this + dylibs[index].address - mappings[0].address);
+ return (mach_header*)((uintptr_t)this + dylibs[index].address - mappings[0].address);
}
const mach_header* DyldSharedCache::getIndexedImageEntry(uint32_t index) const
@@ -1135,7 +1168,8 @@
#if BUILDING_SHARED_CACHE_UTIL
void DyldSharedCache::forEachPatchableUseOfExport(uint32_t imageIndex, uint32_t dylibVMOffsetOfImpl,
void (^handler)(uint32_t userImageIndex, uint32_t userVMOffset,
- MachOLoaded::PointerMetaData pmd, uint64_t addend)) const {
+ MachOLoaded::PointerMetaData pmd, uint64_t addend,
+ bool isWeakImport)) const {
if ( header.patchInfoAddr == 0 )
return;
@@ -1241,7 +1275,7 @@
pmd.key = patchLocation.key;
pmd.usesAddrDiversity = patchLocation.usesAddressDiversity;
- handler(userImageIndex, userVMOffset, pmd, patchLocation.getAddend());
+ handler(userImageIndex, userVMOffset, pmd, patchLocation.getAddend(), false);
}
}
return;
@@ -1271,7 +1305,8 @@
}
void DyldSharedCache::forEachPatchableUseOfExportInImage(uint32_t imageIndex, uint32_t dylibVMOffsetOfImpl, uint32_t userImageIndex,
- void (^handler)(uint32_t userVMOffset, MachOLoaded::PointerMetaData pmd, uint64_t addend)) const {
+ void (^handler)(uint32_t userVMOffset, MachOLoaded::PointerMetaData pmd, uint64_t addend,
+ bool isWeakImport)) const {
if ( header.patchInfoAddr == 0 )
return;
@@ -1379,7 +1414,7 @@
pmd.key = patchLocation.key;
pmd.usesAddrDiversity = patchLocation.usesAddressDiversity;
- handler(userVMOffset, pmd, patchLocation.getAddend());
+ handler(userVMOffset, pmd, patchLocation.getAddend(), false);
}
}
}
@@ -1394,7 +1429,8 @@
void DyldSharedCache::forEachPatchableUseOfExport(uint32_t imageIndex, uint32_t dylibVMOffsetOfImpl,
void (^handler)(uint64_t cacheVMOffset,
- MachOLoaded::PointerMetaData pmd, uint64_t addend)) const {
+ MachOLoaded::PointerMetaData pmd, uint64_t addend,
+ bool isWeakImport)) const {
if ( header.patchInfoAddr == 0 )
return;
@@ -1442,7 +1478,7 @@
pmd.key = patchLocation.key;
pmd.usesAddrDiversity = patchLocation.usesAddressDiversity;
- handler(patchLocation.cacheOffset, pmd, patchLocation.getAddend());
+ handler(patchLocation.cacheOffset, pmd, patchLocation.getAddend(), false);
}
}
return;
@@ -1464,7 +1500,8 @@
void DyldSharedCache::forEachPatchableGOTUseOfExport(uint32_t imageIndex, uint32_t dylibVMOffsetOfImpl,
void (^handler)(uint64_t cacheVMOffset,
MachOFile::PointerMetaData pmd,
- uint64_t addend)) const {
+ uint64_t addend,
+ bool isWeakImport)) const {
if ( header.patchInfoAddr == 0 )
return;
@@ -1592,6 +1629,9 @@
assert(slideInfo->delta_mask == 0x00000000C0000000);
pointerFormat = VMAddrConverter::SharedCacheFormat::v4;
pointerValueAdd = slideInfo->value_add;
+ } else if ( slideInfoHeader->version == 5 ) {
+ pointerFormat = VMAddrConverter::SharedCacheFormat::v5;
+ pointerValueAdd = unslidLoadAddress();
} else {
assert(false);
}
@@ -2053,7 +2093,8 @@
if ( header.swiftOptsOffset == 0 )
return nullptr;
- return (SwiftOptimizationHeader*)((char*)this + header.swiftOptsOffset);
+ SwiftOptimizationHeader* optHeader = (SwiftOptimizationHeader*)((char*)this + header.swiftOptsOffset);
+ return optHeader;
}
std::pair<const void*, uint64_t> DyldSharedCache::getObjCConstantRange() const
@@ -2200,3 +2241,5 @@
});
}
#endif
+
+#endif // !TARGET_OS_EXCLAVEKIT