Use the sym operator for inline assembly (#5459)
* Use the `sym` operator for inline assembly Avoids extra `#[no_mangle]` functions and undue symbols being exposed from Wasmtime. This is a newly stabilized feature in Rust 1.66.0. I've also added a `rust-version` entry to the `wasmtime` crate to try to head off possible reports in the future about odd error messages or usage of unstable features if the rustc version is too old. * Fix a s390x warning * Add `rust-version` annotation to Wasmtime crate As the other main entrypoint for embedders.
This commit is contained in:
4
.github/workflows/main.yml
vendored
4
.github/workflows/main.yml
vendored
@@ -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`.
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -5,35 +5,30 @@
|
||||
//! 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!(
|
||||
($name:expr, $body:expr $(, $($args:tt)*)?) => {
|
||||
std::arch::global_asm!(
|
||||
concat!(
|
||||
".p2align 4\n",
|
||||
".private_extern _", $name, "\n",
|
||||
".global _", $name, "\n",
|
||||
"_", $name, ":\n",
|
||||
$($body)*
|
||||
));
|
||||
$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!(
|
||||
($name:expr, $body:expr $(, $($args:tt)*)?) => {
|
||||
std::arch::global_asm!(
|
||||
concat!(
|
||||
".def ", $name, "\n",
|
||||
".scl 2\n",
|
||||
".type 32\n",
|
||||
@@ -41,15 +36,12 @@ cfg_if::cfg_if! {
|
||||
".global ", $name, "\n",
|
||||
".p2align 4\n",
|
||||
$name, ":\n",
|
||||
$($body)*
|
||||
));
|
||||
$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!(
|
||||
($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",
|
||||
concat!($($body)*),
|
||||
$body,
|
||||
".size ", $name, ",.-", $name,
|
||||
));
|
||||
)
|
||||
$(, $($args)*)?
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! asm_sym {
|
||||
( $( $name:tt )* ) => ( $( $name )* )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<F, A, B, C>(arg0: *mut u8, top_of_stack: *mut u8)
|
||||
|
||||
@@ -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,6 +40,7 @@ cfg_if::cfg_if! {
|
||||
// fn(top_of_stack(%x0): *mut u8)
|
||||
asm_func!(
|
||||
"wasmtime_fiber_switch",
|
||||
concat!(
|
||||
"
|
||||
.cfi_startproc
|
||||
",
|
||||
@@ -85,6 +87,7 @@ asm_func!(
|
||||
ret
|
||||
.cfi_endproc
|
||||
",
|
||||
),
|
||||
);
|
||||
|
||||
// fn(
|
||||
@@ -112,12 +115,13 @@ asm_func!(
|
||||
#[rustfmt::skip]
|
||||
asm_func!(
|
||||
"wasmtime_fiber_init",
|
||||
concat!(
|
||||
"
|
||||
.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"), "
|
||||
adrp x17, ", sym_adrp!("{fiber}"), "
|
||||
add x17, x17, ", sym_add!("{fiber}"), "
|
||||
",
|
||||
paci1716!(),
|
||||
"
|
||||
@@ -132,6 +136,8 @@ asm_func!(
|
||||
ret
|
||||
.cfi_endproc
|
||||
",
|
||||
),
|
||||
fiber = sym wasmtime_fiber_start,
|
||||
);
|
||||
|
||||
// See the x86_64 file for more commentary on what these CFI directives are
|
||||
|
||||
@@ -92,7 +92,7 @@ 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.
|
||||
@@ -103,6 +103,7 @@ asm_func!(
|
||||
sd t0,-0x10(a0)
|
||||
ret
|
||||
",
|
||||
sym super::wasmtime_fiber_start,
|
||||
);
|
||||
|
||||
asm_func!(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 [<impl_ $name>](
|
||||
vmctx : *mut VMContext,
|
||||
$( $pname : libcall!(@ty $param), )*
|
||||
|
||||
@@ -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
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -95,6 +95,7 @@ macro_rules! wasm_to_libcall_trampoline {
|
||||
($libcall:ident ; $libcall_impl:ident) => {
|
||||
wasmtime_asm_macros::asm_func!(
|
||||
stringify!($libcall),
|
||||
concat!(
|
||||
"
|
||||
.cfi_startproc
|
||||
|
||||
@@ -108,10 +109,12 @@ macro_rules! wasm_to_libcall_trampoline {
|
||||
sd ra, 32(t0)
|
||||
|
||||
// Tail call to the actual implementation of this libcall.
|
||||
j ", wasmtime_asm_macros::asm_sym!(stringify!($libcall_impl)), "
|
||||
j {}
|
||||
|
||||
.cfi_endproc
|
||||
"
|
||||
",
|
||||
),
|
||||
sym $libcall_impl,
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ cfg_if::cfg_if! {
|
||||
#[rustfmt::skip]
|
||||
asm_func!(
|
||||
"host_to_wasm_trampoline",
|
||||
concat!(
|
||||
"
|
||||
.cfi_startproc simple
|
||||
.cfi_def_cfa_offset 0
|
||||
@@ -43,6 +44,7 @@ asm_func!(
|
||||
|
||||
.cfi_endproc
|
||||
",
|
||||
),
|
||||
);
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -64,6 +66,7 @@ mod host_to_wasm_trampoline_offsets_tests {
|
||||
#[rustfmt::skip]
|
||||
asm_func!(
|
||||
"wasm_to_host_trampoline",
|
||||
concat!(
|
||||
"
|
||||
.cfi_startproc simple
|
||||
.cfi_def_cfa_offset 0
|
||||
@@ -86,6 +89,7 @@ asm_func!(
|
||||
|
||||
.cfi_endproc
|
||||
",
|
||||
),
|
||||
);
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -111,6 +115,7 @@ macro_rules! wasm_to_libcall_trampoline {
|
||||
($libcall:ident ; $libcall_impl:ident) => {
|
||||
wasmtime_asm_macros::asm_func!(
|
||||
stringify!($libcall),
|
||||
concat!(
|
||||
"
|
||||
.cfi_startproc simple
|
||||
.cfi_def_cfa_offset 0
|
||||
@@ -126,10 +131,12 @@ macro_rules! wasm_to_libcall_trampoline {
|
||||
mov 32[", scratch0!(), "], ", scratch1!(), "
|
||||
|
||||
// Tail call to the actual implementation of this libcall.
|
||||
jmp ", wasmtime_asm_macros::asm_sym!(stringify!($libcall_impl)), "
|
||||
jmp {}
|
||||
|
||||
.cfi_endproc
|
||||
",
|
||||
),
|
||||
sym $libcall_impl
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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"]
|
||||
|
||||
Reference in New Issue
Block a user