From 7500ce76fc711c74c6bcb861e2e588dbad2b4adb Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Wed, 22 Mar 2023 15:26:28 +0100 Subject: [PATCH] Feat riscv llvm and cranelift (#3244) * Basic changes for RISC-V support * RISC-V in compiler LLVM * RISC-V support in dylib engine * RISC-V support in universal engine * Various small fixes * [RISCV] LLVM-riscv working, with some ignored tests to be worked on later * Update rustc to 4.65 (1.64 has some issue with riscv64 target) * Fixed some (new) Linting issues * Updated Cargo.toml and remove split-debuginfo for Windows build * Removed profile.dev from Cargo.toml as it cannot be per platform (breaks Windows). split-debug info is now the default value * Enable Cranelift compiler for RISCV * Update crates and fixed all the new clippy errors * Taken review remarks into account * Removed change from deny.toml, it's not needed anymore * Added some more comment about llvm abi hack * Added doc about current state of RISCV support * Fixed (newer) linter --------- Co-authored-by: Toru Nayuki --- .github/workflows/benchmark.yaml | 2 +- .github/workflows/build.yml | 2 +- .github/workflows/cloudcompiler.yaml | 2 +- .github/workflows/documentation.yaml | 2 +- .github/workflows/test.yaml | 10 +-- Cargo.lock | 44 +++++++----- Cargo.toml | 3 - Makefile | 28 ++++++-- docs/RISCV.md | 12 ++++ lib/api/src/access.rs | 4 +- lib/api/src/imports.rs | 1 + lib/api/src/instance.rs | 2 + lib/api/src/sys/instance.rs | 2 + lib/api/src/sys/module.rs | 1 + lib/cache/src/hash.rs | 2 +- lib/cli/Cargo.toml | 10 ++- lib/cli/build.rs | 2 +- lib/cli/src/commands/create_exe.rs | 8 +-- lib/cli/src/commands/init.rs | 4 +- lib/cli/src/commands/publish.rs | 4 +- lib/cli/src/commands/run.rs | 2 +- lib/cli/src/commands/run_unstable.rs | 4 +- lib/compiler-cranelift/Cargo.toml | 2 +- lib/compiler-cranelift/src/config.rs | 17 +++-- .../src/translator/translation_utils.rs | 1 + lib/compiler-llvm/Cargo.toml | 2 +- lib/compiler-llvm/src/abi/aarch64_systemv.rs | 13 ++-- lib/compiler-llvm/src/abi/x86_64_systemv.rs | 13 ++-- lib/compiler-llvm/src/config.rs | 68 +++++++++++++++++-- lib/compiler-llvm/src/object_file.rs | 30 +++++++- .../src/artifact_builders/trampoline.rs | 21 ++++++ lib/compiler/src/engine/artifact.rs | 3 + lib/compiler/src/engine/link.rs | 32 +++++++++ lib/compiler/src/engine/resolver.rs | 1 + lib/compiler/src/engine/tunables.rs | 3 + lib/object/src/module.rs | 19 ++++-- lib/registry/Cargo.toml | 7 +- lib/registry/src/lib.rs | 2 +- lib/types/src/compilation/relocation.rs | 19 ++++-- lib/vfs/src/webc_fs.rs | 3 +- lib/wasi/Cargo.toml | 8 ++- lib/wasi/src/lib.rs | 2 + lib/wasi/src/state/builder.rs | 5 ++ lib/wasi/src/state/env.rs | 2 + lib/wasi/src/syscalls/wasi/environ_get.rs | 2 +- lib/wasi/src/syscalls/wasi/path_rename.rs | 2 +- rust-toolchain | 2 +- tests/ignores.txt | 29 ++++++++ tests/lib/compiler-test-derive/src/ignores.rs | 2 +- tests/lib/wast/src/wast.rs | 2 +- 50 files changed, 358 insertions(+), 105 deletions(-) create mode 100755 docs/RISCV.md diff --git a/.github/workflows/benchmark.yaml b/.github/workflows/benchmark.yaml index c303bddb705..e0c221b6eb4 100644 --- a/.github/workflows/benchmark.yaml +++ b/.github/workflows/benchmark.yaml @@ -24,7 +24,7 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@stable with: - toolchain: 1.64 + toolchain: 1.65 - name: Configure cargo data directory # After this point, all cargo registry and crate data is stored in # $GITHUB_WORKSPACE/.cargo_home. This allows us to cache only the files diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c96fdc4e60c..493d748364c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -94,7 +94,7 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@stable with: - toolchain: 1.64 + toolchain: 1.65 target: ${{ matrix.target }} - name: Install Rust nightly (to build capi-headless) uses: dtolnay/rust-toolchain@stable diff --git a/.github/workflows/cloudcompiler.yaml b/.github/workflows/cloudcompiler.yaml index c7ef5b8ec78..ecd29660785 100644 --- a/.github/workflows/cloudcompiler.yaml +++ b/.github/workflows/cloudcompiler.yaml @@ -21,7 +21,7 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@stable with: - toolchain: 1.64 + toolchain: 1.65 target: ${{ matrix.target }} - name: Install wasm32-wasi target shell: bash diff --git a/.github/workflows/documentation.yaml b/.github/workflows/documentation.yaml index 4ffdfb468cf..9ac7eaae484 100644 --- a/.github/workflows/documentation.yaml +++ b/.github/workflows/documentation.yaml @@ -16,7 +16,7 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@stable with: - toolchain: 1.64 + toolchain: 1.65 - name: Install LLVM shell: bash run: | diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 37c85536d0d..f56071356b8 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -43,7 +43,7 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@stable with: - toolchain: 1.64 + toolchain: 1.65 components: rustfmt, clippy - name: Install libtinfo shell: bash @@ -95,7 +95,7 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@stable with: - toolchain: 1.64 + toolchain: 1.65 - name: Install NodeJS uses: actions/setup-node@v2 with: @@ -263,7 +263,7 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@stable with: - toolchain: 1.64 + toolchain: 1.65 target: ${{ matrix.metadata.target }} - name: Install Rust nightly (to build capi-headless) uses: dtolnay/rust-toolchain@stable @@ -487,7 +487,7 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@stable with: - toolchain: 1.64 + toolchain: 1.65 target: ${{ matrix.metadata.target }} - name: Install LLVM (macOS Apple Silicon) if: matrix.metadata.os == 'macos-11.0' && !matrix.metadata.llvm_url @@ -587,7 +587,7 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@stable with: - toolchain: 1.64 + toolchain: 1.65 target: ${{ matrix.metadata.target }} - name: Cache uses: whywaita/actions-cache-s3@v2 diff --git a/Cargo.lock b/Cargo.lock index 754f1f254d3..dccebda6aff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -143,7 +143,7 @@ checksum = "86ea188f25f0255d8f92797797c97ebf5631fa88178beb1a46fdf5622c9a00e4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.3", + "syn 2.0.5", ] [[package]] @@ -926,7 +926,7 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.3", + "syn 2.0.5", ] [[package]] @@ -943,7 +943,7 @@ checksum = "631569015d0d8d54e6c241733f944042623ab6df7bc3be7466874b05fcdb1c5f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.3", + "syn 2.0.5", ] [[package]] @@ -1487,7 +1487,7 @@ checksum = "e77ac7b51b8e6313251737fcef4b1c01a2ea102bde68415b62c0ee9268fec357" dependencies = [ "proc-macro2", "quote", - "syn 2.0.3", + "syn 2.0.5", ] [[package]] @@ -1763,6 +1763,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e6cd45a270dff33553602fd84beb02c89460ee32db638715f10d9060389fd6a" dependencies = [ + "native-tls", "rustls 0.19.1", "unicase", "webpki 0.21.4", @@ -1833,16 +1834,16 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.53" +version = "0.1.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +checksum = "0c17cc76786e99f8d2f055c11159e7f0091c42474dcc3189fbab96072e873e6d" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "winapi", + "windows", ] [[package]] @@ -2994,9 +2995,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.52" +version = "1.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d0e1ae9e836cc3beddd63db0df682593d7e2d3d891ae8c9083d2113e1744224" +checksum = "ba466839c78239c09faf015484e5cc04860f88242cff4d03eb038f04b4699b73" dependencies = [ "unicode-ident", ] @@ -3219,9 +3220,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" +checksum = "cce168fea28d3e05f158bda4576cf0c844d5045bc2cc3620fa0292ed5bb5814c" dependencies = [ "aho-corasick", "memchr", @@ -3239,9 +3240,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.28" +version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "region" @@ -3718,7 +3719,7 @@ checksum = "e801c1712f48475582b7696ac71e0ca34ebb30e09338425384269d9717c62cad" dependencies = [ "proc-macro2", "quote", - "syn 2.0.3", + "syn 2.0.5", ] [[package]] @@ -4037,9 +4038,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.3" +version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8234ae35e70582bfa0f1fedffa6daa248e41dd045310b19800c4a36382c8f60" +checksum = "89c2d1c76a26822187a1fbb5964e3fff108bc208f02e820ab9dac1234f6b388a" dependencies = [ "proc-macro2", "quote", @@ -4201,7 +4202,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.3", + "syn 2.0.5", ] [[package]] @@ -6253,6 +6254,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdacb41e6a96a052c6cb63a144f24900236121c6f63f4f8219fef5977ecb0c25" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.33.0" diff --git a/Cargo.toml b/Cargo.toml index 5c753eaf9c1..e38c8e7f129 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -129,9 +129,6 @@ test-universal = ["test-generator/test-universal"] # that raise signals because that interferes with tarpaulin. coverage = [] -[profile.dev] -split-debuginfo = "unpacked" - #[profile.release] #debug = true diff --git a/Makefile b/Makefile index 6ce50c26839..e6f820d3519 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ SHELL=/usr/bin/env bash # |------------|----------|--------------|-------| # | Cranelift | Linux | amd64 | glibc | # | LLVM | Darwin | aarch64 | musl | -# | Singlepass | Windows | | | +# | Singlepass | Windows | riscv | | # |------------|----------|--------------|-------| # # Here is what works and what doesn't: @@ -22,13 +22,16 @@ SHELL=/usr/bin/env bash # * Cranelift works everywhere, # # * LLVM works on Linux+Darwin/`amd64`, -# but it doesn't work on */`aarch64` or Windows/*. +# and linux+`aarch64`, linux+`riscv` +# but it doesn't work on Darwin/`aarch64` or Windows/`aarch64`. # -# * Singlepass works on Linux+Darwin/`amd64`, but -# it doesn't work on */`aarch64` or Windows/*. +# * Singlepass works on Linux+Darwin+Windows/`amd64`, +# and Linux+Darwin/`aarch64` +# it doesn't work on */`riscv`. # # * Windows isn't tested on `aarch64`, that's why we consider it's not # working, but it might possibly be. +# * The Only target for `riscv` familly of processor is the RV64, with the `GC` extensions ##### @@ -45,6 +48,7 @@ IS_FREEBSD := 0 IS_WINDOWS := 0 IS_AMD64 := 0 IS_AARCH64 := 0 +IS_RISCV64 := 0 # Test Windows apart because it doesn't support `uname -s`. ifeq ($(OS), Windows_NT) @@ -75,6 +79,8 @@ else IS_AMD64 := 1 else ifneq (, $(filter $(uname), aarch64 arm64)) IS_AARCH64 := 1 + else ifneq (, $(filter $(uname), riscv64)) + IS_RISCV64 := 1 else # We use spaces instead of tabs to indent `$(error)` # otherwise it's considered as a command outside a @@ -116,8 +122,16 @@ compilers := # If the user didn't disable the Cranelift compiler… ifneq ($(ENABLE_CRANELIFT), 0) - # … then it can always be enabled. - compilers += cranelift + # … then maybe the user forced to enable the Cranelift compiler. + ifeq ($(ENABLE_CRANELIFT), 1) + compilers += cranelift + # … otherwise, we try to check whether Cranelift works on this host. + else + compilers += cranelift + endif +endif + +ifneq (, $(findstring cranelift,$(compilers))) ENABLE_CRANELIFT := 1 endif @@ -235,6 +249,8 @@ ifeq ($(ENABLE_LLVM), 1) compilers_engines += llvm-universal else ifeq ($(IS_AARCH64), 1) compilers_engines += llvm-universal + else ifeq ($(IS_RISCV64), 1) + compilers_engines += llvm-universal endif endif endif diff --git a/docs/RISCV.md b/docs/RISCV.md new file mode 100755 index 00000000000..0cd470a5c95 --- /dev/null +++ b/docs/RISCV.md @@ -0,0 +1,12 @@ +# Current state of the RISCV support + +Only Cranelift and LLVM compiler are supported. +Singlepass can be done, but no ressources are allocated on this task for now. + +Both LLVM and Cranelift support are quite new, and so it is expected to have a few things not working well. + +LLVM code needs a hack to force the ABI to "lp64d", and some tested with funciton & float/double values are still not working correctly and have be disable for now. + +On Cranelift, SIMD is not supported as the CPU doesn't have official SIMD/Vector extension for now, and no Workaround is in place. + +Test have be conducted on actual hardware, with a Vision Fixe 2 board running Debian. Some previous tests have also be done on a Vison Five 1 running Fedora (with LLVM only). \ No newline at end of file diff --git a/lib/api/src/access.rs b/lib/api/src/access.rs index e1d5cc16c95..7d10348f139 100644 --- a/lib/api/src/access.rs +++ b/lib/api/src/access.rs @@ -118,7 +118,7 @@ pub(super) enum RefCow<'a, T> { impl<'a, T> AsRef for RefCow<'a, T> { fn as_ref(&self) -> &T { match self { - Self::Borrowed(val) => *val, + Self::Borrowed(val) => val, Self::Owned(val, _) => val, } } @@ -130,7 +130,7 @@ impl<'a, T> AsMut for RefCow<'a, T> { // not leak the bytes into the memory // https://stackoverflow.com/questions/61114026/does-stdptrwrite-transfer-the-uninitialized-ness-of-the-bytes-it-writes match self { - Self::Borrowed(val) => *val, + Self::Borrowed(val) => val, Self::Owned(val, modified) => { *modified = true; val diff --git a/lib/api/src/imports.rs b/lib/api/src/imports.rs index f50b2c2e7f7..344bc24e28f 100644 --- a/lib/api/src/imports.rs +++ b/lib/api/src/imports.rs @@ -140,6 +140,7 @@ impl Imports { /// Resolve and return a vector of imports in the order they are defined in the `module`'s source code. /// /// This means the returned `Vec` might be a subset of the imports contained in `self`. + #[allow(clippy::result_large_err)] pub fn imports_for_module(&self, module: &Module) -> Result, LinkError> { let mut ret = vec![]; for import in module.imports() { diff --git a/lib/api/src/instance.rs b/lib/api/src/instance.rs index a43d896355d..576256a3d7e 100644 --- a/lib/api/src/instance.rs +++ b/lib/api/src/instance.rs @@ -58,6 +58,7 @@ impl Instance { /// Those are, as defined by the spec: /// * Link errors that happen when plugging the imports into the instance /// * Runtime errors that happen when running the module `start` function. + #[allow(clippy::result_large_err)] pub fn new( store: &mut impl AsStoreMut, module: &Module, @@ -81,6 +82,7 @@ impl Instance { /// Those are, as defined by the spec: /// * Link errors that happen when plugging the imports into the instance /// * Runtime errors that happen when running the module `start` function. + #[allow(clippy::result_large_err)] pub fn new_by_index( store: &mut impl AsStoreMut, module: &Module, diff --git a/lib/api/src/sys/instance.rs b/lib/api/src/sys/instance.rs index 3b8396d11b4..0b5060a2853 100644 --- a/lib/api/src/sys/instance.rs +++ b/lib/api/src/sys/instance.rs @@ -37,6 +37,7 @@ impl From for InstantiationError { } impl Instance { + #[allow(clippy::result_large_err)] pub(crate) fn new( store: &mut impl AsStoreMut, module: &Module, @@ -55,6 +56,7 @@ impl Instance { Ok((instance, exports)) } + #[allow(clippy::result_large_err)] pub(crate) fn new_by_index( store: &mut impl AsStoreMut, module: &Module, diff --git a/lib/api/src/sys/module.rs b/lib/api/src/sys/module.rs index 1f42db7017b..419041725d3 100644 --- a/lib/api/src/sys/module.rs +++ b/lib/api/src/sys/module.rs @@ -94,6 +94,7 @@ impl Module { Self { artifact } } + #[allow(clippy::result_large_err)] pub(crate) fn instantiate( &self, store: &mut impl AsStoreMut, diff --git a/lib/cache/src/hash.rs b/lib/cache/src/hash.rs index 8c202ef6185..5a088dc5a03 100644 --- a/lib/cache/src/hash.rs +++ b/lib/cache/src/hash.rs @@ -32,7 +32,7 @@ impl Display for Hash { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { let mut buffer = [0_u8; 64]; - hex::encode_to_slice(&self.0, &mut buffer) + hex::encode_to_slice(self.0, &mut buffer) .expect("Can never fail with a hard-coded buffer length"); let s = std::str::from_utf8(&buffer).map_err(|_| fmt::Error)?; diff --git a/lib/cli/Cargo.toml b/lib/cli/Cargo.toml index 70b7eb42f88..92598d2b22f 100644 --- a/lib/cli/Cargo.toml +++ b/lib/cli/Cargo.toml @@ -54,8 +54,6 @@ distance = "0.4" bytesize = "1.0" cfg-if = "1.0" tempfile = "3.4.0" -http_req = { version="^0.8", default-features = false, features = ["rust-tls"] } -reqwest = { version = "^0.11", default-features = false, features = ["rustls-tls", "json", "multipart"] } serde = { version = "1.0.147", features = ["derive"] } dirs = { version = "4.0" } serde_json = { version = "1.0" } @@ -95,6 +93,14 @@ tracing-subscriber = { version = "0.3", features = [ "env-filter", "fmt" ] } clap-verbosity-flag = "1" wapm-targz-to-pirita = "0.1.7" +[target.'cfg(not(target_arch = "riscv64"))'.dependencies] +http_req = { version="^0.8", default-features = false, features = ["rust-tls"] } +reqwest = { version = "^0.11", default-features = false, features = ["rustls-tls", "json", "multipart"] } + +[target.'cfg(target_arch = "riscv64")'.dependencies] +http_req = { version="^0.8", default-features = false, features = ["native-tls"] } +reqwest = { version = "^0.11", default-features = false, features = ["native-tls", "json", "multipart"] } + [build-dependencies] chrono = { version = "^0.4", default-features = false, features = ["std", "clock"] } diff --git a/lib/cli/build.rs b/lib/cli/build.rs index b5e0f8550b6..3691225adf1 100644 --- a/lib/cli/build.rs +++ b/lib/cli/build.rs @@ -4,7 +4,7 @@ use std::process::Command; pub fn main() { // Set WASMER_GIT_HASH let git_hash = Command::new("git") - .args(&["rev-parse", "HEAD"]) + .args(["rev-parse", "HEAD"]) .output() .ok() .and_then(|output| String::from_utf8(output.stdout).ok()) diff --git a/lib/cli/src/commands/create_exe.rs b/lib/cli/src/commands/create_exe.rs index cabb2edfb38..7c2565d315a 100644 --- a/lib/cli/src/commands/create_exe.rs +++ b/lib/cli/src/commands/create_exe.rs @@ -826,7 +826,7 @@ fn write_volume_obj( object_name, )?; - let mut writer = BufWriter::new(File::create(&output_path)?); + let mut writer = BufWriter::new(File::create(output_path)?); volumes_object .write_stream(&mut writer) .map_err(|err| anyhow::anyhow!(err.to_string()))?; @@ -1136,7 +1136,7 @@ fn link_exe_from_dir( .as_ref() .ok_or_else(|| anyhow::anyhow!("could not find zig in $PATH {}", directory.display()))?; - let mut cmd = Command::new(&zig_binary_path); + let mut cmd = Command::new(zig_binary_path); cmd.arg("build-exe"); cmd.arg("--verbose-cc"); cmd.arg("--verbose-link"); @@ -1796,7 +1796,7 @@ pub(super) mod utils { let path_var = std::env::var("PATH").unwrap_or_default(); #[cfg(unix)] let system_path_var = std::process::Command::new("getconf") - .args(&["PATH"]) + .args(["PATH"]) .output() .map(|output| output.stdout) .unwrap_or_default(); @@ -2187,7 +2187,7 @@ mod http_fetch { pub(crate) fn list_dir(target: &Path) -> Vec { use walkdir::WalkDir; - WalkDir::new(&target) + WalkDir::new(target) .into_iter() .filter_map(|e| e.ok()) .map(|entry| entry.path().to_path_buf()) diff --git a/lib/cli/src/commands/init.rs b/lib/cli/src/commands/init.rs index 16ec43d89cb..47624f41489 100644 --- a/lib/cli/src/commands/init.rs +++ b/lib/cli/src/commands/init.rs @@ -161,7 +161,7 @@ impl Init { .collect::>() .join(NEWLINE); - std::fs::write(&path, &toml_string) + std::fs::write(path, &toml_string) .with_context(|| format!("Unable to write to \"{}\"", path.display()))?; Ok(()) @@ -494,7 +494,7 @@ fn construct_manifest( } fn parse_cargo_toml(manifest_path: &PathBuf) -> Result { let mut metadata = MetadataCommand::new(); - metadata.manifest_path(&manifest_path); + metadata.manifest_path(manifest_path); metadata.no_deps(); metadata.features(CargoOpt::AllFeatures); diff --git a/lib/cli/src/commands/publish.rs b/lib/cli/src/commands/publish.rs index 145092bc472..192db4e0cb4 100644 --- a/lib/cli/src/commands/publish.rs +++ b/lib/cli/src/commands/publish.rs @@ -247,7 +247,7 @@ fn append_path_to_tar_gz( .metadata() .map_err(|e| (normalized_path.clone(), e))?; builder - .append_path_with_name(&normalized_path, &target_path) + .append_path_with_name(&normalized_path, target_path) .map_err(|e| (normalized_path.clone(), e))?; Ok(normalized_path) } @@ -386,7 +386,7 @@ fn apply_migration(conn: &mut Connection, migration_number: i32) -> Result<(), M tx.execute_batch(migration_to_apply) .map_err(|e| MigrationError::TransactionFailed(migration_number, format!("{}", e)))?; - tx.pragma_update(None, "user_version", &(migration_number + 1)) + tx.pragma_update(None, "user_version", migration_number + 1) .map_err(|e| MigrationError::TransactionFailed(migration_number, format!("{}", e)))?; tx.commit() .map_err(|_| MigrationError::CommitFailed(migration_number)) diff --git a/lib/cli/src/commands/run.rs b/lib/cli/src/commands/run.rs index 10c9fb9cfb7..7a795ef86ef 100644 --- a/lib/cli/src/commands/run.rs +++ b/lib/cli/src/commands/run.rs @@ -125,7 +125,7 @@ impl RunWithPathBuf { let default = indexmap::IndexMap::default(); let fs = manifest.fs.as_ref().unwrap_or(&default); for (alias, real_dir) in fs.iter() { - let real_dir = self_clone.path.join(&real_dir); + let real_dir = self_clone.path.join(real_dir); if !real_dir.exists() { #[cfg(feature = "debug")] if self_clone.debug { diff --git a/lib/cli/src/commands/run_unstable.rs b/lib/cli/src/commands/run_unstable.rs index 0bdda35bbc1..8ef2b98b813 100644 --- a/lib/cli/src/commands/run_unstable.rs +++ b/lib/cli/src/commands/run_unstable.rs @@ -464,7 +464,7 @@ impl TargetOnDisk { Ok(ExecutableTarget::Webc(container)) } TargetOnDisk::WebAssemblyBinary(path) => { - let wasm = std::fs::read(&path) + let wasm = std::fs::read(path) .with_context(|| format!("Unable to read \"{}\"", path.display()))?; let module = compile_wasm_cached(path, &wasm, cache, store)?; Ok(ExecutableTarget::WebAssembly(module)) @@ -566,7 +566,7 @@ fn generate_coredump(err: &Error, source: &Path, coredump_path: &Path) -> Result .map_err(Error::msg) .context("Coredump serializing failed")?; - std::fs::write(&coredump_path, &coredump).with_context(|| { + std::fs::write(coredump_path, &coredump).with_context(|| { format!( "Unable to save the coredump to \"{}\"", coredump_path.display() diff --git a/lib/compiler-cranelift/Cargo.toml b/lib/compiler-cranelift/Cargo.toml index 25967ea43f8..d9c72dee235 100644 --- a/lib/compiler-cranelift/Cargo.toml +++ b/lib/compiler-cranelift/Cargo.toml @@ -15,7 +15,7 @@ edition = "2018" wasmer-compiler = { path = "../compiler", version = "=3.2.0-alpha.1", features = ["translator", "compiler"], default-features = false } wasmer-types = { path = "../types", version = "=3.2.0-alpha.1", default-features = false, features = ["std"] } cranelift-entity = { version = "0.91.1", default-features = false } -cranelift-codegen = { version = "0.91.1", default-features = false, features = ["x86", "arm64"] } +cranelift-codegen = { version = "0.91.1", default-features = false, features = ["x86", "arm64", "riscv64"] } cranelift-frontend = { version = "0.91.1", default-features = false } tracing = "0.1" hashbrown = { version = "0.11", optional = true } diff --git a/lib/compiler-cranelift/src/config.rs b/lib/compiler-cranelift/src/config.rs index dff2ba11919..d990d59c849 100644 --- a/lib/compiler-cranelift/src/config.rs +++ b/lib/compiler-cranelift/src/config.rs @@ -117,11 +117,12 @@ impl Cranelift { builder.enable("has_lzcnt").expect("should be valid flag"); } - builder.finish(self.flags()) + builder.finish(self.flags(target)) } /// Generates the flags for the compiler - pub fn flags(&self) -> settings::Flags { + pub fn flags(&self, target: &Target) -> settings::Flags { + let is_riscv = matches!(target.triple().architecture, Architecture::Riscv64(_)); let mut flags = settings::builder(); // Enable probestack @@ -169,9 +170,15 @@ impl Cranelift { ) .expect("should be valid flag"); - flags - .set("enable_simd", "true") - .expect("should be valid flag"); + if is_riscv { + flags + .set("enable_simd", "false") + .expect("should be valid flag"); + } else { + flags + .set("enable_simd", "true") + .expect("should be valid flag"); + } let enable_nan_canonicalization = if self.enable_nan_canonicalization { "true" diff --git a/lib/compiler-cranelift/src/translator/translation_utils.rs b/lib/compiler-cranelift/src/translator/translation_utils.rs index ecc6beb93c4..bd1a8a13339 100644 --- a/lib/compiler-cranelift/src/translator/translation_utils.rs +++ b/lib/compiler-cranelift/src/translator/translation_utils.rs @@ -84,6 +84,7 @@ pub fn irreloc_to_relocationkind(reloc: Reloc) -> RelocationKind { Reloc::X86CallPLTRel4 => RelocationKind::X86CallPLTRel4, Reloc::X86GOTPCRel4 => RelocationKind::X86GOTPCRel4, Reloc::Arm64Call => RelocationKind::Arm64Call, + Reloc::RiscvCall => RelocationKind::RiscvCall, _ => panic!("The relocation {} is not yet supported.", reloc), } } diff --git a/lib/compiler-llvm/Cargo.toml b/lib/compiler-llvm/Cargo.toml index b5992384945..d1ad750da7c 100644 --- a/lib/compiler-llvm/Cargo.toml +++ b/lib/compiler-llvm/Cargo.toml @@ -29,7 +29,7 @@ rayon = "1.5" package = "inkwell" version = "0.1.1" default-features = false -features = ["llvm14-0", "target-x86", "target-aarch64"] +features = ["llvm14-0", "target-x86", "target-aarch64", "target-riscv"] [build-dependencies] cc = "1.0" diff --git a/lib/compiler-llvm/src/abi/aarch64_systemv.rs b/lib/compiler-llvm/src/abi/aarch64_systemv.rs index 89e07a80cec..04fa4514d10 100644 --- a/lib/compiler-llvm/src/abi/aarch64_systemv.rs +++ b/lib/compiler-llvm/src/abi/aarch64_systemv.rs @@ -21,19 +21,14 @@ impl Abi for Aarch64SystemV { // Given a function definition, retrieve the parameter that is the vmctx pointer. fn get_vmctx_ptr_param<'ctx>(&self, func_value: &FunctionValue<'ctx>) -> PointerValue<'ctx> { func_value - .get_nth_param( - if func_value + .get_nth_param(u32::from( + func_value .get_enum_attribute( AttributeLoc::Param(0), Attribute::get_named_enum_kind_id("sret"), ) - .is_some() - { - 1 - } else { - 0 - }, - ) + .is_some(), + )) .unwrap() .into_pointer_value() } diff --git a/lib/compiler-llvm/src/abi/x86_64_systemv.rs b/lib/compiler-llvm/src/abi/x86_64_systemv.rs index bf02a1f4591..0d186715ee9 100644 --- a/lib/compiler-llvm/src/abi/x86_64_systemv.rs +++ b/lib/compiler-llvm/src/abi/x86_64_systemv.rs @@ -23,19 +23,14 @@ impl Abi for X86_64SystemV { // Given a function definition, retrieve the parameter that is the vmctx pointer. fn get_vmctx_ptr_param<'ctx>(&self, func_value: &FunctionValue<'ctx>) -> PointerValue<'ctx> { func_value - .get_nth_param( - if func_value + .get_nth_param(u32::from( + func_value .get_enum_attribute( AttributeLoc::Param(0), Attribute::get_named_enum_kind_id("sret"), ) - .is_some() - { - 1 - } else { - 0 - }, - ) + .is_some(), + )) .unwrap() .into_pointer_value() } diff --git a/lib/compiler-llvm/src/config.rs b/lib/compiler-llvm/src/config.rs index bb81a85938a..928dd9fe53b 100644 --- a/lib/compiler-llvm/src/config.rs +++ b/lib/compiler-llvm/src/config.rs @@ -97,6 +97,13 @@ impl LLVM { } fn target_triple(&self, target: &Target) -> TargetTriple { + let architecture = if target.triple().architecture + == Architecture::Riscv64(target_lexicon::Riscv64Architecture::Riscv64gc) + { + target_lexicon::Architecture::Riscv64(target_lexicon::Riscv64Architecture::Riscv64) + } else { + target.triple().architecture + }; // Hack: we're using is_pic to determine whether this is a native // build or not. let operating_system = if target.triple().operating_system @@ -123,7 +130,7 @@ impl LLVM { target_lexicon::BinaryFormat::Elf }; let triple = Triple { - architecture: target.triple().architecture, + architecture, vendor: target.triple().vendor.clone(), operating_system, environment: target.triple().environment, @@ -156,6 +163,14 @@ impl LLVM { info: true, machine_code: true, }), + Architecture::Riscv64(_) => InkwellTarget::initialize_riscv(&InitializationConfig { + asm_parser: true, + asm_printer: true, + base: true, + disassembler: true, + info: true, + machine_code: true, + }), // Architecture::Arm(_) => InkwellTarget::initialize_arm(&InitializationConfig { // asm_parser: true, // asm_printer: true, @@ -177,16 +192,57 @@ impl LLVM { let target_triple = self.target_triple(target); let llvm_target = InkwellTarget::from_triple(&target_triple).unwrap(); - llvm_target + let llvm_target_machine = llvm_target .create_target_machine( &target_triple, - "generic", - &llvm_cpu_features, + match triple.architecture { + Architecture::Riscv64(_) => "generic-rv64", + _ => "generic", + }, + match triple.architecture { + Architecture::Riscv64(_) => "+m,+a,+c,+d,+f", + _ => &llvm_cpu_features, + }, self.opt_level, self.reloc_mode(), - self.code_model(), + match triple.architecture { + Architecture::Riscv64(_) => CodeModel::Medium, + _ => self.code_model(), + }, ) - .unwrap() + .unwrap(); + + if let Architecture::Riscv64(_) = triple.architecture { + // TODO: totally non-portable way to change ABI + unsafe { + // This structure mimic the internal structure from inkwell + // that is defined as + // #[derive(Debug)] + // pub struct TargetMachine { + // pub(crate) target_machine: LLVMTargetMachineRef, + // } + pub struct MyTargetMachine { + pub target_machine: *const u8, + } + // It is use to live patch the create LLVMTargetMachine + // to hard change the ABI and force "-mabi=lp64d" ABI + // instead of the default that don't use float registers + // because there is no current way to do this change + + let my_target_machine: MyTargetMachine = std::mem::transmute(llvm_target_machine); + + *((my_target_machine.target_machine as *mut u8).offset(0x410) as *mut u64) = 5; + std::ptr::copy_nonoverlapping( + "lp64d\0".as_ptr(), + (my_target_machine.target_machine as *mut u8).offset(0x418), + 6, + ); + + std::mem::transmute(my_target_machine) + } + } else { + llvm_target_machine + } } } diff --git a/lib/compiler-llvm/src/object_file.rs b/lib/compiler-llvm/src/object_file.rs index 5e5734e9728..de8702b44c9 100644 --- a/lib/compiler-llvm/src/object_file.rs +++ b/lib/compiler-llvm/src/object_file.rs @@ -216,6 +216,21 @@ where object::RelocationKind::Elf(object::elf::R_AARCH64_MOVW_UABS_G3), 0, ) => RelocationKind::Arm64Movw3, + ( + object::Architecture::Riscv64, + object::RelocationKind::Elf(object::elf::R_RISCV_CALL_PLT), + 0, + ) => RelocationKind::RiscvCall, + ( + object::Architecture::Riscv64, + object::RelocationKind::Elf(object::elf::R_RISCV_PCREL_HI20), + 0, + ) => RelocationKind::RiscvPCRelHi20, + ( + object::Architecture::Riscv64, + object::RelocationKind::Elf(object::elf::R_RISCV_PCREL_LO12_I), + 0, + ) => RelocationKind::RiscvPCRelLo12I, _ => { return Err(CompileError::Codegen(format!( "unknown relocation {:?}", @@ -223,7 +238,7 @@ where ))); } }; - let addend = reloc.addend(); + let mut addend = reloc.addend(); let target = match reloc.target() { object::read::RelocationTarget::Symbol(index) => { let symbol = elf.symbol_by_index(index).map_err(map_object_err)?; @@ -254,6 +269,19 @@ where symbol_name_to_relocation_target(symbol_name)? { reloc_target + } else if let object::SymbolSection::Section(section_index) = symbol.section() { + // TODO: Encode symbol address into addend, I think this is a bit hacky. + addend = addend.wrapping_add(symbol.address() as i64); + + if section_index == root_section_index { + root_section_reloc_target + } else { + if visited.insert(section_index) { + worklist.push(section_index); + } + + elf_section_to_target(section_index) + } } else { return Err(CompileError::Codegen(format!( "relocation targets unknown symbol {:?}", diff --git a/lib/compiler/src/artifact_builders/trampoline.rs b/lib/compiler/src/artifact_builders/trampoline.rs index 6c634e148af..387b62608a2 100644 --- a/lib/compiler/src/artifact_builders/trampoline.rs +++ b/lib/compiler/src/artifact_builders/trampoline.rs @@ -25,6 +25,17 @@ const X86_64_TRAMPOLINE: [u8; 16] = [ 0xff, 0x25, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]; +// can it be shorter than this? +// 4 padding bytes are used to preserve alignment. +// AUIPC t1,0 17 03 00 00 +// LD t1, 16(t1) 03 33 03 01 +// JR t1 67 00 03 00 [00 00 00 00] +// JMPADDR 00 00 00 00 00 00 00 00 +const RISCV64_TRAMPOLINE: [u8; 24] = [ + 0x17, 0x03, 0x00, 0x00, 0x03, 0x33, 0x03, 0x01, 0x67, 0x00, 0x03, 0x00, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, +]; + fn make_trampoline( target: &Target, libcall: LibCall, @@ -50,6 +61,15 @@ fn make_trampoline( addend: 0, }); } + Architecture::Riscv64(_) => { + code.extend(RISCV64_TRAMPOLINE); + relocations.push(Relocation { + kind: RelocationKind::Abs8, + reloc_target: RelocationTarget::LibCall(libcall), + offset: code.len() as u32 - 8, + addend: 0, + }); + } arch => panic!("Unsupported architecture: {}", arch), }; } @@ -59,6 +79,7 @@ pub fn libcall_trampoline_len(target: &Target) -> usize { match target.triple().architecture { Architecture::Aarch64(_) => AARCH64_TRAMPOLINE.len(), Architecture::X86_64 => X86_64_TRAMPOLINE.len(), + Architecture::Riscv64(_) => RISCV64_TRAMPOLINE.len(), arch => panic!("Unsupported architecture: {}", arch), } } diff --git a/lib/compiler/src/engine/artifact.rs b/lib/compiler/src/engine/artifact.rs index 6505ed3dde2..6c20b397686 100644 --- a/lib/compiler/src/engine/artifact.rs +++ b/lib/compiler/src/engine/artifact.rs @@ -420,6 +420,7 @@ impl Artifact { } /// Do preinstantiation logic that is executed before instantiating + #[allow(clippy::result_large_err)] pub fn preinstantiate(&self) -> Result<(), InstantiationError> { Ok(()) } @@ -429,6 +430,7 @@ impl Artifact { /// # Safety /// /// See [`VMInstance::new`]. + #[allow(clippy::result_large_err)] pub unsafe fn instantiate( &self, tunables: &dyn Tunables, @@ -509,6 +511,7 @@ impl Artifact { /// # Safety /// /// See [`VMInstance::finish_instantiation`]. + #[allow(clippy::result_large_err)] pub unsafe fn finish_instantiation( &self, trap_handler: Option<*const TrapHandlerFn<'static>>, diff --git a/lib/compiler/src/engine/link.rs b/lib/compiler/src/engine/link.rs index 153d581b446..2ddf1173759 100644 --- a/lib/compiler/src/engine/link.rs +++ b/lib/compiler/src/engine/link.rs @@ -2,6 +2,7 @@ use crate::get_libcall_trampoline; use crate::FunctionExtent; +use std::collections::HashMap; use std::ptr::{read_unaligned, write_unaligned}; use wasmer_types::entity::PrimaryMap; use wasmer_types::{LocalFunctionIndex, ModuleInfo}; @@ -16,6 +17,7 @@ fn apply_relocation( allocated_sections: &PrimaryMap, libcall_trampolines: SectionIndex, libcall_trampoline_len: usize, + riscv_pcrel_hi20s: &mut HashMap, ) { let target_func_address: usize = match r.reloc_target { RelocationTarget::LocalFunc(index) => *allocated_functions[index].ptr as usize, @@ -93,6 +95,32 @@ fn apply_relocation( | read_unaligned(reloc_address as *mut u32); write_unaligned(reloc_address as *mut u32, reloc_delta); }, + RelocationKind::RiscvPCRelHi20 => unsafe { + let (reloc_address, reloc_delta) = r.for_address(body, target_func_address as u64); + + // save for later reference with RiscvPCRelLo12I + riscv_pcrel_hi20s.insert(reloc_address, reloc_delta as u32); + + let reloc_delta = ((reloc_delta.wrapping_add(0x800) & 0xfffff000) as u32) + | read_unaligned(reloc_address as *mut u32); + write_unaligned(reloc_address as *mut u32, reloc_delta); + }, + RelocationKind::RiscvPCRelLo12I => unsafe { + let (reloc_address, reloc_abs) = r.for_address(body, target_func_address as u64); + let reloc_delta = ((riscv_pcrel_hi20s.get(&(reloc_abs as usize)).expect( + "R_RISCV_PCREL_LO12_I relocation target must be a symbol with R_RISCV_PCREL_HI20", + ) & 0xfff) + << 20) + | read_unaligned(reloc_address as *mut u32); + write_unaligned(reloc_address as *mut u32, reloc_delta); + }, + RelocationKind::RiscvCall => unsafe { + let (reloc_address, reloc_delta) = r.for_address(body, target_func_address as u64); + let reloc_delta = ((reloc_delta & 0xfff) << 52) + | (reloc_delta.wrapping_add(0x800) & 0xfffff000) + | read_unaligned(reloc_address as *mut u64); + write_unaligned(reloc_address as *mut u64, reloc_delta); + }, kind => panic!( "Relocation kind unsupported in the current architecture {}", kind @@ -111,6 +139,8 @@ pub fn link_module( libcall_trampolines: SectionIndex, trampoline_len: usize, ) { + let mut riscv_pcrel_hi20s: HashMap = HashMap::new(); + for (i, section_relocs) in section_relocations.iter() { let body = *allocated_sections[i] as usize; for r in section_relocs { @@ -121,6 +151,7 @@ pub fn link_module( allocated_sections, libcall_trampolines, trampoline_len, + &mut riscv_pcrel_hi20s, ); } } @@ -134,6 +165,7 @@ pub fn link_module( allocated_sections, libcall_trampolines, trampoline_len, + &mut riscv_pcrel_hi20s, ); } } diff --git a/lib/compiler/src/engine/resolver.rs b/lib/compiler/src/engine/resolver.rs index 9fac5fc0aec..e4699370bd0 100644 --- a/lib/compiler/src/engine/resolver.rs +++ b/lib/compiler/src/engine/resolver.rs @@ -60,6 +60,7 @@ fn get_runtime_size(context: &StoreObjects, extern_: &VMExtern) -> Option { /// a `Resolver`. /// /// If all imports are satisfied returns an `Imports` instance required for a module instantiation. +#[allow(clippy::result_large_err)] pub fn resolve_imports( module: &ModuleInfo, imports: &[VMExtern], diff --git a/lib/compiler/src/engine/tunables.rs b/lib/compiler/src/engine/tunables.rs index 596af921dc5..945908a18cb 100644 --- a/lib/compiler/src/engine/tunables.rs +++ b/lib/compiler/src/engine/tunables.rs @@ -60,6 +60,7 @@ pub trait Tunables { /// /// # Safety /// - `memory_definition_locations` must point to a valid locations in VM memory. + #[allow(clippy::result_large_err)] unsafe fn create_memories( &self, context: &mut StoreObjects, @@ -93,6 +94,7 @@ pub trait Tunables { /// # Safety /// /// To be done + #[allow(clippy::result_large_err)] unsafe fn create_tables( &self, context: &mut StoreObjects, @@ -123,6 +125,7 @@ pub trait Tunables { /// Allocate memory for just the globals of the current module, /// with initializers applied. + #[allow(clippy::result_large_err)] fn create_globals( &self, context: &mut StoreObjects, diff --git a/lib/object/src/module.rs b/lib/object/src/module.rs index cece8077b2e..1063f17868a 100644 --- a/lib/object/src/module.rs +++ b/lib/object/src/module.rs @@ -3,8 +3,8 @@ use object::write::{ Object, Relocation, StandardSection, StandardSegment, Symbol as ObjSymbol, SymbolSection, }; use object::{ - elf, macho, RelocationEncoding, RelocationKind, SectionKind, SymbolFlags, SymbolKind, - SymbolScope, + elf, macho, FileFlags, RelocationEncoding, RelocationKind, SectionKind, SymbolFlags, + SymbolKind, SymbolScope, }; use wasmer_types::entity::PrimaryMap; use wasmer_types::LocalFunctionIndex; @@ -46,6 +46,7 @@ pub fn get_object_for_target(triple: &Triple) -> Result { let obj_architecture = match triple.architecture { Architecture::X86_64 => object::Architecture::X86_64, Architecture::Aarch64(_) => object::Architecture::Aarch64, + Architecture::Riscv64(_) => object::Architecture::Riscv64, architecture => { return Err(ObjectError::UnsupportedArchitecture(format!( "{}", @@ -61,11 +62,15 @@ pub fn get_object_for_target(triple: &Triple) -> Result { Endianness::Big => object::Endianness::Big, }; - Ok(Object::new( - obj_binary_format, - obj_architecture, - obj_endianness, - )) + let mut object = Object::new(obj_binary_format, obj_architecture, obj_endianness); + + if let Architecture::Riscv64(_) = triple.architecture { + object.flags = FileFlags::Elf { + e_flags: elf::EF_RISCV_FLOAT_ABI_DOUBLE, + }; + } + + Ok(object) } /// Write data into an existing object. diff --git a/lib/registry/Cargo.toml b/lib/registry/Cargo.toml index 217b6609686..a607d2bde75 100644 --- a/lib/registry/Cargo.toml +++ b/lib/registry/Cargo.toml @@ -13,7 +13,6 @@ dirs = "4.0.0" graphql_client = "0.11.0" serde = { version = "1.0.145", features = ["derive"] } anyhow = "1.0.65" -reqwest = { version = "0.11.12", default-features = false, features = ["rustls-tls", "blocking", "multipart", "json", "stream"] } futures-util = "0.3.25" whoami = "1.2.3" serde_json = "1.0.85" @@ -37,3 +36,9 @@ console = "0.15.2" indicatif = "0.17.2" lazy_static = "1.4.0" tempfile = "3.4.0" + +[target.'cfg(not(target_arch = "riscv64"))'.dependencies] +reqwest = { version = "0.11.12", default-features = false, features = ["rustls-tls", "blocking", "multipart", "json", "stream"] } + +[target.'cfg(target_arch = "riscv64")'.dependencies] +reqwest = { version = "0.11.12", default-features = false, features = ["native-tls", "blocking", "multipart", "json", "stream"] } diff --git a/lib/registry/src/lib.rs b/lib/registry/src/lib.rs index 4bd8764ae92..632e753dec2 100644 --- a/lib/registry/src/lib.rs +++ b/lib/registry/src/lib.rs @@ -475,7 +475,7 @@ pub fn try_unpack_targz>( ) }) } else { - ar.unpack(&target_path).map_err(|e| { + ar.unpack(target_path).map_err(|e| { anyhow::anyhow!( "failed to unpack (with parent) {}: {e}", target_targz_path.display() diff --git a/lib/types/src/compilation/relocation.rs b/lib/types/src/compilation/relocation.rs index 4bdb0184d3e..b1a18e42da0 100644 --- a/lib/types/src/compilation/relocation.rs +++ b/lib/types/src/compilation/relocation.rs @@ -50,8 +50,12 @@ pub enum RelocationKind { Arm64Movw2, /// Arm64 movk/z part 3 Arm64Movw3, - // /// RISC-V call target - // RiscvCall, + /// RISC-V PC-relative high 20bit + RiscvPCRelHi20, + /// RISC-V PC-relative low 12bit, I-type + RiscvPCRelLo12I, + /// RISC-V call target + RiscvCall, /// Elf x86_64 32 bit signed PC relative offset to two GOT entries for GD symbol. ElfX86_64TlsGd, // /// Mach-O x86_64 32 bit signed PC relative offset to a `__thread_vars` entry. @@ -70,12 +74,14 @@ impl fmt::Display for RelocationKind { Self::X86CallPCRel4 => write!(f, "CallPCRel4"), Self::X86CallPLTRel4 => write!(f, "CallPLTRel4"), Self::X86GOTPCRel4 => write!(f, "GOTPCRel4"), - Self::Arm32Call | Self::Arm64Call => write!(f, "Call"), + Self::Arm32Call | Self::Arm64Call | Self::RiscvCall => write!(f, "Call"), Self::Arm64Movw0 => write!(f, "Arm64MovwG0"), Self::Arm64Movw1 => write!(f, "Arm64MovwG1"), Self::Arm64Movw2 => write!(f, "Arm64MovwG2"), Self::Arm64Movw3 => write!(f, "Arm64MovwG3"), Self::ElfX86_64TlsGd => write!(f, "ElfX86_64TlsGd"), + Self::RiscvPCRelHi20 => write!(f, "RiscvPCRelHi20"), + Self::RiscvPCRelLo12I => write!(f, "RiscvPCRelLo12I"), // Self::MachOX86_64Tlv => write!(f, "MachOX86_64Tlv"), } } @@ -119,7 +125,8 @@ impl Relocation { | RelocationKind::Arm64Movw0 | RelocationKind::Arm64Movw1 | RelocationKind::Arm64Movw2 - | RelocationKind::Arm64Movw3 => { + | RelocationKind::Arm64Movw3 + | RelocationKind::RiscvPCRelLo12I => { let reloc_address = start + self.offset as usize; let reloc_addend = self.addend as isize; let reloc_abs = target_func_address @@ -153,7 +160,9 @@ impl Relocation { .wrapping_add(reloc_addend as u32); (reloc_address, reloc_delta_u32 as u64) } - RelocationKind::Arm64Call => { + RelocationKind::Arm64Call + | RelocationKind::RiscvCall + | RelocationKind::RiscvPCRelHi20 => { let reloc_address = start + self.offset as usize; let reloc_addend = self.addend as isize; let reloc_delta_u32 = target_func_address diff --git a/lib/vfs/src/webc_fs.rs b/lib/vfs/src/webc_fs.rs index 0bb1970cc81..2dace6d5119 100644 --- a/lib/vfs/src/webc_fs.rs +++ b/lib/vfs/src/webc_fs.rs @@ -85,7 +85,8 @@ where ) -> Result, FsError> { match get_volume_name_opt(path) { Some(volume) => { - let file = (*self.webc) + let file = self + .webc .volumes .get(&volume) .ok_or(FsError::EntryNotFound)? diff --git a/lib/wasi/Cargo.toml b/lib/wasi/Cargo.toml index 19a261b84b3..6cd761de808 100644 --- a/lib/wasi/Cargo.toml +++ b/lib/wasi/Cargo.toml @@ -63,12 +63,18 @@ wcgi-host = { version = "0.1.0", optional = true } tower-http = { version = "0.4.0", features = ["trace", "util", "catch-panic", "cors"], optional = true } tower = { version = "0.4.13", features = ["make", "util"], optional = true } -[dependencies.reqwest] +[target.'cfg(not(target_arch = "riscv64"))'.dependencies.reqwest] version = "0.11" default-features = false features = ["rustls-tls", "json"] optional = true +[target.'cfg(target_arch = "riscv64")'.dependencies.reqwest] +version = "0.11" +default-features = false +features = ["native-tls", "json"] +optional = true + [target.'cfg(unix)'.dependencies] libc = { version = "^0.2", default-features = false } termios = { version = "0.3" } diff --git a/lib/wasi/src/lib.rs b/lib/wasi/src/lib.rs index 85549d39f6e..61b26758c9b 100644 --- a/lib/wasi/src/lib.rs +++ b/lib/wasi/src/lib.rs @@ -258,6 +258,7 @@ impl WasiRuntimeError { } } +#[allow(clippy::result_large_err)] pub(crate) fn run_wasi_func( func: &wasmer::Function, store: &mut impl AsStoreMut, @@ -279,6 +280,7 @@ pub(crate) fn run_wasi_func( /// The function will not receive arguments or return values. /// /// An exit code that is not 0 will be returned as a `WasiError::Exit`. +#[allow(clippy::result_large_err)] pub(crate) fn run_wasi_func_start( func: &wasmer::Function, store: &mut impl AsStoreMut, diff --git a/lib/wasi/src/state/builder.rs b/lib/wasi/src/state/builder.rs index 68bc42ab058..32d810197a5 100644 --- a/lib/wasi/src/state/builder.rs +++ b/lib/wasi/src/state/builder.rs @@ -764,6 +764,7 @@ impl WasiEnvBuilder { Ok(init) } + #[allow(clippy::result_large_err)] pub fn build(self) -> Result { let init = self.build_init()?; WasiEnv::from_init(init) @@ -774,6 +775,7 @@ impl WasiEnvBuilder { /// NOTE: you still must call [`WasiFunctionEnv::initialize`] to make an /// instance usable. #[doc(hidden)] + #[allow(clippy::result_large_err)] pub fn finalize( self, store: &mut impl AsStoreMut, @@ -789,6 +791,7 @@ impl WasiEnvBuilder { /// /// Returns the error from `WasiFs::new` if there's an error // FIXME: use a proper custom error type + #[allow(clippy::result_large_err)] pub fn instantiate( self, module: Module, @@ -798,11 +801,13 @@ impl WasiEnvBuilder { WasiEnv::instantiate(init, module, store) } + #[allow(clippy::result_large_err)] pub fn run(self, module: Module) -> Result<(), WasiRuntimeError> { let mut store = wasmer::Store::default(); self.run_with_store(module, &mut store) } + #[allow(clippy::result_large_err)] pub fn run_with_store( self, module: Module, diff --git a/lib/wasi/src/state/env.rs b/lib/wasi/src/state/env.rs index 867193d9299..d2d6687998b 100644 --- a/lib/wasi/src/state/env.rs +++ b/lib/wasi/src/state/env.rs @@ -375,6 +375,7 @@ impl WasiEnv { self.thread.tid() } + #[allow(clippy::result_large_err)] pub(crate) fn from_init(init: WasiEnvInit) -> Result { let process = if let Some(p) = init.process { p @@ -415,6 +416,7 @@ impl WasiEnv { } // FIXME: use custom error type + #[allow(clippy::result_large_err)] pub(crate) fn instantiate( mut init: WasiEnvInit, module: Module, diff --git a/lib/wasi/src/syscalls/wasi/environ_get.rs b/lib/wasi/src/syscalls/wasi/environ_get.rs index 3db40af1828..35425551c5d 100644 --- a/lib/wasi/src/syscalls/wasi/environ_get.rs +++ b/lib/wasi/src/syscalls/wasi/environ_get.rs @@ -18,5 +18,5 @@ pub fn environ_get( let env = ctx.data(); let (memory, mut state) = env.get_memory_and_wasi_state(&ctx, 0); - write_buffer_array(&memory, &*state.envs, environ, environ_buf) + write_buffer_array(&memory, &state.envs, environ, environ_buf) } diff --git a/lib/wasi/src/syscalls/wasi/path_rename.rs b/lib/wasi/src/syscalls/wasi/path_rename.rs index 3eb34a7302d..316fec63ffa 100644 --- a/lib/wasi/src/syscalls/wasi/path_rename.rs +++ b/lib/wasi/src/syscalls/wasi/path_rename.rs @@ -121,7 +121,7 @@ pub fn path_rename( // implements the logic of "I'm not actually a file, I'll try to be as needed". let result = if let Some(h) = handle { drop(guard); - state.fs_rename(&source_path, &host_adjusted_target_path) + state.fs_rename(source_path, &host_adjusted_target_path) } else { let path_clone = path.clone(); drop(guard); diff --git a/rust-toolchain b/rust-toolchain index 8725364a8ec..5b6cd6b3cd7 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.64 +1.65 diff --git a/tests/ignores.txt b/tests/ignores.txt index 4a86746e18a..d4a4af91a11 100644 --- a/tests/ignores.txt +++ b/tests/ignores.txt @@ -8,6 +8,7 @@ singlepass spec::simd # Singlepass doesn't support yet SIMD (no one asked for th singlepass+aarch64+macos traps::test_trap_trace cranelift+aarch64+macos traps::test_trap_trace llvm+aarch64 traps::test_trap_trace +llvm+riscv64 traps::test_trap_trace singlepass+aarch64+macos traps::test_trap_stack_overflow # Need to investigate singlepass+aarch64+macos traps::trap_display_pretty llvm traps::trap_display_pretty @@ -28,6 +29,34 @@ cranelift+aarch64+macos traps::start_trap_pretty # https://github.com/wasmerio/wasmer/issues/2808 cranelift+aarch64 spec::skip_stack_guard_page llvm+aarch64 spec::skip_stack_guard_page +cranelift+riscv64 spec::skip_stack_guard_page +llvm+riscv64 spec::skip_stack_guard_page + +# riscv support is still early, function call ABI needs some work +llvm+riscv64 static_function::llvm::universal +llvm+riscv64 static_function_with_env::llvm::universal +llvm+riscv64 static_function_with_results::llvm::universal +llvm+riscv64 spec::f32::llvm::universal +llvm+riscv64 spec::f64::llvm::universal +llvm+riscv64 spec::float_misc::llvm::universal +llvm+riscv64 spec::memory_copy::llvm::universal +llvm+riscv64 spec::memory_init::llvm::universal +llvm+riscv64 spec::memory_trap::llvm::universal +llvm+riscv64 spec::multi_value::binary::llvm::universal +llvm+riscv64 spec::multi_value::block::llvm::universal +llvm+riscv64 spec::simd::simd_align::llvm::universal +llvm+riscv64 spec::simd::simd_f32x4_rounding::llvm::universal +llvm+riscv64 spec::simd::simd_f64x2_rounding::llvm::universal +llvm+riscv64 wasmer::nan_canonicalization::llvm::universal +llvm+riscv64 wasmer::stack_overflow_sret::llvm::universal +# riscv support on Cranelift is also very young +cranelift+riscv64 spec::align::cranelift::universal +cranelift+riscv64 spec::memory_copy::cranelift::universal +cranelift+riscv64 spec::memory_trap::cranelift::universal +cranelift+riscv64 spec::r#if::cranelift::universal + +# no SIMD on riscv, Cranelift will not handle them +cranelift+riscv64 spec::simd # Windows doesn't overcommit and fails to allocate 4GB of memory windows wasmer::max_size_of_memory diff --git a/tests/lib/compiler-test-derive/src/ignores.rs b/tests/lib/compiler-test-derive/src/ignores.rs index c9425355033..12364cf2191 100644 --- a/tests/lib/compiler-test-derive/src/ignores.rs +++ b/tests/lib/compiler-test-derive/src/ignores.rs @@ -111,7 +111,7 @@ impl Ignores { target_env = Some(alias.to_string()); } // Chipset architectures - "aarch64" | "x86" | "x64" => { + "aarch64" | "x86" | "x64" | "riscv64" => { arch = Some(alias.to_string()); } // Engines diff --git a/tests/lib/wast/src/wast.rs b/tests/lib/wast/src/wast.rs index 50bc02b3883..80b02adc276 100644 --- a/tests/lib/wast/src/wast.rs +++ b/tests/lib/wast/src/wast.rs @@ -437,7 +437,7 @@ impl Wast { // Checks if the `assert_unlinkable` message matches the expected one fn matches_message_assert_unlinkable(expected: &str, actual: &str) -> bool { - actual.contains(&expected) + actual.contains(expected) } // Checks if the `assert_invalid` message matches the expected one