linera_wasmer_compiler/artifact_builders/
trampoline.rs1use enum_iterator::IntoEnumIterator;
7use wasmer_types::{
8 Architecture, CustomSection, CustomSectionProtection, LibCall, Relocation, RelocationKind,
9 RelocationTarget, SectionBody, Target,
10};
11
12const AARCH64_TRAMPOLINE: [u8; 16] = [
18 0x51, 0x00, 0x00, 0x58, 0x20, 0x02, 0x1f, 0xd6, 0, 0, 0, 0, 0, 0, 0, 0,
19];
20
21const X86_64_TRAMPOLINE: [u8; 16] = [
25 0xff, 0x25, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
26];
27
28const RISCV64_TRAMPOLINE: [u8; 24] = [
35 0x17, 0x03, 0x00, 0x00, 0x03, 0x33, 0x03, 0x01, 0x67, 0x00, 0x03, 0x00, 0, 0, 0, 0, 0, 0, 0, 0,
36 0, 0, 0, 0,
37];
38
39fn make_trampoline(
40 target: &Target,
41 libcall: LibCall,
42 code: &mut Vec<u8>,
43 relocations: &mut Vec<Relocation>,
44) {
45 match target.triple().architecture {
46 Architecture::Aarch64(_) => {
47 code.extend(AARCH64_TRAMPOLINE);
48 relocations.push(Relocation {
49 kind: RelocationKind::Abs8,
50 reloc_target: RelocationTarget::LibCall(libcall),
51 offset: code.len() as u32 - 8,
52 addend: 0,
53 });
54 }
55 Architecture::X86_64 => {
56 code.extend(X86_64_TRAMPOLINE);
57 relocations.push(Relocation {
58 kind: RelocationKind::Abs8,
59 reloc_target: RelocationTarget::LibCall(libcall),
60 offset: code.len() as u32 - 8,
61 addend: 0,
62 });
63 }
64 Architecture::Riscv64(_) => {
65 code.extend(RISCV64_TRAMPOLINE);
66 relocations.push(Relocation {
67 kind: RelocationKind::Abs8,
68 reloc_target: RelocationTarget::LibCall(libcall),
69 offset: code.len() as u32 - 8,
70 addend: 0,
71 });
72 }
73 arch => panic!("Unsupported architecture: {}", arch),
74 };
75}
76
77pub fn libcall_trampoline_len(target: &Target) -> usize {
79 match target.triple().architecture {
80 Architecture::Aarch64(_) => AARCH64_TRAMPOLINE.len(),
81 Architecture::X86_64 => X86_64_TRAMPOLINE.len(),
82 Architecture::Riscv64(_) => RISCV64_TRAMPOLINE.len(),
83 arch => panic!("Unsupported architecture: {}", arch),
84 }
85}
86
87pub fn make_libcall_trampolines(target: &Target) -> CustomSection {
89 let mut code = vec![];
90 let mut relocations = vec![];
91 for libcall in LibCall::into_enum_iter() {
92 make_trampoline(target, libcall, &mut code, &mut relocations);
93 }
94 CustomSection {
95 protection: CustomSectionProtection::ReadExecute,
96 bytes: SectionBody::new_with_vec(code),
97 relocations,
98 }
99}
100
101pub fn get_libcall_trampoline(
103 libcall: LibCall,
104 libcall_trampolines: usize,
105 libcall_trampoline_len: usize,
106) -> usize {
107 libcall_trampolines + libcall as usize * libcall_trampoline_len
108}