Loading...
common/MachOFile.cpp dyld-1235.2 dyld-1122.1
--- dyld/dyld-1235.2/common/MachOFile.cpp
+++ dyld/dyld-1122.1/common/MachOFile.cpp
@@ -52,30 +52,17 @@
 }
 #endif
 
-
-
-
 #include "Defines.h"
 
 #include <mach-o/nlist.h>
-
-#if !BUILDING_DYLD
-  #include <vector>
-#endif // !BUILDING_DYLD
 
 #include "Array.h"
 #include "MachOFile.h"
 #include "SupportedArchs.h"
 #include "CodeSigningTypes.h"
 
-#include "ObjC.h"
-
 #if (BUILDING_DYLD || BUILDING_LIBDYLD) && !TARGET_OS_EXCLAVEKIT
     #include <subsystem.h>
-#endif
-
-#if !BUILDING_DYLD
-#include "ObjCVisitor.h"
 #endif
 
 namespace dyld3 {
@@ -308,6 +295,7 @@
 #define GRADE_arm64e      CPU_TYPE_ARM64,      CPU_SUBTYPE_ARM64E,      false
 #define GRADE_arm64e_pb   CPU_TYPE_ARM64,      CPU_SUBTYPE_ARM64E,      true
 #define GRADE_arm64_32    CPU_TYPE_ARM64_32,   CPU_SUBTYPE_ARM64_32_V8, false
+
 const GradedArchs GradedArchs::i386              = GradedArchs({GRADE_i386,    1});
 const GradedArchs GradedArchs::x86_64            = GradedArchs({GRADE_x86_64,  1});
 const GradedArchs GradedArchs::x86_64h           = GradedArchs({GRADE_x86_64h, 2}, {GRADE_x86_64, 1});
@@ -328,7 +316,6 @@
 #if SUPPORT_ARCH_arm64_32
 const GradedArchs GradedArchs::arm64_32          = GradedArchs({GRADE_arm64_32, 1});
 #endif
-
 #if BUILDING_LIBDYLD || BUILDING_UNIT_TESTS
 const GradedArchs GradedArchs::launch_AS         = GradedArchs({GRADE_arm64e,  3}, {GRADE_arm64,  2}, {GRADE_x86_64, 1});
 const GradedArchs GradedArchs::launch_AS_Sim     = GradedArchs({GRADE_arm64,   2}, {GRADE_x86_64, 1});
@@ -408,12 +395,20 @@
     return arm64_32;
 #elif __arm64__
     return arm64;
+#elif __ARM_ARCH_7K__
+    return armv7k;
+#elif __ARM_ARCH_7S__
+    return armv7s;
+#elif __ARM_ARCH_7A__
+    return armv7;
 #elif __x86_64__
  #if TARGET_OS_SIMULATOR
     return x86_64;
   #else
     return isHaswell() ? x86_64h : x86_64;
   #endif
+#elif __i386__
+    return i386;
 #else
     #error unknown platform
 #endif
@@ -499,25 +494,16 @@
 };
 
 const MachOFile::PlatformInfo MachOFile::_s_platformInfos[] = {
-    { "macOS",              Platform::macOS,                LC_VERSION_MIN_MACOSX   },
-    { "iOS",                Platform::iOS,                  LC_VERSION_MIN_IPHONEOS },
-    { "tvOS",               Platform::tvOS,                 LC_VERSION_MIN_TVOS     },
-    { "watchOS",            Platform::watchOS,              LC_VERSION_MIN_WATCHOS  },
-    { "bridgeOS",           Platform::bridgeOS,             LC_BUILD_VERSION        },
-    { "MacCatalyst",        Platform::iOSMac,               LC_BUILD_VERSION        },
-    { "iOS-sim",            Platform::iOS_simulator,        LC_BUILD_VERSION        },
-    { "tvOS-sim",           Platform::tvOS_simulator,       LC_BUILD_VERSION        },
-    { "watchOS-sim",        Platform::watchOS_simulator,    LC_BUILD_VERSION        },
-    { "driverKit",          Platform::driverKit,            LC_BUILD_VERSION        },
-    { "visionOS",           Platform::visionOS,             LC_BUILD_VERSION        },
-    { "visionOS-sim",       Platform::visionOS_simulator,   LC_BUILD_VERSION        },
-    { "macOSExclaveCore",   Platform::macOSExclaveCore,     LC_BUILD_VERSION        },
-    { "macOSExclaveKit",    Platform::macOSExclaveKit,      LC_BUILD_VERSION        },
-    { "iOSExclaveCore",     Platform::iOSExclaveCore,       LC_BUILD_VERSION        },
-    { "iOSExclaveKit",      Platform::iOSExclaveKit,        LC_BUILD_VERSION        },
-    { "tvOSExclaveCore",    Platform::tvOSExclaveCore,      LC_BUILD_VERSION        },
-    { "tvOSExclaveKit",     Platform::tvOSExclaveKit,       LC_BUILD_VERSION        },
-
+    { "macOS",       Platform::macOS,             LC_VERSION_MIN_MACOSX   },
+    { "iOS",         Platform::iOS,               LC_VERSION_MIN_IPHONEOS },
+    { "tvOS",        Platform::tvOS,              LC_VERSION_MIN_TVOS     },
+    { "watchOS",     Platform::watchOS,           LC_VERSION_MIN_WATCHOS  },
+    { "bridgeOS",    Platform::bridgeOS,          LC_BUILD_VERSION        },
+    { "MacCatalyst", Platform::iOSMac,            LC_BUILD_VERSION        },
+    { "iOS-sim",     Platform::iOS_simulator,     LC_BUILD_VERSION        },
+    { "tvOS-sim",    Platform::tvOS_simulator,    LC_BUILD_VERSION        },
+    { "watchOS-sim", Platform::watchOS_simulator, LC_BUILD_VERSION        },
+    { "driverKit",   Platform::driverKit,         LC_BUILD_VERSION        },
 };
 
 
