elf_loader 0.15.0

A no_std-friendly ELF loader, runtime linker, and JIT linker for Rust.
pub(crate) const DYLIB_OFFSET: usize = 1;
pub(crate) const RESOLVE_FUNCTION_OFFSET: usize = 2;

#[unsafe(naked)]
pub(crate) extern "C" fn dl_runtime_resolve() {
    core::arch::naked_asm!(
        "
    // 保存调用者保存的寄存器
    push eax
    push ecx
    push edx

    // 此时栈布局:
    // [esp]      : edx
    // [esp + 4]  : ecx
    // [esp + 8]  : eax
    // [esp + 12] : link_map (由 PLT0 压入)
    // [esp + 16] : reloc_offset (由 PLT 条目压入)
    // [esp + 20] : 返回地址

    // 准备 dl_fixup(link_map, reloc_idx) 的参数
    // reloc_idx = reloc_offset / 8 (x86 Rel 条目大小为 8)
    mov eax, [esp + 16]
    shr eax, 3
    
    push eax         // 参数 2: reloc_idx
    push dword ptr [esp + 16]  // 参数 1: link_map (原本在 +12,现在因为 push eax 变成了 +16)

    call {0}

    // 清理参数
    add esp, 8

    // eax 现在包含解析后的地址。将其存入栈中原本 reloc_offset 的位置。
    mov [esp + 16], eax

    // 恢复寄存器
    pop edx
    pop ecx
    pop eax

    // 跳过 link_map,此时栈顶是解析后的地址
    add esp, 4

    // 弹出解析后的地址并跳转
    ret
    ",
        sym crate::relocation::dl_fixup,
    )
}