diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fdedd59560f..8a8655b9228 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -119,7 +119,7 @@ jobs: target: aarch64-apple-darwin artifact_name: 'wasmer-darwin-arm64' use_sccache: false - use_llvm: false + use_llvm: true build_wasm: false # [todo] xdoardo: Reinstate when the code we generate for aarch64 is working correctly. llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/18.x/llvm-darwin-aarch64.tar.xz' @@ -573,70 +573,70 @@ jobs: if-no-files-found: error retention-days: 2 - # linux_riscv64: - # name: Linux riscv64 - # runs-on: ubuntu-latest - # steps: - # - uses: actions/checkout@v3 - # - uses: dtolnay/rust-toolchain@stable - # with: - # target: riscv64gc-unknown-linux-gnu - # - name: Build cross image - # run: | - # docker build -t wasmer/riscv64 ${GITHUB_WORKSPACE}/.github/cross-linux-riscv64/ - # env: - # CROSS_DOCKER_IN_DOCKER: true - # - name: Build Wasmer binary - # run: | - # make build-wasmer - # env: - # CARGO_BINARY: docker run -v /var/run/docker.sock:/var/run/docker.sock -v ${GITHUB_WORKSPACE}:/project -w /project wasmer/riscv64:latest cargo - # CROSS_DOCKER_IN_DOCKER: true - # CARGO_TARGET: riscv64gc-unknown-linux-gnu - # PKG_CONFIG_PATH: /usr/lib/riscv64-linux-gnu/pkgconfig - # PKG_CONFIG_ALLOW_CROSS: true - # ENABLE_LLVM: 0 - # - name: Build C API headless - # shell: bash - # run: | - # make package-capi-headless - # env: - # CARGO_BINARY: docker run -v /var/run/docker.sock:/var/run/docker.sock -v ${GITHUB_WORKSPACE}:/project -w /project wasmer/riscv64:latest cargo - # CROSS_DOCKER_IN_DOCKER: true - # CARGO_TARGET: riscv64gc-unknown-linux-gnu - # PKG_CONFIG_PATH: /usr/lib/riscv64-linux-gnu/pkgconfig - # PKG_CONFIG_ALLOW_CROSS: true - # ENABLE_LLVM: 0 - # TARGET: riscv64gc-unknown-linux-gnu - # TARGET_DIR: target/riscv64gc-unknown-linux-gnu/release - # - name: Build C API - # run: | - # make build-capi - # env: - # CARGO_BINARY: docker run -v /var/run/docker.sock:/var/run/docker.sock -v ${GITHUB_WORKSPACE}:/project -w /project wasmer/riscv64:latest cargo - # CROSS_DOCKER_IN_DOCKER: true - # CARGO_TARGET: riscv64gc-unknown-linux-gnu - # PKG_CONFIG_PATH: /usr/lib/riscv64-linux-gnu/pkgconfig - # PKG_CONFIG_ALLOW_CROSS: true - # ENABLE_LLVM: 0 - # - name: Dist - # run: | - # make distribution - # env: - # CARGO_BINARY: docker run -v /var/run/docker.sock:/var/run/docker.sock -v ${GITHUB_WORKSPACE}:/project -w /project wasmer/riscv64:latest cargo - # CROSS_DOCKER_IN_DOCKER: true - # CARGO_TARGET: riscv64gc-unknown-linux-gnu - # PKG_CONFIG_PATH: /usr/lib/riscv64-linux-gnu/pkgconfig - # PKG_CONFIG_ALLOW_CROSS: true - # TARGET: riscv64gc-unknown-linux-gnu - # TARGET_DIR: target/riscv64gc-unknown-linux-gnu/release - # - name: Upload Artifacts - # uses: actions/upload-artifact@v4 - # with: - # name: wasmer-linux-riscv64 - # path: dist - # if-no-files-found: error - # retention-days: 2 + linux_riscv64: + name: Linux riscv64 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@stable + with: + target: riscv64gc-unknown-linux-gnu + - name: Build cross image + run: | + docker build -t wasmer/riscv64 ${GITHUB_WORKSPACE}/.github/cross-linux-riscv64/ + env: + CROSS_DOCKER_IN_DOCKER: true + - name: Build Wasmer binary + run: | + make build-wasmer + env: + CARGO_BINARY: docker run -v /var/run/docker.sock:/var/run/docker.sock -v ${GITHUB_WORKSPACE}:/project -w /project wasmer/riscv64:latest cargo + CROSS_DOCKER_IN_DOCKER: true + CARGO_TARGET: riscv64gc-unknown-linux-gnu + PKG_CONFIG_PATH: /usr/lib/riscv64-linux-gnu/pkgconfig + PKG_CONFIG_ALLOW_CROSS: true + ENABLE_LLVM: 0 + - name: Build C API headless + shell: bash + run: | + make package-capi-headless + env: + CARGO_BINARY: docker run -v /var/run/docker.sock:/var/run/docker.sock -v ${GITHUB_WORKSPACE}:/project -w /project wasmer/riscv64:latest cargo + CROSS_DOCKER_IN_DOCKER: true + CARGO_TARGET: riscv64gc-unknown-linux-gnu + PKG_CONFIG_PATH: /usr/lib/riscv64-linux-gnu/pkgconfig + PKG_CONFIG_ALLOW_CROSS: true + ENABLE_LLVM: 0 + TARGET: riscv64gc-unknown-linux-gnu + TARGET_DIR: target/riscv64gc-unknown-linux-gnu/release + - name: Build C API + run: | + make build-capi + env: + CARGO_BINARY: docker run -v /var/run/docker.sock:/var/run/docker.sock -v ${GITHUB_WORKSPACE}:/project -w /project wasmer/riscv64:latest cargo + CROSS_DOCKER_IN_DOCKER: true + CARGO_TARGET: riscv64gc-unknown-linux-gnu + PKG_CONFIG_PATH: /usr/lib/riscv64-linux-gnu/pkgconfig + PKG_CONFIG_ALLOW_CROSS: true + ENABLE_LLVM: 0 + - name: Dist + run: | + make distribution + env: + CARGO_BINARY: docker run -v /var/run/docker.sock:/var/run/docker.sock -v ${GITHUB_WORKSPACE}:/project -w /project wasmer/riscv64:latest cargo + CROSS_DOCKER_IN_DOCKER: true + CARGO_TARGET: riscv64gc-unknown-linux-gnu + PKG_CONFIG_PATH: /usr/lib/riscv64-linux-gnu/pkgconfig + PKG_CONFIG_ALLOW_CROSS: true + TARGET: riscv64gc-unknown-linux-gnu + TARGET_DIR: target/riscv64gc-unknown-linux-gnu/release + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: wasmer-linux-riscv64 + path: dist + if-no-files-found: error + retention-days: 2 release: # needs: [setup, build, linux_aarch64, windows_gnu, linux_riscv64] diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 8b1545862e6..b12ecc4355a 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -511,8 +511,7 @@ jobs: os: macos-14, target: aarch64-apple-darwin, exe: '', - # [todo] xdoardo: Reinstate when the code we generate for aarch64 is working correctly. - # llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/18.x/llvm-darwin-aarch64.tar.xz' + llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/18.x/llvm-darwin-aarch64.tar.xz' }, { build: windows-x64, @@ -765,8 +764,7 @@ jobs: os: macos-14, target: aarch64-apple-darwin, exe: '', - # [todo] xdoardo: Reinstate when the code we generate for aarch64 is working correctly. - # llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/18.x/llvm-darwin-aarch64.tar.xz' + llvm_url: 'https://github.com/wasmerio/llvm-custom-builds/releases/download/18.x/llvm-darwin-aarch64.tar.xz' }, { build: windows-x64, diff --git a/examples/memory.rs b/examples/memory.rs index 2ea623bda39..26446387084 100644 --- a/examples/memory.rs +++ b/examples/memory.rs @@ -108,8 +108,8 @@ fn main() -> anyhow::Result<()> { // see how we can do that: println!("Growing memory..."); - // 'wasm-c-api' does not support direct calls to memory.grow() - #[cfg(not(feature = "wasm-c-api"))] + // 'wamr' does not support direct calls to memory.grow() + #[cfg(not(feature = "wamr"))] { // Here we are requesting two more pages for our memory. memory.grow(&mut store, 2)?; diff --git a/examples/table.rs b/examples/table.rs index cd74083694e..52e5b9f4589 100644 --- a/examples/table.rs +++ b/examples/table.rs @@ -154,7 +154,6 @@ fn main() -> anyhow::Result<()> { // This test is currently failing with: // not implemented: Native function definitions can't be directly called from the host yet -#[cfg(FALSE)] #[test] fn test_table() -> anyhow::Result<()> { main() diff --git a/lib/compiler-llvm/src/config.rs b/lib/compiler-llvm/src/config.rs index 5d76872ec46..c30776406f9 100644 --- a/lib/compiler-llvm/src/config.rs +++ b/lib/compiler-llvm/src/config.rs @@ -119,11 +119,13 @@ impl LLVM { // but not in the case of Aarch64, there the ABI is slightly different #[allow(clippy::match_single_binding)] match target.triple().architecture { + Architecture::Aarch64(_) => wasmer_types::OperatingSystem::Darwin, _ => wasmer_types::OperatingSystem::Linux, } } else { target.triple().operating_system }; + let binary_format = if self.is_pic { target.triple().binary_format } else { diff --git a/lib/compiler-llvm/src/object_file.rs b/lib/compiler-llvm/src/object_file.rs index 06b196326ed..df1641d2706 100644 --- a/lib/compiler-llvm/src/object_file.rs +++ b/lib/compiler-llvm/src/object_file.rs @@ -251,6 +251,32 @@ where object::RelocationKind::Elf(object::elf::R_LARCH_ABS64_LO20), 0, ) => RelocationKind::LArchAbs64Lo20, + ( + object::Architecture::Aarch64, + object::RelocationKind::Elf(object::elf::R_AARCH64_ADR_PREL_LO21), + 0, + ) => RelocationKind::Aarch64AdrPrelLo21, + ( + object::Architecture::Aarch64, + object::RelocationKind::Elf(object::elf::R_AARCH64_ADR_PREL_PG_HI21), + 0, + ) => RelocationKind::Aarch64AdrPrelPgHi21, + ( + object::Architecture::Aarch64, + object::RelocationKind::Elf(object::elf::R_AARCH64_LDST128_ABS_LO12_NC), + 0, + ) => RelocationKind::Aarch64Ldst128AbsLo12Nc, + ( + object::Architecture::Aarch64, + object::RelocationKind::Elf(object::elf::R_AARCH64_ADD_ABS_LO12_NC), + 0, + ) => RelocationKind::Aarch64AddAbsLo12Nc, + ( + object::Architecture::Aarch64, + object::RelocationKind::Elf(object::elf::R_AARCH64_LDST64_ABS_LO12_NC), + 0, + ) => RelocationKind::Aarch64Ldst64AbsLo12Nc, + _ => { return Err(CompileError::Codegen(format!( "unknown relocation {:?}", diff --git a/lib/compiler-llvm/src/translator/intrinsics.rs b/lib/compiler-llvm/src/translator/intrinsics.rs index ca48b07e533..3585af37399 100644 --- a/lib/compiler-llvm/src/translator/intrinsics.rs +++ b/lib/compiler-llvm/src/translator/intrinsics.rs @@ -1104,10 +1104,6 @@ impl<'ctx> Intrinsics<'ctx> { intrinsics .throw_trap .add_attribute(AttributeLoc::Function, noreturn); - //intrinsics - // .func_ref - // .add_attribute(AttributeLoc::Function, intrinsics.readonly); - intrinsics } } diff --git a/lib/compiler/src/engine/link.rs b/lib/compiler/src/engine/link.rs index a3fc64dd2da..7aafeb82de9 100644 --- a/lib/compiler/src/engine/link.rs +++ b/lib/compiler/src/engine/link.rs @@ -146,6 +146,59 @@ fn apply_relocation( | read_unaligned(reloc_address as *mut u32); write_unaligned(reloc_address as *mut u32, reloc_abs); }, + RelocationKind::Aarch64AdrPrelPgHi21 => unsafe { + let (reloc_address, delta) = r.for_address(body, target_func_address as u64); + + let delta = delta as isize; + assert!( + ((-1 << 32)..(1 << 32)).contains(&delta), + "can't generate page-relative relocation with ±4GB `adrp` instruction" + ); + + let op = read_unaligned(reloc_address as *mut u32); + let delta = delta >> 12; + let immlo = ((delta as u32) & 0b11) << 29; + let immhi = (((delta as u32) >> 2) & 0x7ffff) << 5; + let mask = !((0x7ffff << 5) | (0b11 << 29)); + let op = (op & mask) | immlo | immhi; + + write_unaligned(reloc_address as *mut u32, op); + }, + RelocationKind::Aarch64AdrPrelLo21 => unsafe { + let (reloc_address, delta) = r.for_address(body, target_func_address as u64); + + let delta = delta as isize; + assert!( + ((-1 << 20)..(1 << 20)).contains(&delta), + "can't generate an ADR_PREL_LO21 relocation with an immediate larger than 20 bits" + ); + + let op = read_unaligned(reloc_address as *mut u32); + let immlo = ((delta as u32) & 0b11) << 29; + let immhi = (((delta as u32) >> 2) & 0x7ffff) << 5; + let mask = !((0x7ffff << 5) | (0b11 << 29)); + let op = (op & mask) | immlo | immhi; + + write_unaligned(reloc_address as *mut u32, op); + }, + RelocationKind::Aarch64AddAbsLo12Nc => unsafe { + let (reloc_address, reloc_delta) = r.for_address(body, target_func_address as u64); + let reloc_delta = (reloc_delta as u32 & 0xfff) + | (read_unaligned(reloc_address as *mut u32) & 0xFFC003FF); + write_unaligned(reloc_address as *mut u32, reloc_delta); + }, + RelocationKind::Aarch64Ldst128AbsLo12Nc => unsafe { + let (reloc_address, reloc_delta) = r.for_address(body, target_func_address as u64); + let reloc_delta = ((reloc_delta as u32 & 0xfff) >> 4) << 10 + | (read_unaligned(reloc_address as *mut u32) & 0xFFC003FF); + write_unaligned(reloc_address as *mut u32, reloc_delta); + }, + RelocationKind::Aarch64Ldst64AbsLo12Nc => unsafe { + let (reloc_address, reloc_delta) = r.for_address(body, target_func_address as u64); + let reloc_delta = ((reloc_delta as u32 & 0xfff) >> 3) << 10 + | (read_unaligned(reloc_address as *mut u32) & 0xFFC003FF); + write_unaligned(reloc_address as *mut u32, reloc_delta); + }, kind => panic!( "Relocation kind unsupported in the current architecture {}", kind diff --git a/lib/types/src/compilation/relocation.rs b/lib/types/src/compilation/relocation.rs index 54060c9f6f2..f714542b2bf 100644 --- a/lib/types/src/compilation/relocation.rs +++ b/lib/types/src/compilation/relocation.rs @@ -46,6 +46,22 @@ pub enum RelocationKind { X86CallPLTRel4, /// x86 GOT PC-relative 4-byte X86GOTPCRel4, + + /// R_AARCH64_ADR_PREL_LO21 + Aarch64AdrPrelLo21, + + /// R_AARCH64_ADR_PREL_PG_HI21 + Aarch64AdrPrelPgHi21, + + /// R_AARCH64_ADD_ABS_LO12_NC + Aarch64AddAbsLo12Nc, + + /// R_AARCH64_LDST128_ABS_LO12_NC + Aarch64Ldst128AbsLo12Nc, + + /// R_AARCH64_LDST64_ABS_LO12_NC + Aarch64Ldst64AbsLo12Nc, + /// Arm32 call target Arm32Call, /// Arm64 call target @@ -102,6 +118,11 @@ impl fmt::Display for RelocationKind { Self::LArchAbsLo12 => write!(f, "LArchAbsLo12"), Self::LArchAbs64Hi12 => write!(f, "LArchAbs64Hi12"), Self::LArchAbs64Lo20 => write!(f, "LArchAbs64Lo20"), + Self::Aarch64AdrPrelLo21 => write!(f, "Aarch64AdrPrelLo21"), + Self::Aarch64AdrPrelPgHi21 => write!(f, "Aarch64AdrPrelPgHi21"), + Self::Aarch64AddAbsLo12Nc => write!(f, "Aarch64AddAbsLo12Nc"), + Self::Aarch64Ldst128AbsLo12Nc => write!(f, "Aarch64Ldst128AbsLo12Nc"), + Self::Aarch64Ldst64AbsLo12Nc => write!(f, "Aarch64Ldst64AbsLo12Nc"), // Self::MachOX86_64Tlv => write!(f, "MachOX86_64Tlv"), } } @@ -142,7 +163,10 @@ pub trait RelocationLike { | RelocationKind::Arm64Movw1 | RelocationKind::Arm64Movw2 | RelocationKind::Arm64Movw3 - | RelocationKind::RiscvPCRelLo12I => { + | RelocationKind::RiscvPCRelLo12I + | RelocationKind::Aarch64AddAbsLo12Nc + | RelocationKind::Aarch64Ldst128AbsLo12Nc + | RelocationKind::Aarch64Ldst64AbsLo12Nc => { let reloc_address = start + self.offset() as usize; let reloc_addend = self.addend() as isize; let reloc_abs = target_func_address @@ -178,7 +202,8 @@ pub trait RelocationLike { } RelocationKind::Arm64Call | RelocationKind::RiscvCall - | RelocationKind::RiscvPCRelHi20 => { + | RelocationKind::RiscvPCRelHi20 + | RelocationKind::Aarch64AdrPrelLo21 => { let reloc_address = start + self.offset() as usize; let reloc_addend = self.addend() as isize; let reloc_delta_u32 = target_func_address @@ -186,6 +211,14 @@ pub trait RelocationLike { .wrapping_add(reloc_addend as u64); (reloc_address, reloc_delta_u32) } + RelocationKind::Aarch64AdrPrelPgHi21 => { + let reloc_address = start + self.offset() as usize; + let reloc_addend = self.addend() as isize; + let target_page = + (target_func_address.wrapping_add(reloc_addend as u64) & !(0xFFF)) as usize; + let pc_page = reloc_address & !(0xFFF); + (reloc_address, target_page.wrapping_sub(pc_page) as u64) + } _ => panic!("Relocation kind unsupported"), } } diff --git a/tests/compilers/artifact.rs b/tests/compilers/artifact.rs index 334ec9d2af3..53eca021058 100644 --- a/tests/compilers/artifact.rs +++ b/tests/compilers/artifact.rs @@ -1,6 +1,4 @@ use std::{fs, path::PathBuf}; - -use cfg_if::cfg_if; use wasmer::{Engine, Module}; #[test] @@ -57,6 +55,7 @@ fn artifact_serialization_build() { #[test] #[cfg(target_arch = "x86_64")] fn artifact_deserialization_roundtrip() { + use cfg_if::cfg_if; // This test is included to make sure we don't break the serialized format // by mistake. Otherwise, everything in this test is already tested in // `artifact_serialization_roundtrip`.