diff --git a/libchisel/Cargo.toml b/libchisel/Cargo.toml index dc83453..2379189 100644 --- a/libchisel/Cargo.toml +++ b/libchisel/Cargo.toml @@ -22,3 +22,4 @@ default = [] [dev-dependencies] rustc-hex = "1.0" +wabt = "0.9.0" diff --git a/libchisel/src/imports.rs b/libchisel/src/imports.rs index 63dcfdd..6bab4c4 100644 --- a/libchisel/src/imports.rs +++ b/libchisel/src/imports.rs @@ -393,6 +393,421 @@ impl<'a> ModulePreset for ImportList<'a> { ), ), ])), + "wasi" => Ok(ImportList(vec![ + ImportType::Function( + "wasi_unstable", + "args_get", + FunctionType::new(vec![ValueType::I32, ValueType::I32], Some(ValueType::I32)), + ), + ImportType::Function( + "wasi_unstable", + "args_sizes_get", + FunctionType::new(vec![ValueType::I32, ValueType::I32], Some(ValueType::I32)), + ), + ImportType::Function( + "wasi_unstable", + "environ_get", + FunctionType::new(vec![ValueType::I32, ValueType::I32], Some(ValueType::I32)), + ), + ImportType::Function( + "wasi_unstable", + "environ_sizes_get", + FunctionType::new(vec![ValueType::I32, ValueType::I32], Some(ValueType::I32)), + ), + ImportType::Function( + "wasi_unstable", + "clock_res_get", + FunctionType::new(vec![ValueType::I32, ValueType::I32], Some(ValueType::I32)), + ), + ImportType::Function( + "wasi_unstable", + "clock_time_get", + FunctionType::new( + vec![ValueType::I32, ValueType::I64, ValueType::I32], + Some(ValueType::I32), + ), + ), + ImportType::Function( + "wasi_unstable", + "fd_advise", + FunctionType::new( + vec![ + ValueType::I32, + ValueType::I64, + ValueType::I64, + ValueType::I32, + ], + Some(ValueType::I32), + ), + ), + ImportType::Function( + "wasi_unstable", + "fd_allocate", + FunctionType::new( + vec![ValueType::I32, ValueType::I64, ValueType::I64], + Some(ValueType::I32), + ), + ), + ImportType::Function( + "wasi_unstable", + "fd_close", + FunctionType::new(vec![ValueType::I32], Some(ValueType::I32)), + ), + ImportType::Function( + "wasi_unstable", + "fd_datasync", + FunctionType::new(vec![ValueType::I32], Some(ValueType::I32)), + ), + ImportType::Function( + "wasi_unstable", + "fd_fdstat_get", + FunctionType::new(vec![ValueType::I32, ValueType::I32], Some(ValueType::I32)), + ), + ImportType::Function( + "wasi_unstable", + "fd_fdstat_set_flags", + FunctionType::new(vec![ValueType::I32, ValueType::I32], Some(ValueType::I32)), + ), + ImportType::Function( + "wasi_unstable", + "fd_fdstat_set_rights", + FunctionType::new( + vec![ValueType::I32, ValueType::I64, ValueType::I64], + Some(ValueType::I32), + ), + ), + ImportType::Function( + "wasi_unstable", + "fd_filestat_get", + FunctionType::new(vec![ValueType::I32, ValueType::I32], Some(ValueType::I32)), + ), + ImportType::Function( + "wasi_unstable", + "fd_filestat_set_size", + FunctionType::new(vec![ValueType::I32, ValueType::I64], Some(ValueType::I32)), + ), + ImportType::Function( + "wasi_unstable", + "fd_filestat_set_times", + FunctionType::new( + vec![ + ValueType::I32, + ValueType::I64, + ValueType::I64, + ValueType::I32, + ], + Some(ValueType::I32), + ), + ), + ImportType::Function( + "wasi_unstable", + "fd_pread", + FunctionType::new( + vec![ + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I64, + ValueType::I32, + ], + Some(ValueType::I32), + ), + ), + ImportType::Function( + "wasi_unstable", + "fd_prestat_get", + FunctionType::new(vec![ValueType::I32, ValueType::I32], Some(ValueType::I32)), + ), + ImportType::Function( + "wasi_unstable", + "fd_prestat_dir_name", + FunctionType::new( + vec![ValueType::I32, ValueType::I32, ValueType::I32], + Some(ValueType::I32), + ), + ), + ImportType::Function( + "wasi_unstable", + "fd_pwrite", + FunctionType::new( + vec![ + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I64, + ValueType::I32, + ], + Some(ValueType::I32), + ), + ), + ImportType::Function( + "wasi_unstable", + "fd_read", + FunctionType::new( + vec![ + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ], + Some(ValueType::I32), + ), + ), + ImportType::Function( + "wasi_unstable", + "fd_readdir", + FunctionType::new( + vec![ + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I64, + ValueType::I32, + ], + Some(ValueType::I32), + ), + ), + ImportType::Function( + "wasi_unstable", + "fd_renumber", + FunctionType::new(vec![ValueType::I32, ValueType::I32], Some(ValueType::I32)), + ), + ImportType::Function( + "wasi_unstable", + "fd_seek", + FunctionType::new( + vec![ + ValueType::I32, + ValueType::I64, + ValueType::I32, + ValueType::I32, + ], + Some(ValueType::I32), + ), + ), + ImportType::Function( + "wasi_unstable", + "fd_sync", + FunctionType::new(vec![ValueType::I32], Some(ValueType::I32)), + ), + ImportType::Function( + "wasi_unstable", + "fd_tell", + FunctionType::new(vec![ValueType::I32, ValueType::I32], Some(ValueType::I32)), + ), + ImportType::Function( + "wasi_unstable", + "fd_write", + FunctionType::new( + vec![ + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ], + Some(ValueType::I32), + ), + ), + ImportType::Function( + "wasi_unstable", + "path_create_directory", + FunctionType::new( + vec![ValueType::I32, ValueType::I32, ValueType::I32], + Some(ValueType::I32), + ), + ), + ImportType::Function( + "wasi_unstable", + "path_filestat_get", + FunctionType::new( + vec![ + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ], + Some(ValueType::I32), + ), + ), + ImportType::Function( + "wasi_unstable", + "path_filestat_set_times", + FunctionType::new( + vec![ + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I64, + ValueType::I64, + ValueType::I32, + ], + Some(ValueType::I32), + ), + ), + ImportType::Function( + "wasi_unstable", + "path_link", + FunctionType::new( + vec![ + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ], + Some(ValueType::I32), + ), + ), + ImportType::Function( + "wasi_unstable", + "path_open", + FunctionType::new( + vec![ + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I64, + ValueType::I64, + ValueType::I32, + ValueType::I32, + ], + Some(ValueType::I32), + ), + ), + ImportType::Function( + "wasi_unstable", + "path_readlink", + FunctionType::new( + vec![ + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ], + Some(ValueType::I32), + ), + ), + ImportType::Function( + "wasi_unstable", + "path_remove_directory", + FunctionType::new( + vec![ValueType::I32, ValueType::I32, ValueType::I32], + Some(ValueType::I32), + ), + ), + ImportType::Function( + "wasi_unstable", + "path_rename", + FunctionType::new( + vec![ + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ], + Some(ValueType::I32), + ), + ), + ImportType::Function( + "wasi_unstable", + "path_symlink", + FunctionType::new( + vec![ + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ], + Some(ValueType::I32), + ), + ), + ImportType::Function( + "wasi_unstable", + "path_unlink_file", + FunctionType::new( + vec![ValueType::I32, ValueType::I32, ValueType::I32], + Some(ValueType::I32), + ), + ), + ImportType::Function( + "wasi_unstable", + "poll_oneoff", + FunctionType::new( + vec![ + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ], + Some(ValueType::I32), + ), + ), + ImportType::Function( + "wasi_unstable", + "proc_exit", + FunctionType::new(vec![ValueType::I32], None), + ), + ImportType::Function( + "wasi_unstable", + "proc_raise", + FunctionType::new(vec![ValueType::I32], Some(ValueType::I32)), + ), + ImportType::Function( + "wasi_unstable", + "sched_yield", + FunctionType::new(vec![], Some(ValueType::I32)), + ), + ImportType::Function( + "wasi_unstable", + "random_get", + FunctionType::new(vec![ValueType::I32, ValueType::I32], Some(ValueType::I32)), + ), + ImportType::Function( + "wasi_unstable", + "sock_recv", + FunctionType::new( + vec![ + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ], + Some(ValueType::I32), + ), + ), + ImportType::Function( + "wasi_unstable", + "sock_send", + FunctionType::new( + vec![ + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ], + Some(ValueType::I32), + ), + ), + ImportType::Function( + "wasi_unstable", + "sock_shutdown", + FunctionType::new(vec![ValueType::I32, ValueType::I32], Some(ValueType::I32)), + ), + ])), _ => Err(ModuleError::NotSupported), } } diff --git a/libchisel/src/remapimports.rs b/libchisel/src/remapimports.rs index fd5ce04..92bf598 100644 --- a/libchisel/src/remapimports.rs +++ b/libchisel/src/remapimports.rs @@ -70,6 +70,10 @@ impl<'a> ModulePreset for RemapImports<'a> { ImportList::with_preset("bignum")?, Some("bignum_"), )), + "wasi" => interface_set.push(ImportInterface::new( + ImportList::with_preset("wasi")?, + Some("wasi_"), + )), _ => return Err(ModuleError::NotSupported), } } @@ -193,6 +197,7 @@ impl<'a> RemapImports<'a> { #[cfg(test)] mod tests { use rustc_hex::FromHex; + use wabt::wat2wasm; use super::*; use crate::verifyimports::*; @@ -226,23 +231,17 @@ mod tests { #[test] fn remap_did_mutate() { - // wast: - // (module - // (import "env" "ethereum_useGas" (func (param i64))) - // (memory 1) - // (export "main" (func $main)) - // (export "memory" (memory 0)) - // - // (func $main) - // ) - let wasm: Vec = vec![ - 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x02, 0x60, 0x01, 0x7e, - 0x00, 0x60, 0x00, 0x00, 0x02, 0x17, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x0f, 0x65, 0x74, - 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5f, 0x75, 0x73, 0x65, 0x47, 0x61, 0x73, 0x00, - 0x00, 0x03, 0x02, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00, 0x01, 0x07, 0x11, 0x02, 0x04, - 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x01, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, - 0x00, 0x0a, 0x04, 0x01, 0x02, 0x00, 0x0b, - ]; + let wasm = wat2wasm( + r#" + (module + (import "env" "ethereum_useGas" (func (param i64))) + (memory 1) + (export "main" (func $main)) + (export "memory" (memory 0)) + (func $main) + )"#, + ) + .expect("unable to convert wat to wasm"); let module = Module::from_bytes(&wasm).unwrap(); @@ -256,23 +255,17 @@ mod tests { #[test] fn remap_did_mutate_verify() { - // wast: - // (module - // (import "env" "ethereum_useGas" (func (param i64))) - // (memory 1) - // (export "main" (func $main)) - // (export "memory" (memory 0)) - // - // (func $main) - // ) - let wasm: Vec = vec![ - 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x02, 0x60, 0x01, 0x7e, - 0x00, 0x60, 0x00, 0x00, 0x02, 0x17, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x0f, 0x65, 0x74, - 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5f, 0x75, 0x73, 0x65, 0x47, 0x61, 0x73, 0x00, - 0x00, 0x03, 0x02, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00, 0x01, 0x07, 0x11, 0x02, 0x04, - 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x01, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, - 0x00, 0x0a, 0x04, 0x01, 0x02, 0x00, 0x0b, - ]; + let wasm = wat2wasm( + r#" + (module + (import "env" "ethereum_useGas" (func (param i64))) + (memory 1) + (export "main" (func $main)) + (export "memory" (memory 0)) + (func $main) + )"#, + ) + .expect("unable to convert wat to wasm"); let module = Module::from_bytes(&wasm).unwrap(); @@ -293,24 +286,18 @@ mod tests { #[test] fn remap_did_mutate_verify_explicit_type_section() { - // wast: - // (module - // (type (;0;) (func (result i64))) - // (import "env" "ethereum_getGasLeft" (func (;0;) (type 0))) - // (memory 1) - // (func $main) - // (export "main" (func $main)) - // (export "memory" (memory 0)) - // ) - - let wasm: Vec = vec![ - 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x02, 0x60, 0x00, 0x01, - 0x7e, 0x60, 0x00, 0x00, 0x02, 0x1b, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x13, 0x65, 0x74, - 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x5f, 0x67, 0x65, 0x74, 0x47, 0x61, 0x73, 0x4c, - 0x65, 0x66, 0x74, 0x00, 0x00, 0x03, 0x02, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00, 0x01, - 0x07, 0x11, 0x02, 0x04, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x01, 0x06, 0x6d, 0x65, 0x6d, - 0x6f, 0x72, 0x79, 0x02, 0x00, 0x0a, 0x04, 0x01, 0x02, 0x00, 0x0b, - ]; + let wasm = wat2wasm( + r#" + (module + (type (;0;) (func (result i64))) + (import "env" "ethereum_getGasLeft" (func (;0;) (type 0))) + (memory 1) + (func $main) + (export "main" (func $main)) + (export "memory" (memory 0)) + )"#, + ) + .expect("unable to convert wat to wasm"); let module = Module::from_bytes(&wasm).unwrap(); @@ -331,42 +318,34 @@ mod tests { #[test] fn remap_mutated_multiple_interfaces() { - // wast: - // (module - // (type (;0;) (func (result i64))) - // (type (;1;) (func (param i32 i32 i32))) - // (type (;2;) (func (param i32))) - // (import "env" "ethereum_getGasLeft" (func (;0;) (type 0))) - // (import "env" "bignum_mul256" (func (;1;) (type 1))) - // (import "env" "debug_printStorage" (func (;2;) (type 2))) - // (memory 1) - // (func $main) - // (export "main" (func $main)) - // (export "memory" (memory 0)) - // ) - - let wasm: Vec = vec![ - 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x12, 0x04, 0x60, 0x00, 0x01, - 0x7e, 0x60, 0x03, 0x7f, 0x7f, 0x7f, 0x00, 0x60, 0x01, 0x7f, 0x00, 0x60, 0x00, 0x00, - 0x02, 0x48, 0x03, 0x03, 0x65, 0x6e, 0x76, 0x13, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, - 0x75, 0x6d, 0x5f, 0x67, 0x65, 0x74, 0x47, 0x61, 0x73, 0x4c, 0x65, 0x66, 0x74, 0x00, - 0x00, 0x03, 0x65, 0x6e, 0x76, 0x0d, 0x62, 0x69, 0x67, 0x6e, 0x75, 0x6d, 0x5f, 0x6d, - 0x75, 0x6c, 0x32, 0x35, 0x36, 0x00, 0x01, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x64, 0x65, - 0x62, 0x75, 0x67, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x53, 0x74, 0x6f, 0x72, 0x61, - 0x67, 0x65, 0x00, 0x02, 0x03, 0x02, 0x01, 0x03, 0x05, 0x03, 0x01, 0x00, 0x01, 0x07, - 0x11, 0x02, 0x04, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x03, 0x06, 0x6d, 0x65, 0x6d, 0x6f, - 0x72, 0x79, 0x02, 0x00, 0x0a, 0x04, 0x01, 0x02, 0x00, 0x0b, - ]; + let wasm = wat2wasm( + r#" + (module + (type (;0;) (func (result i64))) + (type (;1;) (func (param i32 i32 i32))) + (type (;2;) (func (param i32))) + (type (;3;) (func (param i32 i32) (result i32))) + (import "env" "ethereum_getGasLeft" (func (;0;) (type 0))) + (import "env" "bignum_mul256" (func (;1;) (type 1))) + (import "env" "debug_printStorage" (func (;2;) (type 2))) + (import "env" "wasi_args_get" (func (;3;) (type 3))) + (memory 1) + (func $main) + (export "main" (func $main)) + (export "memory" (memory 0)) + )"#, + ) + .expect("unable to convert wat to wasm"); let module = Module::from_bytes(&wasm).unwrap(); - let new = RemapImports::with_preset("ewasm, bignum, debug") + let new = RemapImports::with_preset("ewasm, bignum, debug, wasi") .unwrap() .translate(&module) .expect("Module internal error") .expect("Module was not mutated"); - let verifier = VerifyImports::with_preset("ewasm, bignum, debug").unwrap(); + let verifier = VerifyImports::with_preset("ewasm, bignum, debug, wasi").unwrap(); assert_eq!(verifier.validate(&new), Ok(true)); }