Use trampolines for all libcalls in engine-universal and engine-dylib

In both of these engines, the compiled code may be loaded in memory far
from the Wasmer runtime which means that libcalls may not be reachable
through the normal relocation types. Instead a trampoline is needed to
allow reaching any address in the 64-bit address space.

In the case of engine-dylib, this is even worse since the symbols are
not exported by the executable without some special linker flags. The
solution here is to manually patch in the addresses at load time into
a data table of function pointers.
This commit is contained in:
Amanieu d'Antras
2022-01-11 19:34:35 +00:00
parent 3501e48567
commit ffb9cd33b9
29 changed files with 430 additions and 201 deletions

View File

@ -12,10 +12,9 @@ use rayon::iter::ParallelBridge;
use rayon::prelude::{IntoParallelIterator, IntoParallelRefIterator, ParallelIterator};
use std::sync::Arc;
use wasmer_compiler::{
Architecture, Compilation, CompileError, CompileModuleInfo, Compiler, CustomSection,
CustomSectionProtection, Dwarf, FunctionBodyData, ModuleMiddleware, ModuleTranslationState,
RelocationTarget, SectionBody, SectionIndex, Symbol, SymbolRegistry, Target,
TrampolinesSection,
Compilation, CompileError, CompileModuleInfo, Compiler, CustomSection, CustomSectionProtection,
Dwarf, FunctionBodyData, ModuleMiddleware, ModuleTranslationState, RelocationTarget,
SectionBody, SectionIndex, Symbol, SymbolRegistry, Target,
};
use wasmer_types::entity::{EntityRef, PrimaryMap};
use wasmer_types::{FunctionIndex, LocalFunctionIndex, SignatureIndex};
@ -305,37 +304,6 @@ impl Compiler for LLVMCompiler {
})
.collect::<PrimaryMap<LocalFunctionIndex, _>>();
let trampolines = match target.triple().architecture {
Architecture::Aarch64(_) => {
let nj = 16;
// We create a jump to an absolute 64bits address
// using x17 as a scratch register, SystemV declare both x16 and x17 as Intra-Procedural scratch register
// but Apple ask to just not use x16
// LDR x17, #8 51 00 00 58
// BR x17 20 02 1f d6
// JMPADDR 00 00 00 00 00 00 00 00
let onejump = [
0x51, 0x00, 0x00, 0x58, 0x20, 0x02, 0x1f, 0xd6, 0, 0, 0, 0, 0, 0, 0, 0,
];
let trampolines = Some(TrampolinesSection::new(
SectionIndex::from_u32(module_custom_sections.len() as u32),
nj,
onejump.len(),
));
let mut alljmps = vec![];
for _ in 0..nj {
alljmps.extend(onejump.iter().copied());
}
module_custom_sections.push(CustomSection {
protection: CustomSectionProtection::ReadExecute,
bytes: SectionBody::new_with_vec(alljmps),
relocations: vec![],
});
trampolines
}
_ => None,
};
let dwarf = if !frame_section_bytes.is_empty() {
let dwarf = Some(Dwarf::new(SectionIndex::from_u32(
module_custom_sections.len() as u32,
@ -400,7 +368,6 @@ impl Compiler for LLVMCompiler {
function_call_trampolines,
dynamic_function_trampolines,
dwarf,
trampolines,
))
}
}