wasmer_compiler_singlepass/
elf.rs1use crate::unwind::UnwindFrame;
2#[cfg(feature = "unwind")]
3use crate::unwind::create_systemv_cie;
4#[cfg(feature = "unwind")]
5use gimli::{
6 constants,
7 write::{EhFrame, FrameTable},
8};
9use object::{
10 SymbolFlags, SymbolKind, SymbolScope,
11 write::{StandardSection, Symbol, SymbolSection},
12};
13
14#[cfg(feature = "unwind")]
15use wasmer_compiler::dwarf::{DwarfState, WriterRelocate};
16#[cfg(feature = "unwind")]
17use wasmer_compiler::elf::emit_eh_frame_section;
18use wasmer_compiler::{
19 elf::{add_relocations, emit_trap_section},
20 misc::{CompiledFunctionExt, CompiledKind},
21 object::get_object_for_target,
22 types::function::CompiledFunction,
23};
24use wasmer_types::{CompileError, LocalFunctionIndex, target::Target};
25
26pub(crate) use wasmer_compiler::elf::{
27 CompileOutput, compile_output_in_memory, compile_output_objects, emit_function_body,
28 emit_import_trampoline, link_module,
29};
30
31pub(crate) fn emit_local_function(
32 target: &Target,
33 index: LocalFunctionIndex,
34 function: CompiledFunction,
35 fde: Option<UnwindFrame>,
36 #[cfg(feature = "unwind")] mut dwarf_state: Option<DwarfState>,
37) -> Result<Vec<u8>, CompileError> {
38 let kind = CompiledKind::Local(index, String::new());
39 let mut object = get_object_for_target(target.triple())
40 .map_err(|e| CompileError::Codegen(format!("cannot create object: {e}")))?;
41 let symbol = object.add_symbol(Symbol {
42 name: kind.linkage_name().into_bytes(),
43 value: 0,
44 size: function.body.body.len() as u64,
45 kind: SymbolKind::Text,
46 scope: SymbolScope::Linkage,
47 weak: false,
48 section: SymbolSection::Undefined,
49 flags: SymbolFlags::None,
50 });
51 let text = object.section_id(StandardSection::Text);
52 object.add_symbol_data(symbol, text, &function.body.body, 4);
53 add_relocations(
54 &mut object,
55 text,
56 &function.relocations,
57 Some((index, symbol)),
58 )?;
59
60 #[cfg(feature = "unwind")]
61 if let Some(dwarf_state) = dwarf_state.as_mut() {
62 dwarf_state.write_sections(
63 &mut object,
64 symbol,
65 function.body.body.len() as u64,
66 target.triple().endianness().ok(),
67 )?;
68 }
69
70 emit_trap_section(&mut object, &kind, &function.frame_info.traps);
71
72 #[cfg(feature = "unwind")]
73 if let Some(fde) = fde
74 && let Some(mut cie) = create_systemv_cie(target.triple().architecture)
75 {
76 cie.fde_address_encoding = constants::DW_EH_PE_pcrel | constants::DW_EH_PE_sdata4;
79 let mut frametable = FrameTable::default();
80 let cie_id = frametable.add_cie(cie);
81 match fde {
82 UnwindFrame::SystemV(fde) => {
83 frametable.add_fde(cie_id, fde);
84 }
85 }
86 let mut eh_frame = EhFrame(WriterRelocate::new());
87 frametable
88 .write_eh_frame(&mut eh_frame)
89 .map_err(|e| CompileError::Codegen(format!("failed to write .eh_frame: {e}")))?;
90
91 let relocations = eh_frame.0.relocs.clone();
92 emit_eh_frame_section(
93 &mut object,
94 &eh_frame.0.into_bytes(),
95 &relocations,
96 symbol,
97 None,
98 )?;
99 }
100 #[cfg(not(feature = "unwind"))]
101 let _ = fde;
102
103 object
104 .write()
105 .map_err(|e| CompileError::Codegen(format!("failed to serialize object: {e}")))
106}