@@ -697,14 +683,6 @@
         return true;
 #endif
 
-    // allow iOS executables to use visionOS dylibs
-    if ( (processPlatform == Platform::iOS) && this->builtForPlatform(Platform::visionOS, true) )
-        return true;
-
-    // allow iOS_Sim executables to use visionOS_Sim dylibs
-    if ( (processPlatform == Platform::iOS_simulator) && this->builtForPlatform(Platform::visionOS_simulator, true) )
-        return true;
-
 
     bool iOSonMac = (processPlatform == Platform::iOSMac);
 #if (TARGET_OS_OSX && TARGET_CPU_ARM64)
@@ -720,6 +698,7 @@
     if ( (iOSonMac) && this->builtForPlatform(Platform::macOS, true) )
         return true;
 
+
     return false;
 }
 
@@ -747,9 +726,7 @@
     return Platform::watchOS_simulator;
   #elif TARGET_OS_TV
     return Platform::tvOS_simulator;
-  #elif TARGET_OS_VISION
-    return Platform::visionOS_simulator;
-  #elif TARGET_OS_IOS
+  #else
     return Platform::iOS_simulator;
   #endif
 #elif TARGET_OS_BRIDGE
@@ -764,32 +741,8 @@
     return Platform::macOS;
 #elif TARGET_OS_DRIVERKIT
     return Platform::driverKit;
-#elif TARGET_OS_VISION
-  return Platform::visionOS;
 #else
-    #if TARGET_OS_EXCLAVECORE
-      #if __is_target_os(macos)
-        return Platform::macOSExclaveCore
-      #elif __is_target_os(ios)
-        return Platform::iOSExclaveCore;
-      #elif __is_target_os(tvos)
-        return Platform::tvOSExclaveCore;
-      #else
-        #error unknown platform
-      #endif
-    #elif TARGET_OS_EXCLAVEKIT
-      #if __is_target_os(macos)
-        return Platform::macOSExclaveKit;
-      #elif __is_target_os(ios)
-        return Platform::iOSExclaveKit;
-      #elif __is_target_os(tvos)
-        return Platform::tvOSExclaveKit;
-      #else
-        #error unknown platform
-      #endif
-    #else
-      #error unknown platform
-    #endif
+    #error unknown platform
 #endif
 }
 
@@ -806,24 +759,20 @@
         case Platform::tvOS_simulator:        return Platform::tvOS;
         case Platform::watchOS_simulator:     return Platform::watchOS;
         case Platform::driverKit:             return Platform::driverKit;
-        case Platform::visionOS:              return Platform::visionOS;
-        case Platform::visionOS_simulator:    return Platform::visionOS;
-        case Platform::macOSExclaveCore:      return Platform::macOSExclaveCore;
-        case Platform::macOSExclaveKit:       return Platform::macOSExclaveKit;
-        case Platform::iOSExclaveCore:        return Platform::iOSExclaveCore;
-        case Platform::iOSExclaveKit:         return Platform::iOSExclaveKit;
-        case Platform::tvOSExclaveCore:       return Platform::tvOSExclaveCore;
-        case Platform::tvOSExclaveKit:        return Platform::tvOSExclaveKit;
-
-
-        default:                              return reqPlatform;
+        default:                              return Platform::unknown;
     }
 }
 
 
 const char* MachOFile::currentArchName()
 {
-#if __arm64e__
+#if __ARM_ARCH_7K__
+    return "armv7k";
+#elif __ARM_ARCH_7A__
+    return "armv7";
+#elif __ARM_ARCH_7S__
+    return "armv7s";
+#elif __arm64e__
     return "arm64e";
 #elif __arm64__
 #if __LP64__
@@ -833,29 +782,11 @@
 #endif
 #elif __x86_64__
     return isHaswell() ? "x86_64h" : "x86_64";
+#elif __i386__
+    return "i386";
 #else
     #error unknown arch
 #endif
-}
-
-bool MachOFile::isExclaveKitPlatform(Platform platform, Platform* basePlatform)
-{
-    switch ( platform ) {
-        case Platform::macOSExclaveKit:
-            if ( basePlatform )
-                *basePlatform = Platform::macOS;
-            return true;
-        case Platform::iOSExclaveKit:
-            if ( basePlatform )
-                *basePlatform = Platform::iOS;
-            return true;
-        case Platform::tvOSExclaveKit:
-            if ( basePlatform )
-                *basePlatform = Platform::tvOS;
-            return true;
-       default:
-            return false;
-    }
 }
 
 bool MachOFile::isSimulatorPlatform(Platform platform, Platform* basePlatform)
@@ -873,10 +804,6 @@
             if ( basePlatform )
                 *basePlatform = Platform::tvOS;
             return true;
-        case Platform::visionOS_simulator:
-            if ( basePlatform )
-                *basePlatform = Platform::visionOS;
-            return true;
        default:
             return false;
     }
@@ -890,7 +817,6 @@
             case Platform::iOS_simulator:
             case Platform::watchOS_simulator:
             case Platform::tvOS_simulator:
-            case Platform::visionOS_simulator:
                 result = true;
                 break;
            default:
