Loading...
dyld3/MachOFile.cpp dyld-832.7.1 dyld-625.13
--- dyld/dyld-832.7.1/dyld3/MachOFile.cpp
+++ dyld/dyld-625.13/dyld3/MachOFile.cpp
@@ -25,63 +25,34 @@
 #include <assert.h>
 #include <string.h>
 #include <stdio.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/errno.h>
-#include <sys/fcntl.h>
-#include <unistd.h>
 #include <TargetConditionals.h>
 #include <mach/host_info.h>
 #include <mach/mach.h>
 #include <mach/mach_host.h>
 
-#include "Array.h"
 #include "MachOFile.h"
 #include "SupportedArchs.h"
 
-#if BUILDING_DYLD || BUILDING_LIBDYLD
-    // define away restrict until rdar://60166935 is fixed
-    #define restrict
-    #include <subsystem.h>
+#ifndef EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE
+    #define EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE 0x02
+#endif
+
+#ifndef CPU_SUBTYPE_ARM64_E
+    #define CPU_SUBTYPE_ARM64_E    2
+#endif
+
+#ifndef CPU_SUBTYPE_ARM64_32_V8
+    #define CPU_SUBTYPE_ARM64_32_V8    1
+#endif
+
+#ifndef CPU_TYPE_ARM64_32
+    #ifndef CPU_ARCH_ABI64_32
+        #define CPU_ARCH_ABI64_32            0x02000000
+    #endif
+    #define CPU_TYPE_ARM64_32            (CPU_TYPE_ARM | CPU_ARCH_ABI64_32)
 #endif
 
 namespace dyld3 {
-
-////////////////////////////  posix wrappers ////////////////////////////////////////
-
-// <rdar://problem/10111032> wrap calls to stat() with check for EAGAIN
-int stat(const char* path, struct stat* buf)
-{
-    int result;
-    do {
-#if BUILDING_DYLD || BUILDING_LIBDYLD
-        result = ::stat_with_subsystem(path, buf);
-#else
-        result = ::stat(path, buf);
-#endif
-    } while ((result == -1) && ((errno == EAGAIN) || (errno == EINTR)));
-
-    return result;
-}
-
-// <rdar://problem/13805025> dyld should retry open() if it gets an EGAIN
-int open(const char* path, int flag, int other)
-{
-    int result;
-    do {
-#if BUILDING_DYLD || BUILDING_LIBDYLD
-        if (flag & O_CREAT)
-            result = ::open(path, flag, other);
-        else
-            result = ::open_with_subsystem(path, flag);
-#else
-        result = ::open(path, flag, other);
-#endif
-    } while ((result == -1) && ((errno == EAGAIN) || (errno == EINTR)));
-
-    return result;
-}
-
 
 ////////////////////////////  FatFile ////////////////////////////////////////
 
@@ -94,63 +65,27 @@
         return nullptr;
 }
 
