Loading...
common/MachOFile.cpp dyld-1042.1 dyld-1122.1
--- dyld/dyld-1042.1/common/MachOFile.cpp
+++ dyld/dyld-1122.1/common/MachOFile.cpp
@@ -24,23 +24,36 @@
 #include <stdlib.h>
 #include <assert.h>
 #include <string.h>
+#include <strings.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 "Defines.h"
+#if TARGET_OS_EXCLAVEKIT
+  #define OSSwapBigToHostInt32 __builtin_bswap32
+  #define OSSwapBigToHostInt64 __builtin_bswap64
+  #define htonl                __builtin_bswap32
+#else
+  #include <sys/stat.h>
+  #include <sys/types.h>
+  #include <sys/errno.h>
+  #include <sys/fcntl.h>
+  #include <unistd.h>
+  #include <mach/host_info.h>
+  #include <mach/mach.h>
+  #include <mach/mach_host.h>
+#if SUPPORT_CLASSIC_RELOCS
+  #include <mach-o/reloc.h>
+  #include <mach-o/x86_64/reloc.h>
+#endif
 extern "C" {
   #include <corecrypto/ccdigest.h>
   #include <corecrypto/ccsha1.h>
   #include <corecrypto/ccsha2.h>
 }
-#include <mach-o/reloc.h>
-#include <mach-o/x86_64/reloc.h>
+#endif
+
+#include "Defines.h"
+
 #include <mach-o/nlist.h>
 
 #include "Array.h"
@@ -48,13 +61,13 @@
 #include "SupportedArchs.h"
 #include "CodeSigningTypes.h"
 
-#if BUILDING_DYLD || BUILDING_LIBDYLD
-    // define away restrict until rdar://60166935 is fixed
-    #define restrict
+#if (BUILDING_DYLD || BUILDING_LIBDYLD) && !TARGET_OS_EXCLAVEKIT
     #include <subsystem.h>
 #endif
 
 namespace dyld3 {
+
+#if !TARGET_OS_EXCLAVEKIT
 
 ////////////////////////////  posix wrappers ////////////////////////////////////////
 
@@ -101,6 +114,7 @@
 
     return result;
 }
+#endif // !TARGET_OS_EXCLAVEKIT
 
 
 ////////////////////////////  FatFile ////////////////////////////////////////
@@ -640,7 +654,7 @@
     return false;
 }
 
-bool MachOFile::loadableIntoProcess(Platform processPlatform, const char* path) const
+bool MachOFile::loadableIntoProcess(Platform processPlatform, const char* path, bool internalInstall) const
 {
     if ( this->builtForPlatform(processPlatform) )
         return true;
@@ -1223,6 +1237,10 @@
     if ( (count == 0) && !stopped ) {
         // The dylibs that make up libSystem can link with nothing
         // except for dylibs in libSystem.dylib which are ok to link with nothing (they are on bottom)
+#if TARGET_OS_EXCLAVEKIT
+        if ( !this->isDylib() || (strncmp(this->installName(), "/System/ExclaveKit/usr/lib/system/", 34) != 0) )
+            callback("/System/ExclaveKit/usr/lib/libSystem.dylib", false, false, false, 0x00010000, 0x00010000, stopped);
+#else
         if ( this->builtForPlatform(Platform::driverKit, true) ) {
             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);
@@ -1231,8 +1249,9 @@
             if ( !this->isDylib() || (strncmp(this->installName(), "/usr/lib/system/", 16) != 0) )
                 callback("/usr/lib/libSystem.B.dylib", false, false, false, 0x00010000, 0x00010000, stopped);
         }
-    }
-#endif
+#endif // TARGET_OS_EXCLAVEKIT
+    }
+#endif // !BUILDING_SHARED_CACHE_UTIL && !BUILDING_DYLDINFO && !BUILDING_UNIT_TESTS
     diag.assertNoError();   // any malformations in the file should have been caught by earlier validate() call
 }
 
@@ -1698,6 +1717,12 @@
         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;
 }
 
@@ -1870,18 +1895,19 @@
         }
 
         // <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)
         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
-                if ( addend > 31 ) {
-                    addendTooLarge = true;
-                    stop = true;
-                }
+                targetAddends.push_back(addend);
             });
             // check each pointer for embedded addend
             fixups.withChainStarts(diag, ^(const dyld_chained_starts_in_image* starts) {
@@ -1889,26 +1915,60 @@
                     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.bind.bind && !fixupLoc->arm64e.authBind.auth ) {
-                                if ( fixupLoc->arm64e.bind.addend > 31 ) {
+                            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_64:
-                        case DYLD_CHAINED_PTR_64_OFFSET:
-                            if ( fixupLoc->generic64.rebase.bind ) {
-                                if ( fixupLoc->generic64.bind.addend > 31 ) {
-                                    addendTooLarge = true;
-                                    stop = true;
-                                }
-                            }
-                            break;
+                        }
                         case DYLD_CHAINED_PTR_32:
                             if ( fixupLoc->generic32.bind.bind ) {
-                                if ( fixupLoc->generic32.bind.addend > 31 ) {
+                                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;
                                 }
@@ -1924,7 +1984,7 @@
                 uint64_t addend = info.addend;
                 if ( is64bit )
                     addend &= 0x00FFFFFFFFFFFFFF; // ignore TBI
-                if ( addend > 31 ) {
+                if ( addend >= tooLargeRegularAddend ) {
                     addendTooLarge = true;
                     stop = true;
                 }
@@ -1985,6 +2045,33 @@
             }
 
             if ( !rebasesOk )
+                return;
+        }
+
+        // Check that shared cache dylibs don't use undefined lookup
+        {
+            __block bool bindsOk = true;
+
+            auto checkBind = ^(int libOrdinal, bool& stop) {
+                if ( libOrdinal == BIND_SPECIAL_DYLIB_FLAT_LOOKUP ) {
+                    failureReason("has dynamic_lookup binds");
+                    bindsOk = false;
+                    stop = true;
+                }
+            };
+
+            if (hasChainedFixups()) {
+                fixups.forEachChainedFixupTarget(diag, ^(int libOrdinal, const char* symbolName, uint64_t addend, bool weakImport, bool& stop) {
+                    checkBind(libOrdinal, stop);
+                });
+            } else {
+                auto handler = ^(const mach_o::Fixups::BindTargetInfo &info, bool &stop) {
+                    checkBind(info.libOrdinal, stop);
+                };
+                fixups.forEachBindTarget_Opcodes(diag, true, handler, handler);
+            }
+
+            if ( !bindsOk )
                 return;
         }
 
@@ -2614,12 +2701,12 @@
     buffer[0] = '\0';
     archs.forEachArch(isOSBinary, ^(const char* archName) {
         if ( buffer[0] != '\0' )
-            strcat(buffer, "' or '");
-        strcat(buffer, archName);
-    });
-}
-
-const MachOFile* MachOFile::compatibleSlice(Diagnostics& diag, const void* fileContent, size_t contentSize, const char* path, Platform platform, bool isOSBinary, const GradedArchs& archs)
+            strlcat(buffer, "' or '", 256);
+        strlcat(buffer, archName, 256);
+    });
+}
+
+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) ) {
@@ -2655,7 +2742,7 @@
         return nullptr;
     }
 
-    if ( !mf->loadableIntoProcess(platform, path) ) {
+    if ( !mf->loadableIntoProcess(platform, path, internalInstall) ) {
         __block Platform havePlatform = Platform::unknown;
         mf->forEachSupportedPlatform(^(Platform aPlat, uint32_t minOS, uint32_t sdk) {
             havePlatform = aPlat;
@@ -3046,7 +3133,7 @@
     return true;
 }
 
-
+#if !TARGET_OS_EXCLAVEKIT
 // Note, this has to match the kernel
 static const uint32_t hashPriorities[] = {
     CS_HASHTYPE_SHA1,
@@ -3203,6 +3290,7 @@
         }
     });
 }
+#endif // !TARGET_OS_EXCLAVEKIT
 
 // These are mangled symbols for all the variants of operator new and delete
 // which a main executable can define (non-weak) and override the
@@ -3215,7 +3303,8 @@
     "__ZnwmSt11align_val_t", "__ZnwmSt11align_val_tRKSt9nothrow_t",
     "__ZnamSt11align_val_t", "__ZnamSt11align_val_tRKSt9nothrow_t",
     "__ZdlPvSt11align_val_t", "__ZdlPvSt11align_val_tRKSt9nothrow_t", "__ZdlPvmSt11align_val_t",
-    "__ZdaPvSt11align_val_t", "__ZdaPvSt11align_val_tRKSt9nothrow_t", "__ZdaPvmSt11align_val_t"
+    "__ZdaPvSt11align_val_t", "__ZdaPvSt11align_val_tRKSt9nothrow_t", "__ZdaPvmSt11align_val_t",
+    "__ZnwmSt19__type_descriptor_t", "__ZnamSt19__type_descriptor_t"
 };
 
 void MachOFile::forEachTreatAsWeakDef(void (^handler)(const char* symbolName))
@@ -3262,6 +3351,15 @@
                 this->high8             = fixupLoc->generic64.rebase.high8;
             break;
     }
+}
+
+bool MachOFile::PointerMetaData::operator==(const PointerMetaData& other) const
+{
+    return (this->diversity == other.diversity)
+        && (this->high8 == other.high8)
+        && (this->authenticated == other.authenticated)
+        && (this->key == other.key)
+        && (this->usesAddrDiversity == other.usesAddrDiversity);
 }
 
 #if !SUPPORT_VM_LAYOUT