@@ -1210,14 +1136,6 @@
         }
     });
     return result;
-}
-
-bool MachOFile::hasConstObjCSection() const
-{
-    return hasSection("__DATA_CONST", "__objc_selrefs")
-        || hasSection("__DATA_CONST", "__objc_classrefs")
-        || hasSection("__DATA_CONST", "__objc_protorefs")
-        || hasSection("__DATA_CONST", "__objc_superrefs");
 }
 
 bool MachOFile::hasSection(const char* segName, const char* sectName) const
@@ -1314,8 +1232,6 @@
             break;
         }
     });
-    (void)count;
-    (void)stopped;
 #if !BUILDING_SHARED_CACHE_UTIL && !BUILDING_DYLDINFO && !BUILDING_UNIT_TESTS
     // everything must link with something
     if ( (count == 0) && !stopped ) {
@@ -1329,12 +1245,6 @@
             if ( !this->isDylib() || (strncmp(this->installName(), "/System/DriverKit/usr/lib/system/", 33) != 0) )
                 callback("/System/DriverKit/usr/lib/libSystem.B.dylib", false, false, false, 0x00010000, 0x00010000, stopped);
         }
-        else if ( this->builtForPlatform(Platform::macOSExclaveKit, true)
-                 || this->builtForPlatform(Platform::iOSExclaveKit, true)
-                 || this->builtForPlatform(Platform::tvOSExclaveKit, true) ) {
-            // do nothing for ExclaveKit dylibs
-            // FIXME: only allow this behavior on internal builds
-        }
         else {
             if ( !this->isDylib() || (strncmp(this->installName(), "/usr/lib/system/", 16) != 0) )
                 callback("/usr/lib/libSystem.B.dylib", false, false, false, 0x00010000, 0x00010000, stopped);
@@ -1352,11 +1262,13 @@
          if ( cmd->cmd == LC_DYLD_ENVIRONMENT ) {
             const dylinker_command* envCmd = (dylinker_command*)cmd;
             const char* keyEqualsValue = (char*)envCmd + envCmd->name.offset;
-            // only process variables that start with DYLD_
+            // only process variables that start with DYLD_ and end in _PATH
             if ( (strncmp(keyEqualsValue, "DYLD_", 5) == 0) ) {
                 const char* equals = strchr(keyEqualsValue, '=');
                 if ( equals != NULL ) {
-                    callback(keyEqualsValue, stop);
+                    if ( strncmp(&equals[-5], "_PATH", 5) == 0 ) {
+                        callback(keyEqualsValue, stop);
+                    }
                 }
             }
         }
@@ -1393,20 +1305,6 @@
             case Platform::iOSMac:
                 result = false;
                 break;
-            case Platform::visionOS:
-            case Platform::visionOS_simulator:
-                result = false;
-                break;
-            case Platform::macOSExclaveCore:
-            case Platform::macOSExclaveKit:
-            case Platform::iOSExclaveCore:
-            case Platform::iOSExclaveKit:
-            case Platform::tvOSExclaveCore:
-            case Platform::tvOSExclaveKit:
-                result = false;
-                break;
-
-
             case Platform::unknown:
                 break;
         }
@@ -1733,7 +1631,7 @@
     return (this->flags & MH_HAS_TLV_DESCRIPTORS);
 }
 
-#if BUILDING_CACHE_BUILDER || BUILDING_CACHE_BUILDER_UNIT_TESTS || BUILDING_UNIT_TESTS || BUILDING_DYLD_SYMBOLS_CACHE
+#if BUILDING_CACHE_BUILDER || BUILDING_CACHE_BUILDER_UNIT_TESTS
 static bool endsWith(const char* str, const char* suffix)
 {
     size_t strLen    = strlen(str);
@@ -1754,9 +1652,7 @@
             || (strncmp(dylibName, "/System/Cryptexes/OS/usr/lib/", 29) == 0)
             || (strncmp(dylibName, "/System/Cryptexes/OS/System/Library/", 36) == 0)
             || (strncmp(dylibName, "/System/Cryptexes/OS/System/iOSSupport/usr/lib/", 47) == 0)
-            || (strncmp(dylibName, "/System/Cryptexes/OS/System/iOSSupport/System/Library/", 54) == 0)
-            || (strncmp(dylibName, "/System/ExclaveKit/usr/lib/", 27) == 0)
-            || (strncmp(dylibName, "/System/ExclaveKit/System/Library/", 34) == 0));
+            || (strncmp(dylibName, "/System/Cryptexes/OS/System/iOSSupport/System/Library/", 54) == 0));
 }
 
 static bool startsWith(const char* buffer, const char* valueToFind) {
@@ -1805,123 +1701,43 @@
     return false;
 }
 