-bool FatFile::isValidSlice(Diagnostics& diag, uint64_t fileLen, uint32_t sliceIndex,
-                           uint32_t sliceCpuType, uint32_t sliceCpuSubType, uint64_t sliceOffset, uint64_t sliceLen) const {
-    if ( greaterThanAddOrOverflow(sliceOffset, sliceLen, fileLen) ) {
-        diag.error("slice %d extends beyond end of file", sliceIndex);
-        return false;
-    }
-    const dyld3::MachOFile* mf = (const dyld3::MachOFile*)((uint8_t*)this+sliceOffset);
-    if (!mf->isMachO(diag, sliceLen))
-        return false;
-    if ( (mf->cputype != (cpu_type_t)sliceCpuType) || (mf->cpusubtype != (cpu_subtype_t)sliceCpuSubType) ) {
-        diag.error("cpu type/subtype mismatch");
-        return false;
-    }
-    uint32_t pageSizeMask = mf->uses16KPages() ? 0x3FFF : 0xFFF;
-    if ( (sliceOffset & pageSizeMask) != 0 ) {
-        // slice not page aligned
-        if ( strncmp((char*)this+sliceOffset, "!<arch>", 7) == 0 )
-            diag.error("file is static library");
-        else
-            diag.error("slice is not page aligned");
-        return false;
-    }
-    return true;
-}
-
 void FatFile::forEachSlice(Diagnostics& diag, uint64_t fileLen, void (^callback)(uint32_t sliceCpuType, uint32_t sliceCpuSubType, const void* sliceStart, uint64_t sliceSize, bool& stop)) const
 {
 	if ( this->magic == OSSwapBigToHostInt32(FAT_MAGIC) ) {
-        const uint64_t maxArchs = ((4096 - sizeof(fat_header)) / sizeof(fat_arch));
-        const uint32_t numArchs = OSSwapBigToHostInt32(nfat_arch);
-        if ( numArchs > maxArchs ) {
-            diag.error("fat header too large: %u entries", numArchs);
+        if ( OSSwapBigToHostInt32(nfat_arch) > ((4096 - sizeof(fat_header)) / sizeof(fat_arch)) ) {
+            diag.error("fat header too large: %u entries", OSSwapBigToHostInt32(nfat_arch));
             return;
         }
         bool stop = false;
         const fat_arch* const archs = (fat_arch*)(((char*)this)+sizeof(fat_header));
-        for (uint32_t i=0; i < numArchs; ++i) {
+        for (uint32_t i=0; i < OSSwapBigToHostInt32(nfat_arch); ++i) {
             uint32_t cpuType    = OSSwapBigToHostInt32(archs[i].cputype);
             uint32_t cpuSubType = OSSwapBigToHostInt32(archs[i].cpusubtype);
             uint32_t offset     = OSSwapBigToHostInt32(archs[i].offset);
             uint32_t len        = OSSwapBigToHostInt32(archs[i].size);
-            if (isValidSlice(diag, fileLen, i, cpuType, cpuSubType, offset, len))
-                callback(cpuType, cpuSubType, (uint8_t*)this+offset, len, stop);
+            if ( greaterThanAddOrOverflow(offset, len, fileLen) ) {
+                diag.error("slice %d extends beyond end of file", i);
+                return;
+            }
+            callback(cpuType, cpuSubType, (uint8_t*)this+offset, len, stop);
             if ( stop )
                 break;
-        }
-
-        // Look for one more slice
-        if ( numArchs != maxArchs ) {
-            uint32_t cpuType    = OSSwapBigToHostInt32(archs[numArchs].cputype);
-            uint32_t cpuSubType = OSSwapBigToHostInt32(archs[numArchs].cpusubtype);
-            uint32_t offset     = OSSwapBigToHostInt32(archs[numArchs].offset);
-            uint32_t len        = OSSwapBigToHostInt32(archs[numArchs].size);
-            if ((cpuType == CPU_TYPE_ARM64) && ((cpuSubType == CPU_SUBTYPE_ARM64_ALL || cpuSubType == CPU_SUBTYPE_ARM64_V8))) {
-                if (isValidSlice(diag, fileLen, numArchs, cpuType, cpuSubType, offset, len))
-                    callback(cpuType, cpuSubType, (uint8_t*)this+offset, len, stop);
-            }
         }
     }
     else if ( this->magic == OSSwapBigToHostInt32(FAT_MAGIC_64) ) {
@@ -165,8 +100,11 @@
             uint32_t cpuSubType = OSSwapBigToHostInt32(archs[i].cpusubtype);
             uint64_t offset     = OSSwapBigToHostInt64(archs[i].offset);
             uint64_t len        = OSSwapBigToHostInt64(archs[i].size);
-            if (isValidSlice(diag, fileLen, i, cpuType, cpuSubType, offset, len))
-                callback(cpuType, cpuSubType, (uint8_t*)this+offset, len, stop);
+            if ( greaterThanAddOrOverflow(offset, len, fileLen) ) {
+                diag.error("slice %d extends beyond end of file", i);
+                return;
+            }
+            callback(cpuType, cpuSubType, (uint8_t*)this+offset, len, stop);
             if ( stop )
                 break;
         }
@@ -176,83 +114,215 @@
     }
 }
 
-bool FatFile::isFatFileWithSlice(Diagnostics& diag, uint64_t fileLen, const GradedArchs& archs, bool isOSBinary,
-                                 uint64_t& sliceOffset, uint64_t& sliceLen, bool& missingSlice) const
+bool FatFile::isFatFileWithSlice(Diagnostics& diag, uint64_t fileLen, const char* archName, uint64_t& sliceOffset, uint64_t& sliceLen, bool& missingSlice) const
 {
     missingSlice = false;
     if ( (this->magic != OSSwapBigToHostInt32(FAT_MAGIC)) && (this->magic != OSSwapBigToHostInt32(FAT_MAGIC_64)) )
         return false;
 
-    __block int bestGrade = 0;
+    __block bool found = false;
     forEachSlice(diag, fileLen, ^(uint32_t sliceCpuType, uint32_t sliceCpuSubType, const void* sliceStart, uint64_t sliceSize, bool& stop) {
-        if (int sliceGrade = archs.grade(sliceCpuType, sliceCpuSubType, isOSBinary)) {
-            if ( sliceGrade > bestGrade ) {
-                sliceOffset = (char*)sliceStart - (char*)this;
-                sliceLen    = sliceSize;
-                bestGrade   = sliceGrade;
-            }
+        const char* sliceArchName = MachOFile::archName(sliceCpuType, sliceCpuSubType);
+        if ( strcmp(sliceArchName, archName) == 0 ) {
+            sliceOffset = (char*)sliceStart - (char*)this;
+            sliceLen    = sliceSize;
+            found       = true;
+            stop        = true;
         }
     });
     if ( diag.hasError() )
         return false;
 
-    if ( bestGrade == 0 )
+    if ( !found )
         missingSlice = true;
 
-    return (bestGrade != 0);
-}
-
-
-////////////////////////////  GradedArchs ////////////////////////////////////////
-
-
-#define GRADE_i386        CPU_TYPE_I386,       CPU_SUBTYPE_I386_ALL,    false
-#define GRADE_x86_64      CPU_TYPE_X86_64,     CPU_SUBTYPE_X86_64_ALL,  false
-#define GRADE_x86_64h     CPU_TYPE_X86_64,     CPU_SUBTYPE_X86_64_H,    false
-#define GRADE_armv7       CPU_TYPE_ARM,        CPU_SUBTYPE_ARM64_ALL,   false
-#define GRADE_armv7s      CPU_TYPE_ARM,        CPU_SUBTYPE_ARM_V7,      false
-#define GRADE_armv7k      CPU_TYPE_ARM,        CPU_SUBTYPE_ARM_V7K,     false
-#define GRADE_arm64       CPU_TYPE_ARM64,      CPU_SUBTYPE_ARM64_ALL,   false
-#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              = { {{GRADE_i386,    1}} };
-const GradedArchs GradedArchs::x86_64            = { {{GRADE_x86_64,  1}} };
-const GradedArchs GradedArchs::x86_64h           = { {{GRADE_x86_64h, 2}, {GRADE_x86_64, 1}} };
-const GradedArchs GradedArchs::arm64             = { {{GRADE_arm64,   1}} };
+    // when looking for x86_64h fallback to x86_64
+    if ( !found && (strcmp(archName, "x86_64h") == 0) )
+        return isFatFileWithSlice(diag, fileLen, "x86_64", sliceOffset, sliceLen, missingSlice);
+
+    return found;
+}
+
+
+////////////////////////////  MachOFile ////////////////////////////////////////
+
+
+const MachOFile::ArchInfo MachOFile::_s_archInfos[] = {
+    { "x86_64",   CPU_TYPE_X86_64,   CPU_SUBTYPE_X86_64_ALL  },
+    { "x86_64h",  CPU_TYPE_X86_64,   CPU_SUBTYPE_X86_64_H    },
+    { "i386",     CPU_TYPE_I386,     CPU_SUBTYPE_I386_ALL    },
+    { "arm64",    CPU_TYPE_ARM64,    CPU_SUBTYPE_ARM64_ALL   },
 #if SUPPORT_ARCH_arm64e
-const GradedArchs GradedArchs::arm64e_keysoff    = { {{GRADE_arm64e,    2}, {GRADE_arm64, 1}} };
-const GradedArchs GradedArchs::arm64e_keysoff_pb = { {{GRADE_arm64e_pb, 2}, {GRADE_arm64, 1}} };
-const GradedArchs GradedArchs::arm64e            = { {{GRADE_arm64e,    1}} };
-const GradedArchs GradedArchs::arm64e_pb         = { {{GRADE_arm64e_pb, 1}} };
-#endif
-const GradedArchs GradedArchs::armv7             = { {{GRADE_armv7,   1}} };
-const GradedArchs GradedArchs::armv7s            = { {{GRADE_armv7s,  2}, {GRADE_armv7, 1}} };
-const GradedArchs GradedArchs::armv7k            = { {{GRADE_armv7k,  1}} };
+    { "arm64e",   CPU_TYPE_ARM64,    CPU_SUBTYPE_ARM64_E     },
+#endif
 #if SUPPORT_ARCH_arm64_32
-const GradedArchs GradedArchs::arm64_32          = { {{GRADE_arm64_32, 1}} };
-#endif
-
-int GradedArchs::grade(uint32_t cputype, uint32_t cpusubtype, bool isOSBinary) const
-{
-    for (const CpuGrade* p = _orderedCpuTypes; p->type != 0; ++p) {
-        if ( (p->type == cputype) && (p->subtype == (cpusubtype & ~CPU_SUBTYPE_MASK)) ) {
-            if ( p->osBinary ) {
-                if ( isOSBinary )
-                    return p->grade;
-            }
-            else {
-                return p->grade;
-            }
+    { "arm64_32", CPU_TYPE_ARM64_32, CPU_SUBTYPE_ARM64_32_V8 },
+#endif
+    { "armv7k",   CPU_TYPE_ARM,      CPU_SUBTYPE_ARM_V7K     },
+    { "armv7s",   CPU_TYPE_ARM,      CPU_SUBTYPE_ARM_V7S     },
+    { "armv7",    CPU_TYPE_ARM,      CPU_SUBTYPE_ARM_V7      }
+};
+
+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        },
+    { "iOSMac",      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        },
+};
+
+
+bool MachOFile::is64() const
+{
+    return (this->magic == MH_MAGIC_64);
+}
+
+uint32_t MachOFile::pointerSize() const
+{
+    if (this->magic == MH_MAGIC_64)
+        return 8;
+    else
+        return 4;
+}
+
+bool MachOFile::uses16KPages() const
+{
+    switch (this->cputype) {
+        case CPU_TYPE_ARM64:
+        case CPU_TYPE_ARM:
+        case CPU_TYPE_ARM64_32:
+            return true;
+        default:
+            return false;
+    }
+}
+
+bool MachOFile::isArch(const char* aName) const
+{
+    return (strcmp(aName, archName(this->cputype, this->cpusubtype)) == 0);
+}
+
+const char* MachOFile::archName(uint32_t cputype, uint32_t cpusubtype)
+{
+    for (const ArchInfo& info : _s_archInfos) {
+        if ( (cputype == info.cputype) && ((cpusubtype & ~CPU_SUBTYPE_MASK) == info.cpusubtype) ) {
+            return info.name;
+        }
+    }
+    return "unknown";
+}
+
+uint32_t MachOFile::cpuTypeFromArchName(const char* archName)
+{
+    for (const ArchInfo& info : _s_archInfos) {
+        if ( strcmp(archName, info.name) == 0 ) {
+            return info.cputype;
         }
     }
     return 0;
 }
 
-const char* GradedArchs::name() const
-{
-    return MachOFile::archName(_orderedCpuTypes[0].type, _orderedCpuTypes[0].subtype);
+uint32_t MachOFile::cpuSubtypeFromArchName(const char* archName)
+{
+    for (const ArchInfo& info : _s_archInfos) {
+        if ( strcmp(archName, info.name) == 0 ) {
+            return info.cpusubtype;
+        }
+    }
+    return 0;
+}
+
+const char* MachOFile::archName() const
+{
+    return archName(this->cputype, this->cpusubtype);
+}
+
+static void appendDigit(char*& s, unsigned& num, unsigned place, bool& startedPrinting)
+{
+    if ( num >= place ) {
+        unsigned dig = (num/place);
+        *s++ = '0' + dig;
+        num -= (dig*place);
+        startedPrinting = true;
+    }
+    else if ( startedPrinting ) {
+        *s++ = '0';
+    }
+}
+
+static void appendNumber(char*& s, unsigned num)
+{
+    assert(num < 99999);
+    bool startedPrinting = false;
+    appendDigit(s, num, 10000, startedPrinting);
+    appendDigit(s, num,  1000, startedPrinting);
+    appendDigit(s, num,   100, startedPrinting);
+    appendDigit(s, num,    10, startedPrinting);
+    appendDigit(s, num,     1, startedPrinting);
+    if ( !startedPrinting )
+        *s++ = '0';
+}
+
+void MachOFile::packedVersionToString(uint32_t packedVersion, char versionString[32])
+{
+    // sprintf(versionString, "%d.%d.%d", (packedVersion >> 16), ((packedVersion >> 8) & 0xFF), (packedVersion & 0xFF));
+    char* s = versionString;
+    appendNumber(s, (packedVersion >> 16));
+    *s++ = '.';
+    appendNumber(s, (packedVersion >> 8) & 0xFF);
+    *s++ = '.';
+    appendNumber(s, (packedVersion & 0xFF));
+    *s++ = '\0';
+}
+
+bool MachOFile::supportsPlatform(Platform reqPlatform) const
+{
+    __block bool foundRequestedPlatform = false;
+    __block bool foundOtherPlatform = false;
+    forEachSupportedPlatform(^(Platform platform, uint32_t minOS, uint32_t sdk) {
+        if ( platform == reqPlatform )
+            foundRequestedPlatform = true;
+        else
+            foundOtherPlatform = true;
+    });
+    if ( foundRequestedPlatform )
+        return true;
+
+    // we did find some platform info, but not requested, so return false
+    if ( foundOtherPlatform )
+        return false;
+
+    // binary has no explict load command to mark platform
+    // could be an old macOS binary, look at arch
+    if  ( reqPlatform == Platform::macOS ) {
+        if ( this->cputype == CPU_TYPE_X86_64 )
+            return true;
+        if ( this->cputype == CPU_TYPE_I386 )
+            return true;
+    }
+
+    return false;
+}
+
+Platform MachOFile::currentPlatform()
+{
+#if TARGET_OS_BRIDGE
+    return Platform::bridgeOS;
+#elif TARGET_OS_WATCH
+    return Platform::watchOS;
+#elif TARGET_OS_TV
+    return Platform::tvOS;
+#elif TARGET_OS_IOS
+    return Platform::iOS;
+#elif TARGET_OS_MAC
+    return Platform::macOS;
+#else
+    #error unknown platform
+#endif
 }
 
 #if __x86_64__
@@ -273,335 +343,6 @@
     return sHaswell;
 }
 #endif
-
-const GradedArchs& GradedArchs::forCurrentOS(bool keysOff, bool osBinariesOnly)
-{
-#if __arm64e__
-    if ( osBinariesOnly )
-        return (keysOff ? arm64e_keysoff_pb : arm64e_pb);
-    else
-        return (keysOff ? arm64e_keysoff : arm64e);
-#elif __ARM64_ARCH_8_32__
-    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__
-    return isHaswell() ? x86_64h : x86_64;
-#elif __i386__
-    return i386;
-#else
-    #error unknown platform
-#endif
-}
-
-const GradedArchs& GradedArchs::forName(const char* archName, bool keysOff)
-{
-    if (strcmp(archName, "x86_64h") == 0 )
-        return x86_64h;
-    else if (strcmp(archName, "x86_64") == 0 )
-        return x86_64;
-#if SUPPORT_ARCH_arm64e
-    else if (strcmp(archName, "arm64e") == 0 )
-        return keysOff ? arm64e_keysoff : arm64e;
-#endif
-    else if (strcmp(archName, "arm64") == 0 )
-        return arm64;
-    else if (strcmp(archName, "armv7k") == 0 )
-        return armv7k;
-    else if (strcmp(archName, "armv7s") == 0 )
-        return armv7s;
-    else if (strcmp(archName, "armv7") == 0 )
-        return armv7;
-#if SUPPORT_ARCH_arm64_32
-    else if (strcmp(archName, "arm64_32") == 0 )
-        return arm64_32;
-#endif
-    else if (strcmp(archName, "i386") == 0 )
-        return i386;
-    assert(0 && "unknown arch name");
-}
-
-
-
-////////////////////////////  MachOFile ////////////////////////////////////////
-
-
-const MachOFile::ArchInfo MachOFile::_s_archInfos[] = {
-    { "x86_64",   CPU_TYPE_X86_64,   CPU_SUBTYPE_X86_64_ALL  },
-    { "x86_64h",  CPU_TYPE_X86_64,   CPU_SUBTYPE_X86_64_H    },
-    { "i386",     CPU_TYPE_I386,     CPU_SUBTYPE_I386_ALL    },
-    { "arm64",    CPU_TYPE_ARM64,    CPU_SUBTYPE_ARM64_ALL   },
-#if SUPPORT_ARCH_arm64e
-    { "arm64e",   CPU_TYPE_ARM64,    CPU_SUBTYPE_ARM64E     },
-#endif
-#if SUPPORT_ARCH_arm64_32
-    { "arm64_32", CPU_TYPE_ARM64_32, CPU_SUBTYPE_ARM64_32_V8 },
-#endif
-    { "armv7k",   CPU_TYPE_ARM,      CPU_SUBTYPE_ARM_V7K     },
-    { "armv7s",   CPU_TYPE_ARM,      CPU_SUBTYPE_ARM_V7S     },
-    { "armv7",    CPU_TYPE_ARM,      CPU_SUBTYPE_ARM_V7      }
-};
-
-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        },
-};
-
-
-
-bool MachOFile::is64() const
-{
-    return (this->magic == MH_MAGIC_64);
-}
-
-size_t MachOFile::machHeaderSize() const
-{
-    return is64() ? sizeof(mach_header_64) : sizeof(mach_header);
-}
-
-uint32_t MachOFile::maskedCpuSubtype() const
-{
-    return (this->cpusubtype & ~CPU_SUBTYPE_MASK);
-}
-
-uint32_t MachOFile::pointerSize() const
-{
-    if (this->magic == MH_MAGIC_64)
-        return 8;
-    else
-        return 4;
-}
-
-bool MachOFile::uses16KPages() const
-{
-    switch (this->cputype) {
-        case CPU_TYPE_ARM64:
-        case CPU_TYPE_ARM64_32:
-            return true;
-        case CPU_TYPE_ARM:
-            // iOS is 16k aligned for armv7/armv7s and watchOS armv7k is 16k aligned
-            return this->cpusubtype == CPU_SUBTYPE_ARM_V7K;
-        default:
-            return false;
-    }
-}
-
-bool MachOFile::isArch(const char* aName) const
-{
-    return (strcmp(aName, archName(this->cputype, this->cpusubtype)) == 0);
-}
-
-const char* MachOFile::archName(uint32_t cputype, uint32_t cpusubtype)
-{
-    for (const ArchInfo& info : _s_archInfos) {
-        if ( (cputype == info.cputype) && ((cpusubtype & ~CPU_SUBTYPE_MASK) == info.cpusubtype) ) {
-            return info.name;
-        }
-    }
-    return "unknown";
-}
-
-uint32_t MachOFile::cpuTypeFromArchName(const char* archName)
-{
-    for (const ArchInfo& info : _s_archInfos) {
-        if ( strcmp(archName, info.name) == 0 ) {
-            return info.cputype;
-        }
-    }
-    return 0;
-}
-
-uint32_t MachOFile::cpuSubtypeFromArchName(const char* archName)
-{
-    for (const ArchInfo& info : _s_archInfos) {
-        if ( strcmp(archName, info.name) == 0 ) {
-            return info.cpusubtype;
-        }
-    }
-    return 0;
-}
-
-const char* MachOFile::archName() const
-{
-    return archName(this->cputype, this->cpusubtype);
-}
-
-static void appendDigit(char*& s, unsigned& num, unsigned place, bool& startedPrinting)
-{
-    if ( num >= place ) {
-        unsigned dig = (num/place);
-        *s++ = '0' + dig;
-        num -= (dig*place);
-        startedPrinting = true;
-    }
-    else if ( startedPrinting ) {
-        *s++ = '0';
-    }
-}
-
-static void appendNumber(char*& s, unsigned num)
-{
-    assert(num < 99999);
-    bool startedPrinting = false;
-    appendDigit(s, num, 10000, startedPrinting);
-    appendDigit(s, num,  1000, startedPrinting);
-    appendDigit(s, num,   100, startedPrinting);
-    appendDigit(s, num,    10, startedPrinting);
-    appendDigit(s, num,     1, startedPrinting);
-    if ( !startedPrinting )
-        *s++ = '0';
-}
-
-void MachOFile::packedVersionToString(uint32_t packedVersion, char versionString[32])
-{
-    // sprintf(versionString, "%d.%d.%d", (packedVersion >> 16), ((packedVersion >> 8) & 0xFF), (packedVersion & 0xFF));
-    char* s = versionString;
-    appendNumber(s, (packedVersion >> 16));
-    *s++ = '.';
-    appendNumber(s, (packedVersion >> 8) & 0xFF);
-    *s++ = '.';
-    appendNumber(s, (packedVersion & 0xFF));
-    *s++ = '\0';
-}
-
-bool MachOFile::builtForPlatform(Platform reqPlatform, bool onlyOnePlatform) const
-{
-    __block bool foundRequestedPlatform = false;
-    __block bool foundOtherPlatform     = false;
-    forEachSupportedPlatform(^(Platform platform, uint32_t minOS, uint32_t sdk) {
-        if ( platform == reqPlatform )
-            foundRequestedPlatform = true;
-        else
-            foundOtherPlatform = true;
-    });
-    // if checking that this binary is built for exactly one platform, fail if more
-    if ( foundOtherPlatform && onlyOnePlatform )
-        return false;
-    if ( foundRequestedPlatform )
-        return true;
-
-    // binary has no explict load command to mark platform
-    // could be an old macOS binary, look at arch
-    if  ( !foundOtherPlatform && (reqPlatform == Platform::macOS) ) {
-        if ( this->cputype == CPU_TYPE_X86_64 )
-            return true;
-        if ( this->cputype == CPU_TYPE_I386 )
-            return true;
-    }
-
-#if BUILDING_DYLDINFO
-    // Allow offline tools to analyze binaries dyld doesn't load, ie, those with platforms
-    if ( !foundOtherPlatform && (reqPlatform == Platform::unknown) )
-        return true;
-#endif
-
-    return false;
-}
-
-bool MachOFile::loadableIntoProcess(Platform processPlatform, const char* path) const
-{
-    if ( this->builtForPlatform(processPlatform) )
-        return true;
-
-    // Some host macOS dylibs can be loaded into simulator processes
-    if ( MachOFile::isSimulatorPlatform(processPlatform) && this->builtForPlatform(Platform::macOS)) {
-        static const char* macOSHost[] = {
-            "/usr/lib/system/libsystem_kernel.dylib",
-            "/usr/lib/system/libsystem_platform.dylib",
-            "/usr/lib/system/libsystem_pthread.dylib",
-            "/usr/lib/system/libsystem_platform_debug.dylib",
-            "/usr/lib/system/libsystem_pthread_debug.dylib",
-            "/usr/lib/system/host/liblaunch_sim.dylib",
-        };
-        for (const char* libPath : macOSHost) {
-            if (strcmp(libPath, path) == 0)
-                return true;
-        }
-    }
-
-    // If this is being called on main executable where we expect a macOS program, Catalyst programs are also runnable
-    if ( (this->filetype == MH_EXECUTE) && (processPlatform == Platform::macOS) && this->builtForPlatform(Platform::iOSMac, true) )
-        return true;
-#if (TARGET_OS_OSX && TARGET_CPU_ARM64)
-    if ( (this->filetype == MH_EXECUTE) && (processPlatform == Platform::macOS) && this->builtForPlatform(Platform::iOS, true) )
-        return true;
-#endif
-
-    bool iOSonMac = (processPlatform == Platform::iOSMac);
-#if (TARGET_OS_OSX && TARGET_CPU_ARM64)
-    // allow iOS binaries in iOSApp
-    if ( processPlatform == Platform::iOS ) {
-        // can load Catalyst binaries into iOS process
-        if ( this->builtForPlatform(Platform::iOSMac) )
-            return true;
-        iOSonMac = true;
-    }
-#endif
-    // macOS dylibs can be loaded into iOSMac processes
-    if ( (iOSonMac) && this->builtForPlatform(Platform::macOS, true) )
-        return true;
-
-    return false;
-}
-
-bool MachOFile::isZippered() const
-{
-    __block bool macOS = false;
-    __block bool iOSMac = false;
-    forEachSupportedPlatform(^(Platform platform, uint32_t minOS, uint32_t sdk) {
-        if ( platform == Platform::macOS )
-            macOS = true;
-        else if ( platform == Platform::iOSMac )
-            iOSMac = true;
-    });
-    return macOS && iOSMac;
-}
-
-bool MachOFile::inDyldCache() const {
-    return (this->flags & 0x80000000);
-}
-
-Platform MachOFile::currentPlatform()
-{
-
-#if TARGET_OS_SIMULATOR
-#if TARGET_OS_WATCH
-    return Platform::watchOS_simulator;
-#elif TARGET_OS_TV
-    return Platform::tvOS_simulator;
-#else
-    return Platform::iOS_simulator;
-#endif
-#elif TARGET_OS_BRIDGE
-    return Platform::bridgeOS;
-#elif TARGET_OS_WATCH
-    return Platform::watchOS;
-#elif TARGET_OS_TV
-    return Platform::tvOS;
-#elif TARGET_OS_IOS
-    return Platform::iOS;
-#elif TARGET_OS_OSX
-    return Platform::macOS;
-#elif TARGET_OS_DRIVERKIT
-    return Platform::driverKit;
-#else
-    #error unknown platform
-#endif
-}
-
 
 const char* MachOFile::currentArchName()
 {
@@ -628,12 +369,6 @@
 #endif
 }
 
