Page 1 of 1

dyld в macOS/iOS

Posted: Tue Jun 09, 2026 7:32 am
by Admin
Интересно наблюдать за "эволюцией" программистов из Apple.

dyld 852 и старше:

Code: Select all

    struct SectionInfo
    {
        SegmentInfo segInfo;
        uint64_t    sectAddr;
        uint64_t    sectSize;
        const char* sectName;
        uint32_t    sectFileOffset;
        uint32_t    sectFlags;
        uint32_t    sectAlignP2;
        uint32_t    reserved1;
        uint32_t    reserved2;
    };

const void* MachOLoaded::findSectionContent(const char* segName, const char* sectName, uint64_t& size) const
{
    __block const void* result = nullptr;
    forEachSection(^(const SectionInfo& sectInfo, bool malformedSectionRange, bool& stop) {
        if ( (strcmp(sectInfo.sectName, sectName) == 0) && (strcmp(sectInfo.segInfo.segName, segName) == 0) ) {
            size = sectInfo.sectSize;
            result = (void*)(sectInfo.sectAddr + getSlide());
        }
    });
    return result;
}
dyld 940 и новее (macOS >= 12, iOS >= 15):

Code: Select all

    struct SectionInfo {
        std::string_view    sectionName;
        std::string_view    segmentName;
        uint32_t            segIndex        = 0;
        uint32_t            segMaxProt      = 0;
        uint32_t            segInitProt     = 0;
        uint32_t            flags           = 0;
        uint32_t            alignment       = 0;
        uint64_t            address         = 0;
        uint64_t            size            = 0;
        uint32_t            fileOffset      = 0;
        uint32_t            relocsOffset    = 0;
        uint32_t            relocsCount     = 0;
        uint32_t            reserved1       = 0;
        uint32_t            reserved2       = 0;
    };

const void* MachOLoaded::findSectionContent(const char* segName, const char* sectName, uint64_t& size) const
{
    __block const void* result = nullptr;
    forEachSection(^(const UnsafeHeader::SectionInfo& sectInfo, bool& stop) {
        if ( sectInfo.sectionName != sectName )
            return;

        if ( sectInfo.segmentName != segName )
            return;

        size = sectInfo.size;
        if ( this->isPreload() )
            result = (uint8_t*)this + sectInfo.fileOffset;
        else
            result = (void*)(sectInfo.address + getSlide());
        stop = true;
    });
    return result;
}
Принципиальная разница в том, что SectionInfo по сути является оберткой над "struct section" и внутри себя уже содержит не только имя секции, но и имя сегмента:

Code: Select all

struct section {
	char		sectname[16];	/* name of this section */
	char		segname[16];	/* segment this section goes in */
...
};
До dyld 940 они за именем сегмента лазили в вышестоящую структуру "struct segment".