56 lines
2.0 KiB
Rust
56 lines
2.0 KiB
Rust
use cranelift_codegen::binemit::Reloc;
|
|
use cranelift_codegen::ir::ExternalName;
|
|
use cranelift_module::RelocRecord;
|
|
|
|
#[derive(Clone)]
|
|
pub(crate) struct CompiledBlob {
|
|
pub(crate) ptr: *mut u8,
|
|
pub(crate) size: usize,
|
|
pub(crate) relocs: Vec<RelocRecord>,
|
|
}
|
|
|
|
impl CompiledBlob {
|
|
pub(crate) fn perform_relocations(&self, get_definition: impl Fn(&ExternalName) -> *const u8) {
|
|
use std::ptr::write_unaligned;
|
|
|
|
for &RelocRecord {
|
|
reloc,
|
|
offset,
|
|
ref name,
|
|
addend,
|
|
} in &self.relocs
|
|
{
|
|
debug_assert!((offset as usize) < self.size);
|
|
let at = unsafe { self.ptr.offset(offset as isize) };
|
|
let base = get_definition(name);
|
|
// TODO: Handle overflow.
|
|
let what = unsafe { base.offset(addend as isize) };
|
|
match reloc {
|
|
Reloc::Abs4 => {
|
|
// TODO: Handle overflow.
|
|
#[cfg_attr(feature = "cargo-clippy", allow(clippy::cast_ptr_alignment))]
|
|
unsafe {
|
|
write_unaligned(at as *mut u32, what as u32)
|
|
};
|
|
}
|
|
Reloc::Abs8 => {
|
|
#[cfg_attr(feature = "cargo-clippy", allow(clippy::cast_ptr_alignment))]
|
|
unsafe {
|
|
write_unaligned(at as *mut u64, what as u64)
|
|
};
|
|
}
|
|
Reloc::X86PCRel4 | Reloc::X86CallPCRel4 => {
|
|
// TODO: Handle overflow.
|
|
let pcrel = ((what as isize) - (at as isize)) as i32;
|
|
#[cfg_attr(feature = "cargo-clippy", allow(clippy::cast_ptr_alignment))]
|
|
unsafe {
|
|
write_unaligned(at as *mut i32, pcrel)
|
|
};
|
|
}
|
|
Reloc::X86GOTPCRel4 | Reloc::X86CallPLTRel4 => panic!("unexpected PIC relocation"),
|
|
_ => unimplemented!(),
|
|
}
|
|
}
|
|
}
|
|
}
|