-bool MachOFile::isSimulatorPlatform(Platform platform)
-{
-    return ( (platform == Platform::iOS_simulator) ||
-             (platform == Platform::watchOS_simulator) ||
-             (platform == Platform::tvOS_simulator) );
-}
 
 bool MachOFile::isDylib() const
 {
@@ -656,36 +391,20 @@
         return false;
 
     // static executables do not have dyld load command
-    return hasLoadCommand(LC_LOAD_DYLINKER);
-}
-
-bool MachOFile::isStaticExecutable() const
-{
-    if ( this->filetype != MH_EXECUTE )
-        return false;
-
-    // static executables do not have dyld load command
-    return !hasLoadCommand(LC_LOAD_DYLINKER);
-}
-
-bool MachOFile::isKextBundle() const
-{
-    return (this->filetype == MH_KEXT_BUNDLE);
-}
-
-bool MachOFile::isFileSet() const
-{
-    return (this->filetype == MH_FILESET);
+    __block bool hasDyldLoad = false;
+    Diagnostics diag;
+    forEachLoadCommand(diag, ^(const load_command* cmd, bool& stop) {
+        if ( cmd->cmd == LC_LOAD_DYLINKER ) {
+            hasDyldLoad = true;
+            stop = true;
+        }
+    });
+    return hasDyldLoad;
 }
 
 bool MachOFile::isPIE() const
 {
     return (this->flags & MH_PIE);
-}
-
-bool MachOFile::isPreload() const
-{
-    return (this->filetype == MH_PRELOAD);
 }
 
 const char* MachOFile::platformName(Platform reqPlatform)
