diff --git a/src/webassembly/instance.rs b/src/webassembly/instance.rs index 6579077e5..e13eaa342 100644 --- a/src/webassembly/instance.rs +++ b/src/webassembly/instance.rs @@ -21,8 +21,8 @@ use super::super::common::slice::{BoundedSlice, UncheckedSlice}; use super::errors::ErrorKind; use super::import_object::ImportObject; use super::memory::LinearMemory; -use super::module::Module; use super::module::Export; +use super::module::Module; use super::relocation::{Reloc, RelocSink, RelocationType}; pub fn protect_codebuf(code_buf: &Vec) -> Result<(), String> { @@ -204,11 +204,10 @@ impl Instance { // The relocations are relative to the relocation's address plus four bytes // TODO: Support architectures other than x64, and other reloc kinds. for (i, function_relocs) in relocations.iter().enumerate() { - // for r in function_relocs { - for (ref reloc, ref reloc_type) in function_relocs { - let target_func_address: isize = match reloc_type { + for ref reloc in function_relocs { + let target_func_address: isize = match reloc.target { RelocationType::Normal(func_index) => { - get_function_addr(&FuncIndex::new(*func_index as usize), &import_functions, &functions) as isize + get_function_addr(&FuncIndex::new(func_index as usize), &import_functions, &functions) as isize }, RelocationType::CurrentMemory => { current_memory as isize @@ -244,15 +243,8 @@ impl Instance { // RelocationType::Intrinsic(name) => { // get_abi_intrinsic(name)? // }, - // RelocationTarget::UserFunc(index) => { - // functions[module.defined_func_index(index).expect( - // "relocation to imported function not supported yet", - // )].as_ptr() as isize - // } - // RelocationTarget::GrowMemory => grow_memory as isize, - // RelocationTarget::CurrentMemory => current_memory as isize, }; - // print!("FUNCTION {:?}", target_func_address); + let func_addr = get_function_addr(&FuncIndex::new(i), &import_functions, &functions); match reloc.reloc { @@ -272,47 +264,6 @@ impl Instance { }, _ => panic!("unsupported reloc kind"), } - // let reloc_address = unsafe { - // (target_func_address.to_owned().as_mut_ptr() as *const u8).offset(reloc.offset as isize) - // }; - - // match reloc.reloc { - // Reloc::Abs8 => { - // unsafe { - // // (reloc_address as *mut usize).write(target_func_address.to_owned().as_ptr() as usize); - // } - // } - // _ => unimplemented!() - // } - - // let target_func_address: isize = match r.reloc_target { - // RelocationTarget::UserFunc(index) => { - // functions[module.defined_func_index(index).expect( - // "relocation to imported function not supported yet", - // )].as_ptr() as isize - // } - // RelocationTarget::GrowMemory => grow_memory as isize, - // RelocationTarget::CurrentMemory => current_memory as isize, - // }; - - // let body = &mut functions[i]; - // match r.reloc { - // Reloc::Abs8 => unsafe { - // let reloc_address = body.as_mut_ptr().offset(r.offset as isize) as i64; - // let reloc_addend = r.addend; - // let reloc_abs = target_func_address as i64 + reloc_addend; - // write_unaligned(reloc_address as *mut i64, reloc_abs); - // }, - // Reloc::X86PCRel4 => unsafe { - // let reloc_address = body.as_mut_ptr().offset(r.offset as isize) as isize; - // let reloc_addend = r.addend as isize; - // // TODO: Handle overflow. - // let reloc_delta_i32 = - // (target_func_address - reloc_address + reloc_addend) as i32; - // write_unaligned(reloc_address as *mut i32, reloc_delta_i32); - // }, - // _ => panic!("unsupported reloc kind"), - // } } } @@ -547,10 +498,10 @@ impl Clone for Instance { extern "C" fn grow_memory(size: u32, memory_index: u32, vmctx: &mut VmCtx) -> i32 { let mut instance = &mut vmctx.user_data.instance; - instance.memory_mut(memory_index as usize) - .grow(size) - .unwrap_or(i32::max_value()) // Should be -1 ? - + instance + .memory_mut(memory_index as usize) + .grow(size) + .unwrap_or(i32::max_value()) // Should be -1 ? } extern "C" fn current_memory(memory_index: u32, vmctx: &VmCtx) -> u32 { diff --git a/src/webassembly/relocation.rs b/src/webassembly/relocation.rs index 179986e5e..5a9d00d6a 100644 --- a/src/webassembly/relocation.rs +++ b/src/webassembly/relocation.rs @@ -8,7 +8,7 @@ use cranelift_codegen::ir::{self, ExternalName, LibCall, SourceLoc, TrapCode}; pub use cranelift_codegen::binemit::Reloc; use cranelift_wasm::FuncIndex; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct Relocation { /// The relocation code. pub reloc: binemit::Reloc, @@ -16,10 +16,12 @@ pub struct Relocation { pub offset: binemit::CodeOffset, /// The addend to add to the relocation value. pub addend: binemit::Addend, + /// Relocation type. + pub target: RelocationType, } /// Specify the type of relocation -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum RelocationType { Normal(u32), Intrinsic(String), @@ -30,9 +32,8 @@ pub enum RelocationType { /// Implementation of a relocation sink that just saves all the information for later pub struct RelocSink { - // func: &'func ir::Function, /// Relocations recorded for the function. - pub func_relocs: Vec<(Relocation, RelocationType)>, + pub func_relocs: Vec, } impl binemit::RelocSink for RelocSink { @@ -57,14 +58,12 @@ impl binemit::RelocSink for RelocSink { namespace: 0, index, } => { - self.func_relocs.push(( - Relocation { - reloc, - offset, - addend, - }, - RelocationType::Normal(index as _), - )); + self.func_relocs.push(Relocation { + reloc, + offset, + addend, + target: RelocationType::Normal(index as _), + }); } ExternalName::TestCase { length, ascii } => { let (slice, _) = ascii.split_at(length as usize); @@ -74,25 +73,21 @@ impl binemit::RelocSink for RelocSink { "grow_memory" => RelocationType::GrowMemory, _ => RelocationType::Intrinsic(name), }; - self.func_relocs.push(( - Relocation { - reloc, - offset, - addend, - }, - relocation_type, - )); + self.func_relocs.push(Relocation { + reloc, + offset, + addend, + target: relocation_type, + }); } ExternalName::LibCall(libcall) => { let relocation_type = RelocationType::LibCall(libcall); - self.func_relocs.push(( - Relocation { - reloc, - offset, - addend, - }, - relocation_type, - )); + self.func_relocs.push(Relocation { + reloc, + offset, + addend, + target: relocation_type, + }); } _ => { unimplemented!(); @@ -109,6 +104,7 @@ impl binemit::RelocSink for RelocSink { } } +/// Implementation of a relocation sink that just saves all the information for later impl RelocSink { pub fn new() -> RelocSink { RelocSink { @@ -117,88 +113,6 @@ impl RelocSink { } } -/// Implementation of a relocation sink that just saves all the information for later -// pub struct RelocSink { -// /// Relocations recorded for the function. -// pub func_relocs: Vec, -// } - -// impl binemit::RelocSink for RelocSink { -// fn reloc_ebb( -// &mut self, -// _offset: binemit::CodeOffset, -// _reloc: binemit::Reloc, -// _ebb_offset: binemit::CodeOffset, -// ) { -// // This should use the `offsets` field of `ir::Function`. -// panic!("ebb headers not yet implemented"); -// } -// fn reloc_external( -// &mut self, -// offset: binemit::CodeOffset, -// reloc: binemit::Reloc, -// name: &ExternalName, -// addend: binemit::Addend, -// ) { -// let reloc_target = if let ExternalName::User { namespace, index } = *name { -// debug_assert!(namespace == 0); -// RelocationTarget::UserFunc(FuncIndex::new(index as usize)) -// } else if *name == ExternalName::testcase("grow_memory") { -// RelocationTarget::GrowMemory -// } else if *name == ExternalName::testcase("current_memory") { -// RelocationTarget::CurrentMemory -// } else { -// panic!("unrecognized external name") -// }; -// self.func_relocs.push(Relocation { -// reloc, -// reloc_target, -// offset, -// addend, -// }); -// } -// fn reloc_jt( -// &mut self, -// _offset: binemit::CodeOffset, -// _reloc: binemit::Reloc, -// _jt: ir::JumpTable, -// ) { -// panic!("jump tables not yet implemented"); -// } -// } - -// impl RelocSink { -// pub fn new() -> Self { -// Self { -// func_relocs: Vec::new(), -// } -// } -// } - -// /// A record of a relocation to perform. -// #[derive(Debug, Clone)] -// pub struct Relocation { -// /// The relocation code. -// pub reloc: binemit::Reloc, -// /// Relocation target. -// pub reloc_target: RelocationTarget, -// /// The offset where to apply the relocation. -// pub offset: binemit::CodeOffset, -// /// The addend to add to the relocation value. -// pub addend: binemit::Addend, -// } - -// /// Destination function. Can be either user function or some special one, like grow_memory. -// #[derive(Debug, Copy, Clone)] -// pub enum RelocationTarget { -// /// The user function index. -// UserFunc(FuncIndex), -// /// Function for growing the default memory by the specified amount of pages. -// GrowMemory, -// /// Function for query current size of the default linear memory. -// CurrentMemory, -// } - pub struct TrapData { pub offset: usize, pub code: TrapCode,