From 69cdfbb134348de15c7353c38afa6357f971d050 Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Wed, 28 Jul 2021 14:41:22 -0700 Subject: [PATCH 1/3] Added issues to test in compilers --- tests/compilers/issues.rs | 71 +++++++++++++++++++++++++++++++++++++++ tests/compilers/main.rs | 1 + 2 files changed, 72 insertions(+) create mode 100644 tests/compilers/issues.rs diff --git a/tests/compilers/issues.rs b/tests/compilers/issues.rs new file mode 100644 index 00000000000..cae62d891cd --- /dev/null +++ b/tests/compilers/issues.rs @@ -0,0 +1,71 @@ +//! This file is mainly to assure specific issues are working well +use anyhow::Result; +use wasmer::*; + +/// Corruption of WasmerEnv when using call indirect. +/// +/// Note: this one is specific to Singlepass, but we want to test in all +/// available compilers. +/// +/// https://github.com/wasmerio/wasmer/issues/2329 +#[compiler_test(issues)] +fn issue_2329(mut config: crate::Config) -> Result<()> { + let store = config.store(); + + #[derive(Clone, Default, WasmerEnv)] + pub struct Env { + #[wasmer(export)] + memory: LazyInit, + } + + impl Env { + pub fn new() -> Self { + Self { + memory: LazyInit::new(), + } + } + } + + pub fn read_memory(env: &Env, guest_ptr: u32) -> u32 { + dbg!(env.memory_ref()); + dbg!(guest_ptr); + 0 + } + + let wat = r#" + (module + (type (;0;) (func (param i32) (result i32))) + (type (;1;) (func)) + (import "env" "__read_memory" (func $__read_memory (type 0))) + (func $read_memory (type 1) + (drop + (call $__read_memory + (i32.const 2))) + (drop + (call $__read_memory + (i32.const 1)))) + (table (;0;) 1 1 funcref) + (memory (;0;) 16) + (global (;0;) (mut i32) (i32.const 1048576)) + (global (;1;) i32 (i32.const 1048576)) + (global (;2;) i32 (i32.const 1048576)) + (export "memory" (memory 0)) + (export "read_memory" (func $read_memory)) + (export "__data_end" (global 1)) + (export "__heap_base" (global 2))) + "#; + let module = Module::new(&store, wat)?; + let env = Env::new(); + let imports: ImportObject = imports! { + "env" => { + "__read_memory" => Function::new_native_with_env( + &store, + env.clone(), + read_memory + ), + } + }; + let instance = Instance::new(&module, &imports)?; + instance.exports.get_function("read_memory")?.call(&[])?; + Ok(()) +} diff --git a/tests/compilers/main.rs b/tests/compilers/main.rs index b80a13e482c..5b85deb0382 100644 --- a/tests/compilers/main.rs +++ b/tests/compilers/main.rs @@ -7,6 +7,7 @@ extern crate compiler_test_derive; mod config; mod imports; +mod issues; mod metering; mod middlewares; // mod multi_value_imports; From e0fce0ae9d87c273e0b523ebb51d3245036fe95b Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Wed, 28 Jul 2021 17:05:46 -0700 Subject: [PATCH 2/3] Use test that trigger issue --- tests/compilers/issues.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/tests/compilers/issues.rs b/tests/compilers/issues.rs index cae62d891cd..508ec0fee7a 100644 --- a/tests/compilers/issues.rs +++ b/tests/compilers/issues.rs @@ -36,15 +36,21 @@ fn issue_2329(mut config: crate::Config) -> Result<()> { (module (type (;0;) (func (param i32) (result i32))) (type (;1;) (func)) + (type (;2;) (func (param i32 i32) (result i32))) (import "env" "__read_memory" (func $__read_memory (type 0))) (func $read_memory (type 1) (drop - (call $__read_memory + (call $_ZN5other8dispatch17h053cb34ef5d0d7b0E + (i32.const 1) (i32.const 2))) (drop (call $__read_memory (i32.const 1)))) - (table (;0;) 1 1 funcref) + (func $_ZN5other8dispatch17h053cb34ef5d0d7b0E (type 2) (param i32 i32) (result i32) + (call_indirect (type 0) + (local.get 1) + (local.get 0))) + (table (;0;) 2 2 funcref) (memory (;0;) 16) (global (;0;) (mut i32) (i32.const 1048576)) (global (;1;) i32 (i32.const 1048576)) @@ -52,8 +58,9 @@ fn issue_2329(mut config: crate::Config) -> Result<()> { (export "memory" (memory 0)) (export "read_memory" (func $read_memory)) (export "__data_end" (global 1)) - (export "__heap_base" (global 2))) - "#; + (export "__heap_base" (global 2)) + (elem (;0;) (i32.const 1) func $__read_memory)) + "#; let module = Module::new(&store, wat)?; let env = Env::new(); let imports: ImportObject = imports! { From 9ecedc3925f7c764916025c78bdc626cf45ef46b Mon Sep 17 00:00:00 2001 From: Syrus Akbary Date: Wed, 28 Jul 2021 17:09:55 -0700 Subject: [PATCH 3/3] Fix issue #2329 based on @olonho suggestion --- lib/compiler-singlepass/src/codegen_x64.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/compiler-singlepass/src/codegen_x64.rs b/lib/compiler-singlepass/src/codegen_x64.rs index bd02ddc2a4a..9d5fe93b522 100644 --- a/lib/compiler-singlepass/src/codegen_x64.rs +++ b/lib/compiler-singlepass/src/codegen_x64.rs @@ -5388,6 +5388,8 @@ impl<'a> FuncGen<'a> { let vmcaller_checked_anyfunc_func_ptr = self.vmoffsets.vmcaller_checked_anyfunc_func_ptr() as usize; + let vmcaller_checked_anyfunc_vmctx = + self.vmoffsets.vmcaller_checked_anyfunc_vmctx() as usize; self.emit_call_sysv( |this| { @@ -5403,6 +5405,14 @@ impl<'a> FuncGen<'a> { this.trap_table .offset_to_code .insert(offset, TrapCode::StackOverflow); + + // We set the context pointer + this.assembler.emit_mov( + Size::S64, + Location::Memory(GPR::RAX, vmcaller_checked_anyfunc_vmctx as i32), + Machine::get_param_location(0), + ); + this.assembler.emit_call_location(Location::Memory( GPR::RAX, vmcaller_checked_anyfunc_func_ptr as i32,