Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/cage/src/memory/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ pub fn fork_vmmap(parent_cageid: u64, child_cageid: u64) {

// set the wasm linear memory base address to vmmap
pub fn init_vmmap(cageid: u64, base_address: usize, program_break: Option<u32>) {
println!("[debug] init vmmap: base_address: {:?}", base_address);
let cage = get_cage(cageid).unwrap();
let mut vmmap = cage.vmmap.write();
vmmap.set_base_address(base_address);
Expand Down
1 change: 1 addition & 0 deletions src/rawposix/src/fs_calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,7 @@ pub fn mmap_syscall(
// if mmap addr is positive, that would mean the mapping is successful and we need to update the vmmap entry
if result >= 0 {
if result != useraddr {
println!("result: {}, useraddr: {}", result, useraddr);
panic!("MAP_FIXED not fixed");
}

Expand Down
2 changes: 2 additions & 0 deletions src/wasmtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ threei = { workspace = true }
cage = { workspace = true, optional = false }
fdtables = { workspace = true }
sysdefs = { workspace = true }
typemap = { workspace = true }
clap = { workspace = true }
anyhow = { workspace = true, features = ['std'] }
target-lexicon = { workspace = true }
Expand Down Expand Up @@ -233,6 +234,7 @@ rawposix = { path = "crates/rawposix" }
fdtables = { path = "crates/fdtables" }
sysdefs = { path = "crates/sysdefs" }
cage = { path = "crates/cage" }
typemap = { path = "crates/typemap" }

cranelift-wasm = { path = "cranelift/wasm", version = "0.110.0" }
cranelift-codegen = { path = "cranelift/codegen", version = "0.110.0", default-features = false, features = ["std", "unwind", "trace-log"] }
Expand Down
41 changes: 41 additions & 0 deletions src/wasmtime/crates/environ/src/compile/module_environ.rs
Original file line number Diff line number Diff line change
Expand Up @@ -769,6 +769,47 @@ and for re-adding support for interface types you can see this issue:
log::warn!("failed to parse name section {:?}", e);
}
}
KnownCustom::Dylink0(dylinks) => {
println!("[debug]: encounter dylink section");

for subsection in dylinks {
let subsection = subsection.unwrap();
match subsection {
wasmparser::Dylink0Subsection::MemInfo(meminfo) => {
println!("[debug]: meminfo: {:?}", meminfo);
self.result.module.dylink_mem_info.insert(crate::DylinkMemInfo {
memory_size: meminfo.memory_size,
memory_alignment: meminfo.memory_alignment,
table_size: meminfo.table_size,
table_alignment: meminfo.table_alignment
});
},
wasmparser::Dylink0Subsection::Needed(needed) => {
println!("[debug]: needed: {:?}", needed);
},
wasmparser::Dylink0Subsection::ExportInfo(exportinfo) => {
println!("[debug]: exportinfo: {:?}", exportinfo);
},
wasmparser::Dylink0Subsection::ImportInfo(importinfo) => {
println!("[debug]: importinfo: {:?}", importinfo);
let mut imports = vec![];
for import in importinfo {
imports.push(crate::DylinkImport {
module: import.module.to_owned(),
field: import.field.to_owned(),
flags: 0 // TODO: we assume the flag is always BINDING_WEAK for now
});
}
self.result.module.dylink_import_info.insert(crate::DylinkImportInfo {
imports: imports
});
},
_ => {
println!("[debug]: unknown dylink subsection!");
},
}
}
}
_ => {
let name = section.name().trim_end_matches(".dwo");
if name.starts_with(".debug_") {
Expand Down
59 changes: 59 additions & 0 deletions src/wasmtime/crates/environ/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,65 @@ pub struct Module {

/// WebAssembly global initializers for locally-defined globals.
pub global_initializers: PrimaryMap<DefinedGlobalIndex, ConstExpr>,

/// dylink memory information
pub dylink_mem_info: Option<DylinkMemInfo>,

/// dylink import information
pub dylink_import_info: Option<DylinkImportInfo>
}


/// lind-wasm addition: dylink memory information
#[derive(Debug, Serialize, Deserialize)]
pub struct DylinkMemInfo {
/// Size of the memory area the loader should reserve for the module, which
/// will begin at `env.__memory_base`.
pub memory_size: u32,

/// The required alignment of the memory area, in bytes, encoded as a power
/// of 2.
pub memory_alignment: u32,

/// Size of the table area the loader should reserve for the module, which
/// will begin at `env.__table_base`.
pub table_size: u32,

/// The required alignment of the table area, in elements, encoded as a
/// power of 2.
pub table_alignment: u32,
}

/// lind-wasm addition: dylink import information
#[derive(Debug, Serialize, Deserialize)]
pub struct DylinkImport {
/// module name of the import
pub module: String,
/// field name of the import
pub field: String,
/// flags associated with the import
pub flags: i32,
}

/// lind-wasm addition: dylink import information
#[derive(Debug, Serialize, Deserialize)]
pub struct DylinkImportInfo {
/// import info consist of a list of imports
pub imports: Vec<DylinkImport>
}

impl DylinkImportInfo {
/// check if the symbol is listed as a weak import
pub fn is_weak_symbol(&self, module: &str, field: &str) -> bool {
// TODO: doing linear search here is slow
for import in &self.imports {
if import.module == module && import.field == field {
// TODO: should check flag here
return true;
}
}
return false;
}
}

/// Initialization routines for creating an instance, encompassing imports,
Expand Down
36 changes: 33 additions & 3 deletions src/wasmtime/crates/lind-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use sysdefs::constants::lind_platform_const::{UNUSED_ARG, UNUSED_ID};
use threei::threei::{
copy_data_between_cages, copy_handler_table_to_cage, make_syscall, register_handler,
};
use wasmtime::Caller;
use wasmtime::{AsContextMut, Caller};
use wasmtime_lind_multi_process::{clone_constants::CloneArgStruct, get_memory_base, LindHost};
// These syscalls (`clone`, `exec`, `exit`, `fork`) require special handling
// inside Lind Wasmtime before delegating to RawPOSIX. For example, they may
Expand Down Expand Up @@ -56,15 +56,15 @@ impl LindCommonCtx {
&self,
call_number: u32,
call_name: u64,
caller: &mut Caller<'_, T>,
mut caller: &mut Caller<'_, T>,
arg1: u64,
arg2: u64,
arg3: u64,
arg4: u64,
arg5: u64,
arg6: u64,
) -> i32 {
let start_address = get_memory_base(&caller);
let start_address = get_memory_base(&mut caller);
// todo:
// replacing the execution path by calling to 3i first
match call_number as i32 {
Expand Down Expand Up @@ -211,6 +211,36 @@ pub fn add_to_linker<
},
)?;


linker.func_wrap(
"lind",
"lind-debug-num",
move |mut caller: Caller<'_, T>,
num: i32,|
-> i32 {
let base = get_memory_base(&mut caller);
// if num == 192456 || num == 192472 {
// let addr = (base + num as u64) as usize;
// unsafe {
// let p = addr as *const u8;
// let buf = std::slice::from_raw_parts(p, 128);
// for (i, &b) in buf.iter().enumerate() {
// if i % 16 == 0 { print!("\n{:016x}: ", addr + i); }
// print!("{:02x} ", b);
// }
// println!();
// }
// }
// unsafe {
// let debug_ptr = (base + 40960080) as *const i32;
// println!("[debug] memory base + 40960080: {} ({:?})", *debug_ptr, debug_ptr);
// }

println!("[debug] lind-debug-num: {} (base: {})", num, base);
num
},
)?;

// Registers grate-specific syscall-like host functions `register-syscall` / `cp-data-syscall` /
// `copy_handler_table_to_cage` into the Wasmtime linker. This is part of the 3i (inter-cage
// interposition) system, which allows user-level libc code (e.g., glibc) to perform cage-to-grate
Expand Down
24 changes: 15 additions & 9 deletions src/wasmtime/crates/lind-multi-process/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ impl<
.expect("Failed to find epoch global export!");

// retrieve the handler (underlying pointer) for the epoch global
let pointer = lind_epoch.get_handler(&mut store);
let pointer = lind_epoch.get_handler_as_u64(&mut store);
}
}

Expand Down Expand Up @@ -747,7 +747,7 @@ impl<
.expect("Failed to find epoch global export!");

// retrieve the handler (underlying pointer) for the epoch global
let pointer = lind_epoch.get_handler(&mut store);
let pointer = lind_epoch.get_handler_as_u64(&mut store);
}
}

