diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f7dbdf5d91..86ef20f56a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -77,7 +77,7 @@ jobs: submodules: true - uses: ./.github/actions/install-rust with: - toolchain: nightly-2022-09-07 + toolchain: nightly-2022-12-15 # Build C API documentation - run: curl -L https://sourceforge.net/projects/doxygen/files/rel-1.9.3/doxygen-1.9.3.linux.bin.tar.gz/download | tar xzf - @@ -197,7 +197,7 @@ jobs: # flags to rustc. - uses: ./.github/actions/install-rust with: - toolchain: nightly-2022-09-07 + toolchain: nightly-2022-12-15 - run: cargo install cargo-fuzz --vers "^0.11" # Install the OCaml packages necessary for fuzz targets that use the # `wasm-spec-interpreter`. diff --git a/Cargo.toml b/Cargo.toml index 20f37ce917..b17382b577 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ repository = "https://github.com/bytecodealliance/wasmtime" readme = "README.md" edition.workspace = true default-run = "wasmtime" +rust-version.workspace = true [lib] doctest = false @@ -105,6 +106,7 @@ exclude = [ version = "5.0.0" authors = ["The Wasmtime Project Developers"] edition = "2021" +rust-version = "1.66.0" [workspace.dependencies] wasmtime = { path = "crates/wasmtime", version = "5.0.0", default-features = false } diff --git a/crates/asm-macros/src/lib.rs b/crates/asm-macros/src/lib.rs index 50c0ef848e..efd970d6bc 100644 --- a/crates/asm-macros/src/lib.rs +++ b/crates/asm-macros/src/lib.rs @@ -5,51 +5,43 @@ //! attributes correct (e.g. ELF symbols get a size and are flagged as a //! function) and additionally handles visibility across platforms. All symbols //! should be visible to Rust but not visible externally outside of a `*.so`. -//! -//! It also exports a an `asm_sym!` macro which can be used to reference symbols -//! from within `global_asm!`-defined functions, and handles adding the leading -//! underscore that macOS prepends to symbols for you. cfg_if::cfg_if! { if #[cfg(target_os = "macos")] { #[macro_export] macro_rules! asm_func { - ($name:expr, $($body:tt)*) => { - std::arch::global_asm!(concat!( - ".p2align 4\n", - ".private_extern _", $name, "\n", - ".global _", $name, "\n", - "_", $name, ":\n", - $($body)* - )); + ($name:expr, $body:expr $(, $($args:tt)*)?) => { + std::arch::global_asm!( + concat!( + ".p2align 4\n", + ".private_extern _", $name, "\n", + ".global _", $name, "\n", + "_", $name, ":\n", + $body, + ), + $($($args)*)? + ); }; } - - #[macro_export] - macro_rules! asm_sym { - ( $( $name:tt )* ) => ( concat!("_", $( $name )* ) ) - } } else if #[cfg(target_os = "windows")] { #[macro_export] macro_rules! asm_func { - ($name:expr, $($body:tt)*) => { - std::arch::global_asm!(concat!( - ".def ", $name, "\n", - ".scl 2\n", - ".type 32\n", - ".endef\n", - ".global ", $name, "\n", - ".p2align 4\n", - $name, ":\n", - $($body)* - )); + ($name:expr, $body:expr $(, $($args:tt)*)?) => { + std::arch::global_asm!( + concat!( + ".def ", $name, "\n", + ".scl 2\n", + ".type 32\n", + ".endef\n", + ".global ", $name, "\n", + ".p2align 4\n", + $name, ":\n", + $body + ), + $($($args)*)? + ); }; } - - #[macro_export] - macro_rules! asm_sym { - ( $( $name:tt )* ) => ( $( $name )* ) - } } else { // Note that for now this "else" clause just assumes that everything // other than macOS is ELF and has the various directives here for @@ -70,22 +62,20 @@ cfg_if::cfg_if! { #[macro_export] macro_rules! asm_func { - ($name:expr, $($body:tt)*) => { - std::arch::global_asm!(concat!( - ".p2align 4\n", - ".hidden ", $name, "\n", - ".global ", $name, "\n", - $crate::elf_func_type_header!($name), - $name, ":\n", - concat!($($body)*), - ".size ", $name, ",.-", $name, - )); + ($name:expr, $body:expr $(, $($args:tt)*)?) => { + std::arch::global_asm!( + concat!( + ".p2align 4\n", + ".hidden ", $name, "\n", + ".global ", $name, "\n", + $crate::elf_func_type_header!($name), + $name, ":\n", + $body, + ".size ", $name, ",.-", $name, + ) + $(, $($args)*)? + ); }; } - - #[macro_export] - macro_rules! asm_sym { - ( $( $name:tt )* ) => ( $( $name )* ) - } } } diff --git a/crates/fiber/src/unix.rs b/crates/fiber/src/unix.rs index 6739aca66b..e9c4ce64f7 100644 --- a/crates/fiber/src/unix.rs +++ b/crates/fiber/src/unix.rs @@ -110,6 +110,8 @@ extern "C" { entry_arg0: *mut u8, ); fn wasmtime_fiber_switch(top_of_stack: *mut u8); + #[allow(dead_code)] // only used in inline assembly for some platforms + fn wasmtime_fiber_start(); } extern "C" fn fiber_start(arg0: *mut u8, top_of_stack: *mut u8) diff --git a/crates/fiber/src/unix/aarch64.rs b/crates/fiber/src/unix/aarch64.rs index 8a94283937..d77b1f2fbe 100644 --- a/crates/fiber/src/unix/aarch64.rs +++ b/crates/fiber/src/unix/aarch64.rs @@ -18,6 +18,7 @@ // `DW_CFA_AARCH64_negate_ra_state` DWARF operation (aliased with the // `.cfi_window_save` assembler directive) informs an unwinder about this +use super::wasmtime_fiber_start; use wasmtime_asm_macros::asm_func; cfg_if::cfg_if! { @@ -25,8 +26,8 @@ cfg_if::cfg_if! { macro_rules! paci1716 { () => ("pacib1716\n"); } macro_rules! pacisp { () => ("pacibsp\n"); } macro_rules! autisp { () => ("autibsp\n"); } - macro_rules! sym_adrp { ($s:tt) => (concat!("_", $s, "@PAGE")); } - macro_rules! sym_add { ($s:tt) => (concat!("_", $s, "@PAGEOFF")); } + macro_rules! sym_adrp { ($s:tt) => (concat!($s, "@PAGE")); } + macro_rules! sym_add { ($s:tt) => (concat!($s, "@PAGEOFF")); } } else { macro_rules! paci1716 { () => ("pacia1716\n"); } macro_rules! pacisp { () => ("paciasp\n"); } @@ -39,52 +40,54 @@ cfg_if::cfg_if! { // fn(top_of_stack(%x0): *mut u8) asm_func!( "wasmtime_fiber_switch", - " - .cfi_startproc - ", - pacisp!(), - " - .cfi_window_save - // Save all callee-saved registers on the stack since we're - // assuming they're clobbered as a result of the stack switch. - stp x29, x30, [sp, -16]! - stp x20, x19, [sp, -16]! - stp x22, x21, [sp, -16]! - stp x24, x23, [sp, -16]! - stp x26, x25, [sp, -16]! - stp x28, x27, [sp, -16]! - stp d9, d8, [sp, -16]! - stp d11, d10, [sp, -16]! - stp d13, d12, [sp, -16]! - stp d15, d14, [sp, -16]! + concat!( + " + .cfi_startproc + ", + pacisp!(), + " + .cfi_window_save + // Save all callee-saved registers on the stack since we're + // assuming they're clobbered as a result of the stack switch. + stp x29, x30, [sp, -16]! + stp x20, x19, [sp, -16]! + stp x22, x21, [sp, -16]! + stp x24, x23, [sp, -16]! + stp x26, x25, [sp, -16]! + stp x28, x27, [sp, -16]! + stp d9, d8, [sp, -16]! + stp d11, d10, [sp, -16]! + stp d13, d12, [sp, -16]! + stp d15, d14, [sp, -16]! - // Load our previously saved stack pointer to resume to, and save - // off our current stack pointer on where to come back to - // eventually. - ldr x8, [x0, -0x10] - mov x9, sp - str x9, [x0, -0x10] + // Load our previously saved stack pointer to resume to, and save + // off our current stack pointer on where to come back to + // eventually. + ldr x8, [x0, -0x10] + mov x9, sp + str x9, [x0, -0x10] - // Switch to the new stack and restore all our callee-saved - // registers after the switch and return to our new stack. - mov sp, x8 - ldp d15, d14, [sp], 16 - ldp d13, d12, [sp], 16 - ldp d11, d10, [sp], 16 - ldp d9, d8, [sp], 16 - ldp x28, x27, [sp], 16 - ldp x26, x25, [sp], 16 - ldp x24, x23, [sp], 16 - ldp x22, x21, [sp], 16 - ldp x20, x19, [sp], 16 - ldp x29, x30, [sp], 16 - ", - autisp!(), - " - .cfi_window_save - ret - .cfi_endproc - ", + // Switch to the new stack and restore all our callee-saved + // registers after the switch and return to our new stack. + mov sp, x8 + ldp d15, d14, [sp], 16 + ldp d13, d12, [sp], 16 + ldp d11, d10, [sp], 16 + ldp d9, d8, [sp], 16 + ldp x28, x27, [sp], 16 + ldp x26, x25, [sp], 16 + ldp x24, x23, [sp], 16 + ldp x22, x21, [sp], 16 + ldp x20, x19, [sp], 16 + ldp x29, x30, [sp], 16 + ", + autisp!(), + " + .cfi_window_save + ret + .cfi_endproc + ", + ), ); // fn( @@ -112,26 +115,29 @@ asm_func!( #[rustfmt::skip] asm_func!( "wasmtime_fiber_init", - " - .cfi_startproc - hint #34 // bti c - sub x16, x0, #16 - adrp x17, ", sym_adrp!("wasmtime_fiber_start"), " - add x17, x17, ", sym_add!("wasmtime_fiber_start"), " - ", - paci1716!(), - " - str x17, [x16, -0x8] // x17 => lr - str x0, [x16, -0x18] // x0 => x19 - stp x2, x1, [x0, -0x38] // x1 => x20, x2 => x21 + concat!( + " + .cfi_startproc + hint #34 // bti c + sub x16, x0, #16 + adrp x17, ", sym_adrp!("{fiber}"), " + add x17, x17, ", sym_add!("{fiber}"), " + ", + paci1716!(), + " + str x17, [x16, -0x8] // x17 => lr + str x0, [x16, -0x18] // x0 => x19 + stp x2, x1, [x0, -0x38] // x1 => x20, x2 => x21 - // `wasmtime_fiber_switch` has an 0xa0 byte stack, and we add 0x10 more for - // the original reserved 16 bytes. - add x8, x0, -0xb0 - str x8, [x0, -0x10] - ret - .cfi_endproc - ", + // `wasmtime_fiber_switch` has an 0xa0 byte stack, and we add 0x10 more for + // the original reserved 16 bytes. + add x8, x0, -0xb0 + str x8, [x0, -0x10] + ret + .cfi_endproc + ", + ), + fiber = sym wasmtime_fiber_start, ); // See the x86_64 file for more commentary on what these CFI directives are diff --git a/crates/fiber/src/unix/riscv64.rs b/crates/fiber/src/unix/riscv64.rs index 6c3c71714f..9c7b0cb01f 100644 --- a/crates/fiber/src/unix/riscv64.rs +++ b/crates/fiber/src/unix/riscv64.rs @@ -92,17 +92,18 @@ asm_func!( asm_func!( "wasmtime_fiber_init", " - lla t0,wasmtime_fiber_start + lla t0,{} sd t0,-0x18(a0) // ra,first should be wasmtime_fiber_start. sd a0,-0x20(a0) // fp pointer. - sd a1,-0x28(a0) // entry_point will load to s1. + sd a1,-0x28(a0) // entry_point will load to s1. sd a2,-0x30(a0) // entry_arg0 will load to s2. - // + // addi t0,a0,-0xe0 sd t0,-0x10(a0) ret ", + sym super::wasmtime_fiber_start, ); asm_func!( @@ -118,8 +119,8 @@ asm_func!( 0x06, /* DW_OP_deref */ \ 0x08, 0xd0 , /* DW_OP_const1u 0xc8 */ \ 0x22 /* DW_OP_plus */ - - + + .cfi_rel_offset ra,-0x8 .cfi_rel_offset fp,-0x10 .cfi_rel_offset s1,-0x18 diff --git a/crates/fiber/src/unix/x86_64.rs b/crates/fiber/src/unix/x86_64.rs index b7d73dc21e..420111c043 100644 --- a/crates/fiber/src/unix/x86_64.rs +++ b/crates/fiber/src/unix/x86_64.rs @@ -5,7 +5,7 @@ // all the other bits. Documentation tries to reference various bits here and // there but try to make sure to read over everything before tweaking things! -use wasmtime_asm_macros::{asm_func, asm_sym}; +use wasmtime_asm_macros::asm_func; // fn(top_of_stack(rdi): *mut u8) asm_func!( @@ -58,7 +58,7 @@ asm_func!( // // The first 16 bytes of stack are reserved for metadata, so we start // storing values beneath that. - lea rax, ", asm_sym!("wasmtime_fiber_start"), "[rip] + lea rax, {start}[rip] mov -0x18[rdi], rax mov -0x20[rdi], rdi // loaded into rbp during switch mov -0x28[rdi], rsi // loaded into rbx during switch @@ -73,6 +73,7 @@ asm_func!( mov -0x10[rdi], rax ret ", + start = sym super::wasmtime_fiber_start, ); // This is a pretty special function that has no real signature. Its use is to diff --git a/crates/runtime/src/libcalls.rs b/crates/runtime/src/libcalls.rs index e6bebc25df..5bed4d8ef6 100644 --- a/crates/runtime/src/libcalls.rs +++ b/crates/runtime/src/libcalls.rs @@ -104,7 +104,12 @@ pub mod trampolines { // This will delegate to the outer module to the actual // implementation and automatically perform `catch_unwind` along // with conversion of the return value in the face of traps. - #[no_mangle] + // + // Note that rust targets which support `global_asm!` can use + // the `sym` operator to get the symbol here, but other targets + // like s390x need to use outlined assembly files which requires + // `no_mangle`. + #[cfg_attr(target_arch = "s390x", no_mangle)] unsafe extern "C" fn []( vmctx : *mut VMContext, $( $pname : libcall!(@ty $param), )* diff --git a/crates/runtime/src/trampolines/aarch64.rs b/crates/runtime/src/trampolines/aarch64.rs index 7312bd827c..5716821a90 100644 --- a/crates/runtime/src/trampolines/aarch64.rs +++ b/crates/runtime/src/trampolines/aarch64.rs @@ -112,10 +112,11 @@ macro_rules! wasm_to_libcall_trampoline { stur lr, [x9, #32] // Tail call to the actual implementation of this libcall. - b ", wasmtime_asm_macros::asm_sym!(stringify!($libcall_impl)), " + b {} .cfi_endproc - " + ", + sym $libcall_impl ); }; } diff --git a/crates/runtime/src/trampolines/riscv64.rs b/crates/runtime/src/trampolines/riscv64.rs index 950d9b73c9..b2af6c5d3e 100644 --- a/crates/runtime/src/trampolines/riscv64.rs +++ b/crates/runtime/src/trampolines/riscv64.rs @@ -23,7 +23,7 @@ asm_func!( // Store the last Wasm SP into the `last_wasm_entry_sp` in the limits, if this // was core Wasm, otherwise store an invalid sentinal value. sd t1,40(t0) - + ld t0,16(a1) jr t0 @@ -95,23 +95,26 @@ macro_rules! wasm_to_libcall_trampoline { ($libcall:ident ; $libcall_impl:ident) => { wasmtime_asm_macros::asm_func!( stringify!($libcall), - " - .cfi_startproc + concat!( + " + .cfi_startproc - // Load the pointer to `VMRuntimeLimits` in `t0`. - ld t0, 8(a0) + // Load the pointer to `VMRuntimeLimits` in `t0`. + ld t0, 8(a0) - // Store the last Wasm FP into the `last_wasm_exit_fp` in the limits. - sd fp, 24(t0) + // Store the last Wasm FP into the `last_wasm_exit_fp` in the limits. + sd fp, 24(t0) - // Store the last Wasm PC into the `last_wasm_exit_pc` in the limits. - sd ra, 32(t0) + // Store the last Wasm PC into the `last_wasm_exit_pc` in the limits. + sd ra, 32(t0) - // Tail call to the actual implementation of this libcall. - j ", wasmtime_asm_macros::asm_sym!(stringify!($libcall_impl)), " + // Tail call to the actual implementation of this libcall. + j {} - .cfi_endproc - " + .cfi_endproc + ", + ), + sym $libcall_impl, ); }; } diff --git a/crates/runtime/src/trampolines/x86_64.rs b/crates/runtime/src/trampolines/x86_64.rs index 0eae6af46a..1f237c42fe 100644 --- a/crates/runtime/src/trampolines/x86_64.rs +++ b/crates/runtime/src/trampolines/x86_64.rs @@ -22,27 +22,29 @@ cfg_if::cfg_if! { #[rustfmt::skip] asm_func!( "host_to_wasm_trampoline", - " - .cfi_startproc simple - .cfi_def_cfa_offset 0 + concat!( + " + .cfi_startproc simple + .cfi_def_cfa_offset 0 - // Load the pointer to `VMRuntimeLimits` in `scratch0`. - mov ", scratch0!(), ", 8[", arg1!(), "] + // Load the pointer to `VMRuntimeLimits` in `scratch0`. + mov ", scratch0!(), ", 8[", arg1!(), "] - // Check to see if this is a core `VMContext` (MAGIC == 'core'). - cmp DWORD PTR [", arg0!(), "], 0x65726f63 + // Check to see if this is a core `VMContext` (MAGIC == 'core'). + cmp DWORD PTR [", arg0!(), "], 0x65726f63 - // Store the last Wasm SP into the `last_wasm_entry_sp` in the limits, if this - // was core Wasm, otherwise store an invalid sentinal value. - mov ", scratch1!(), ", -1 - cmove ", scratch1!(), ", rsp - mov 40[", scratch0!(), "], ", scratch1!(), " + // Store the last Wasm SP into the `last_wasm_entry_sp` in the limits, if this + // was core Wasm, otherwise store an invalid sentinal value. + mov ", scratch1!(), ", -1 + cmove ", scratch1!(), ", rsp + mov 40[", scratch0!(), "], ", scratch1!(), " - // Tail call to the callee function pointer in the vmctx. - jmp 16[", arg1!(), "] + // Tail call to the callee function pointer in the vmctx. + jmp 16[", arg1!(), "] - .cfi_endproc - ", + .cfi_endproc + ", + ), ); #[cfg(test)] @@ -64,28 +66,30 @@ mod host_to_wasm_trampoline_offsets_tests { #[rustfmt::skip] asm_func!( "wasm_to_host_trampoline", - " - .cfi_startproc simple - .cfi_def_cfa_offset 0 + concat!( + " + .cfi_startproc simple + .cfi_def_cfa_offset 0 - // Load the pointer to `VMRuntimeLimits` in `scratch0`. - mov ", scratch0!(), ", 8[", arg1!(), "] + // Load the pointer to `VMRuntimeLimits` in `scratch0`. + mov ", scratch0!(), ", 8[", arg1!(), "] - // Store the last Wasm FP into the `last_wasm_exit_fp` in the limits. - mov 24[", scratch0!(), "], rbp + // Store the last Wasm FP into the `last_wasm_exit_fp` in the limits. + mov 24[", scratch0!(), "], rbp - // Store the last Wasm PC into the `last_wasm_exit_pc` in the limits. - mov ", scratch1!(), ", [rsp] - mov 32[", scratch0!(), "], ", scratch1!(), " + // Store the last Wasm PC into the `last_wasm_exit_pc` in the limits. + mov ", scratch1!(), ", [rsp] + mov 32[", scratch0!(), "], ", scratch1!(), " - // Tail call to the actual host function. - // - // This *must* be a tail call so that we do not push to the stack and mess - // up the offsets of stack arguments (if any). - jmp 8[", arg0!(), "] + // Tail call to the actual host function. + // + // This *must* be a tail call so that we do not push to the stack and mess + // up the offsets of stack arguments (if any). + jmp 8[", arg0!(), "] - .cfi_endproc - ", + .cfi_endproc + ", + ), ); #[cfg(test)] @@ -111,25 +115,28 @@ macro_rules! wasm_to_libcall_trampoline { ($libcall:ident ; $libcall_impl:ident) => { wasmtime_asm_macros::asm_func!( stringify!($libcall), - " - .cfi_startproc simple - .cfi_def_cfa_offset 0 + concat!( + " + .cfi_startproc simple + .cfi_def_cfa_offset 0 - // Load the pointer to `VMRuntimeLimits` in `", scratch0!(), "`. - mov ", scratch0!(), ", 8[", arg0!(), "] + // Load the pointer to `VMRuntimeLimits` in `", scratch0!(), "`. + mov ", scratch0!(), ", 8[", arg0!(), "] - // Store the last Wasm FP into the `last_wasm_exit_fp` in the limits. - mov 24[", scratch0!(), "], rbp + // Store the last Wasm FP into the `last_wasm_exit_fp` in the limits. + mov 24[", scratch0!(), "], rbp - // Store the last Wasm PC into the `last_wasm_exit_pc` in the limits. - mov ", scratch1!(), ", [rsp] - mov 32[", scratch0!(), "], ", scratch1!(), " + // Store the last Wasm PC into the `last_wasm_exit_pc` in the limits. + mov ", scratch1!(), ", [rsp] + mov 32[", scratch0!(), "], ", scratch1!(), " - // Tail call to the actual implementation of this libcall. - jmp ", wasmtime_asm_macros::asm_sym!(stringify!($libcall_impl)), " + // Tail call to the actual implementation of this libcall. + jmp {} - .cfi_endproc - ", + .cfi_endproc + ", + ), + sym $libcall_impl ); }; } diff --git a/crates/wasmtime/Cargo.toml b/crates/wasmtime/Cargo.toml index 2372b51e5c..20fc5a79da 100644 --- a/crates/wasmtime/Cargo.toml +++ b/crates/wasmtime/Cargo.toml @@ -8,6 +8,7 @@ license = "Apache-2.0 WITH LLVM-exception" repository = "https://github.com/bytecodealliance/wasmtime" readme = "README.md" edition.workspace = true +rust-version.workspace = true [package.metadata.docs.rs] rustdoc-args = ["--cfg", "nightlydoc"]