#[repr(C)]
pub struct Rela {
pub r_offset: u64, pub r_info: u64, pub r_addend: i64, }
impl Rela {
#[inline]
fn r_type_raw(&self) -> u32 {
(self.r_info & 0xFFFFFFFF) as u32
}
}
pub unsafe fn apply_reloc(load_offset: i128, start: *mut u8, end: *const u8, r_type: u32) {
let num_entries = (end as usize - start as usize) / size_of::<Rela>();
let relocations = unsafe { core::slice::from_raw_parts_mut(start as *mut Rela, num_entries) };
for reloc in relocations {
if reloc.r_type_raw() == r_type {
let addr = (reloc.r_offset as i128 + load_offset) as usize as *mut usize;
let val = (reloc.r_addend as i128 + load_offset) as usize;
unsafe { *addr = val };
}
}
}
pub unsafe fn reset(r_type: u32) {
unsafe extern "C" {
fn __rela_dyn_begin();
fn __rela_dyn_end();
}
let start = __rela_dyn_begin as *mut u8;
let end = __rela_dyn_end as *const u8;
let num_entries = (end as usize - start as usize) / size_of::<Rela>();
let relocations = unsafe { core::slice::from_raw_parts_mut(start as *mut Rela, num_entries) };
for reloc in relocations {
if reloc.r_type_raw() == r_type {
let addr = reloc.r_offset as usize as *mut usize;
unsafe { addr.write_volatile(reloc.r_addend as u64 as usize) };
}
}
}