Expand Down Expand Up @@ -1076,9 +1076,10 @@ impl<
// TODO: exit_call should be switched to epoch interrupt method later
pub fn exit_call(&self, mut caller: &mut Caller<'_, T>, code: i32) {
// get the base address of the memory
let handle = caller.as_context().0.instance(InstanceId::from_index(0));
let defined_memory = handle.get_memory(MemoryIndex::from_u32(0));
let address = defined_memory.base;
// let handle = caller.as_context().0.instance(InstanceId::from_index(0));
// let defined_memory = handle.get_memory(MemoryIndex::from_u32(0));
// let address = defined_memory.base;
let address = get_memory_base(&mut caller) as *mut u8;

// get the wasm stack top address
let parent_stack_low_usr = caller.as_context().get_stack_top();
Expand Down Expand Up @@ -1372,11 +1373,16 @@ impl<

// get the base address of the wasm process
pub fn get_memory_base<T: Clone + Send + 'static + std::marker::Sync>(
caller: &Caller<'_, T>,
mut caller: &mut Caller<'_, T>,
) -> u64 {
let handle = caller.as_context().0.instance(InstanceId::from_index(0));
let defined_memory = handle.get_memory(MemoryIndex::from_u32(0));
defined_memory.base as u64
// let handle = caller.as_context().0.instance(InstanceId::from_index(1));
// let defined_memory = handle.get_memory(MemoryIndex::from_u32(0));
let mut memory_iter = caller.as_context_mut().0.all_memories();
let memory = memory_iter.next().expect("no defined memory found").clone();
// assert!(memory_iter.next().is_none(), "multiple defined memory found");
drop(memory_iter);

memory.data_ptr(caller.as_context()) as u64
}

