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!(
"
// sp has original lr (4 bytes)
// push r0-r4 (5 regs, 20 bytes). sp aligned to 8 bytes (aligned - 24).
push {{r0, r1, r2, r3, r4}}
",
#[cfg(target_feature = "vfp2")]
"vpush {{d0, d1, d2, d3, d4, d5, d6, d7}}",
"
// r0 = link_map (GOT[1])
// Case for thumb-1 compatibility: mov + sub + ldr
mov r0, lr
subs r0, r0, #4
ldr r0, [r0]
// r1 = index
mov r1, lr
adds r1, r1, #4
mov r2, ip
subs r1, r2, r1
lsrs r1, r1, #2
bl {fixup}
mov ip, r0
",
#[cfg(target_feature = "vfp2")]
"vpop {{d0, d1, d2, d3, d4, d5, d6, d7}}",
"
pop {{r0, r1, r2, r3, r4, lr}}
bx ip
",
fixup = sym crate::relocation::dl_fixup,
)
}