+// HACK: Remove this function.  Its only here until we can handle cache overflow
+static bool platformExcludesSharedCache_sim(const char* installName) {
+    if ( startsWith(installName, "/System/Library/PrivateFrameworks/iWorkImport.framework/") )
+        return true;
+    if ( startsWith(installName, "/System/Library/PrivateFrameworks/News") )
+        return true;
+    if ( strcmp(installName, "/System/Library/PrivateFrameworks/StocksUI.framework/StocksUI") == 0 )
+        return true;
+    if ( strcmp(installName, "/System/Library/PrivateFrameworks/NewsUI.framework/NewsUI") == 0 )
+        return true;
+    if ( strcmp(installName, "/System/Library/PrivateFrameworks/CompassUI.framework/CompassUI") == 0 )
+        return true;
+    if ( strcmp(installName, "/System/Library/PrivateFrameworks/WeatherUI.framework/WeatherUI") == 0 )
+        return true;
+    if ( strcmp(installName, "/System/Library/PrivateFrameworks/NewsUI2.framework/NewsUI2") == 0 )
+        return true;
+    if ( strcmp(installName, "/System/Library/PrivateFrameworks/MLCompilerOS.framework/MLCompilerOS") == 0 )
+        return true;
+    if ( strcmp(installName, "/System/Library/PrivateFrameworks/HomeKitDaemon.framework/HomeKitDaemon") == 0 )
+        return true;
+    if ( strcmp(installName, "/System/Library/PrivateFrameworks/HomeKitDaemonLegacy.framework/HomeKitDaemonLegacy") == 0 )
+        return true;
+    return false;
+}
+
 // Returns true if the current platform requires that this install name be excluded from the shared cache
 // Note that this overrides any exclusion from anywhere else.
 static bool platformExcludesSharedCache(Platform platform, const char* installName) {
+    if ( MachOFile::isSimulatorPlatform(platform) )
+        return platformExcludesSharedCache_sim(installName);
     if ( (platform == dyld3::Platform::macOS) || (platform == dyld3::Platform::iOSMac) )
         return platformExcludesSharedCache_macOS(installName);
     // Everything else is based on iOS so just use that value
     return platformExcludesSharedCache_iOS(installName);
 }
 
-#if !BUILDING_DYLD
-
-bool MachOFile::addendsExceedPatchTableLimit(Diagnostics& diag, mach_o::Fixups fixups) const
-{
-    // rdar://122906481 (Shared cache builder - explicitly model dylibs without a need for a patch table)
-    if ( strcmp(installName(), "/usr/lib/libswiftPrespecialized.dylib") == 0 )
-        return false;
-
-    const bool     is64bit = is64();
-    const uint64_t tooLargeRegularAddend = 1 << 23;
-    const uint64_t tooLargeAuthAddend = 1 << 5;
-    __block bool addendTooLarge = false;
-    if ( this->hasChainedFixups() ) {
-
-        // with chained fixups, addends can be in the import table or embedded in a bind pointer
-        __block std::vector<uint64_t> targetAddends;
-        fixups.forEachChainedFixupTarget(diag, ^(int libOrdinal, const char* symbolName, uint64_t addend, bool weakImport, bool& stop) {
-            if ( is64bit )
-                addend &= 0x00FFFFFFFFFFFFFF; // ignore TBI
-            targetAddends.push_back(addend);
-        });
-        // check each pointer for embedded addend
-        fixups.withChainStarts(diag, ^(const dyld_chained_starts_in_image* starts) {
-            fixups.forEachFixupInAllChains(diag, starts, false, ^(mach_o::ChainedFixupPointerOnDisk* fixupLoc, uint64_t fixupSegmentOffset, const dyld_chained_starts_in_segment* segInfo, bool& stop) {
-                switch (segInfo->pointer_format) {
-                    case DYLD_CHAINED_PTR_ARM64E:
-                    case DYLD_CHAINED_PTR_ARM64E_USERLAND:
-                        if ( fixupLoc->arm64e.bind.bind ) {
-                            uint64_t ordinal = fixupLoc->arm64e.bind.ordinal;
-                            uint64_t addend = (ordinal < targetAddends.size()) ? targetAddends[ordinal] : 0;
-                            if ( fixupLoc->arm64e.bind.auth ) {
-                                if ( addend >= tooLargeAuthAddend ) {
-                                    addendTooLarge = true;
-                                    stop = true;
-                                }
-                            } else {
-                                addend += fixupLoc->arm64e.signExtendedAddend();
-                                if ( addend >= tooLargeRegularAddend ) {
-                                    addendTooLarge = true;
-                                    stop = true;
-                                }
-                            }
-                        }
-                        break;
-                    case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
-                        if ( fixupLoc->arm64e.bind24.bind ) {
-                            uint64_t ordinal = fixupLoc->arm64e.bind24.ordinal;
-                            uint64_t addend = (ordinal < targetAddends.size()) ? targetAddends[ordinal] : 0;
-                            if ( fixupLoc->arm64e.bind24.auth ) {
-                                if ( addend >= tooLargeAuthAddend ) {
-                                    addendTooLarge = true;
-                                    stop = true;
-                                }
-                            } else {
-                                addend += fixupLoc->arm64e.signExtendedAddend();
-                                if ( addend >= tooLargeRegularAddend ) {
-                                    addendTooLarge = true;
-                                    stop = true;
-                                }
-                            }
-                        }
-                        break;
-                    case DYLD_CHAINED_PTR_64:
-                    case DYLD_CHAINED_PTR_64_OFFSET: {
-                        if ( fixupLoc->generic64.rebase.bind ) {
-                            uint64_t ordinal = fixupLoc->generic64.bind.ordinal;
-                            uint64_t addend = (ordinal < targetAddends.size()) ? targetAddends[ordinal] : 0;
-                            addend += fixupLoc->generic64.bind.addend;
-                            if ( addend >= tooLargeRegularAddend ) {
-                                addendTooLarge = true;
-                                stop = true;
-                            }
-                        }
-                        break;
-                    }
-                    case DYLD_CHAINED_PTR_32:
-                        if ( fixupLoc->generic32.bind.bind ) {
-                            uint64_t ordinal = fixupLoc->generic32.bind.ordinal;
-                            uint64_t addend = (ordinal < targetAddends.size()) ? targetAddends[ordinal] : 0;
-                            addend += fixupLoc->generic32.bind.addend;
-                            if ( addend >= tooLargeRegularAddend ) {
-                                addendTooLarge = true;
-                                stop = true;
-                            }
-                        }
-                        break;
-                }
-            });
-        });
-    }
-    else {
-        // scan bind opcodes for large addend
-        auto handler = ^(const mach_o::Fixups::BindTargetInfo &info, bool &stop) {
-            uint64_t addend = info.addend;
-            if ( is64bit )
-                addend &= 0x00FFFFFFFFFFFFFF; // ignore TBI
-            if ( addend >= tooLargeRegularAddend ) {
-                addendTooLarge = true;
-                stop = true;
-            }
-        };
-        fixups.forEachBindTarget_Opcodes(diag, true, handler, handler);
-    }
-
-    return addendTooLarge;
-}
-
-bool MachOFile::canBePlacedInDyldCache(const char* path, void (^failureReason)(const char* format, ...)) const
+bool MachOFile::canBePlacedInDyldCache(const char* path, void (^failureReason)(const char*)) const
 {
     if ( !isSharedCacheEligiblePath(path) ) {
         // Dont spam the user with an error about paths when we know these are never eligible.
@@ -1983,18 +1799,12 @@
 
     // dylib must have extra info for moving DATA and TEXT segments apart
     __block bool hasExtraInfo = false;
-    __block bool hasSplitSegMarker = false;
     __block bool hasDyldInfo = false;
     __block bool hasExportTrie = false;
     __block Diagnostics diag;
     forEachLoadCommand(diag, ^(const load_command* cmd, bool& stop) {
-        if ( cmd->cmd == LC_SEGMENT_SPLIT_INFO ) {
-            const linkedit_data_command* sigCmd = (linkedit_data_command*)cmd;
-            if ( sigCmd->datasize == 0 )
-                hasSplitSegMarker = true;
-            else
-                hasExtraInfo = true;
-        }
+        if ( cmd->cmd == LC_SEGMENT_SPLIT_INFO )
+            hasExtraInfo = true;
         if ( cmd->cmd == LC_DYLD_INFO_ONLY )
             hasDyldInfo = true;
         if ( cmd->cmd == LC_DYLD_EXPORTS_TRIE )
@@ -2009,10 +1819,7 @@
             if ( ignorePath == path )
                 return false;
         }
-        if ( hasSplitSegMarker )
-            failureReason("Dylib explicitly linked with '-not_for_dyld_shared_cache'");
-        else
-            failureReason("Missing split seg info");
+        failureReason("Missing split seg info");
         return false;
     }
     if ( !hasDyldInfo && !hasExportTrie ) {
@@ -2021,19 +1828,18 @@
     }
 
     // dylib can only depend on other dylibs in the shared cache
-    __block const char* badDep = nullptr;
+    __block bool allDepPathsAreGood = true;
     forEachDependentDylib(^(const char* loadPath, bool isWeak, bool isReExport, bool isUpward, uint32_t compatVersion, uint32_t curVersion, bool& stop) {
         // Skip weak links.  They are allowed to be missing
         if ( isWeak )
             return;
         if ( !isSharedCacheEligiblePath(loadPath) ) {
-            badDep = loadPath;
+            allDepPathsAreGood = false;
             stop = true;
         }
     });
-    if ( badDep != nullptr ) {
-        failureReason("Depends on dylibs ineligible for dyld cache '%s'.  (cache dylibs must start /usr/lib or /System/Library or similar)",
-                      badDep);
+    if ( !allDepPathsAreGood ) {
+        failureReason("Depends on dylibs ineligable for dyld cache");
         return false;
     }
 
@@ -2069,16 +1875,6 @@
         // evict swift dylibs with split seg v1 info
         if ( layout.isSwiftLibrary() && splitSeg.isV1() )
             return;
-
-        // arm64e requires signed class ROs
-        if ( isArch("arm64e") ) {
-            if ( std::optional<uint32_t> flags = layout.getObjcInfoFlags(); flags.has_value() ) {
-                if ( (flags.value() & mach_o::ObjCImageInfo::OBJC_IMAGE_SIGNED_CLASS_RO) == 0 ) {
-                    failureReason("arm64e binaries must have signed Objective-C class_ro_t pointers");
-                    return;
-                }
-            }
-        }
 
         if ( splitSeg.isV1() ) {
             // Split seg v1 can only support 1 __DATA, and no other writable segments
@@ -2100,7 +1896,101 @@
 
         // <rdar://problem/57769033> dyld_cache_patchable_location only supports addend in range 0..31
         // rdar://96164956 (dyld needs to support arbitrary addends in cache patch table)
-        bool addendTooLarge = addendsExceedPatchTableLimit(diag, fixups);
+        const bool is64bit = is64();
+        __block bool addendTooLarge = false;
+        const uint64_t tooLargeRegularAddend = 1 << 23;
+        const uint64_t tooLargeAuthAddend = 1 << 5;
+        if ( this->hasChainedFixups() ) {
+
+            // with chained fixups, addends can be in the import table or embedded in a bind pointer
+            __block std::vector<uint64_t> targetAddends;
+            fixups.forEachChainedFixupTarget(diag, ^(int libOrdinal, const char* symbolName, uint64_t addend, bool weakImport, bool& stop) {
+                if ( is64bit )
+                    addend &= 0x00FFFFFFFFFFFFFF; // ignore TBI
+                targetAddends.push_back(addend);
+            });
+            // check each pointer for embedded addend
+            fixups.withChainStarts(diag, ^(const dyld_chained_starts_in_image* starts) {
+                fixups.forEachFixupInAllChains(diag, starts, false, ^(mach_o::ChainedFixupPointerOnDisk* fixupLoc, uint64_t fixupSegmentOffset, const dyld_chained_starts_in_segment* segInfo, bool& stop) {
+                    switch (segInfo->pointer_format) {
+                        case DYLD_CHAINED_PTR_ARM64E:
+                        case DYLD_CHAINED_PTR_ARM64E_USERLAND:
+                            if ( fixupLoc->arm64e.bind.bind ) {
+                                uint64_t ordinal = fixupLoc->arm64e.bind.ordinal;
+                                uint64_t addend = (ordinal < targetAddends.size()) ? targetAddends[ordinal] : 0;
+                                if ( fixupLoc->arm64e.bind.auth ) {
+                                    if ( addend >= tooLargeAuthAddend ) {
+                                        addendTooLarge = true;
+                                        stop = true;
+                                    }
+                                } else {
+                                    addend += fixupLoc->arm64e.signExtendedAddend();
+                                    if ( addend >= tooLargeRegularAddend ) {
+                                        addendTooLarge = true;
+                                        stop = true;
+                                    }
+                                }
+                            }
+                            break;
+                        case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
+                            if ( fixupLoc->arm64e.bind24.bind ) {
+                                uint64_t ordinal = fixupLoc->arm64e.bind24.ordinal;
+                                uint64_t addend = (ordinal < targetAddends.size()) ? targetAddends[ordinal] : 0;
+                                if ( fixupLoc->arm64e.bind24.auth ) {
+                                    if ( addend >= tooLargeAuthAddend ) {
+                                        addendTooLarge = true;
+                                        stop = true;
+                                    }
+                                } else {
+                                    addend += fixupLoc->arm64e.signExtendedAddend();
+                                    if ( addend >= tooLargeRegularAddend ) {
+                                        addendTooLarge = true;
+                                        stop = true;
+                                    }
+                                }
+                            }
+                            break;
+                        case DYLD_CHAINED_PTR_64:
+                        case DYLD_CHAINED_PTR_64_OFFSET: {
+                            if ( fixupLoc->generic64.rebase.bind ) {
+                                uint64_t ordinal = fixupLoc->generic64.bind.ordinal;
+                                uint64_t addend = (ordinal < targetAddends.size()) ? targetAddends[ordinal] : 0;
+                                addend += fixupLoc->generic64.bind.addend;
+                                if ( addend >= tooLargeRegularAddend ) {
+                                    addendTooLarge = true;
+                                    stop = true;
+                                }
+                            }
+                            break;
+                        }
+                        case DYLD_CHAINED_PTR_32:
+                            if ( fixupLoc->generic32.bind.bind ) {
+                                uint64_t ordinal = fixupLoc->generic32.bind.ordinal;
+                                uint64_t addend = (ordinal < targetAddends.size()) ? targetAddends[ordinal] : 0;
+                                addend += fixupLoc->generic32.bind.addend;
+                                if ( addend >= tooLargeRegularAddend ) {
+                                    addendTooLarge = true;
+                                    stop = true;
+                                }
+                            }
+                            break;
+                    }
+                });
+            });
+        }
+        else {
+            // scan bind opcodes for large addend
+            auto handler = ^(const mach_o::Fixups::BindTargetInfo &info, bool &stop) {
+                uint64_t addend = info.addend;
+                if ( is64bit )
+                    addend &= 0x00FFFFFFFFFFFFFF; // ignore TBI
+                if ( addend >= tooLargeRegularAddend ) {
+                    addendTooLarge = true;
+                    stop = true;
+                }
+            };
+            fixups.forEachBindTarget_Opcodes(diag, true, handler, handler);
+        }
         if ( addendTooLarge ) {
             failureReason("bind addend too large");
             return;
@@ -2188,144 +2078,8 @@
         passedLinkeditChecks = true;
     });
 
-    if ( !passedLinkeditChecks )
-        return false;
-
-    // Check there are no pointer based objc method lists in CONST segments
-#if BUILDING_CACHE_BUILDER || BUILDING_CACHE_BUILDER_UNIT_TESTS
-    {
-        typedef std::pair<VMAddress, VMAddress> Range;
-        __block std::vector<Range> constRanges;
-        this->forEachSegment(^(const SegmentInfo& info, bool& stop) {
-            if ( info.vmSize == 0 )
-                return;
-            if ( !strcmp(info.segName, "__DATA_CONST") || !strcmp(info.segName, "__AUTH_CONST") )
-                constRanges.push_back({ VMAddress(info.vmAddr), VMAddress(info.vmAddr + info.vmSize) });
-        });
-
-        if ( !constRanges.empty() ) {
-            __block objc_visitor::Visitor objcVisitor = this->makeObjCVisitor(diag);
-            if ( diag.hasError() )
-                return false;
-
-            // Returns true if the method list is bad, ie, a pointer based method list in _CONST segment
-            auto isConstPointerBasedMethodList = ^(const objc_visitor::MethodList& methodList) {
-                if ( (methodList.numMethods() == 0) || methodList.usesRelativeOffsets() )
-                    return false;
-
-                VMAddress methodListVMAddr = methodList.getVMAddress().value();
-                for ( const Range& range : constRanges ) {
-                    if ( (methodListVMAddr >= range.first) && (methodListVMAddr < range.second) )
-                        return true;
-                }
-
-                return false;
-            };
-
-            __block bool hasPointerMethodList = false;
-            objcVisitor.forEachClassAndMetaClass(^(const objc_visitor::Class& objcClass, bool& stopClass) {
-                if ( isConstPointerBasedMethodList(objcClass.getBaseMethods(objcVisitor)) ) {
-                    failureReason("has pointer based objc class method list in _CONST segment");
-                    hasPointerMethodList = true;
-                    stopClass = true;
-                }
-            });
-            if ( hasPointerMethodList )
-                return false;
-
-            objcVisitor.forEachCategory(^(const objc_visitor::Category& objcCategory, bool& stopCategory) {
-                if ( isConstPointerBasedMethodList(objcCategory.getInstanceMethods(objcVisitor)) ) {
-                    failureReason("has pointer based objc category instance method list in _CONST segment");
-                    hasPointerMethodList = true;
-                    stopCategory = true;
-                }
-                if ( isConstPointerBasedMethodList(objcCategory.getClassMethods(objcVisitor)) ) {
-                    failureReason("has pointer based objc category class method list in _CONST segment");
-                    hasPointerMethodList = true;
-                    stopCategory = true;
-                }
-            });
-            if ( hasPointerMethodList )
-                return false;
-        }
-    }
-#endif // BUILDING_CACHE_BUILDER || BUILDING_CACHE_BUILDER_UNIT_TESTS
-
-    return true;
-}
-
-#if BUILDING_CACHE_BUILDER || BUILDING_CACHE_BUILDER_UNIT_TESTS
-objc_visitor::Visitor MachOFile::makeObjCVisitor(Diagnostics& diag) const
-{
-    VMAddress dylibBaseAddress(this->preferredLoadAddress());
-
-    __block std::vector<metadata_visitor::Segment> segments;
-    __block std::vector<uint64_t> bindTargets;
-    this->withFileLayout(diag, ^(const mach_o::Layout &layout) {
-        for ( uint32_t segIndex = 0; segIndex != layout.segments.size(); ++segIndex ) {
-            const auto& layoutSegment = layout.segments[segIndex];
-            metadata_visitor::Segment segment {
-                .startVMAddr = VMAddress(layoutSegment.vmAddr),
-                .endVMAddr = VMAddress(layoutSegment.vmAddr + layoutSegment.vmSize),
-                .bufferStart = (uint8_t*)layoutSegment.buffer,
-                .onDiskDylibChainedPointerFormat = 0,
-                .segIndex = segIndex
-            };
-            segments.push_back(std::move(segment));
-        }
-
-        // Add chained fixup info to each segment, if we have it
-        if ( this->hasChainedFixups() ) {
-            mach_o::Fixups fixups(layout);
-            fixups.withChainStarts(diag, ^(const dyld_chained_starts_in_image* starts) {
-                mach_o::Fixups::forEachFixupChainSegment(diag, starts,
-                                                         ^(const dyld_chained_starts_in_segment *segInfo, uint32_t segIndex, bool &stop) {
-                    segments[segIndex].onDiskDylibChainedPointerFormat = segInfo->pointer_format;
-                });
-            });
-        }
-
-        // ObjC patching needs the bind targets for interposable references to the classes
-        // build targets table
-        if ( this->hasChainedFixupsLoadCommand() ) {
-            mach_o::Fixups fixups(layout);
-            fixups.forEachBindTarget_ChainedFixups(diag, ^(const mach_o::Fixups::BindTargetInfo &info, bool &stop) {
-                if ( info.libOrdinal != BIND_SPECIAL_DYLIB_SELF ) {
-                    bindTargets.push_back(0);
-                    return;
-                }
-
-                mach_o::Layout::FoundSymbol foundInfo;
-                if ( !layout.findExportedSymbol(diag, info.symbolName, info.weakImport, foundInfo) ) {
-                    bindTargets.push_back(0);
-                    return;
-                }
-
-                // We only support header offsets in this dylib, as we are looking for self binds
-                // which are likely only to classes
-                if ( (foundInfo.kind != mach_o::Layout::FoundSymbol::Kind::headerOffset)
-                    || (foundInfo.foundInDylib.value() != this) ) {
-                    bindTargets.push_back(0);
-                    return;
-                }
-
-                uint64_t vmAddr = layout.textUnslidVMAddr() + foundInfo.value;
-                bindTargets.push_back(vmAddr);
-            });
-        }
-    });
-
-    std::optional<VMAddress> selectorStringsBaseAddress;
-    objc_visitor::Visitor objcVisitor(dylibBaseAddress, this,
-                                      std::move(segments), selectorStringsBaseAddress,
-                                      std::move(bindTargets));
-
-    return objcVisitor;
-}
-#endif // BUILDING_CACHE_BUILDER || BUILDING_CACHE_BUILDER_UNIT_TESTS
-
-#endif // !BUILDING_DYLD
-
+    return passedLinkeditChecks;
+}
 
 // Returns true if the executable path is eligible for a PrebuiltLoader on the given platform.
 bool MachOFile::canHavePrebuiltExecutableLoader(dyld3::Platform platform, const std::string_view& path,
@@ -2367,6 +2121,12 @@
             failureReason("path not eligible");
             return false;
         }
+    } else {
+        // On embedded, only staged apps are excluded.  They will run from a different location at runtime
+        if ( path.find("/staged_system_apps/") != std::string::npos ) {
+            // Dont spam the user with an error about paths when we know these are never eligible.
+            return false;
+        }
     }
 
     if ( !hasCodeSignature() ) {
@@ -2480,9 +2240,7 @@
 
     return true;
 }
-#endif // BUILDING_APP_CACHE_UTIL
-
-#if BUILDING_APP_CACHE_UTIL || BUILDING_DYLDINFO
+
 bool MachOFile::usesClassicRelocationsInKernelCollection() const {
     // The xnu x86_64 static executable needs to do the i386->x86_64 transition
     // so will be emitted with classic relocations
@@ -2491,7 +2249,7 @@
     }
     return false;
 }
-#endif // BUILDING_APP_CACHE_UTIL || BUILDING_DYLDINFO
+#endif
 
 #if BUILDING_CACHE_BUILDER || BUILDING_CACHE_BUILDER_UNIT_TESTS
 static bool platformExcludesPrebuiltClosure_macOS(const char* path) {
@@ -2741,12 +2499,6 @@
                         chainEnd = true;
                     else
                         chain = (ChainedFixupPointerOnDisk*)((uint8_t*)chain + chainContent.arm64e.rebase.next*stride);
-                    break;
-                case DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE:
-                    if ( chainContent.cache64e.regular.next == 0 )
-                        chainEnd = true;
-                    else
-                        chain = (ChainedFixupPointerOnDisk*)((uint8_t*)chain + chainContent.cache64e.regular.next*stride);
                     break;
                 case DYLD_CHAINED_PTR_64:
                 case DYLD_CHAINED_PTR_64_OFFSET:
@@ -2954,7 +2706,7 @@
     });
 }
 
