mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-22 13:11:32 +00:00
add support for symbol maps
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -1330,6 +1330,7 @@ name = "wasmer"
|
|||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
"structopt 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"wabt 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"wasmer-clif-backend 0.2.0",
|
"wasmer-clif-backend 0.2.0",
|
||||||
|
@ -21,6 +21,7 @@ include = [
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
structopt = "0.2.11"
|
structopt = "0.2.11"
|
||||||
wabt = "0.7.2"
|
wabt = "0.7.2"
|
||||||
|
hashbrown = "0.1.8"
|
||||||
wasmer-clif-backend = { path = "lib/clif-backend" }
|
wasmer-clif-backend = { path = "lib/clif-backend" }
|
||||||
wasmer-runtime = { path = "lib/runtime" }
|
wasmer-runtime = { path = "lib/runtime" }
|
||||||
wasmer-runtime-core = { path = "lib/runtime-core" }
|
wasmer-runtime-core = { path = "lib/runtime-core" }
|
||||||
|
@ -385,7 +385,13 @@ extern "C" fn f32_print(_ctx: &mut vm::Ctx, n: f32) {
|
|||||||
extern "C" fn f64_print(_ctx: &mut vm::Ctx, n: f64) {
|
extern "C" fn f64_print(_ctx: &mut vm::Ctx, n: f64) {
|
||||||
print!(" f64: {},", n);
|
print!(" f64: {},", n);
|
||||||
}
|
}
|
||||||
extern "C" fn start_debug(_ctx: &mut vm::Ctx, func_index: u32) {
|
extern "C" fn start_debug(ctx: &mut vm::Ctx, func_index: u32) {
|
||||||
|
if let Some(symbol_map) = &ctx.maybe_symbol_map {
|
||||||
|
if let Some(fn_name) = symbol_map.get(&func_index) {
|
||||||
|
print!("func ({} - {}), args: [", fn_name, func_index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
print!("func ({}), args: [", func_index);
|
print!("func ({}), args: [", func_index);
|
||||||
}
|
}
|
||||||
extern "C" fn end_debug(_ctx: &mut vm::Ctx) {
|
extern "C" fn end_debug(_ctx: &mut vm::Ctx) {
|
||||||
|
@ -13,6 +13,7 @@ use crate::{
|
|||||||
types::{FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, TableIndex, Value},
|
types::{FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, TableIndex, Value},
|
||||||
vm,
|
vm,
|
||||||
};
|
};
|
||||||
|
use hashbrown::HashMap;
|
||||||
use std::{mem, sync::Arc};
|
use std::{mem, sync::Arc};
|
||||||
|
|
||||||
pub(crate) struct InstanceInner {
|
pub(crate) struct InstanceInner {
|
||||||
@ -39,12 +40,16 @@ impl Drop for InstanceInner {
|
|||||||
pub struct Instance {
|
pub struct Instance {
|
||||||
module: Arc<ModuleInner>,
|
module: Arc<ModuleInner>,
|
||||||
inner: Box<InstanceInner>,
|
inner: Box<InstanceInner>,
|
||||||
#[allow(dead_code)]
|
|
||||||
import_object: ImportObject,
|
import_object: ImportObject,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Instance {
|
impl Instance {
|
||||||
pub(crate) fn new(module: Arc<ModuleInner>, imports: &ImportObject) -> Result<Instance> {
|
pub(crate) fn new(
|
||||||
|
module: Arc<ModuleInner>,
|
||||||
|
imports: &ImportObject,
|
||||||
|
maybe_symbol_map: Option<HashMap<u32, String>>,
|
||||||
|
) -> Result<Instance> {
|
||||||
// We need the backing and import_backing to create a vm::Ctx, but we need
|
// We need the backing and import_backing to create a vm::Ctx, but we need
|
||||||
// a vm::Ctx to create a backing and an import_backing. The solution is to create an
|
// a vm::Ctx to create a backing and an import_backing. The solution is to create an
|
||||||
// uninitialized vm::Ctx and then initialize it in-place.
|
// uninitialized vm::Ctx and then initialize it in-place.
|
||||||
@ -63,7 +68,12 @@ impl Instance {
|
|||||||
// Initialize the vm::Ctx in-place after the backing
|
// Initialize the vm::Ctx in-place after the backing
|
||||||
// has been boxed.
|
// has been boxed.
|
||||||
unsafe {
|
unsafe {
|
||||||
*inner.vmctx = vm::Ctx::new(&mut inner.backing, &mut inner.import_backing, &module)
|
*inner.vmctx = vm::Ctx::new(
|
||||||
|
&mut inner.backing,
|
||||||
|
&mut inner.import_backing,
|
||||||
|
&module,
|
||||||
|
maybe_symbol_map,
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let instance = Instance {
|
let instance = Instance {
|
||||||
|
@ -100,8 +100,12 @@ impl Module {
|
|||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn instantiate(&self, import_object: &ImportObject) -> error::Result<Instance> {
|
pub fn instantiate(
|
||||||
Instance::new(Arc::clone(&self.inner), import_object)
|
&self,
|
||||||
|
import_object: &ImportObject,
|
||||||
|
maybe_symbol_map: Option<HashMap<u32, String>>,
|
||||||
|
) -> error::Result<Instance> {
|
||||||
|
Instance::new(Arc::clone(&self.inner), import_object, maybe_symbol_map)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cache(&self) -> Result<Artifact, CacheError> {
|
pub fn cache(&self) -> Result<Artifact, CacheError> {
|
||||||
|
@ -5,6 +5,7 @@ use crate::{
|
|||||||
structures::TypedIndex,
|
structures::TypedIndex,
|
||||||
types::{LocalOrImport, MemoryIndex},
|
types::{LocalOrImport, MemoryIndex},
|
||||||
};
|
};
|
||||||
|
use hashbrown::HashMap;
|
||||||
use std::{ffi::c_void, mem, ptr};
|
use std::{ffi::c_void, mem, ptr};
|
||||||
|
|
||||||
/// The context of the currently running WebAssembly instance.
|
/// The context of the currently running WebAssembly instance.
|
||||||
@ -24,6 +25,8 @@ pub struct Ctx {
|
|||||||
|
|
||||||
pub data: *mut c_void,
|
pub data: *mut c_void,
|
||||||
pub data_finalizer: Option<extern "C" fn(data: *mut c_void)>,
|
pub data_finalizer: Option<extern "C" fn(data: *mut c_void)>,
|
||||||
|
|
||||||
|
pub maybe_symbol_map: Option<HashMap<u32, String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The internal context of the currently running WebAssembly instance.
|
/// The internal context of the currently running WebAssembly instance.
|
||||||
@ -67,6 +70,7 @@ impl Ctx {
|
|||||||
local_backing: &mut LocalBacking,
|
local_backing: &mut LocalBacking,
|
||||||
import_backing: &mut ImportBacking,
|
import_backing: &mut ImportBacking,
|
||||||
module: &ModuleInner,
|
module: &ModuleInner,
|
||||||
|
maybe_symbol_map: Option<HashMap<u32, String>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
internal: InternalCtx {
|
internal: InternalCtx {
|
||||||
@ -89,6 +93,7 @@ impl Ctx {
|
|||||||
|
|
||||||
data: ptr::null_mut(),
|
data: ptr::null_mut(),
|
||||||
data_finalizer: None,
|
data_finalizer: None,
|
||||||
|
maybe_symbol_map,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,6 +126,7 @@ impl Ctx {
|
|||||||
|
|
||||||
data,
|
data,
|
||||||
data_finalizer: Some(data_finalizer),
|
data_finalizer: Some(data_finalizer),
|
||||||
|
maybe_symbol_map: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ pub fn compile(wasm: &[u8]) -> error::CompileResult<Module> {
|
|||||||
/// depending on the cause of the failure.
|
/// depending on the cause of the failure.
|
||||||
pub fn instantiate(wasm: &[u8], import_object: &ImportObject) -> error::Result<Instance> {
|
pub fn instantiate(wasm: &[u8], import_object: &ImportObject) -> error::Result<Instance> {
|
||||||
let module = compile(wasm)?;
|
let module = compile(wasm)?;
|
||||||
module.instantiate(import_object)
|
module.instantiate(import_object, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a single instance of the default compiler to use.
|
/// Get a single instance of the default compiler to use.
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
extern crate structopt;
|
extern crate structopt;
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs::File;
|
use std::fs::{read_to_string, File};
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
|
|
||||||
|
use hashbrown::HashMap;
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
|
|
||||||
use wasmer::webassembly::InstanceABI;
|
use wasmer::webassembly::InstanceABI;
|
||||||
@ -44,6 +45,10 @@ struct Run {
|
|||||||
/// Application arguments
|
/// Application arguments
|
||||||
#[structopt(name = "--", raw(multiple = "true"))]
|
#[structopt(name = "--", raw(multiple = "true"))]
|
||||||
args: Vec<String>,
|
args: Vec<String>,
|
||||||
|
|
||||||
|
/// Symbol map
|
||||||
|
#[structopt(long = "symbol-map", parse(from_os_str))]
|
||||||
|
symbol_map: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, StructOpt)]
|
#[derive(Debug, StructOpt)]
|
||||||
@ -98,6 +103,48 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
|
|||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
let maybe_symbol_map = if let Some(symbol_map_path) = options.symbol_map.clone() {
|
||||||
|
let symbol_map_content: String = read_to_string(&symbol_map_path)
|
||||||
|
.map_err(|err| {
|
||||||
|
format!(
|
||||||
|
"Can't read symbol map file {}: {}",
|
||||||
|
symbol_map_path.as_os_str().to_string_lossy(),
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
})?
|
||||||
|
.to_owned();
|
||||||
|
let mut symbol_map = HashMap::new();
|
||||||
|
for line in symbol_map_content.lines() {
|
||||||
|
let mut split = line.split(':');
|
||||||
|
let num_str = if let Some(ns) = split.next() {
|
||||||
|
ns
|
||||||
|
} else {
|
||||||
|
return Err(format!(
|
||||||
|
"Can't parse symbol map (expected each entry to be of the form: `0:func_name`)"
|
||||||
|
));
|
||||||
|
};
|
||||||
|
let num: u32 = num_str.parse::<u32>().map_err(|err| {
|
||||||
|
format!(
|
||||||
|
"Failed to parse {} as a number in symbol map: {}",
|
||||||
|
num_str, err
|
||||||
|
)
|
||||||
|
})?;
|
||||||
|
let name_str: String = if let Some(name_str) = split.next() {
|
||||||
|
name_str
|
||||||
|
} else {
|
||||||
|
return Err(format!(
|
||||||
|
"Can't parse symbol map (expected each entry to be of the form: `0:func_name`)"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
.to_owned();
|
||||||
|
|
||||||
|
symbol_map.insert(num, name_str);
|
||||||
|
}
|
||||||
|
Some(symbol_map)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
if !utils::is_wasm_binary(&wasm_binary) {
|
if !utils::is_wasm_binary(&wasm_binary) {
|
||||||
wasm_binary = wabt::wat2wasm(wasm_binary)
|
wasm_binary = wabt::wat2wasm(wasm_binary)
|
||||||
.map_err(|e| format!("Can't convert from wast to wasm: {:?}", e))?;
|
.map_err(|e| format!("Can't convert from wast to wasm: {:?}", e))?;
|
||||||
@ -159,7 +206,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut instance = module
|
let mut instance = module
|
||||||
.instantiate(&import_object)
|
.instantiate(&import_object, maybe_symbol_map)
|
||||||
.map_err(|e| format!("Can't instantiate module: {:?}", e))?;
|
.map_err(|e| format!("Can't instantiate module: {:?}", e))?;
|
||||||
|
|
||||||
webassembly::run_instance(
|
webassembly::run_instance(
|
||||||
|
@ -42,7 +42,7 @@ pub fn instantiate(buffer_source: &[u8], import_object: ImportObject) -> Result<
|
|||||||
let module = compile(&buffer_source[..])?;
|
let module = compile(&buffer_source[..])?;
|
||||||
|
|
||||||
debug!("webassembly - instantiating");
|
debug!("webassembly - instantiating");
|
||||||
let instance = module.instantiate(&import_object)?;
|
let instance = module.instantiate(&import_object, None)?;
|
||||||
|
|
||||||
debug!("webassembly - instance created");
|
debug!("webassembly - instance created");
|
||||||
Ok(ResultObject {
|
Ok(ResultObject {
|
||||||
|
Reference in New Issue
Block a user