@@ -737,12 +456,10 @@
 bool MachOFile::isMachO(Diagnostics& diag, uint64_t fileSize) const
 {
     if ( !hasMachOMagic() ) {
-        // old PPC slices are not currently valid "mach-o" but should not cause an error
-        if ( !hasMachOBigEndianMagic() )
-            diag.error("file does not start with MH_MAGIC[_64]");
+        diag.error("file does not start with MH_MAGIC[_64]");
         return false;
     }
-    if ( this->sizeofcmds + machHeaderSize() > fileSize ) {
+    if ( this->sizeofcmds + sizeof(mach_header_64) > fileSize ) {
         diag.error("load commands exceed length of first segment");
         return false;
     }
@@ -754,12 +471,6 @@
 {
     return ( (this->magic == MH_MAGIC) || (this->magic == MH_MAGIC_64) );
 }
-
-bool MachOFile::hasMachOBigEndianMagic() const
-{
-    return ( (this->magic == MH_CIGAM) || (this->magic == MH_CIGAM_64) );
-}
-
 
 void MachOFile::forEachLoadCommand(Diagnostics& diag, void (^callback)(const load_command* cmd, bool& stop)) const
 {
@@ -769,11 +480,8 @@
         startCmds = (load_command*)((char *)this + sizeof(mach_header_64));
     else if ( this->magic == MH_MAGIC )
         startCmds = (load_command*)((char *)this + sizeof(mach_header));
-    else if ( hasMachOBigEndianMagic() )
-        return;  // can't process big endian mach-o
     else {
-        const uint32_t* h = (uint32_t*)this;
-        diag.error("file does not start with MH_MAGIC[_64]: 0x%08X 0x%08X", h[0], h [1]);
+        diag.error("file does not start with MH_MAGIC[_64]");
         return;  // not a mach-o file
     }
     const load_command* const cmdsEnd = (load_command*)((char*)startCmds + this->sizeofcmds);
@@ -781,11 +489,11 @@
     for (uint32_t i = 0; i < this->ncmds; ++i) {
         const load_command* nextCmd = (load_command*)((char *)cmd + cmd->cmdsize);
         if ( cmd->cmdsize < 8 ) {
-            diag.error("malformed load command #%d of %d at %p with mh=%p, size (0x%X) too small", i, this->ncmds, cmd, this, cmd->cmdsize);
+            diag.error("malformed load command #%d, size too small %d", i, cmd->cmdsize);
             return;
         }
         if ( (nextCmd > cmdsEnd) || (nextCmd < startCmds) ) {
-            diag.error("malformed load command #%d of %d at %p with mh=%p, size (0x%X) is too large, load commands end at %p", i, this->ncmds, cmd, this, cmd->cmdsize, cmdsEnd);
+            diag.error("malformed load command #%d, size too large 0x%X", i, cmd->cmdsize);
             return;
         }
         callback(cmd, stop);
@@ -793,52 +501,6 @@
             return;
         cmd = nextCmd;
     }
-}
-
-void MachOFile::removeLoadCommand(Diagnostics& diag, void (^callback)(const load_command* cmd, bool& remove, bool& stop))
-{
-    bool stop = false;
-    const load_command* startCmds = nullptr;
-    if ( this->magic == MH_MAGIC_64 )
-        startCmds = (load_command*)((char *)this + sizeof(mach_header_64));
-    else if ( this->magic == MH_MAGIC )
-        startCmds = (load_command*)((char *)this + sizeof(mach_header));
-    else if ( hasMachOBigEndianMagic() )
-        return;  // can't process big endian mach-o
-    else {
-        const uint32_t* h = (uint32_t*)this;
-        diag.error("file does not start with MH_MAGIC[_64]: 0x%08X 0x%08X", h[0], h [1]);
-        return;  // not a mach-o file
-    }
-    const load_command* const cmdsEnd = (load_command*)((char*)startCmds + this->sizeofcmds);
-    auto cmd = (load_command*)startCmds;
-    const uint32_t origNcmds = this->ncmds;
-    unsigned bytesRemaining = this->sizeofcmds;
-    for (uint32_t i = 0; i < origNcmds; ++i) {
-        bool remove = false;
-        auto nextCmd = (load_command*)((char *)cmd + cmd->cmdsize);
-        if ( cmd->cmdsize < 8 ) {
-            diag.error("malformed load command #%d of %d at %p with mh=%p, size (0x%X) too small", i, this->ncmds, cmd, this, cmd->cmdsize);
-            return;
-        }
-        if ( (nextCmd > cmdsEnd) || (nextCmd < startCmds) ) {
-            diag.error("malformed load command #%d of %d at %p with mh=%p, size (0x%X) is too large, load commands end at %p", i, this->ncmds, cmd, this, cmd->cmdsize, cmdsEnd);
-            return;
-        }
-        callback(cmd, remove, stop);
-        if ( remove ) {
-            this->sizeofcmds -= cmd->cmdsize;
-            ::memmove((void*)cmd, (void*)nextCmd, bytesRemaining);
-            this->ncmds--;
-        } else {
-            bytesRemaining -= cmd->cmdsize;
-            cmd = nextCmd;
-        }
-        if ( stop )
-            break;
-    }
-    if ( cmd )
-     ::bzero(cmd, bytesRemaining);
 }
 
 const char* MachOFile::installName() const
@@ -953,7 +615,6 @@
                 if ( minOS >= 0x00030000 )  // bridgeOS 3.0
                     result = false;
                 break;
-            case Platform::driverKit:
             case Platform::iOSMac:
                 result = false;
                 break;
@@ -962,48 +623,6 @@
         }
     });
     return result;
