Implement GOT relocations in SimpleJIT

This commit is contained in:
bjorn3
2020-11-12 15:06:52 +01:00
parent 11a3bdfc6a
commit eaa2c5b3c2
3 changed files with 207 additions and 14 deletions

View File

@@ -1,6 +1,7 @@
use cranelift_codegen::binemit::Reloc;
use cranelift_codegen::ir::ExternalName;
use cranelift_module::RelocRecord;
use std::convert::TryFrom;
#[derive(Clone)]
pub(crate) struct CompiledBlob {
@@ -10,7 +11,11 @@ pub(crate) struct CompiledBlob {
}
impl CompiledBlob {
pub(crate) fn perform_relocations(&self, get_definition: impl Fn(&ExternalName) -> *const u8) {
pub(crate) fn perform_relocations(
&self,
get_address: impl Fn(&ExternalName) -> *const u8,
get_got_entry: impl Fn(&ExternalName) -> *const u8,
) {
use std::ptr::write_unaligned;
for &RelocRecord {
@@ -22,29 +27,42 @@ impl CompiledBlob {
{
debug_assert!((offset as usize) < self.size);
let at = unsafe { self.ptr.offset(isize::try_from(offset).unwrap()) };
let base = get_definition(name);
let what = unsafe { base.offset(isize::try_from(addend).unwrap()) };
match reloc {
Reloc::Abs4 => {
let base = get_address(name);
let what = unsafe { base.offset(isize::try_from(addend).unwrap()) };
#[cfg_attr(feature = "cargo-clippy", allow(clippy::cast_ptr_alignment))]
unsafe {
write_unaligned(at as *mut u32, u32::try_from(what as usize).unwrap())
};
}
Reloc::Abs8 => {
let base = get_address(name);
let what = unsafe { base.offset(isize::try_from(addend).unwrap()) };
#[cfg_attr(feature = "cargo-clippy", allow(clippy::cast_ptr_alignment))]
unsafe {
write_unaligned(at as *mut u64, u64::try_from(what as usize).unwrap())
};
}
Reloc::X86PCRel4 | Reloc::X86CallPCRel4 => {
let base = get_address(name);
let what = unsafe { base.offset(isize::try_from(addend).unwrap()) };
let pcrel = i32::try_from((what as isize) - (at as isize)).unwrap();
#[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"),
Reloc::X86GOTPCRel4 => {
let base = get_got_entry(name);
let what = unsafe { base.offset(isize::try_from(addend).unwrap()) };
let pcrel = i32::try_from((what as isize) - (at as isize)).unwrap();
#[cfg_attr(feature = "cargo-clippy", allow(clippy::cast_ptr_alignment))]
unsafe {
write_unaligned(at as *mut i32, pcrel)
};
}
Reloc::X86CallPLTRel4 => todo!("PLT relocation"),
_ => unimplemented!(),
}
}