wasmer_engine_jit/
link.rs1use std::ptr::write_unaligned;
4use wasmer_compiler::{
5 JumpTable, JumpTableOffsets, Relocation, RelocationKind, RelocationTarget, Relocations,
6 SectionIndex,
7};
8use wasmer_engine::FunctionExtent;
9use wasmer_types::entity::{EntityRef, PrimaryMap};
10use wasmer_types::LocalFunctionIndex;
11use wasmer_vm::ModuleInfo;
12use wasmer_vm::SectionBodyPtr;
13
14fn apply_relocation(
15 body: usize,
16 r: &Relocation,
17 allocated_functions: &PrimaryMap<LocalFunctionIndex, FunctionExtent>,
18 jt_offsets: &PrimaryMap<LocalFunctionIndex, JumpTableOffsets>,
19 allocated_sections: &PrimaryMap<SectionIndex, SectionBodyPtr>,
20) {
21 let target_func_address: usize = match r.reloc_target {
22 RelocationTarget::LocalFunc(index) => *allocated_functions[index].ptr as usize,
23 RelocationTarget::LibCall(libcall) => libcall.function_pointer(),
24 RelocationTarget::CustomSection(custom_section) => {
25 *allocated_sections[custom_section] as usize
26 }
27 RelocationTarget::JumpTable(func_index, jt) => {
28 let offset = *jt_offsets
29 .get(func_index)
30 .and_then(|ofs| ofs.get(JumpTable::new(jt.index())))
31 .expect("func jump table");
32 *allocated_functions[func_index].ptr as usize + offset as usize
33 }
34 };
35
36 match r.kind {
37 #[cfg(target_pointer_width = "64")]
38 RelocationKind::Abs8 => unsafe {
39 let (reloc_address, reloc_delta) = r.for_address(body, target_func_address as u64);
40 write_unaligned(reloc_address as *mut u64, reloc_delta);
41 },
42 #[cfg(target_pointer_width = "32")]
43 RelocationKind::X86PCRel4 => unsafe {
44 let (reloc_address, reloc_delta) = r.for_address(body, target_func_address as u64);
45 write_unaligned(reloc_address as *mut u32, reloc_delta as _);
46 },
47 #[cfg(target_pointer_width = "64")]
48 RelocationKind::X86PCRel8 => unsafe {
49 let (reloc_address, reloc_delta) = r.for_address(body, target_func_address as u64);
50 write_unaligned(reloc_address as *mut u64, reloc_delta);
51 },
52 #[cfg(target_pointer_width = "32")]
53 RelocationKind::X86CallPCRel4 => unsafe {
54 let (reloc_address, reloc_delta) = r.for_address(body, target_func_address as u64);
55 write_unaligned(reloc_address as *mut u32, reloc_delta as _);
56 },
57 RelocationKind::X86PCRelRodata4 => {}
58 kind => panic!(
59 "Relocation kind unsupported in the current architecture {}",
60 kind
61 ),
62 }
63}
64
65pub fn link_module(
68 _module: &ModuleInfo,
69 allocated_functions: &PrimaryMap<LocalFunctionIndex, FunctionExtent>,
70 jt_offsets: &PrimaryMap<LocalFunctionIndex, JumpTableOffsets>,
71 function_relocations: Relocations,
72 allocated_sections: &PrimaryMap<SectionIndex, SectionBodyPtr>,
73 section_relocations: &PrimaryMap<SectionIndex, Vec<Relocation>>,
74) {
75 for (i, section_relocs) in section_relocations.iter() {
76 let body = *allocated_sections[i] as usize;
77 for r in section_relocs {
78 apply_relocation(body, r, allocated_functions, jt_offsets, allocated_sections);
79 }
80 }
81 for (i, function_relocs) in function_relocations.iter() {
82 let body = *allocated_functions[i].ptr as usize;
83 for r in function_relocs {
84 apply_relocation(body, r, allocated_functions, jt_offsets, allocated_sections);
85 }
86 }
87}