Implement Abs8 relocations, and fix X86PCRel4 relocations.

With new versions of cretonne-codegen:

 - Non-colocated calls are emitted as a movabs with an indirect call.
   This uses an Abs8 relocation.

 - Colocated calls are emitted as direct calls, but the "+ 4"
   adjustment is now folded into the addend, so we don't need to
   handle it explicitly in the X86PCRel4 code anymore.
This commit is contained in:
Dan Gohman
2018-05-17 23:27:00 -07:00
parent 9d41135fe3
commit d162f8bc59

View File

@@ -8,6 +8,7 @@ extern crate region;
extern crate wasmstandalone_runtime; extern crate wasmstandalone_runtime;
use cretonne_codegen::isa::TargetIsa; use cretonne_codegen::isa::TargetIsa;
use cretonne_codegen::binemit::Reloc;
use std::mem::transmute; use std::mem::transmute;
use region::Protection; use region::Protection;
use region::protect; use region::protect;
@@ -41,11 +42,22 @@ fn relocate(compilation: &mut Compilation, relocations: &wasmstandalone_runtime:
for ref r in function_relocs { for ref r in function_relocs {
let target_func_address: isize = compilation.functions[r.func_index].as_ptr() as isize; let target_func_address: isize = compilation.functions[r.func_index].as_ptr() as isize;
let body = &mut compilation.functions[i]; let body = &mut compilation.functions[i];
unsafe { match r.reloc {
let reloc_address = body.as_mut_ptr().offset(r.offset as isize + 4) as isize; Reloc::Abs8 => unsafe {
let reloc_addend = r.addend as isize; let reloc_address = body.as_mut_ptr().offset(r.offset as isize) as i64;
let reloc_delta_i32 = (target_func_address - reloc_address + reloc_addend) as i32; let reloc_addend = r.addend as i64;
write_unaligned(reloc_address as *mut i32, reloc_delta_i32); let reloc_abs = target_func_address as i64 + reloc_addend;
write_unaligned(reloc_address as *mut i64, reloc_abs);
},
Reloc::X86PCRel4 => unsafe {
let reloc_address = body.as_mut_ptr().offset(r.offset as isize) as isize;
let reloc_addend = r.addend as isize;
// TODO: Handle overflow.
let reloc_delta_i32 = (target_func_address - reloc_address + reloc_addend) as
i32;
write_unaligned(reloc_address as *mut i32, reloc_delta_i32);
},
_ => panic!("unsupported reloc kind"),
} }
} }
} }