Loading...
cache_builder/CacheDylib.cpp dyld-1122.1 dyld-1042.1
--- dyld/dyld-1122.1/cache_builder/CacheDylib.cpp
+++ dyld/dyld-1042.1/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 &sectInfo, 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;
@@ -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");
 
@@ -962,7 +961,7 @@
                 // Actually change the bindTarget to reflect the new type
                 bindTarget.kind = BindTarget::Kind::cacheImage;
                 bindTarget.inputImage.~InputImage();
-                bindTarget.cacheImage = (BindTarget::CacheImage) { VMOffset(targetCacheVMAddr - inputImage.targetDylib->cacheLoadAddress), inputImage.targetDylib, inputImage.isWeakDef };
+                bindTarget.cacheImage = (BindTarget::CacheImage) { VMOffset(targetCacheVMAddr - inputImage.targetDylib->cacheLoadAddress), inputImage.targetDylib, inputImage.isWeak };
                 break;
             }
             case BindTarget::Kind::cacheImage:
@@ -972,7 +971,6 @@
         }
 
         bindTarget.addend = addend;
-        bindTarget.isWeakImport = weakImport;
         this->bindTargets.push_back(std::move(bindTarget));
         dylibPatchInfo.bindTargetNames.push_back(std::move(bindTargetAndName.second));
     };
@@ -1058,14 +1056,14 @@
             auto gotIt = coalescedGOTs.find(fixupVMAddr);
             if ( gotIt != coalescedGOTs.end() ) {
                 // Probably a missing weak import.  Rewrite the original GOT anyway, but also the coalesced one
-                dyld_cache_patchable_location patchLoc(gotIt->second, pmd, addend, bindTarget.isWeakImport);
+                dyld_cache_patchable_location patchLoc(gotIt->second, pmd, addend);
                 auto& gotUses = dylibPatchInfo.bindGOTUses[bindOrdinal];
                 gotUses.emplace_back((PatchInfo::GOTInfo){ patchLoc, VMOffset(targetValue) });
             } else {
                 auto authgotIt = coalescedAuthGOTs.find(fixupVMAddr);
                 if ( authgotIt != coalescedAuthGOTs.end() ) {
                     // Probably a missing weak import.  Rewrite the original GOT anyway, but also the coalesced one
-                    dyld_cache_patchable_location patchLoc(authgotIt->second, pmd, addend, bindTarget.isWeakImport);
+                    dyld_cache_patchable_location patchLoc(authgotIt->second, pmd, addend);
                     auto &gotUses = dylibPatchInfo.bindAuthGOTUses[bindOrdinal];
                     gotUses.emplace_back((PatchInfo::GOTInfo){ patchLoc, VMOffset(targetValue) });
                 }
@@ -1134,7 +1132,7 @@
 
                 auto gotIt = coalescedGOTs.find(fixupVMAddr);
                 if ( gotIt != coalescedGOTs.end() ) {
-                    dyld_cache_patchable_location patchLoc(gotIt->second, patchTablePMD, patchTableAddend, bindTarget.isWeakImport);
+                    dyld_cache_patchable_location patchLoc(gotIt->second, patchTablePMD, patchTableAddend);
                     auto& gotUses = dylibPatchInfo.bindGOTUses[bindOrdinal];
                     gotUses.emplace_back((PatchInfo::GOTInfo){ patchLoc, finalVMOffset });
 
@@ -1150,7 +1148,7 @@
                 } else {
                     auto authgotIt = coalescedAuthGOTs.find(fixupVMAddr);
                     if ( authgotIt != coalescedAuthGOTs.end() ) {
-                        dyld_cache_patchable_location patchLoc(authgotIt->second, patchTablePMD, patchTableAddend, bindTarget.isWeakImport);
+                        dyld_cache_patchable_location patchLoc(authgotIt->second, patchTablePMD, patchTableAddend);
                         auto& gotUses = dylibPatchInfo.bindAuthGOTUses[bindOrdinal];
                         gotUses.emplace_back((PatchInfo::GOTInfo){ patchLoc, finalVMOffset });
 
@@ -1165,7 +1163,7 @@
                         this->segments[segIndex].tracker.remove(fixupLoc);
                     } else {
                         // Location wasn't coalesced.  So add to the regular list of uses
-                        dylibPatchInfo.bindUses[bindOrdinal].emplace_back(fixupVMAddr, patchTablePMD, patchTableAddend, bindTarget.isWeakImport);
+                        dylibPatchInfo.bindUses[bindOrdinal].emplace_back(fixupVMAddr, patchTablePMD, patchTableAddend);
                     }
                 }
             }
@@ -1440,7 +1438,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 +1671,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 +1729,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 +1871,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 +2123,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 +2140,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) {
@@ -2743,9 +2740,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)
 {
@@ -2758,18 +2753,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
@@ -2794,8 +2787,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;
@@ -2836,19 +2828,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 = { };