Loading...
common/MachOLoaded.cpp dyld-1340 dyld-1122.1
--- dyld/dyld-1340/common/MachOLoaded.cpp
+++ dyld/dyld-1122.1/common/MachOLoaded.cpp
@@ -47,13 +47,11 @@
 }
 #endif
 
-#include "Header.h"
 #include "MachOFile.h"
 #include "MachOLoaded.h"
 #include "CodeSigningTypes.h"
 
 
-using mach_o::Header;
 
 namespace dyld3 {
 
@@ -209,18 +207,18 @@
 
 void MachOLoaded::getLayoutInfo(LayoutInfo& result) const
 {
-    ((const Header*)this)->forEachSegment(^(const Header::SegmentInfo& info, bool& stop) {
-        if ( info.segmentName == "__TEXT" ) {
-            result.textUnslidVMAddr = (uintptr_t)info.vmaddr;
-            result.slide = (uintptr_t)(((uint64_t)this) - info.vmaddr);
-        }
-        else if ( info.segmentName == "__LINKEDIT" ) {
-            result.linkeditUnslidVMAddr = (uintptr_t)info.vmaddr;
+    forEachSegment(^(const SegmentInfo& info, bool& stop) {
+        if ( strcmp(info.segName, "__TEXT") == 0 ) {
+            result.textUnslidVMAddr = (uintptr_t)info.vmAddr;
+            result.slide = (uintptr_t)(((uint64_t)this) - info.vmAddr);
+        }
+        else if ( strcmp(info.segName, "__LINKEDIT") == 0 ) {
+            result.linkeditUnslidVMAddr = (uintptr_t)info.vmAddr;
             result.linkeditFileOffset   = (uint32_t)info.fileOffset;
             result.linkeditFileSize     = (uint32_t)info.fileSize;
-            result.linkeditSegIndex     = info.segmentIndex;
-        }
-        result.lastSegIndex = info.segmentIndex;
+            result.linkeditSegIndex     = info.segIndex;
+        }
+        result.lastSegIndex = info.segIndex;
     });
 }
 
@@ -240,11 +238,11 @@
                 *result = (uint8_t*)foundInfo.foundInDylib + foundInfo.value;
                 *resultPointsToInstructions = false;
                 int64_t slide = foundInfo.foundInDylib->getSlide();
-                foundInfo.foundInDylib->forEachSection(^(const Header::SectionInfo& sectInfo, bool& stop) {
-                    uint64_t sectStartAddr = sectInfo.address + slide;
-                    uint64_t sectEndAddr = sectStartAddr + sectInfo.size;
+                foundInfo.foundInDylib->forEachSection(^(const SectionInfo& sectInfo, bool malformedSectionRange, bool& stop) {
+                    uint64_t sectStartAddr = sectInfo.sectAddr + slide;
+                    uint64_t sectEndAddr = sectStartAddr + sectInfo.sectSize;
                     if ( ((uint64_t)*result >= sectStartAddr) && ((uint64_t)*result < sectEndAddr) ) {
-                        *resultPointsToInstructions = (sectInfo.flags & S_ATTR_PURE_INSTRUCTIONS) || (sectInfo.flags & S_ATTR_SOME_INSTRUCTIONS);
+                        *resultPointsToInstructions = (sectInfo.sectFlags & S_ATTR_PURE_INSTRUCTIONS) || (sectInfo.sectFlags & S_ATTR_SOME_INSTRUCTIONS);
                         stop = true;
                     }
                 });
@@ -537,12 +535,26 @@
     }
 }
 
-std::string_view MachOLoaded::segmentName(uint32_t targetSegIndex) const
-{
-    __block std::string_view result;
-	((const Header*)this)->forEachSegment(^(const Header::SegmentInfo& info, bool& stop) {
-        if ( targetSegIndex == info.segmentIndex ) {
-            result = info.segmentName;
+const char* MachOLoaded::dependentDylibLoadPath(uint32_t depIndex) const
+{
+    __block const char* foundLoadPath = nullptr;
+    __block uint32_t curDepIndex = 0;
+    forEachDependentDylib(^(const char* loadPath, bool isWeak, bool isReExport, bool isUpward, uint32_t compatVersion, uint32_t curVersion, bool& stop) {
+        if ( curDepIndex == depIndex ) {
+            foundLoadPath = loadPath;
+            stop = true;
+        }
+        ++curDepIndex;
+    });
+    return foundLoadPath;
+}
+
+const char* MachOLoaded::segmentName(uint32_t targetSegIndex) const
+{
+    __block const char* result = nullptr;
+	forEachSegment(^(const SegmentInfo& info, bool& stop) {
+        if ( targetSegIndex == info.segIndex ) {
+            result = info.segName;
             stop = true;
         }
     });
@@ -616,9 +628,9 @@
 
     // find section index the address is in to validate n_sect
     __block uint32_t sectionIndexForTargetAddress = 0;
-    forEachSection(^(const Header::SectionInfo& sectInfo, bool& stop) {
+    forEachSection(^(const SectionInfo& sectInfo, bool malformedSectionRange, bool& stop) {
         ++sectionIndexForTargetAddress;
-        if ( (sectInfo.address <= targetUnslidAddress) && (targetUnslidAddress < sectInfo.address+sectInfo.size) ) {
+        if ( (sectInfo.sectAddr <= targetUnslidAddress) && (targetUnslidAddress < sectInfo.sectAddr+sectInfo.sectSize) ) {
             stop = true;
         }
     });
@@ -695,7 +707,14 @@
             }
         }
         if ( bestSymbol != nullptr ) {
+#if __arm__
+            if ( bestSymbol->n_desc & N_ARM_THUMB_DEF )
+                *symbolAddr = (bestSymbol->n_value | 1) + leInfo.layout.slide;
+            else
+                *symbolAddr = bestSymbol->n_value + leInfo.layout.slide;
+#else
             *symbolAddr = bestSymbol->n_value + leInfo.layout.slide;
+#endif
             if ( bestSymbol->n_un.n_strx < maxStringOffset )
                 *symbolName = &stringPool[bestSymbol->n_un.n_strx];
             return true;
@@ -705,21 +724,28 @@
     return false;
 }
 
-const void* MachOLoaded::findSectionContent(const char* segName, const char* sectName, uint64_t& size) const
+const void* MachOLoaded::findSectionContent(const char* segName, const char* sectName, uint64_t& size,
+                                            bool matchSegNameAsPrefix) const
 {
     __block const void* result = nullptr;
-    forEachSection(^(const Header::SectionInfo& sectInfo, bool& stop) {
-        if ( sectInfo.sectionName != sectName )
+    forEachSection(^(const SectionInfo& sectInfo, bool malformedSectionRange, bool& stop) {
+        if ( strcmp(sectInfo.sectName, sectName) != 0 )
             return;
 
-        if ( sectInfo.segmentName != segName )
-            return;
-
-        size = sectInfo.size;
+        // Segment name is either matched exactly or by prefix
+        if ( matchSegNameAsPrefix ) {
+            if ( strstr(sectInfo.segInfo.segName, segName) != sectInfo.segInfo.segName )
+                return;
+        } else {
+            if ( strcmp(sectInfo.segInfo.segName, segName) != 0 )
+                return;
+        }
+
+        size = sectInfo.sectSize;
         if ( this->isPreload() )
-            result = (uint8_t*)this + sectInfo.fileOffset;
+            result = (uint8_t*)this + sectInfo.sectFileOffset;
         else
-            result = (void*)(sectInfo.address + getSlide());
+            result = (void*)(sectInfo.sectAddr + getSlide());
         stop = true;
     });
     return result;
@@ -730,8 +756,8 @@
 {
     __block bool result = false;
     uintptr_t slide = getSlide();
-    ((const Header*)this)->forEachSegment(^(const Header::SegmentInfo& info, bool& stop) {
-        if ( (info.vmaddr + info.vmsize + slide >= start) && (info.vmaddr + slide < start + length) )
+    forEachSegment(^(const SegmentInfo& info, bool& stop) {
+        if ( (info.vmAddr+info.vmSize+slide >= start) && (info.vmAddr+slide < start+length) )
             result = true;
     });
     return result;
@@ -754,7 +780,7 @@
                     if ( fixupLoc->arm64e.authBind.bind ) {
                         uint32_t bindOrdinal = (segInfo->pointer_format == DYLD_CHAINED_PTR_ARM64E_USERLAND24) ? fixupLoc->arm64e.authBind24.ordinal : fixupLoc->arm64e.authBind.ordinal;
                         if ( bindOrdinal >= bindTargets.count() ) {
-                            diag.error("out of range bind ordinal %d (max %llu)", bindOrdinal, bindTargets.count());
+                            diag.error("out of range bind ordinal %d (max %lu)", bindOrdinal, bindTargets.count());
                             stop = true;
                             break;
                         }
@@ -774,7 +800,7 @@
                     if ( fixupLoc->arm64e.bind.bind ) {
                         uint32_t bindOrdinal = (segInfo->pointer_format == DYLD_CHAINED_PTR_ARM64E_USERLAND24) ? fixupLoc->arm64e.bind24.ordinal : fixupLoc->arm64e.bind.ordinal;
                         if ( bindOrdinal >= bindTargets.count() ) {
-                            diag.error("out of range bind ordinal %d (max %llu)", bindOrdinal, bindTargets.count());
+                            diag.error("out of range bind ordinal %d (max %lu)", bindOrdinal, bindTargets.count());
                             stop = true;
                             break;
                         }
@@ -800,7 +826,7 @@
             case DYLD_CHAINED_PTR_64_OFFSET:
                 if ( fixupLoc->generic64.bind.bind ) {
                     if ( fixupLoc->generic64.bind.ordinal >= bindTargets.count() ) {
-                        diag.error("out of range bind ordinal %d (max %llu)", fixupLoc->generic64.bind.ordinal, bindTargets.count());
+                        diag.error("out of range bind ordinal %d (max %lu)", fixupLoc->generic64.bind.ordinal, bindTargets.count());
                         stop = true;
                         break;
                     }
@@ -823,7 +849,7 @@
             case DYLD_CHAINED_PTR_32:
                 if ( fixupLoc->generic32.bind.bind ) {
                     if ( fixupLoc->generic32.bind.ordinal >= bindTargets.count() ) {
-                        diag.error("out of range bind ordinal %d (max %llu)", fixupLoc->generic32.bind.ordinal, bindTargets.count());
+                        diag.error("out of range bind ordinal %d (max %lu)", fixupLoc->generic32.bind.ordinal, bindTargets.count());
                         stop = true;
                         break;
                     }
@@ -914,11 +940,11 @@
         if ( this->isPreload() ) {
             // starts are vm-offsets but image is not loaded with zerofill, so need to map vm-offsets to file-offsets
             __block uint64_t startVmAddr = ~0ULL;
-            ((const Header*)this)->forEachSegment(^(const Header::SegmentInfo& info, bool& stop) {
+            this->forEachSegment(^(const SegmentInfo& info, bool& stop) {
                 if ( startVmAddr == ~0ULL )
-                    startVmAddr = info.vmaddr + startVmOffset;
-                if ( (info.vmaddr <= startVmAddr) && (startVmAddr < (info.vmaddr + info.vmsize)) ) {
-                    uint64_t startFileOffset = info.fileOffset + startVmAddr - info.vmaddr;
+                    startVmAddr = info.vmAddr + startVmOffset;
+                if ( (info.vmAddr <= startVmAddr) && (startVmAddr < (info.vmAddr + info.vmSize)) ) {
+                    uint64_t startFileOffset = info.fileOffset + startVmAddr - info.vmAddr;
                     chain = (ChainedFixupPointerOnDisk*)((uint8_t*)this + startFileOffset);
                     stop = true;
                 }
@@ -935,7 +961,7 @@
 uint64_t MachOLoaded::firstSegmentFileOffset() const
 {
     __block uint64_t result = 0;
-    ((const Header*)this)->forEachSegment(^(const Header::SegmentInfo& info, bool& stop) {
+    this->forEachSegment(^(const SegmentInfo& info, bool& stop) {
         result = info.fileOffset;
         stop = true;
     });