mirror of
https://github.com/mii443/wasmer.git
synced 2025-08-24 01:09:26 +00:00
Added some infrastructure to generate EH_Frame in singlepass compiler
This commit is contained in:
@ -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,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user