-}
-
-const thread_command* MachOFile::unixThreadLoadCommand() const {
-    Diagnostics diag;
-    __block const thread_command* command = nullptr;
-    forEachLoadCommand(diag, ^(const load_command* cmd, bool& stop) {
-        if ( cmd->cmd == LC_UNIXTHREAD ) {
-            command = (const thread_command*)cmd;
-            stop = true;
-        }
-    });
-    return command;
-}
-
-
-uint32_t MachOFile::entryAddrRegisterIndexForThreadCmd() const
-{
-    switch ( this->cputype ) {
-        case CPU_TYPE_I386:
-            return 10; // i386_thread_state_t.eip
-        case CPU_TYPE_X86_64:
-            return 16; // x86_thread_state64_t.rip
-        case CPU_TYPE_ARM:
-            return 15; // arm_thread_state_t.pc
-        case CPU_TYPE_ARM64:
-            return 32; // arm_thread_state64_t.__pc
-    }
-    return ~0U;
-}
-
-
-uint64_t MachOFile::entryAddrFromThreadCmd(const thread_command* cmd) const
-{
-    assert(cmd->cmd == LC_UNIXTHREAD);
-    const uint32_t* regs32 = (uint32_t*)(((char*)cmd) + 16);
-    const uint64_t* regs64 = (uint64_t*)(((char*)cmd) + 16);
-
-    uint32_t index = entryAddrRegisterIndexForThreadCmd();
-    if (index == ~0U)
-        return 0;
-
-    return is64() ? regs64[index] : regs32[index];
 }
 
 