// entry point of fork syscall
Expand Down
1 change: 1 addition & 0 deletions src/wasmtime/crates/lind-utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ workspace = true
[dependencies]
anyhow = { workspace = true }
log = { workspace = true }
dashmap = { version = "5.1", features=["serde"] }
47 changes: 47 additions & 0 deletions src/wasmtime/crates/lind-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

use std::sync::{Condvar, Mutex};

use dashmap::DashMap;

pub mod lind_syscall_numbers;

// used to manage global active cage count. Used to determine when wasmtime can exit
Expand Down Expand Up @@ -57,3 +59,48 @@ pub fn parse_env_var(env_var: &str) -> (String, Option<String>) {
(env_var.to_string(), None)
}
}


#[allow(missing_docs)]
#[derive(Default)]
pub struct LindGOT {
global_offset_table: DashMap<String, u64> // use u64 instead of *mut i32 in order to share this struct across threads
}

impl LindGOT {
pub fn new() -> Self {
Self {
global_offset_table: DashMap::new()
}
}

pub fn new_entry(&mut self, name: String, handler: *mut u32) {
// to-do: handle existing GOT entry
self.global_offset_table.insert(name, handler as u64);
}

pub fn update_entry_if_exist(&self, name: &str, val: u32) -> bool {
if let Some(handler) = self.global_offset_table.get(name) {
let handler = (*handler) as *mut u32;
unsafe {
*handler = val;
}
} else {
// do nothing
return false;
}

return true;
}

pub fn get_entry_if_exist(&self, name: &str) -> Option<u32> {
if let Some(handler) = self.global_offset_table.get(name) {
let handler = (*handler) as *mut u32;
unsafe {
return Some(*handler);
}
} else {
return None;
}
}
}
1 change: 1 addition & 0 deletions src/wasmtime/crates/wasi-threads/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ rand = "0.8"
wasi-common = { workspace = true, features = ["exit"]}
wasmtime = { workspace = true, features = ['threads'] }
wasmtime-environ = { workspace = true }
cage = { path = "../cage" }
3 changes: 3 additions & 0 deletions src/wasmtime/crates/wasi-threads/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//! [`wasi-threads`]: https://github.com/WebAssembly/wasi-threads

use anyhow::{anyhow, Result};
use cage::init_vmmap;
use std::panic::{catch_unwind, AssertUnwindSafe};
use std::sync::atomic::{AtomicI32, Ordering};
use std::sync::Arc;
Expand Down Expand Up @@ -156,6 +157,8 @@ pub fn add_to_linker<T: Clone + Send + 'static>(
if let Some(m) = import.ty().memory() {
if m.is_shared() {
let mem = SharedMemory::new(module.engine(), m.clone())?;
let memory_base = mem.get_memory_base();
init_vmmap(1, memory_base as usize, None);
linker.define(store, import.module(), import.name(), mem.clone())?;
} else {
return Err(anyhow!(
Expand Down
11 changes: 10 additions & 1 deletion src/wasmtime/crates/wasmtime/src/runtime/externals/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ impl Global {
}

// retrieve the underlying pointer of the wasm Global
pub fn get_handler(&self, mut store: impl AsContextMut) -> *mut u64 {
pub fn get_handler_as_u64(&self, mut store: impl AsContextMut) -> *mut u64 {
let mut store = AutoAssertNoGc::new(store.as_context_mut().0);
let global_ty = self._ty(&store);
unsafe {
Expand All @@ -224,6 +224,15 @@ impl Global {
}
}

pub fn get_handler_as_u32(&self, mut store: impl AsContextMut) -> *mut u32 {
let mut store = AutoAssertNoGc::new(store.as_context_mut().0);
let global_ty = self._ty(&store);
unsafe {
let definition = &mut *store[self.0].definition;
definition.as_u32_mut()
}
}

pub(crate) fn trace_root(&self, store: &mut StoreOpaque, gc_roots_list: &mut GcRootsList) {
if let Some(ref_ty) = self._ty(store).content().as_ref() {
if !ref_ty.is_vmgcref_type_and_points_to_object() {
Expand Down
Loading