wasmer_compiler/artifact_builders/
trampoline.rs1#![cfg_attr(not(feature = "compiler"), allow(dead_code))]
7
8use wasmer_types::LibCall;
9use wasmer_types::target::{Architecture, Target};
10
11use crate::types::{
12 relocation::{Relocation, RelocationKind, RelocationTarget},
13 section::{CustomSection, CustomSectionProtection, SectionBody},
14};
15
16const AARCH64_TRAMPOLINE: [u8; 16] = [
22 0x51, 0x00, 0x00, 0x58, 0x20, 0x02, 0x1f, 0xd6, 0, 0, 0, 0, 0, 0, 0, 0,
23];
24
25const X86_64_TRAMPOLINE: [u8; 16] = [
29 0xff, 0x25, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
30];
31
32const RISCV64_TRAMPOLINE: [u8; 24] = [
39 0x17, 0x03, 0x00, 0x00, 0x03, 0x33, 0x03, 0x01, 0x67, 0x00, 0x03, 0x00, 0, 0, 0, 0, 0, 0, 0, 0,
40 0, 0, 0, 0,
41];
42
43const LOONGARCH64_TRAMPOLINE: [u8; 24] = [
48 0x0c, 0x00, 0x00, 0x18, 0x8c, 0x41, 0xc0, 0x28, 0x80, 0x01, 0x00, 0x4c, 0, 0, 0, 0, 0, 0, 0, 0,
49 0, 0, 0, 0,
50];
51
52fn make_trampoline(
53 target: &Target,
54 libcall: LibCall,
55 code: &mut Vec<u8>,
56 relocations: &mut Vec<Relocation>,
57) {
58 match target.triple().architecture {
59 Architecture::Aarch64(_) => {
60 code.extend(AARCH64_TRAMPOLINE);
61 relocations.push(Relocation {
62 kind: RelocationKind::Abs8,
63 reloc_target: RelocationTarget::LibCall(libcall),
64 offset: code.len() as u32 - 8,
65 addend: 0,
66 });
67 }
68 Architecture::X86_64 => {
69 code.extend(X86_64_TRAMPOLINE);
70 relocations.push(Relocation {
71 kind: RelocationKind::Abs8,
72 reloc_target: RelocationTarget::LibCall(libcall),
73 offset: code.len() as u32 - 8,
74 addend: 0,
75 });
76 }
77 Architecture::Riscv64(_) => {
78 code.extend(RISCV64_TRAMPOLINE);
79 relocations.push(Relocation {
80 kind: RelocationKind::Abs8,
81 reloc_target: RelocationTarget::LibCall(libcall),
82 offset: code.len() as u32 - 8,
83 addend: 0,
84 });
85 }
86 Architecture::LoongArch64 => {
87 code.extend(LOONGARCH64_TRAMPOLINE);
88 relocations.push(Relocation {
89 kind: RelocationKind::Abs8,
90 reloc_target: RelocationTarget::LibCall(libcall),
91 offset: code.len() as u32 - 8,
92 addend: 0,
93 });
94 }
95 arch => panic!("Unsupported architecture: {arch}"),
96 };
97}
98
99pub fn libcall_trampoline_len(target: &Target) -> usize {
101 match target.triple().architecture {
102 Architecture::Aarch64(_) => AARCH64_TRAMPOLINE.len(),
103 Architecture::X86_64 => X86_64_TRAMPOLINE.len(),
104 Architecture::Riscv64(_) => RISCV64_TRAMPOLINE.len(),
105 Architecture::LoongArch64 => LOONGARCH64_TRAMPOLINE.len(),
106 arch => panic!("Unsupported architecture: {arch}"),
107 }
108}
109
110pub fn make_libcall_trampolines(target: &Target) -> CustomSection {
112 let mut code = vec![];
113 let mut relocations = vec![];
114 for libcall in enum_iterator::all::<LibCall>() {
115 make_trampoline(target, libcall, &mut code, &mut relocations);
116 }
117 CustomSection {
118 protection: CustomSectionProtection::ReadExecute,
119 alignment: None,
120 bytes: SectionBody::new_with_vec(code),
121 relocations,
122 }
123}
124
125pub fn get_libcall_trampoline(
127 libcall: LibCall,
128 libcall_trampolines: usize,
129 libcall_trampoline_len: usize,
130) -> usize {
131 libcall_trampolines + libcall as usize * libcall_trampoline_len
132}