@@ -1031,11 +650,8 @@
             info.vmSize            = segCmd->vmsize;
             info.sizeOfSections    = sizeOfSections;
             info.segName           = segCmd->segname;
-            info.loadCommandOffset = (uint32_t)((uint8_t*)segCmd - (uint8_t*)this);
             info.protections       = segCmd->initprot;
             info.textRelocs        = false;
-            info.readOnlyData      = ((segCmd->flags & SG_READ_ONLY) != 0);
-            info.isProtected       = (segCmd->flags & SG_PROTECTED_VERSION_1) ? 1 : 0;
             info.p2align           = p2align;
             info.segIndex          = segIndex;
             callback(info, stop);
@@ -1062,11 +678,8 @@
             info.vmSize            = segCmd->vmsize;
             info.sizeOfSections    = sizeOfSections;
             info.segName           = segCmd->segname;
-            info.loadCommandOffset = (uint32_t)((uint8_t*)segCmd - (uint8_t*)this);
             info.protections       = segCmd->initprot;
             info.textRelocs        = intel32 && !info.writable() && hasTextRelocs;
-            info.readOnlyData      = ((segCmd->flags & SG_READ_ONLY) != 0);
-            info.isProtected       = (segCmd->flags & SG_PROTECTED_VERSION_1) ? 1 : 0;
             info.p2align           = p2align;
             info.segIndex          = segIndex;
             callback(info, stop);
