Loading...
--- dyld/dyld-1162/cache_builder/CacheDylib.cpp
+++ dyld/dyld-1066.8/cache_builder/CacheDylib.cpp
@@ -182,17 +182,6 @@
});
});
}
-
- // Move to auth if __objc_const or __objc_data is present.
- // This allows new method lists added by the category optimizer to be signed.
- mf->forEachSection(^(const dyld3::MachOAnalyzer::SectionInfo §Info, bool malformedSectionRange, bool &stop) {
- if ( sectInfo.segInfo.segIndex != segmentIndexToSearch )
- return;
- if ( !strcmp(sectInfo.sectName, "__objc_const") || !strcmp(sectInfo.sectName, "__objc_data")) {
- foundAuthFixup = true;
- stop = true;
- }
- });
});
return foundAuthFixup;
@@ -202,7 +191,7 @@
const CacheDylib& cacheDylib, std::string_view segmentName,
objc_visitor::Visitor& objcVisitor)
{
- // rdar://113642480 (Swift has some mutable data in __objc_const)
+ // <rdar://problem/66284631> Don't put __objc_const read-only memory as Swift has method lists we can't see
__block bool isBadSwiftLibrary = false;
cacheDylib.inputMF->withFileLayout(diag, ^(const mach_o::Layout &layout) {
if ( !layout.isSwiftLibrary() )
@@ -211,6 +200,16 @@
isBadSwiftLibrary = layout.hasSection(segmentName, "__objc_const");
});
if ( isBadSwiftLibrary )
+ return false;
+
+ // <rdar://problem/69813664> _NSTheOneTruePredicate is incompatible with __DATA_CONST
+ if ( (cacheDylib.installName == "/System/Library/Frameworks/Foundation.framework/Foundation")
+ || (cacheDylib.installName == "/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation") )
+ return false;
+
+ // rdar://74112547 CF writes to kCFNull constant object
+ if ( (cacheDylib.installName == "/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation")
+ || (cacheDylib.installName == "/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation") )
return false;
// rdar://77149283 libcrypto.0.9.8.dylib writes to __DATA_CONST
@@ -628,7 +627,7 @@
void CacheDylib::copyRawSegments(const BuilderConfig& config, Timer::AggregateTimer& timer)
{
- const bool log = config.log.printDebug;
+ const bool log = false;
Timer::AggregateTimer::Scope timedScope(timer, "dylib copyRawSegments time");
@@ -1440,7 +1439,6 @@
lsl::EphemeralAllocator allocator;
__block objc_visitor::Visitor objcVisitor = this->makeCacheObjCVisitor(config,
objcSelectorOptimizer.selectorStringsChunk,
- nullptr,
nullptr);
// Update every selector reference to point to the canonical selectors
@@ -1674,7 +1672,7 @@
Timer::AggregateTimer::Scope timedScope(timer, "dylib convertObjCMethodListsToOffsets time");
lsl::EphemeralAllocator allocator;
- __block objc_visitor::Visitor objcVisitor = this->makeCacheObjCVisitor(config, selectorStringsChunk, nullptr, nullptr);
+ __block objc_visitor::Visitor objcVisitor = this->makeCacheObjCVisitor(config, selectorStringsChunk, nullptr);
auto visitMethodList = ^(objc_visitor::MethodList objcMethodList) {
// Skip pointer based method lists
@@ -1732,7 +1730,7 @@
Timer::AggregateTimer::Scope timedScope(timer, "dylib sortObjCMethodLists time");
lsl::EphemeralAllocator allocator;
- __block objc_visitor::Visitor objcVisitor = this->makeCacheObjCVisitor(config, selectorStringsChunk, nullptr, nullptr);
+ __block objc_visitor::Visitor objcVisitor = this->makeCacheObjCVisitor(config, selectorStringsChunk, nullptr);
auto visitMethodList = ^(objc_visitor::MethodList objcMethodList,
std::optional<metadata_visitor::ResolvedValue> extendedMethodTypes) {
@@ -1874,7 +1872,7 @@
Timer::AggregateTimer& timer,
const ObjCStringsChunk* selectorStringsChunk)
{
- const bool logSelectors = config.log.printDebug;
+ const bool logSelectors = false;
Timer::AggregateTimer::Scope timedScope(timer, "dylib optimizeLoadsFromConstants time");
@@ -2126,7 +2124,7 @@
if ( !objcIMPCachesOptimizer.builder )
return Error();
- const bool log = config.log.printDebug;
+ const bool log = false;
Timer::AggregateTimer::Scope timedScope(timer, "emitObjCIMPCaches time");
@@ -2143,7 +2141,7 @@
return Error();
lsl::EphemeralAllocator allocator;
- __block objc_visitor::Visitor objcVisitor = this->makeCacheObjCVisitor(config, nullptr, nullptr, nullptr);
+ __block objc_visitor::Visitor objcVisitor = this->makeCacheObjCVisitor(config, nullptr, nullptr);
// Walk the classes in this dylib, and see if any have an IMP cache
objcVisitor.forEachClassAndMetaClass(^(objc_visitor::Class& objcClass, bool& stopClass) {
@@ -2164,18 +2162,9 @@
if ( objcClass.getMethodCachePropertiesVMAddr(objcVisitor).has_value() )
return;
- MachOFile::PointerMetaData PMD;
- if ( config.layout.hasAuthRegion && (objcIMPCachesOptimizer.libobjcImpCachesVersion >= 4) ) {
- PMD.diversity = 0x9cff; // hash of "originalPreoptCache"
- PMD.high8 = 0;
- PMD.authenticated = 1;
- PMD.key = 2; // DA
- PMD.usesAddrDiversity = 1;
- }
-
// Set the "vtable" to point to the cache
CacheVMAddress impCacheVMAddr = objcIMPCachesOptimizer.impCachesChunk->cacheVMAddress + impCacheOffset;
- objcClass.setMethodCachePropertiesVMAddr(objcVisitor, VMAddress(impCacheVMAddr.rawValue()), PMD);
+ objcClass.setMethodCachePropertiesVMAddr(objcVisitor, VMAddress(impCacheVMAddr.rawValue()));
// Tell the slide info emitter to slide this location
metadata_visitor::ResolvedValue vtableField = objcClass.getMethodCachePropertiesField(objcVisitor);
@@ -2752,9 +2741,7 @@
void CacheDylib::addObjcSegments(Diagnostics& diag, Timer::AggregateTimer& timer,
const ObjCHeaderInfoReadOnlyChunk* headerInfoReadOnlyChunk,
- const ObjCImageInfoChunk* imageInfoChunk,
const ObjCProtocolHashTableChunk* protocolHashTableChunk,
- const ObjCPreAttachedCategoriesChunk* preAttachedCategoriesChunk,
const ObjCHeaderInfoReadWriteChunk* headerInfoReadWriteChunk,
const ObjCCanonicalProtocolsChunk* canonicalProtocolsChunk)
{
@@ -2767,18 +2754,16 @@
// Find the ranges for OBJC_RO and OBJC_RW
// Read-only
- // Note these asserts are just to make sure we use the correct chunks for the start/end
- static_assert(Chunk::Kind::objcHeaderInfoRO < Chunk::Kind::objcImageInfo);
- static_assert(Chunk::Kind::objcImageInfo < Chunk::Kind::objcStrings);
+ // Note these asserts are just to make sure we use the correct
+ static_assert(Chunk::Kind::objcHeaderInfoRO < Chunk::Kind::objcStrings);
static_assert(Chunk::Kind::objcStrings < Chunk::Kind::objcSelectorsHashTable);
static_assert(Chunk::Kind::objcSelectorsHashTable < Chunk::Kind::objcClassesHashTable);
static_assert(Chunk::Kind::objcClassesHashTable < Chunk::Kind::objcProtocolsHashTable);
static_assert(Chunk::Kind::objcProtocolsHashTable < Chunk::Kind::objcIMPCaches);
- static_assert(Chunk::Kind::objcIMPCaches < Chunk::Kind::objcPreAttachedCategories);
CacheFileOffset readOnlyFileOffset = headerInfoReadOnlyChunk->subCacheFileOffset;
CacheVMAddress readOnlyVMAddr = headerInfoReadOnlyChunk->cacheVMAddress;
- CacheVMSize readOnlyVMSize = (preAttachedCategoriesChunk->cacheVMAddress + preAttachedCategoriesChunk->cacheVMSize) - readOnlyVMAddr;
+ CacheVMSize readOnlyVMSize = (protocolHashTableChunk->cacheVMAddress + protocolHashTableChunk->cacheVMSize) - readOnlyVMAddr;
// Read-write
@@ -2803,8 +2788,7 @@
objc_visitor::Visitor CacheDylib::makeCacheObjCVisitor(const BuilderConfig& config,
const Chunk* selectorStringsChunk,
- const ObjCCanonicalProtocolsChunk* canonicalProtocolsChunk,
- const ObjCPreAttachedCategoriesChunk* categoriesChunk) const
+ const ObjCCanonicalProtocolsChunk* canonicalProtocolsChunk) const
{
// Get the segment ranges. We need this as the dylib's segments are in different buffers, not in VM layout
std::vector<metadata_visitor::Segment> cacheSegments;
@@ -2845,19 +2829,6 @@
segment.startVMAddr = VMAddress(canonicalProtocolsChunk->cacheVMAddress.rawValue());
segment.endVMAddr = VMAddress((canonicalProtocolsChunk->cacheVMAddress + canonicalProtocolsChunk->cacheVMSize).rawValue());
segment.bufferStart = canonicalProtocolsChunk->subCacheBuffer;
-
- // Cache segments never have a chained format. They always use the Fixup struct
- segment.onDiskDylibChainedPointerFormat = { };
-
- cacheSegments.push_back(std::move(segment));
- }
-
- // Add the categories data chunk too. That way we can resolve references which land on it
- if ( categoriesChunk != nullptr ) {
- metadata_visitor::Segment segment;
- segment.startVMAddr = VMAddress(categoriesChunk->cacheVMAddress.rawValue());
- segment.endVMAddr = VMAddress((categoriesChunk->cacheVMAddress + categoriesChunk->cacheVMSize).rawValue());
- segment.bufferStart = categoriesChunk->subCacheBuffer;
// Cache segments never have a chained format. They always use the Fixup struct
segment.onDiskDylibChainedPointerFormat = { };