Loading...
common/MachOLayout.cpp dyld-1340 dyld-1122.1
--- dyld/dyld-1340/common/MachOLayout.cpp
+++ dyld/dyld-1122.1/common/MachOLayout.cpp
@@ -22,7 +22,6 @@
  */
 
 #include "Array.h"
-#include "Header.h"
 #include "MachOLayout.h"
 #include "MachOFile.h"
 
@@ -60,37 +59,30 @@
 
 bool Layout::isSwiftLibrary() const
 {
-    if ( std::optional<uint32_t> flags = this->getObjcInfoFlags(); flags.has_value() ) {
-        uint32_t swiftVersion = ((flags.value() >> 8) & 0xFF);
-        return (swiftVersion != 0);
-    }
-    return false;
-}
-
-std::optional<uint32_t> Layout::getObjcInfoFlags() const
-{
     struct objc_image_info {
         int32_t version;
         uint32_t flags;
     };
 
-    __block std::optional<uint32_t> flags;
-    ((const Header*)this->mf)->forEachSection(^(const Header::SegmentInfo& segInfo, const Header::SectionInfo& sectInfo, bool& stop) {
-        if ( (sectInfo.sectionName.starts_with("__objc_imageinfo")) && sectInfo.segmentName.starts_with("__DATA") ) {
-            uint64_t segmentOffset = sectInfo.fileOffset - segInfo.fileOffset;
-            objc_image_info* info =  (objc_image_info*)(this->segments[sectInfo.segIndex].buffer + segmentOffset);
-            flags = info->flags;
+    __block bool result = false;
+    this->mf->forEachSection(^(const dyld3::MachOFile::SectionInfo& sectInfo, bool malformedSectionRange, bool& stop) {
+        if ( (strncmp(sectInfo.sectName, "__objc_imageinfo", 16) == 0) && (strncmp(sectInfo.segInfo.segName, "__DATA", 6) == 0) ) {
+            uint64_t segmentOffset = sectInfo.sectFileOffset - sectInfo.segInfo.fileOffset;
+            objc_image_info* info =  (objc_image_info*)(this->segments[sectInfo.segInfo.segIndex].buffer + segmentOffset);
+            uint32_t swiftVersion = ((info->flags >> 8) & 0xFF);
+            if ( swiftVersion )
+                result = true;
             stop = true;
         }
     });
-    return flags;
+    return result;
 }
 
 bool Layout::hasSection(std::string_view segmentName, std::string_view sectionName) const
 {
     __block bool result = false;
-    ((const Header*)this->mf)->forEachSection(^(const Header::SectionInfo& sectInfo, bool& stop) {
-        if ( (sectInfo.segmentName == segmentName) && (sectInfo.sectionName == sectionName) ) {
+    this->mf->forEachSection(^(const dyld3::MachOFile::SectionInfo& sectInfo, bool malformedSectionRange, bool& stop) {
+        if ( (sectInfo.segInfo.segName == segmentName) && (sectInfo.sectName == sectionName) ) {
             result = true;
             stop = true;
         }
@@ -643,7 +635,7 @@
 #if SUPPORT_OLD_ARM64E_FORMAT
     // don't want this code in non-arm64e dyld because it causes a stack protector which dereferences a GOT pointer before GOT is set up
     // old arm64e binary, create a dyld_chained_starts_in_image for caller
-    uint64_t baseAddress = ((const Header*)this->layout.mf)->preferredLoadAddress();
+    uint64_t baseAddress = this->layout.mf->preferredLoadAddress();
     uint64_t imagePageCount = this->layout.mf->mappedSize()/0x4000;
     size_t bufferSize = this->layout.linkedit.regularBindOpcodes.bufferSize + (size_t)imagePageCount*sizeof(uint16_t) + 512;
     BLOCK_ACCCESSIBLE_ARRAY(uint8_t, buffer, bufferSize);
@@ -1387,8 +1379,8 @@
 static void sortRelocations(dyld3::Array<relocation_info>& relocs)
 {
     // The kernel linker has malloc, and old-style relocations are extremely common.  So use qsort
-#if BUILDING_APP_CACHE_UTIL || BUILDING_DYLDINFO
-    ::qsort(&relocs[0], (size_t)relocs.count(), sizeof(relocation_info),
+#if BUILDING_APP_CACHE_UTIL
+    ::qsort(&relocs[0], relocs.count(), sizeof(relocation_info),
             [](const void* l, const void* r) -> int {
                 if ( ((relocation_info*)l)->r_address < ((relocation_info*)r)->r_address )
                     return -1;
@@ -1396,10 +1388,10 @@
                     return 1;
     });
 #else
-    uint64_t count = relocs.count();
-    for (uint64_t i=0; i < count-1; ++i) {
+    uintptr_t count = relocs.count();
+    for (uintptr_t i=0; i < count-1; ++i) {
         bool done = true;
-        for (uint64_t j=0; j < count-i-1; ++j) {
+        for (uintptr_t j=0; j < count-i-1; ++j) {
             if ( relocs[j].r_address > relocs[j+1].r_address ) {
                 relocation_info temp = relocs[j];
                 relocs[j]   = relocs[j+1];
@@ -1427,7 +1419,7 @@
     for (const relocation_info* reloc=relocsStart; (reloc < relocsEnd) && !stop; ++reloc) {
         if ( reloc->r_length != relocSize ) {
             bool shouldEmitError = true;
-#if BUILDING_APP_CACHE_UTIL || BUILDING_DYLDINFO
+#if BUILDING_APP_CACHE_UTIL
             if ( this->layout.mf->usesClassicRelocationsInKernelCollection() && (reloc->r_length == 2) && (relocSize == 3) )
                 shouldEmitError = false;
 #endif
@@ -1449,7 +1441,7 @@
             uint32_t segIndex  = 0;
             uint64_t segOffset = 0;
             uint64_t addr = 0;
-#if BUILDING_APP_CACHE_UTIL || BUILDING_DYLDINFO
+#if BUILDING_APP_CACHE_UTIL
             // xnu for x86_64 has __HIB mapped before __DATA, so offsets appear to be
             // negative
             if ( this->layout.mf->isStaticExecutable() || this->layout.mf->isFileSet() ) {
@@ -1523,7 +1515,7 @@
     bool                            stop        = false;
     for (const relocation_info* reloc=relocsStart; (reloc < relocsEnd) && !stop; ++reloc) {
         bool isBranch = false;
-#if BUILDING_APP_CACHE_UTIL || BUILDING_DYLDINFO
+#if BUILDING_APP_CACHE_UTIL
         if ( this->layout.mf->isKextBundle() ) {
             // kext's may have other kinds of relocations, eg, branch relocs.  Skip them
             if ( this->layout.mf->isArch("x86_64") || this->layout.mf->isArch("x86_64h") ) {
@@ -1634,20 +1626,20 @@
     if ( (indirectSymbolTableCount == 0) && this->layout.mf->isKextBundle() )
         return;
 
-    ((const Header*)this->layout.mf)->forEachSection(^(const Header::SectionInfo& sectInfo, bool& sectionStop) {
-        uint8_t  sectionType  = (sectInfo.flags & SECTION_TYPE);
-        bool selfModifyingStub = (sectionType == S_SYMBOL_STUBS) && (sectInfo.flags & S_ATTR_SELF_MODIFYING_CODE) && (sectInfo.reserved2 == 5) && (this->layout.mf->cputype == CPU_TYPE_I386);
+    this->layout.mf->forEachSection(^(const dyld3::MachOFile::SectionInfo& sectInfo, bool malformedSectionRange, bool& sectionStop) {
+        uint8_t  sectionType  = (sectInfo.sectFlags & SECTION_TYPE);
+        bool selfModifyingStub = (sectionType == S_SYMBOL_STUBS) && (sectInfo.sectFlags & S_ATTR_SELF_MODIFYING_CODE) && (sectInfo.reserved2 == 5) && (this->layout.mf->cputype == CPU_TYPE_I386);
         if ( (sectionType != S_LAZY_SYMBOL_POINTERS) && (sectionType != S_NON_LAZY_SYMBOL_POINTERS) && !selfModifyingStub )
             return;
-        if ( (sectInfo.flags & S_ATTR_SELF_MODIFYING_CODE) && !selfModifyingStub ) {
+        if ( (sectInfo.sectFlags & S_ATTR_SELF_MODIFYING_CODE) && !selfModifyingStub ) {
             diag.error("S_ATTR_SELF_MODIFYING_CODE section type only valid in old i386 binaries");
             sectionStop = true;
             return;
         }
         uint32_t elementSize = selfModifyingStub ? sectInfo.reserved2 : ptrSize;
-        uint32_t elementCount = (uint32_t)(sectInfo.size/elementSize);
+        uint32_t elementCount = (uint32_t)(sectInfo.sectSize/elementSize);
         if ( dyld3::greaterThanAddOrOverflow(sectInfo.reserved1, elementCount, indirectSymbolTableCount) ) {
-            diag.error("section %.*s overflows indirect symbol table", (int)sectInfo.sectionName.size(), sectInfo.sectionName.data());
+            diag.error("section %s overflows indirect symbol table", sectInfo.sectName);
             sectionStop = true;
             return;
         }
@@ -1657,7 +1649,7 @@
             if ( symNum == INDIRECT_SYMBOL_ABS )
                 continue;
             if ( symNum == INDIRECT_SYMBOL_LOCAL ) {
-                handler(sectInfo.address+i*elementSize, false, 0, "", false, false, false, stop);
+                handler(sectInfo.sectAddr+i*elementSize, false, 0, "", false, false, false, stop);
                 continue;
             }
             if ( symNum > symCount ) {
@@ -1686,7 +1678,7 @@
                 // Note we only want to change the value in memory once, before rebases are applied.  We don't want to accidentally
                 // change it again later.
                 if ( supportPrivateExternsWorkaround ) {
-                    uintptr_t* ptr = (uintptr_t*)((uint8_t*)(sectInfo.address+i*elementSize) + slide);
+                    uintptr_t* ptr = (uintptr_t*)((uint8_t*)(sectInfo.sectAddr+i*elementSize) + slide);
                     uint64_t n_value = is64Bit ? symbols64[symNum].n_value : symbols32[symNum].n_value;
                     *ptr = (uintptr_t)n_value;
                 }
@@ -1696,7 +1688,7 @@
             // Handle defined weak def symbols which need to get a special ordinal
             if ( ((n_type & N_TYPE) == N_SECT) && ((n_type & N_EXT) != 0) && ((n_desc & N_WEAK_DEF) != 0) )
                 libOrdinal = BIND_SPECIAL_DYLIB_WEAK_LOOKUP;
-            handler(sectInfo.address+i*elementSize, true, libOrdinal, symbolName, weakImport, lazy, selfModifyingStub, stop);
+            handler(sectInfo.sectAddr+i*elementSize, true, libOrdinal, symbolName, weakImport, lazy, selfModifyingStub, stop);
         }
         sectionStop = stop;
     });
@@ -1705,7 +1697,7 @@
 uint64_t Fixups::localRelocBaseAddress() const
 {
     if ( this->layout.mf->isArch("x86_64") || this->layout.mf->isArch("x86_64h") ) {
-#if BUILDING_APP_CACHE_UTIL || BUILDING_DYLDINFO
+#if BUILDING_APP_CACHE_UTIL
         if ( this->layout.mf->isKextBundle() ) {
             // for kext bundles the reloc base address starts at __TEXT segment
             return this->layout.segments[0].vmAddr;
@@ -1724,13 +1716,13 @@
 {
     // Dyld caches are too large for a raw r_address, so everything is an offset from the base address
     if ( this->layout.mf->inDyldCache() ) {
-        return ((const Header*)this->layout.mf)->preferredLoadAddress();
-    }
-
-#if BUILDING_APP_CACHE_UTIL || BUILDING_DYLDINFO
+        return this->layout.mf->preferredLoadAddress();
+    }
+
+#if BUILDING_APP_CACHE_UTIL
     if ( this->layout.mf->isKextBundle() ) {
         // for kext bundles the reloc base address starts at __TEXT segment
-        return ((const Header*)this->layout.mf)->preferredLoadAddress();
+        return this->layout.mf->preferredLoadAddress();
     }
 #endif
 
@@ -1785,14 +1777,6 @@
 SplitSeg::SplitSeg(const Layout& layout)
     : layout(layout)
 {
-}
-
-bool SplitSeg::hasMarker() const
-{
-    if ( !this->layout.linkedit.splitSegInfo.hasValue() )
-        return false;
-
-    return this->layout.linkedit.splitSegInfo.bufferSize == 0;
 }
 
 bool SplitSeg::isV1() const
@@ -1845,7 +1829,7 @@
             for (uint64_t k=0; k < fromOffsetCount; ++k) {
                 uint64_t kind = dyld3::MachOFile::read_uleb128(diag, p, infoEnd);
                 if ( kind > 13 ) {
-                    diag.error("bad kind (%llu) value in %s\n", kind, ((const Header*)this->layout.mf)->installName());
+                    diag.error("bad kind (%llu) value in %s\n", kind, this->layout.mf->installName());
                 }
                 uint64_t fromSectDeltaCount = dyld3::MachOFile::read_uleb128(diag, p, infoEnd);
                 uint64_t fromSectionOffset = 0;
@@ -1868,8 +1852,11 @@
                                                        uint64_t sectionVMAddr)) const
 {
     callback("mach header", "", 0);
-    ((const Header*)this->layout.mf)->forEachSection(^(const Header::SectionInfo &sectInfo, bool &stop) {
-        callback(sectInfo.segmentName, sectInfo.sectionName, sectInfo.address);
+    this->layout.mf->forEachSection(^(const dyld3::MachOFile::SectionInfo &sectInfo,
+                                      bool malformedSectionRange, bool &stop) {
+        std::string_view segmentName(sectInfo.segInfo.segName, strnlen(sectInfo.segInfo.segName, 16));
+        std::string_view sectionName(sectInfo.sectName, strnlen(sectInfo.sectName, 16));
+        callback(segmentName, sectionName, sectInfo.sectAddr);
     });
 }
 
@@ -2050,51 +2037,6 @@
     uint8_t keyBits = this->key;
     assert(keyBits < 4);
     return names[keyBits];
-}
-
-uint64_t ChainedFixupPointerOnDisk::Cache64e::high8() const
-{
-    assert(this->regular.auth == 0);
-    return ((uint64_t)(this->regular.high8) << 56);
-}
-
-const char* ChainedFixupPointerOnDisk::Cache64e::keyName() const
-{
-    assert(this->auth.auth == 1);
-    static const char* const names[] = {
-        "IA", "DA"
-    };
-    assert(this->auth.keyIsData < 2);
-    return names[this->auth.keyIsData];
-}
-
-uint64_t ChainedFixupPointerOnDisk::Cache64e::signPointer(uint64_t unsignedAddr, void* loc, bool addrDiv, uint16_t diversity, uint8_t keyIsData)
-{
-    // don't sign NULL
-    if ( unsignedAddr == 0 )
-        return 0;
-
-#if __has_feature(ptrauth_calls)
-    uint64_t extendedDiscriminator = diversity;
-    if ( addrDiv )
-        extendedDiscriminator = __builtin_ptrauth_blend_discriminator(loc, extendedDiscriminator);
-    switch ( keyIsData ) {
-        case 0: // IA
-            return (uintptr_t)__builtin_ptrauth_sign_unauthenticated((void*)unsignedAddr, 0, extendedDiscriminator);
-        case 1: // DA
-            return (uintptr_t)__builtin_ptrauth_sign_unauthenticated((void*)unsignedAddr, 2, extendedDiscriminator);
-    }
-    assert(0 && "invalid signing key");
-#else
-    assert(0 && "arm64e signing only arm64e");
-#endif
-}
-
-
-uint64_t ChainedFixupPointerOnDisk::Cache64e::signPointer(void* loc, uint64_t target) const
-{
-    assert(this->auth.auth == 1);
-    return signPointer(target, loc, auth.addrDiv, auth.diversity, auth.keyIsData);
 }
 
 bool ChainedFixupPointerOnDisk::isRebase(uint16_t pointerFormat, uint64_t preferedLoadAddress, uint64_t& targetRuntimeOffset) const
@@ -2143,16 +2085,6 @@
             targetRuntimeOffset = this->firmware32.target - preferedLoadAddress;
             return true;
             break;
-        case DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE:
-             if ( this->cache64e.regular.auth ) {
-                 targetRuntimeOffset = this->cache64e.auth.runtimeOffset;
-                 return true;
-             }
-             else {
-                 targetRuntimeOffset = this->cache64e.regular.runtimeOffset;
-                 return true;
-             }
-             break;
         default:
             break;
     }
@@ -2216,7 +2148,6 @@
         case DYLD_CHAINED_PTR_ARM64E:
         case DYLD_CHAINED_PTR_ARM64E_USERLAND:
         case DYLD_CHAINED_PTR_ARM64E_USERLAND24:
-        case DYLD_CHAINED_PTR_ARM64E_SHARED_CACHE:
             return 8;
         case DYLD_CHAINED_PTR_ARM64E_KERNEL:
         case DYLD_CHAINED_PTR_ARM64E_FIRMWARE: