use elf::abi::*;
pub const EM_ARCH: u16 = EM_ARM;
pub const TLS_DTV_OFFSET: usize = 0;
pub const REL_RELATIVE: u32 = R_ARM_RELATIVE;
pub const REL_GOT: u32 = R_ARM_GLOB_DAT;
pub const REL_DTPMOD: u32 = R_ARM_TLS_DTPMOD32;
pub const REL_SYMBOLIC: u32 = R_ARM_ABS32;
pub const REL_JUMP_SLOT: u32 = R_ARM_JUMP_SLOT;
pub const REL_DTPOFF: u32 = R_ARM_TLS_DTPOFF32;
pub const REL_IRELATIVE: u32 = R_ARM_IRELATIVE;
pub const REL_COPY: u32 = R_ARM_COPY;
pub const REL_TPOFF: u32 = R_ARM_TLS_TPOFF32;
pub const REL_TLSDESC: u32 = 0xffff_ffff;
#[inline(always)]
pub(crate) unsafe fn get_thread_pointer() -> *mut u8 {
let tp: *mut u8;
unsafe {
core::arch::asm!("mrc p15, 0, {}, c13, c0, 3", out(reg) tp);
}
tp
}
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,
)
}
pub(crate) extern "C" fn tlsdesc_resolver_static() {
unimplemented!("TLSDESC is not supported on ARM yet");
}
pub(crate) extern "C" fn tlsdesc_resolver_dynamic() {
unimplemented!("TLSDESC is not supported on ARM yet");
}
pub(crate) fn rel_type_to_str(r_type: usize) -> &'static str {
match r_type as u32 {
R_ARM_NONE => "R_ARM_NONE",
R_ARM_ABS32 => "R_ARM_ABS32",
R_ARM_GLOB_DAT => "R_ARM_GLOB_DAT",
R_ARM_JUMP_SLOT => "R_ARM_JUMP_SLOT",
R_ARM_RELATIVE => "R_ARM_RELATIVE",
R_ARM_IRELATIVE => "R_ARM_IRELATIVE",
R_ARM_COPY => "R_ARM_COPY",
_ => "UNKNOWN",
}
}