Added some infrastructure to generate EH_Frame in singlepass compiler

This commit is contained in:
ptitSeb
2022-03-02 12:21:55 +01:00
parent 27c30d9060
commit 187b7508c9
10 changed files with 290 additions and 31 deletions

View File

@ -4,21 +4,28 @@
use crate::codegen::FuncGen;
use crate::config::Singlepass;
#[cfg(feature = "unwind")]
use crate::dwarf::WriterRelocate;
use crate::machine::Machine;
use crate::machine::{
gen_import_call_trampoline, gen_std_dynamic_import_trampoline, gen_std_trampoline, CodegenError,
};
use crate::machine_arm64::MachineARM64;
use crate::machine_x64::MachineX86_64;
#[cfg(feature = "unwind")]
use crate::unwind::create_systemv_cie;
#[cfg(feature = "unwind")]
use gimli::write::{EhFrame, FrameTable};
use loupe::MemoryUsage;
#[cfg(feature = "rayon")]
use rayon::prelude::{IntoParallelIterator, ParallelIterator};
use std::sync::Arc;
use wasmer_compiler::{
Architecture, CallingConvention, Compilation, CompileError, CompileModuleInfo,
CompiledFunction, Compiler, CompilerConfig, CpuFeature, FunctionBinaryReader, FunctionBody,
FunctionBodyData, MiddlewareBinaryReader, ModuleMiddleware, ModuleMiddlewareChain,
ModuleTranslationState, OperatingSystem, SectionIndex, Target, TrapInformation,
CompiledFunction, Compiler, CompilerConfig, CpuFeature, Dwarf, FunctionBinaryReader,
FunctionBody, FunctionBodyData, MiddlewareBinaryReader, ModuleMiddleware,
ModuleMiddlewareChain, ModuleTranslationState, OperatingSystem, SectionIndex, Target,
TrapInformation,
};
use wasmer_types::entity::{EntityRef, PrimaryMap};
use wasmer_types::{
@ -94,11 +101,34 @@ impl Compiler for SinglepassCompiler {
_ => panic!("Unsupported Calling convention for Singlepass compiler"),
};
// Generate the frametable
#[cfg(feature = "unwind")]
let dwarf_frametable = if function_body_inputs.is_empty() {
// If we have no function body inputs, we don't need to
// construct the `FrameTable`. Constructing it, with empty
// FDEs will cause some issues in Linux.
None
} else {
match target.triple().default_calling_convention() {
Ok(CallingConvention::SystemV) => {
match create_systemv_cie(target.triple().architecture) {
Some(cie) => {
let mut dwarf_frametable = FrameTable::default();
let cie_id = dwarf_frametable.add_cie(cie);
Some((dwarf_frametable, cie_id))
}
None => None,
}
}
_ => None,
}
};
let memory_styles = &compile_info.memory_styles;
let table_styles = &compile_info.table_styles;
let vmoffsets = VMOffsets::new(8, &compile_info.module);
let module = &compile_info.module;
let import_trampolines: PrimaryMap<SectionIndex, _> = (0..module.num_imported_functions)
let mut custom_sections: PrimaryMap<SectionIndex, _> = (0..module.num_imported_functions)
.map(FunctionIndex::new)
.collect::<Vec<_>>()
.into_par_iter_if_rayon()
@ -114,7 +144,7 @@ impl Compiler for SinglepassCompiler {
.collect::<Vec<_>>()
.into_iter()
.collect();
let functions = function_body_inputs
let (functions, fdes): (Vec<CompiledFunction>, Vec<_>) = function_body_inputs
.iter()
.collect::<Vec<(LocalFunctionIndex, &FunctionBodyData<'_>)>>()
.into_par_iter_if_rayon()
@ -185,9 +215,9 @@ impl Compiler for SinglepassCompiler {
_ => unimplemented!(),
}
})
.collect::<Result<Vec<CompiledFunction>, CompileError>>()?
.collect::<Result<Vec<_>, CompileError>>()?
.into_iter()
.collect::<PrimaryMap<LocalFunctionIndex, CompiledFunction>>();
.unzip();
let function_call_trampolines = module
.signatures
@ -215,12 +245,31 @@ impl Compiler for SinglepassCompiler {
.into_iter()
.collect::<PrimaryMap<FunctionIndex, FunctionBody>>();
#[cfg(feature = "unwind")]
let dwarf = if let Some((mut dwarf_frametable, cie_id)) = dwarf_frametable {
for fde in fdes {
if let Some(fde) = fde {
dwarf_frametable.add_fde(cie_id, fde);
}
}
let mut eh_frame = EhFrame(WriterRelocate::new(target.triple().endianness().ok()));
dwarf_frametable.write_eh_frame(&mut eh_frame).unwrap();
let eh_frame_section = eh_frame.0.into_section();
custom_sections.push(eh_frame_section);
Some(Dwarf::new(SectionIndex::new(custom_sections.len() - 1)))
} else {
None
};
#[cfg(not(feature = "unwind"))]
let dwarf = None;
Ok(Compilation::new(
functions,
import_trampolines,
functions.into_iter().collect(),
custom_sections,
function_call_trampolines,
dynamic_function_trampolines,
None,
dwarf,
))
}
}