1use crate::builder::{ObjectBuilder, ObjectBuilderTarget};
2use crate::context::layout_vmcontext;
3use crate::data_segment::{declare_data_segment, emit_data_segment};
4use crate::table::{declare_table, emit_table};
5use anyhow::Result;
6use object::write::{Object, Relocation, StandardSection, Symbol, SymbolSection};
7use object::{RelocationEncoding, RelocationKind, SymbolFlags, SymbolKind, SymbolScope};
8use wasmtime_debug::DwarfSection;
9use wasmtime_environ::isa::TargetFrontendConfig;
10use wasmtime_environ::{CompiledFunctions, MemoryInitialization, Module};
11
12fn emit_vmcontext_init(
13 obj: &mut Object,
14 module: &Module,
15 target_config: &TargetFrontendConfig,
16) -> Result<()> {
17 let (data, table_relocs) = layout_vmcontext(module, target_config);
18 let symbol_id = obj.add_symbol(Symbol {
19 name: "_vmcontext_init".as_bytes().to_vec(),
20 value: 0,
21 size: 0,
22 kind: SymbolKind::Data,
23 scope: SymbolScope::Linkage,
24 weak: false,
25 section: SymbolSection::Undefined,
26 flags: SymbolFlags::None,
27 });
28 let section_id = obj.section_id(StandardSection::Data);
29 let section_offset = obj.add_symbol_data(symbol_id, section_id, &data, 1);
30
31 for reloc in table_relocs.iter() {
32 let target_name = format!("_table_{}", reloc.index);
33 let target_symbol = obj.symbol_id(target_name.as_bytes()).unwrap();
34 obj.add_relocation(
35 section_id,
36 Relocation {
37 offset: section_offset + reloc.offset as u64,
38 size: 64, kind: RelocationKind::Absolute,
40 encoding: RelocationEncoding::Generic,
41 symbol: target_symbol,
42 addend: 0,
43 },
44 )?;
45 }
46 Ok(())
47}
48
49pub fn emit_module(
52 target: ObjectBuilderTarget,
53 module: &Module,
54 target_config: &TargetFrontendConfig,
55 compilation: CompiledFunctions,
56 dwarf_sections: Vec<DwarfSection>,
57) -> Result<Object> {
58 let mut builder = ObjectBuilder::new(target, module, &compilation);
59 builder.set_dwarf_sections(dwarf_sections);
60 let mut obj = builder.build()?;
61
62 match &module.memory_initialization {
64 MemoryInitialization::Segmented(initializers) => {
65 for (i, initializer) in initializers.iter().enumerate() {
66 declare_data_segment(&mut obj, initializer, i)?;
67 }
68 }
69 _ => unimplemented!(),
70 }
71
72 for i in 0..module.table_plans.len() {
73 declare_table(&mut obj, i)?;
74 }
75
76 match &module.memory_initialization {
77 MemoryInitialization::Segmented(initializers) => {
78 for (i, initializer) in initializers.iter().enumerate() {
79 emit_data_segment(&mut obj, initializer, i)?;
80 }
81 }
82 _ => unimplemented!(),
83 }
84
85 for i in 0..module.table_plans.len() {
86 emit_table(&mut obj, i)?;
87 }
88
89 emit_vmcontext_init(&mut obj, module, target_config)?;
90
91 Ok(obj)
92}