Loading...
mach_o/Header.cpp dyld-1340 dyld-1284.13
--- dyld/dyld-1340/mach_o/Header.cpp
+++ dyld/dyld-1284.13/mach_o/Header.cpp
@@ -286,10 +286,9 @@
     if ( content.size() < sizeof(mach_header) )
         return nullptr;
 
-    if ( const Header* mh = (const Header*)content.data() ) {
-        if ( mh->hasMachOMagic() )
-            return mh;
-    }
+    const Header* mh = (const Header*)content.data();
+    if ( mh->hasMachOMagic() )
+        return mh;
     return nullptr;
 }
 
@@ -324,12 +323,6 @@
     return (this->mh.flags & MH_SIM_SUPPORT) != 0;
 }
 
-bool Header::noDynamicAccess() const
-{
-    return (this->mh.flags & MH_NO_DYNAMIC_ACCESS) != 0;
-}
-
-
 //
 // MARK: --- methods for validating mach-o content ---
 //
@@ -340,7 +333,7 @@
     __block PlatformAndVersions pvs;
     forEachPlatformLoadCommand(^(Platform platform, Version32 minOS, Version32 sdk) {
         Error err = pvs.zip({ platform, minOS, sdk });
-        // .zip() will not combine platforms if it is an invalid combo
+        assert(err.noError());
     });
     return pvs;
 }
@@ -430,7 +423,7 @@
 
     const char* str = (char*)cmd + strOffset;
     const char* end = (char*)cmd + cmd->cmdsize;
-    for ( const char* s = end-1; s >= str; --s ) {
+    for ( const char* s = str; s < end; ++s ) {
         if ( *s == '\0' ) {
             return Error::none();
         }
@@ -446,7 +439,7 @@
         return Error("load commands length (%llu) exceeds length of file (%llu)", headerAndLCSize, fileSize);
     }
 
-    // check for recognized filetype
+    // check for reconized filetype
     switch ( mh.filetype ) {
         case MH_EXECUTE:
         case MH_DYLIB:
@@ -634,12 +627,11 @@
     });
     if ( uuidCount > 1 )
         return Error("too many LC_UUID load commands");
-    if ( (uuidCount == 0) && policy.enforceHasUUID() ) {
-            return Error("missing LC_UUID load command");
-    }
+    if ( (uuidCount == 0) && policy.enforceHasUUID() )
+        return Error("missing LC_UUID load command");
+
     return Error::none();
 }
-
 
 Error Header::validSemanticsInstallName(const Policy& policy) const
 {
@@ -862,7 +854,7 @@
     {
         Interval    vm;
         Interval    file;
-        CString     name;
+        const char* name;
     };
     STACK_ALLOC_OVERFLOW_SAFE_ARRAY(SegRange, ranges, 12);
     __block Error     lcError;
@@ -921,18 +913,15 @@
     }
 
     // check for overlapping segments, by looking at every possible pair of segments
-    const bool checkNames = isDyldManaged() && policy.enforceUniqueSegmentNames();
     for ( const SegRange& r1 : ranges ) {
         for ( const SegRange& r2 : ranges ) {
             if ( &r1 == &r2 )
                 continue;
             if ( r1.vm.overlaps(r2.vm) )
-                return Error("vm range of segment '%s' overlaps segment '%s'", r1.name.c_str(), r2.name.c_str());
+                return Error("vm range of segment '%s' overlaps segment '%s'", r1.name, r2.name);
             // can't compare file offsets for segments in dyld cache because they may be offsets into different files
             if ( !this->inDyldCache() && r1.file.overlaps(r2.file) )
-                return Error("file range of segment '%s' overlaps segment '%s'", r1.name.c_str(), r2.name.c_str());
-            if ( checkNames && (r1.name == r2.name) )
-                return Error("duplicate segment name '%s'", r1.name.c_str());
+                return Error("file range of segment '%s' overlaps segment '%s'", r1.name, r2.name);
         }
     }
 