-const MachOFile* MachOFile::compatibleSlice(Diagnostics& diag, uint64_t& sliceLenOut, const void* fileContent, size_t contentSize, const char* path, Platform platform, bool isOSBinary, const GradedArchs& archs, bool internalInstall)
+const MachOFile* MachOFile::compatibleSlice(Diagnostics& diag, const void* fileContent, size_t contentSize, const char* path, Platform platform, bool isOSBinary, const GradedArchs& archs, bool internalInstall)
 {
     const MachOFile* mf = nullptr;
     if ( const dyld3::FatFile* ff = dyld3::FatFile::isFatFile(fileContent) ) {
@@ -2963,7 +2715,6 @@
         bool      missingSlice;
         if ( ff->isFatFileWithSlice(diag, contentSize, archs, isOSBinary, sliceOffset, sliceLen, missingSlice) ) {
             mf = (MachOFile*)((long)fileContent + sliceOffset);
-            sliceLenOut = sliceLen;
         }
         else {
             BLOCK_ACCCESSIBLE_ARRAY(char, gradedArchsBuf, 256);
@@ -2976,7 +2727,6 @@
     }
     else {
         mf = (MachOFile*)fileContent;
-        sliceLenOut = contentSize;
     }
 
     if ( !mf->hasMachOMagic() || !mf->isMachO(diag, contentSize) ) {
@@ -3311,7 +3061,7 @@
 
     // The aux KC may have __DATA first, in which case we always want to vm_copy to the right place
     bool hasOutOfOrderSegments = false;
-#if BUILDING_APP_CACHE_UTIL || BUILDING_DYLDINFO
+#if BUILDING_APP_CACHE_UTIL
     uint64_t textSegVMAddr = preferredLoadAddress();
     hasOutOfOrderSegments = textSegVMAddr != lowestVmAddr;
 #endif
@@ -3595,17 +3345,6 @@
                 this->high8             = fixupLoc->arm64e.rebase.high8;
             }
             break;
-        case DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE:
-            this->authenticated = fixupLoc->cache64e.auth.auth;
-            if ( this->authenticated ) {
-                this->key               = fixupLoc->cache64e.auth.keyIsData ? 2 : 0; // true -> DA (2), false -> IA (0)
-                this->usesAddrDiversity = fixupLoc->cache64e.auth.addrDiv;
-                this->diversity         = fixupLoc->cache64e.auth.diversity;
-            }
-            else {
-                this->high8 = fixupLoc->cache64e.regular.high8;
-            }
-            break;
         case DYLD_CHAINED_PTR_64:
         case DYLD_CHAINED_PTR_64_OFFSET:
             if ( fixupLoc->generic64.bind.bind == 0 )
@@ -3623,7 +3362,7 @@
         && (this->usesAddrDiversity == other.usesAddrDiversity);
 }
 
-#if !SUPPORT_VM_LAYOUT || BUILDING_UNIT_TESTS || BUILDING_DYLD_SYMBOLS_CACHE
+#if !SUPPORT_VM_LAYOUT
 bool MachOFile::getLinkeditLayout(Diagnostics& diag, mach_o::LinkeditLayout& layout) const
 {
     // Note, in file layout all linkedit offsets are just file offsets.
@@ -4089,16 +3828,6 @@
         case Platform::driverKit:
             result = true;
             break;
-        case Platform::visionOS:
-        case Platform::visionOS_simulator:
-            result = true; // do all checks by default
-            if ( kind == Malformed::sdkOnOrAfter2022 ) {
-                if (sdk < 0x00020000) // visionOS 2.0 FIXME
-                    result = false;
-            }
-            break;
-
-
         default:
             result = true;
             break;
@@ -4295,7 +4024,7 @@
                 }
                 else if ( sect->addr+sect->size > seg->vmaddr+seg->vmsize ) {
                     bool ignoreError = !enforceFormat(Malformed::sectionsAddrRangeWithinSegment);
-#if BUILDING_APP_CACHE_UTIL || BUILDING_DYLDINFO
+#if BUILDING_APP_CACHE_UTIL
                     if ( (seg->vmsize == 0) && !strcmp(seg->segname, "__CTF") )
                         ignoreError = true;
 #endif