Skip to content

Fix InlineFloatCtx (hopefully) and add support for newest rtld version (fix crash on boot + module name printing)#31

Open
dt-12345 wants to merge 5 commits into
shadowninja108:mainfrom
dt-12345:main
Open

Fix InlineFloatCtx (hopefully) and add support for newest rtld version (fix crash on boot + module name printing)#31
dt-12345 wants to merge 5 commits into
shadowninja108:mainfrom
dt-12345:main

Conversation

@dt-12345
Copy link
Copy Markdown

@dt-12345 dt-12345 commented Oct 20, 2025

InlineFloatCtx was adjusted so that the GPRs are now placed after the floating-point registers to match how they are backed up (closes #28).

crt0.s was adjusted to conform to a layout compatible with what newer versions of rtld expect (all while preserving the ever important ~~exlaunch uwu~~).

module_info.hpp was updated to support proper parsing of module names for modules which use the new layout.

Here are the updated rtld structures for reference:

// at the beginning of .text for each module
struct TextSectionHeader {
    u32 entry_instr;
    s32 header_offset;
    s32 sdk_version_offset;
    
    bool IsNewVersion() const {
        return entry_instr != 0xea000000 /* b #0x8 (arm) */ && entry_instr != 0 && entry_instr != 0x14000002 /* b #0x8 (aarch64) */;
    }
};

struct SdkVersion {
    u32 major;
    u32 minor;
    u32 patch;
};

struct ModuleHeader {
    u32 magic; // MOD0
    // offsets relative to the start of the header
    s32 dynamic_offset;
    s32 bss_start_offset;
    s32 bss_end_offset;
    s32 eh_framehdr_start_offset;
    s32 eh_framehdr_end_offset;
    s32 runtime_module_offset;
    // only exist in the new version
    s32 data_offset;
    s32 initialized_offset; // value that's set once module runtime initialization is finished
    s32 module_name_start_offset; // offset to the start of the module name struct, not the name itself
    s32 module_name_end_offset;
    s32 gnu_build_id_start_offset;
    s32 gnu_build_id_end_offset;
};

// found at the start of .rodata for each module
struct ModuleName {
    u32 version;
    union {
        struct {
            u32 name_length;
            char name[];
        } version0;
        struct {
            u32 module_header_offset;
            u32 version_offset;
            u32 unk; // 0, I think this is just the version 0 struct again (module name offset points to here)
            u32 name_length;
            char name[];
        } version1;
    };
};

// rtld module object
struct RoModule {
    RoModule* m_pNext;
    RoModule* m_pPrev;
    union {
        Elf64_Rela* m_RelaPlt;
        Elf64_Rel* m_RelPlt;
    };
    union {
        Elf64_Rela* m_Rela;
        Elf64_Rel* m_Rel;
    };
    u64 _20; // if non-zero, ProtectRelro returns early
    void* m_Base;
    struct {
        Elf64_Dyn* dyn;
        Elf64_Xword pltRelocSize;
        void (*dt_init)(void);
        void (*dt_fini)(void);
        union {
            Elf64_Word* bucket;     // normal hash
            Elf64_Xword* bloom;     // GNU hash
        };
        union {
            Elf64_Word* chain;      // normal hash
            Elf64_Word bloomSize;   // GNU hash
        };
        char* strTable;
        Elf64_Sym* symTable;
        Elf64_Xword strTableSize;
        void* pltGot;
        Elf64_Xword relaSize;
        Elf64_Xword relSize;
        Elf64_Xword relEntryCount;
        Elf64_Xword relaEntryCount;
        union {
            Elf64_Xword nchain;     // normal hash
            Elf64_Xword bloomShift; // GNU hash
        };
        union {
            Elf64_Xword nbucket;    // normal hash
            Elf64_Word* hashTable;  // GNU hash
        };
        Elf64_Xword sharedObjectNameOffset;
        void* moduleEnd;
        u8 _90; // 0x14
        char _91[2];
        u8 flags;
        void* defaultPltGot;
    } m_ArchData;
    
    enum Flags {
        Flags_Rela          = 1 << 1; // DT_RELA as opposed to DT_REL
        Flags_BindNow       = 1 << 2; // DT_BIND_NOW
        Flags_HasNonFunc    = 1 << 3; // has a symbol that isn't STT_FUNC
        Flags_GnuHash       = 1 << 4; // DT_GNU_HASH
    };
};

@KuroiMeansBlack
Copy link
Copy Markdown

Thankyou Dt for the fix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

InlineFloatCtx accessors using bad layout?

2 participants