@@ -943,14 +932,13 @@
             const SegRange& a = ranges[i-1];
             const SegRange& b = ranges[i];
             if ( (b.file.start < a.file.start) && (b.file.start != b.file.end) )
-                return Error("segment '%s' file offset out of order", a.name.c_str());
+                return Error("segment '%s' file offset out of order", a.name);
             if ( b.vm.start < a.vm.start ) {
-                if ( isFileSet() && (b.name == "__PRELINK_INFO") ) {
+                if ( isFileSet() && (strcmp(b.name, "__PRELINK_INFO") == 0) ) {
                     // __PRELINK_INFO may have no vmaddr set
-                } else if ( arch().usesx86_64Instructions() && isDynamicExecutable() && !isPIE() ) {
-                    // rdar://149897776 (allow out of VM address order segments on legacy x86 binaries)
-                } else {
-                    return Error("segment '%s' vm address out of order", b.name.c_str());
+                }
+                else {
+                    return Error("segment '%s' vm address out of order", b.name);
                 }
             }
         }
@@ -1166,7 +1154,7 @@
 
     // old binary with no explicit platform
 #if TARGET_OS_OSX
-    if ( (mh.cputype == CPU_TYPE_X86_64) || (mh.cputype == CPU_TYPE_I386) )
+    if ( (mh.cputype == CPU_TYPE_X86_64) | (mh.cputype == CPU_TYPE_I386) )
         handler(Platform::macOS, Version32(10, 5), Version32(10, 5)); // guess it is a macOS 10.5 binary
     // <rdar://problem/75343399>
     // The Go linker emits non-standard binaries without a platform and we have to live with it.
@@ -1350,9 +1338,6 @@
                                                  Version32 compatVersion, Version32 curVersion,
                                                  bool synthesizedLink, bool& stop)) const
 {
-    if ( this->isDylinker() )
-        return;
-
     __block unsigned count   = 0;
     __block bool     stopped = false;
     forEachLoadCommandSafe(^(const load_command* cmd, bool& stop) {
@@ -1434,7 +1419,7 @@
         case CPU_TYPE_ARM64:
         case CPU_TYPE_ARM64_32:
             if ( flavor == 6 ) {   // ARM_THREAD_STATE64
-                memcpy((uint32_t*)&addr, (uint32_t*)&regs64[32], sizeof(uint64_t)); // arm_thread_state64_t.__pc
+                addr = regs64[32]; // arm_thread_state64_t.__pc
                 return true;
             }
             break;
@@ -1479,14 +1464,7 @@
             stop                          = true;
         }
     });
-
-    // <rdar://problem/13622786> ignore code signatures in macOS binaries built with pre-10.9 tools
-    if ( mh.cputype == CPU_TYPE_X86_64 ) {
-        PlatformAndVersions pvs = platformAndVersions();
-        if ( (pvs.platform == Platform::macOS) && (pvs.sdk < Version32(10,9)) )
-            return false;
-    }
-
+    // FIXME: may need to ignore codesigs from pre 10.9 macOS binaries
     return result;
 }
 
@@ -1514,23 +1492,6 @@
             fileOffset  = dySymCmd->indirectsymoff;
             count       = dySymCmd->nindirectsyms;
             result      = true;
-            stop        = true;
-        }
-    });
-    return result;
-}
-
-bool Header::hasClassicRelocations(uint32_t& nLocRel, uint32_t& nExtRel) const
-{
-    __block bool result = false;
-    nLocRel = 0;
-    nExtRel = 0;
-    forEachLoadCommandSafe(^(const load_command* cmd, bool& stop) {
-        if ( cmd->cmd == LC_DYSYMTAB) {
-            dysymtab_command* dySymCmd = (dysymtab_command*)cmd;
-            nLocRel = dySymCmd->nlocrel;
-            nExtRel = dySymCmd->nextrel;
-            result      = (nLocRel != 0 || nExtRel != 0);
             stop        = true;
         }
     });
@@ -2370,21 +2331,6 @@
     return result;
 }
 
