1 use anyhow::Result;
2 use faerie::{Artifact, Decl, Link};
3 use wasmtime_environ::entity::EntityRef;
4 use wasmtime_environ::settings;
5 use wasmtime_environ::settings::Configurable;
6 use wasmtime_environ::{Compilation, Module, RelocationTarget, Relocations};
7
8 /// Defines module functions
declare_functions( obj: &mut Artifact, module: &Module, relocations: &Relocations, ) -> Result<()>9 pub fn declare_functions(
10 obj: &mut Artifact,
11 module: &Module,
12 relocations: &Relocations,
13 ) -> Result<()> {
14 for i in 0..module.local.num_imported_funcs {
15 let string_name = format!("_wasm_function_{}", i);
16 obj.declare(string_name, Decl::function_import())?;
17 }
18 for (i, _function_relocs) in relocations.iter().rev() {
19 let func_index = module.local.func_index(i);
20 let string_name = format!("_wasm_function_{}", func_index.index());
21 obj.declare(string_name, Decl::function().global())?;
22 }
23 Ok(())
24 }
25
26 /// Emits module functions
emit_functions( obj: &mut Artifact, module: &Module, compilation: &Compilation, relocations: &Relocations, ) -> Result<()>27 pub fn emit_functions(
28 obj: &mut Artifact,
29 module: &Module,
30 compilation: &Compilation,
31 relocations: &Relocations,
32 ) -> Result<()> {
33 debug_assert!(
34 module.start_func.is_none()
35 || module.start_func.unwrap().index() >= module.local.num_imported_funcs,
36 "imported start functions not supported yet"
37 );
38
39 let mut shared_builder = settings::builder();
40 shared_builder
41 .enable("enable_verifier")
42 .expect("Missing enable_verifier setting");
43
44 for (i, _function_relocs) in relocations.iter() {
45 let body = &compilation.get(i).body;
46 let func_index = module.local.func_index(i);
47 let string_name = format!("_wasm_function_{}", func_index.index());
48
49 obj.define(string_name, body.clone())?;
50 }
51
52 for (i, function_relocs) in relocations.iter() {
53 let func_index = module.local.func_index(i);
54 let string_name = format!("_wasm_function_{}", func_index.index());
55 for r in function_relocs {
56 debug_assert_eq!(r.addend, 0);
57 match r.reloc_target {
58 RelocationTarget::UserFunc(target_index) => {
59 let target_name = format!("_wasm_function_{}", target_index.index());
60 obj.link(Link {
61 from: &string_name,
62 to: &target_name,
63 at: r.offset as u64,
64 })?;
65 }
66 RelocationTarget::JumpTable(_, _) => {
67 // ignore relocations for jump tables
68 }
69 _ => panic!("relocations target not supported yet: {:?}", r.reloc_target),
70 };
71 }
72 }
73
74 Ok(())
75 }
76