@@ -1079,7 +692,6 @@
 void MachOFile::forEachSection(void (^callback)(const SectionInfo& sectInfo, bool malformedSectionRange, bool& stop)) const
 {
     Diagnostics diag;
-    BLOCK_ACCCESSIBLE_ARRAY(char, sectNameCopy, 20);  // read as:  char sectNameCopy[20];
     const bool intel32 = (this->cputype == CPU_TYPE_I386);
     __block uint32_t segIndex = 0;
     forEachLoadCommand(diag, ^(const load_command* cmd, bool& stop) {
@@ -1101,15 +713,13 @@
             sectInfo.segInfo.vmSize            = segCmd->vmsize;
             sectInfo.segInfo.sizeOfSections    = sizeOfSections;
             sectInfo.segInfo.segName           = segCmd->segname;
-            sectInfo.segInfo.loadCommandOffset = (uint32_t)((uint8_t*)segCmd - (uint8_t*)this);
             sectInfo.segInfo.protections       = segCmd->initprot;
             sectInfo.segInfo.textRelocs        = false;
-            sectInfo.segInfo.readOnlyData      = ((segCmd->flags & SG_READ_ONLY) != 0);
-            sectInfo.segInfo.isProtected       = (segCmd->flags & SG_PROTECTED_VERSION_1) ? 1 : 0;
             sectInfo.segInfo.p2align           = p2align;
             sectInfo.segInfo.segIndex          = segIndex;
             for (const section_64* sect=sectionsStart; !stop && (sect < sectionsEnd); ++sect) {
                 const char* sectName = sect->sectname;
+                char sectNameCopy[20];
                 if ( sectName[15] != '\0' ) {
                     strlcpy(sectNameCopy, sectName, 17);
                     sectName = sectNameCopy;
@@ -1147,15 +757,13 @@
             sectInfo.segInfo.vmSize            = segCmd->vmsize;
             sectInfo.segInfo.sizeOfSections    = sizeOfSections;
             sectInfo.segInfo.segName           = segCmd->segname;
-            sectInfo.segInfo.loadCommandOffset = (uint32_t)((uint8_t*)segCmd - (uint8_t*)this);
             sectInfo.segInfo.protections       = segCmd->initprot;
             sectInfo.segInfo.textRelocs        = intel32 && !sectInfo.segInfo.writable() && hasTextRelocs;
-            sectInfo.segInfo.readOnlyData      = ((segCmd->flags & SG_READ_ONLY) != 0);
-            sectInfo.segInfo.isProtected       = (segCmd->flags & SG_PROTECTED_VERSION_1) ? 1 : 0;
             sectInfo.segInfo.p2align           = p2align;
             sectInfo.segInfo.segIndex          = segIndex;
             for (const section* sect=sectionsStart; !stop && (sect < sectionsEnd); ++sect) {
                 const char* sectName = sect->sectname;
+                char sectNameCopy[20];
                 if ( sectName[15] != '\0' ) {
                     strlcpy(sectNameCopy, sectName, 17);
                     sectName = sectNameCopy;
@@ -1196,108 +804,8 @@
     return (strcmp(&str[strLen-suffixLen], suffix) == 0);
 }
 
-bool MachOFile::isSharedCacheEligiblePath(const char* dylibName) {
-    return (   (strncmp(dylibName, "/usr/lib/", 9) == 0)
-            || (strncmp(dylibName, "/System/Library/", 16) == 0)
-            || (strncmp(dylibName, "/System/iOSSupport/usr/lib/", 27) == 0)
-            || (strncmp(dylibName, "/System/iOSSupport/System/Library/", 34) == 0)
-            || (strncmp(dylibName, "/Library/Apple/usr/lib/", 23) == 0)
-            || (strncmp(dylibName, "/Library/Apple/System/Library/", 30) == 0) );
-}
-
-static bool startsWith(const char* buffer, const char* valueToFind) {
-    return strncmp(buffer, valueToFind, strlen(valueToFind)) == 0;
-}
-
-static bool platformExcludesSharedCache_macOS(const char* installName) {
-    // Note: This function basically matches dontCache() from update dyld shared cache
-
-    if ( startsWith(installName, "/usr/lib/system/introspection/") )
-        return true;
-    if ( startsWith(installName, "/System/Library/QuickTime/") )
-        return true;
-    if ( startsWith(installName, "/System/Library/Tcl/") )
-        return true;
-    if ( startsWith(installName, "/System/Library/Perl/") )
-        return true;
-    if ( startsWith(installName, "/System/Library/MonitorPanels/") )
-        return true;
-    if ( startsWith(installName, "/System/Library/Accessibility/") )
-        return true;
-    if ( startsWith(installName, "/usr/local/") )
-        return true;
-    if ( startsWith(installName, "/usr/lib/pam/") )
-        return true;
-    // We no longer support ROSP, so skip all paths which start with the special prefix
-    if ( startsWith(installName, "/System/Library/Templates/Data/") )
-        return true;
-
-    // anything inside a .app bundle is specific to app, so should not be in shared cache
-    if ( strstr(installName, ".app/") != NULL )
-        return true;
-
-    return false;
-}
-
-static bool platformExcludesSharedCache_iOS(const char* installName) {
-    if ( strcmp(installName, "/System/Library/Caches/com.apple.xpc/sdk.dylib") == 0 )
-        return true;
-    if ( strcmp(installName, "/System/Library/Caches/com.apple.xpcd/xpcd_cache.dylib") == 0 )
-        return true;
-    return false;
-}
-
-static bool platformExcludesSharedCache_tvOS(const char* installName) {
-    return platformExcludesSharedCache_iOS(installName);
-}
-
-static bool platformExcludesSharedCache_watchOS(const char* installName) {
-    return platformExcludesSharedCache_iOS(installName);
-}
-
-static bool platformExcludesSharedCache_bridgeOS(const char* installName) {
-    return platformExcludesSharedCache_iOS(installName);
-}
-
-// 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) {
-    switch (platform) {
-        case dyld3::Platform::unknown:
-            return false;
-        case dyld3::Platform::macOS:
-            return platformExcludesSharedCache_macOS(installName);
-        case dyld3::Platform::iOS:
-            return platformExcludesSharedCache_iOS(installName);
-        case dyld3::Platform::tvOS:
-            return platformExcludesSharedCache_tvOS(installName);
-        case dyld3::Platform::watchOS:
-            return platformExcludesSharedCache_watchOS(installName);
-        case dyld3::Platform::bridgeOS:
-            return platformExcludesSharedCache_bridgeOS(installName);
-        case dyld3::Platform::iOSMac:
-            return platformExcludesSharedCache_macOS(installName);
-        case dyld3::Platform::iOS_simulator:
-            return false;
-        case dyld3::Platform::tvOS_simulator:
-            return false;
-        case dyld3::Platform::watchOS_simulator:
-            return false;
-        case dyld3::Platform::driverKit:
-            return false;
-    }
-}
-
-
-
 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.
-        return false;
-    }
-
     // only dylibs can go in cache
     if ( this->filetype != MH_DYLIB ) {
         failureReason("Not MH_DYLIB");
@@ -1305,41 +813,16 @@
     }
 
     // only dylibs built for /usr/lib or /System/Library can go in cache
-
+    bool retval = true;
     const char* dylibName = installName();
     if ( dylibName[0] != '/' ) {
+        retval = false;
         failureReason("install name not an absolute path");
-        // Don't continue as we don't want to spam the log with errors we don't need.
-        return false;
-    }
-    else if ( strcmp(dylibName, path) != 0 ) {
-        failureReason("install path does not match install name");
-        return false;
-    }
-    else if ( strstr(dylibName, "//") != 0 ) {
-        failureReason("install name should not include //");
-        return false;
-    }
-    else if ( strstr(dylibName, "./") != 0 ) {
-        failureReason("install name should not include ./");
-        return false;
-    }
-
-    __block bool platformExcludedFile = false;
-    forEachSupportedPlatform(^(Platform platform, uint32_t minOS, uint32_t sdk) {
-        if ( platformExcludedFile )
-            return;
-        if ( platformExcludesSharedCache(platform, dylibName) ) {
-            platformExcludedFile = true;
-            return;
-        }
-    });
-    if ( platformExcludedFile ) {
-        failureReason("install name is not shared cache eligible on platform");
-        return false;
-    }
-
-    bool retval = true;
+    }
+    else if ( (strncmp(dylibName, "/usr/lib/", 9) != 0) && (strncmp(dylibName, "/System/Library/", 16) != 0) ) {
+        retval = false;
+        failureReason("Not in '/usr/lib/' or '/System/Library/'");
+    }
 
     // flat namespace files cannot go in cache
     if ( (this->flags & MH_TWOLEVEL) == 0 ) {
@@ -1356,36 +839,26 @@
     // dylib must have extra info for moving DATA and TEXT segments apart
     __block bool hasExtraInfo = false;
     __block bool hasDyldInfo = false;
-    __block bool hasExportTrie = false;
-    __block bool hasLazyLoad = false;
     Diagnostics diag;
     forEachLoadCommand(diag, ^(const load_command* cmd, bool& stop) {
         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 )
-            hasExportTrie = true;
-        if ( cmd->cmd == LC_LAZY_LOAD_DYLIB )
-            hasLazyLoad = true;
     });
     if ( !hasExtraInfo ) {
         retval = false;
         failureReason("Missing split seg info");
     }
-    if ( !hasDyldInfo && !hasExportTrie ) {
+    if ( !hasDyldInfo ) {
         retval = false;
-        failureReason("Old binary, missing dyld info or export trie");
-    }
-    if ( hasLazyLoad ) {
-        retval = false;
-        failureReason("Has lazy load");
+        failureReason("Old binary, missing dyld info");
     }
 
     // dylib can only depend on other dylibs in the shared cache
     __block bool allDepPathsAreGood = true;
     forEachDependentDylib(^(const char* loadPath, bool isWeak, bool isReExport, bool isUpward, uint32_t compatVersion, uint32_t curVersion, bool& stop) {
-        if ( !isSharedCacheEligiblePath(loadPath) ) {
+        if ( (strncmp(loadPath, "/usr/lib/", 9) != 0) && (strncmp(loadPath, "/System/Library/", 16) != 0) ) {
             allDepPathsAreGood = false;
             stop = true;
         }
@@ -1393,103 +866,6 @@
     if ( !allDepPathsAreGood ) {
         retval = false;
         failureReason("Depends on dylibs ineligable for dyld cache");
-    }
-
-    // dylibs with interposing info cannot be in cache
-    if ( hasInterposingTuples() ) {
-        retval = false;
-        failureReason("Has interposing tuples");
-    }
-
-    // Temporarily kick out swift binaries out of dyld cache on watchOS simulators as they have missing split seg
-    if ( (this->cputype == CPU_TYPE_I386) && builtForPlatform(Platform::watchOS_simulator) ) {
-        if ( strncmp(dylibName, "/usr/lib/swift/", 15) == 0 ) {
-            retval = false;
-            failureReason("i386 swift binary");
-        }
-    }
-
-    return retval;
-}
-
-#if BUILDING_APP_CACHE_UTIL
-bool MachOFile::canBePlacedInKernelCollection(const char* path, void (^failureReason)(const char*)) const
-{
-    // only dylibs and the kernel itself can go in cache
-    if ( this->filetype == MH_EXECUTE ) {
-        // xnu
-    } else if ( this->isKextBundle() ) {
-        // kext's
-    } else {
-        failureReason("Not MH_KEXT_BUNDLE");
-        return false;
-    }
-
-    if ( this->filetype == MH_EXECUTE ) {
-        // xnu
-
-        // two-level namespace binaries cannot go in cache
-        if ( (this->flags & MH_TWOLEVEL) != 0 ) {
-            failureReason("Built with two level namespaces");
-            return false;
-        }
-
-        // xnu kernel cannot have a page zero
-        __block bool foundPageZero = false;
-        forEachSegment(^(const SegmentInfo &segmentInfo, bool &stop) {
-            if ( strcmp(segmentInfo.segName, "__PAGEZERO") == 0 ) {
-                foundPageZero = true;
-                stop = true;
-            }
-        });
-        if (foundPageZero) {
-            failureReason("Has __PAGEZERO");
-            return false;
-        }
-
-        // xnu must have an LC_UNIXTHREAD to point to the entry point
-        __block bool foundMainLC = false;
-        __block bool foundUnixThreadLC = false;
-        Diagnostics diag;
-        forEachLoadCommand(diag, ^(const load_command* cmd, bool& stop) {
-            if ( cmd->cmd == LC_MAIN ) {
-                foundMainLC = true;
-                stop = true;
-            }
-            else if ( cmd->cmd == LC_UNIXTHREAD ) {
-                foundUnixThreadLC = true;
-            }
-        });
-        if (foundMainLC) {
-            failureReason("Found LC_MAIN");
-            return false;
-        }
-        if (!foundUnixThreadLC) {
-            failureReason("Expected LC_UNIXTHREAD");
-            return false;
-        }
-
-        if (diag.hasError()) {
-            failureReason("Error parsing load commands");
-            return false;
-        }
-
-        // The kernel should be a static executable, not a dynamic one
-        if ( !isStaticExecutable() ) {
-            failureReason("Expected static executable");
-            return false;
-        }
-
-        // The kernel must be built with -pie
-        if ( !isPIE() ) {
-            failureReason("Expected pie");
-            return false;
-        }
-    }
-
-    if ( isArch("arm64e") && isKextBundle() && !hasChainedFixups() ) {
-        failureReason("Missing fixup information");
-        return false;
     }
 
     // dylibs with interposing info cannot be in cache
@@ -1499,142 +875,13 @@
             hasInterposing = true;
     });
     if ( hasInterposing ) {
+        retval = false;
         failureReason("Has interposing tuples");
-        return false;
-    }
-
-    return true;
-}
-#endif
-
-static bool platformExcludesPrebuiltClosure_macOS(const char* path) {
-    // We no longer support ROSP, so skip all paths which start with the special prefix
-    if ( startsWith(path, "/System/Library/Templates/Data/") )
-        return true;
-
-    // anything inside a .app bundle is specific to app, so should not get a prebuilt closure
-    if ( strstr(path, ".app/") != NULL )
-        return true;
-
-    return false;
-}
-
-static bool platformExcludesPrebuiltClosure_iOS(const char* path) {
-    if ( strcmp(path, "/System/Library/Caches/com.apple.xpc/sdk.dylib") == 0 )
-        return true;
-    if ( strcmp(path, "/System/Library/Caches/com.apple.xpcd/xpcd_cache.dylib") == 0 )
-        return true;
-    return false;
-}
-
-static bool platformExcludesPrebuiltClosure_tvOS(const char* path) {
-    return platformExcludesPrebuiltClosure_iOS(path);
-}
-
-static bool platformExcludesPrebuiltClosure_watchOS(const char* path) {
-    return platformExcludesPrebuiltClosure_iOS(path);
-}
-
-static bool platformExcludesPrebuiltClosure_bridgeOS(const char* path) {
-    return platformExcludesPrebuiltClosure_iOS(path);
-}
-
-// 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 platformExcludesPrebuiltClosure(Platform platform, const char* path) {
-    switch (platform) {
-        case dyld3::Platform::unknown:
-            return false;
-        case dyld3::Platform::macOS:
-            return platformExcludesPrebuiltClosure_macOS(path);
-        case dyld3::Platform::iOS:
-            return platformExcludesPrebuiltClosure_iOS(path);
-        case dyld3::Platform::tvOS:
-            return platformExcludesPrebuiltClosure_tvOS(path);
-        case dyld3::Platform::watchOS:
-            return platformExcludesPrebuiltClosure_watchOS(path);
-        case dyld3::Platform::bridgeOS:
-            return platformExcludesPrebuiltClosure_bridgeOS(path);
-        case dyld3::Platform::iOSMac:
-            return platformExcludesPrebuiltClosure_macOS(path);
-        case dyld3::Platform::iOS_simulator:
-            return false;
-        case dyld3::Platform::tvOS_simulator:
-            return false;
-        case dyld3::Platform::watchOS_simulator:
-            return false;
-        case dyld3::Platform::driverKit:
-            return false;
-    }
-}
-
-bool MachOFile::canHavePrecomputedDlopenClosure(const char* path, void (^failureReason)(const char*)) const
-{
-    __block bool retval = true;
-
-    // only dylibs can go in cache
-    if ( (this->filetype != MH_DYLIB) && (this->filetype != MH_BUNDLE) ) {
-        retval = false;
-        failureReason("not MH_DYLIB or MH_BUNDLE");
-    }
-
-    // flat namespace files cannot go in cache
-    if ( (this->flags & MH_TWOLEVEL) == 0 ) {
-        retval = false;
-        failureReason("not built with two level namespaces");
-    }
-
-    // can only depend on other dylibs with absolute paths
-    __block bool allDepPathsAreGood = true;
-    forEachDependentDylib(^(const char* loadPath, bool isWeak, bool isReExport, bool isUpward, uint32_t compatVersion, uint32_t curVersion, bool& stop) {
-        if ( loadPath[0] != '/' ) {
-            allDepPathsAreGood = false;
-            stop = true;
-        }
-    });
-    if ( !allDepPathsAreGood ) {
-        retval = false;
-        failureReason("depends on dylibs that are not absolute paths");
-    }
-
-    __block bool platformExcludedFile = false;
-    forEachSupportedPlatform(^(Platform platform, uint32_t minOS, uint32_t sdk) {
-        if ( platformExcludedFile )
-            return;
-        if ( platformExcludesPrebuiltClosure(platform, path) ) {
-            platformExcludedFile = true;
-            return;
-        }
-    });
-    if ( platformExcludedFile ) {
-        failureReason("file cannot get a prebuilt closure on this platform");
-        return false;
-    }
-
-    // dylibs with interposing info cannot have dlopen closure pre-computed
-    if ( hasInterposingTuples() ) {
-        retval = false;
-        failureReason("has interposing tuples");
-    }
-
-    // special system dylib overrides cannot have closure pre-computed
-    if ( strncmp(path, "/usr/lib/system/introspection/", 30) == 0 ) {
-        retval = false;
-        failureReason("override of OS dylib");
     }
 
     return retval;
 }
 
-bool MachOFile::hasInterposingTuples() const
-{
-    __block bool hasInterposing = false;
-    forEachSection(^(const SectionInfo& info, bool malformedSectionRange, bool &stop) {
-        if ( ((info.sectFlags & SECTION_TYPE) == S_INTERPOSING) || ((strcmp(info.sectName, "__interpose") == 0) && (strcmp(info.segInfo.segName, "__DATA") == 0)) )
-            hasInterposing = true;
-    });
-    return hasInterposing;
-}
 
 bool MachOFile::isFairPlayEncrypted(uint32_t& textOffset, uint32_t& size) const
 {
@@ -1673,46 +920,14 @@
 }
 
 
-bool MachOFile::hasLoadCommand(uint32_t cmdNum) const
-{
-    __block bool hasLC = false;
-    Diagnostics diag;
-    forEachLoadCommand(diag, ^(const load_command* cmd, bool& stop) {
-        if ( cmd->cmd == cmdNum ) {
-            hasLC = true;
-            stop = true;
-        }
-    });
-    return hasLC;
-}
-
-bool MachOFile::allowsAlternatePlatform() const
-{
-    __block bool result = false;
-    forEachSection(^(const SectionInfo& info, bool malformedSectionRange, bool& stop) {
-        if ( (strcmp(info.sectName, "__allow_alt_plat") == 0) && (strncmp(info.segInfo.segName, "__DATA", 6) == 0) ) {
-            result = true;
-            stop = true;
-        }
-    });
-    return result;
-}
-
 bool MachOFile::hasChainedFixups() const
 {
 #if SUPPORT_ARCH_arm64e
-    // arm64e always uses chained fixups
-    if ( (this->cputype == CPU_TYPE_ARM64) && (this->maskedCpuSubtype() == CPU_SUBTYPE_ARM64E) ) {
-        // Not all binaries have fixups at all so check for the load commands
-        return hasLoadCommand(LC_DYLD_INFO_ONLY) || hasLoadCommand(LC_DYLD_CHAINED_FIXUPS);
-    }
-#endif
-    return hasLoadCommand(LC_DYLD_CHAINED_FIXUPS);
-}
-
-bool MachOFile::hasChainedFixupsLoadCommand() const
-{
-    return hasLoadCommand(LC_DYLD_CHAINED_FIXUPS);
+    // for now only arm64e uses chained fixups
+    return ( strcmp(archName(), "arm64e") == 0 );
+#else
+    return false;
+#endif
 }
 
 uint64_t MachOFile::read_uleb128(Diagnostics& diag, const uint8_t*& p, const uint8_t* end)
@@ -1755,7 +970,7 @@
         bit += 7;
     } while (byte & 0x80);
     // sign extend negative numbers
-    if ( ((byte & 0x40) != 0) && (bit < 64) )
+    if ( (byte & 0x40) != 0 )
         result |= (~0ULL) << bit;
     return result;
 }