-bool Header::hasDiscontiguousSegments() const
-{
-    uint64_t loadAddr = preferredLoadAddress();
-    __block bool res = false;
-    this->forEachSegment(^(const SegmentInfo& info, bool& stop) {
-        if ( info.maxProt == 0 )
-            return;
-        if ( info.vmaddr < loadAddr ) {
-            res = true;
-            stop = true;
-        }
-    });
-    return res;
-}
-
 std::string_view Header::segmentName(uint32_t segIndex) const
 {
     __block std::string_view    result;
@@ -2531,12 +2477,10 @@
             const segment_command_64* segCmd        = (segment_command_64*)cmd;
             const section_64* const   sectionsStart = (section_64*)((char*)segCmd + sizeof(struct segment_command_64));
             const section_64* const   sectionsEnd   = &sectionsStart[segCmd->nsects];
-            std::string_view segName = name16(segCmd->segname);
             for ( const section_64* sect = sectionsStart; !stop && (sect < sectionsEnd); ++sect ) {
-                std::string_view segNameFromSectLC = name16(sect->segname);
                 SectionInfo info = {
                     // Note: use of segCmd->segname is for bin compat for copy protection in rdar://146096183
-                    .sectionName=name16(sect->sectname), .segmentName=segNameFromSectLC.empty() ? segName : segNameFromSectLC, .segIndex=segmentIndex,
+                    .sectionName=name16(sect->sectname), .segmentName=name16(segCmd->segname), .segIndex=segmentIndex,
                     .segMaxProt=(uint32_t)segCmd->maxprot, .segInitProt=(uint32_t)segCmd->initprot,
                     .flags=sect->flags, .alignment=sect->align, .address=sect->addr, .size=sect->size, .fileOffset=sect->offset,
                     .relocsOffset=sect->reloff, .relocsCount=sect->nreloc, .reserved1=sect->reserved1, .reserved2=sect->reserved2
@@ -2695,25 +2639,16 @@
     return result;
 }
 
-// checks if a section exists.
-// use `segNamePrefix` to just match segment name prefix (e.g. "__DATA" matches "__DATA_CONST")
-bool Header::hasSection(CString segName, CString sectName, bool segNamePrefix) const
+bool Header::isRestricted() const
 {
     __block bool result = false;
     this->forEachSection(^(const SectionInfo& info, bool& stop) {
-        if ( info.sectionName == sectName ) {
-            if ( (segNamePrefix && info.segmentName.starts_with(segName)) || (info.segmentName == segName)) {
-                result = true;
-                stop   = true;
-            }
+        if ( (info.segmentName == "__RESTRICT") && (info.sectionName == "__restrict") ) {
+            result = true;
+            stop   = true;
         }
     });
     return result;
-}
-
-bool Header::isRestricted() const
-{
-    return this->hasSection("__RESTRICT", "__restrict");
 }
 
 bool Header::hasInterposingTuples() const
@@ -2861,7 +2796,7 @@
         cmdSize = Header::pointerAligned(false, 16 + 34 * 8); // base size + ARM_EXCEPTION_STATE64_COUNT * 8
     else if ( arch.sameCpu(Architecture::x86_64) )
         cmdSize = Header::pointerAligned(true, 16 + 42 * 4); // base size + x86_THREAD_STATE64_COUNT * 4
-    else if ( arch.usesArmOrThumbInstructions() )
+    else if ( arch.usesThumbInstructions() || arch.usesArm32Instructions() )
         cmdSize = Header::pointerAligned(false, 16 + 17 * 4); // base size + ARM_THREAD_STATE_COUNT * 4
     else
         assert(0 && "unsupported arch for thread load command");