Skip to content

Commit

Permalink
Support multiple versions of wasmtime in the same crate (#6673)
Browse files Browse the repository at this point in the history
* Attempt versioned exports to facilitate having multiple versions in the same crate

* Modify approach to use `export_name` and `link_name`

* Only apply version to names in assembly and foreign item fns

* Attempt to handle the s390x case

* Fix alignment of backslashes in assembly file

* Pretend I understand the preprocessor

* Version symbols in `crates/runtime/src/helpers.c`

* Stop versioning `__jit_debug_register_code` because gdb relies on it and it is uses `weak` linkage

* Version symbol in `crates/fiber/src/windows.c`

* Consolidate `LitStr` creation in macro

* Add new crate to publish script and supply-chain config

* Fix order in supply chain config

* Set `audit-as-crates-io` to false

* Missing `versioned_link` for Windows

* Version strings used in debug

* Formatting

* Get rid of `versioned_str` and bring back `versioned_suffix`

---------

Co-authored-by: Alex Crichton <alex@alexcrichton.com>
  • Loading branch information
adampetro and alexcrichton authored Jul 7, 2023
1 parent 3efd728 commit ca90650
Show file tree
Hide file tree
Showing 31 changed files with 181 additions and 46 deletions.
13 changes: 13 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ wasmtime-wasi-threads = { path = "crates/wasi-threads", version = "12.0.0" }
wasmtime-component-util = { path = "crates/component-util", version = "=12.0.0" }
wasmtime-component-macro = { path = "crates/component-macro", version = "=12.0.0" }
wasmtime-asm-macros = { path = "crates/asm-macros", version = "=12.0.0" }
wasmtime-versioned-export-macros = { path = "crates/versioned-export-macros", version = "=12.0.0" }
component-test-util = { path = "crates/misc/component-test-util" }
component-fuzz-util = { path = "crates/misc/component-fuzz-util" }
wiggle = { path = "crates/wiggle", version = "=12.0.0", default-features = false }
Expand Down
1 change: 1 addition & 0 deletions crates/cranelift/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ target-lexicon = { workspace = true }
gimli = { workspace = true }
object = { workspace = true, features = ['write'] }
thiserror = { workspace = true }
wasmtime-versioned-export-macros = { workspace = true }

[features]
all-arch = ["cranelift-codegen/all-arch"]
Expand Down
7 changes: 4 additions & 3 deletions crates/cranelift/src/debug/transform/unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use gimli::write;
use gimli::{AttributeValue, DebuggingInformationEntry, Unit};
use std::collections::HashSet;
use wasmtime_environ::DefinedFuncIndex;
use wasmtime_versioned_export_macros::versioned_stringify_ident;

struct InheritedAttr<T> {
stack: Vec<(usize, T)>,
Expand Down Expand Up @@ -198,7 +199,7 @@ where
// .. .. DW_AT_type = <wrapper_ptr_type>
// .. .. DW_AT_artificial = 1
add_tag!(wrapper_die_id, gimli::DW_TAG_subprogram => deref_op_die as deref_op_die_id {
gimli::DW_AT_linkage_name = write::AttributeValue::StringRef(out_strings.add("resolve_vmctx_memory_ptr")),
gimli::DW_AT_linkage_name = write::AttributeValue::StringRef(out_strings.add(versioned_stringify_ident!(resolve_vmctx_memory_ptr))),
gimli::DW_AT_name = write::AttributeValue::StringRef(out_strings.add("ptr")),
gimli::DW_AT_type = write::AttributeValue::UnitRef(ptr_type_id)
});
Expand All @@ -215,7 +216,7 @@ where
// .. .. DW_AT_type = <wrapper_ptr_type>
// .. .. DW_AT_artificial = 1
add_tag!(wrapper_die_id, gimli::DW_TAG_subprogram => deref_op_die as deref_op_die_id {
gimli::DW_AT_linkage_name = write::AttributeValue::StringRef(out_strings.add("resolve_vmctx_memory_ptr")),
gimli::DW_AT_linkage_name = write::AttributeValue::StringRef(out_strings.add(versioned_stringify_ident!(resolve_vmctx_memory_ptr))),
gimli::DW_AT_name = write::AttributeValue::StringRef(out_strings.add("operator*")),
gimli::DW_AT_type = write::AttributeValue::UnitRef(ref_type_id)
});
Expand All @@ -232,7 +233,7 @@ where
// .. .. DW_AT_type = <wrapper_ptr_type>
// .. .. DW_AT_artificial = 1
add_tag!(wrapper_die_id, gimli::DW_TAG_subprogram => deref_op_die as deref_op_die_id {
gimli::DW_AT_linkage_name = write::AttributeValue::StringRef(out_strings.add("resolve_vmctx_memory_ptr")),
gimli::DW_AT_linkage_name = write::AttributeValue::StringRef(out_strings.add(versioned_stringify_ident!(resolve_vmctx_memory_ptr))),
gimli::DW_AT_name = write::AttributeValue::StringRef(out_strings.add("operator->")),
gimli::DW_AT_type = write::AttributeValue::UnitRef(ptr_type_id)
});
Expand Down
6 changes: 3 additions & 3 deletions crates/cranelift/src/debug/transform/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use anyhow::Error;
use cranelift_codegen::isa::TargetIsa;
use gimli::write;
use wasmtime_environ::DefinedFuncIndex;

/// Adds internal Wasm utility types DIEs such as WebAssemblyPtr and
use wasmtime_versioned_export_macros::versioned_stringify_ident;
///Adds internal Wasm utility types DIEs such as WebAssemblyPtr and
/// WasmtimeVMContext.
///
/// For unwrapping Wasm pointer, the WasmtimeVMContext has the `set()` method
Expand Down Expand Up @@ -113,7 +113,7 @@ pub(crate) fn add_internal_types(
// .. .. DW_AT_type = <vmctx_ptr_die>
// .. .. DW_AT_artificial = 1
add_tag!(vmctx_die_id, gimli::DW_TAG_subprogram => vmctx_set as vmctx_set_id {
gimli::DW_AT_linkage_name = write::AttributeValue::StringRef(out_strings.add("set_vmctx_memory")),
gimli::DW_AT_linkage_name = write::AttributeValue::StringRef(out_strings.add(versioned_stringify_ident!(set_vmctx_memory))),
gimli::DW_AT_name = write::AttributeValue::StringRef(out_strings.add("set"))
});
add_tag!(vmctx_set_id, gimli::DW_TAG_formal_parameter => vmctx_set_this_param as vmctx_set_this_param_id {
Expand Down
8 changes: 2 additions & 6 deletions crates/fiber/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,9 @@ license = "Apache-2.0 WITH LLVM-exception"
repository = "https://github.com/bytecodealliance/wasmtime"
edition.workspace = true

# We link to some native code with symbols that don't change often, so let Cargo
# know that we can't show up multiple times in a crate graph. If this is an
# issue in the future we should tweak the build script to set `#define`
# directives or similar to embed a version number of this crate in symbols.
links = "wasmtime-fiber-shims"

[dependencies]
cfg-if = { workspace = true }
wasmtime-versioned-export-macros = { workspace = true }

[target.'cfg(unix)'.dependencies]
rustix = { workspace = true, features = ["mm", "param"] }
Expand All @@ -29,6 +24,7 @@ features = [

[build-dependencies]
cc = "1.0"
wasmtime-versioned-export-macros = { workspace = true }

[dev-dependencies]
backtrace = "0.3.61"
3 changes: 3 additions & 0 deletions crates/fiber/build.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::env;
use wasmtime_versioned_export_macros::versioned_suffix;

fn main() {
let mut build = cc::Build::new();
Expand All @@ -7,9 +8,11 @@ fn main() {
if os == "windows" {
println!("cargo:rerun-if-changed=src/windows.c");
build.file("src/windows.c");
build.define("VERSIONED_SUFFIX", Some(versioned_suffix!()));
} else if arch == "s390x" {
println!("cargo:rerun-if-changed=src/unix/s390x.S");
build.file("src/unix/s390x.S");
build.define("VERSIONED_SUFFIX", Some(versioned_suffix!()));
} else {
// assume that this is included via inline assembly in the crate itself,
// and the crate will otherwise have a `compile_error!` for unsupported
Expand Down
3 changes: 3 additions & 0 deletions crates/fiber/src/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,16 @@ pub struct Fiber;
pub struct Suspend(*mut u8);

extern "C" {
#[wasmtime_versioned_export_macros::versioned_link]
fn wasmtime_fiber_init(
top_of_stack: *mut u8,
entry: extern "C" fn(*mut u8, *mut u8),
entry_arg0: *mut u8,
);
#[wasmtime_versioned_export_macros::versioned_link]
fn wasmtime_fiber_switch(top_of_stack: *mut u8);
#[allow(dead_code)] // only used in inline assembly for some platforms
#[wasmtime_versioned_export_macros::versioned_link]
fn wasmtime_fiber_start();
}

Expand Down
6 changes: 3 additions & 3 deletions crates/fiber/src/unix/aarch64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ cfg_if::cfg_if! {

// fn(top_of_stack(%x0): *mut u8)
asm_func!(
"wasmtime_fiber_switch",
wasmtime_versioned_export_macros::versioned_stringify_ident!(wasmtime_fiber_switch),
concat!(
"
.cfi_startproc
Expand Down Expand Up @@ -114,7 +114,7 @@ asm_func!(
// wasmtime_fiber_start(), and provides wider coverage.
#[rustfmt::skip]
asm_func!(
"wasmtime_fiber_init",
wasmtime_versioned_export_macros::versioned_stringify_ident!(wasmtime_fiber_init),
concat!(
"
.cfi_startproc
Expand Down Expand Up @@ -144,7 +144,7 @@ asm_func!(
// doing. Like over there note that the relative offsets to registers here
// match the frame layout in `wasmtime_fiber_switch`.
asm_func!(
"wasmtime_fiber_start",
wasmtime_versioned_export_macros::versioned_stringify_ident!(wasmtime_fiber_start),
"
.cfi_startproc simple
.cfi_def_cfa_offset 0
Expand Down
6 changes: 3 additions & 3 deletions crates/fiber/src/unix/arm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use wasmtime_asm_macros::{asm_func, asm_sym};

// fn(top_of_stack(%r0): *mut u8)
asm_func!(
"wasmtime_fiber_switch",
wasmtime_versioned_export_macros::versioned_stringify_ident!(wasmtime_fiber_switch),
"
// Save callee-saved registers
push {{r4-r11,lr}}
Expand All @@ -34,7 +34,7 @@ asm_func!(
// entry_arg0(%r2): *mut u8,
// )
asm_func!(
"wasmtime_fiber_init",
wasmtime_versioned_export_macros::versioned_stringify_ident!(wasmtime_fiber_init),
"
adr r3, wasmtime_fiber_start
str r3, [r0, #-0x0c] // => lr
Expand All @@ -49,7 +49,7 @@ asm_func!(
);

asm_func!(
"wasmtime_fiber_start",
wasmtime_versioned_export_macros::versioned_stringify_ident!(wasmtime_fiber_start),
"
.cfi_startproc simple
.cfi_def_cfa_offset 0
Expand Down
6 changes: 3 additions & 3 deletions crates/fiber/src/unix/riscv64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use wasmtime_asm_macros::asm_func;

// fn(top_of_stack(rdi): *mut u8)
asm_func!(
"wasmtime_fiber_switch",
wasmtime_versioned_export_macros::versioned_stringify_ident!(wasmtime_fiber_switch),
"
// See https://github.com/rust-lang/rust/issues/80608.
.attribute arch, \"rv64gc\"
Expand Down Expand Up @@ -90,7 +90,7 @@ asm_func!(
// )
#[rustfmt::skip]
asm_func!(
"wasmtime_fiber_init",
wasmtime_versioned_export_macros::versioned_stringify_ident!(wasmtime_fiber_init),
"
lla t0,{}
sd t0,-0x18(a0) // ra,first should be wasmtime_fiber_start.
Expand All @@ -107,7 +107,7 @@ asm_func!(
);

asm_func!(
"wasmtime_fiber_start",
wasmtime_versioned_export_macros::versioned_stringify_ident!(wasmtime_fiber_start),
"
.cfi_startproc simple
.cfi_def_cfa_offset 0
Expand Down
13 changes: 8 additions & 5 deletions crates/fiber/src/unix/s390x.S
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@

.text

#define GLOBL(fnname) .globl fnname
#define HIDDEN(fnname) .hidden fnname
#define TYPE(fnname) .type fnname,@function
#define FUNCTION(fnname) fnname
#define SIZE(fnname) .size fnname,.-fnname
#define CONCAT2(a, b) a ## b
#define CONCAT(a, b) CONCAT2(a , b)
#define VERSIONED_SYMBOL(a) CONCAT(a, VERSIONED_SUFFIX)
#define GLOBL(fnname) .globl VERSIONED_SYMBOL(fnname)
#define HIDDEN(fnname) .hidden VERSIONED_SYMBOL(fnname)
#define TYPE(fnname) .type VERSIONED_SYMBOL(fnname),@function
#define FUNCTION(fnname) VERSIONED_SYMBOL(fnname)
#define SIZE(fnname) .size VERSIONED_SYMBOL(fnname),.-VERSIONED_SYMBOL(fnname)

// fn(top_of_stack(%x0): *mut u8)
HIDDEN(wasmtime_fiber_switch)
Expand Down
6 changes: 3 additions & 3 deletions crates/fiber/src/unix/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use wasmtime_asm_macros::asm_func;

// fn(top_of_stack(rdi): *mut u8)
asm_func!(
"wasmtime_fiber_switch",
wasmtime_versioned_export_macros::versioned_stringify_ident!(wasmtime_fiber_switch),
"
// We're switching to arbitrary code somewhere else, so pessimistically
// assume that all callee-save register are clobbered. This means we need
Expand Down Expand Up @@ -49,7 +49,7 @@ asm_func!(
// )
#[rustfmt::skip]
asm_func!(
"wasmtime_fiber_init",
wasmtime_versioned_export_macros::versioned_stringify_ident!(wasmtime_fiber_init),
"
// Here we're going to set up a stack frame as expected by
// `wasmtime_fiber_switch`. The values we store here will get restored into
Expand Down Expand Up @@ -89,7 +89,7 @@ asm_func!(
// If you're curious a decent introduction to CFI things and unwinding is at
// https://www.imperialviolet.org/2017/01/18/cfi.html
asm_func!(
"wasmtime_fiber_start",
wasmtime_versioned_export_macros::versioned_stringify_ident!(wasmtime_fiber_start),
"
// Use the `simple` directive on the startproc here which indicates that
// some default settings for the platform are omitted, since this
Expand Down
6 changes: 5 additions & 1 deletion crates/fiber/src/windows.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#include <windows.h>

LPVOID wasmtime_fiber_get_current() {
#define CONCAT2(a, b) a ## b
#define CONCAT(a, b) CONCAT2(a , b)
#define VERSIONED_SYMBOL(a) CONCAT(a, VERSIONED_SUFFIX)

LPVOID VERSIONED_SYMBOL(wasmtime_fiber_get_current)() {
return GetCurrentFiber();
}
1 change: 1 addition & 0 deletions crates/fiber/src/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ struct StartState {
const FIBER_FLAG_FLOAT_SWITCH: u32 = 1;

extern "C" {
#[wasmtime_versioned_export_macros::versioned_link]
fn wasmtime_fiber_get_current() -> *mut c_void;
}

Expand Down
1 change: 1 addition & 0 deletions crates/jit-debug/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ edition.workspace = true
[dependencies]
once_cell = { workspace = true, optional = true }
object = { workspace = true, optional = true }
wasmtime-versioned-export-macros = { workspace = true }

[target.'cfg(target_os = "linux")'.dependencies]
rustix = { workspace = true, features = ["mm", "param", "time"], optional = true }
Expand Down
2 changes: 2 additions & 0 deletions crates/jit-debug/src/gdb_jit_int.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use once_cell::sync::Lazy;
use std::pin::Pin;
use std::ptr;
use std::sync::Mutex;
use wasmtime_versioned_export_macros::versioned_link;

#[repr(C)]
struct JITCodeEntry {
Expand All @@ -28,6 +29,7 @@ struct JITDescriptor {
}

extern "C" {
#[versioned_link]
fn wasmtime_jit_debug_descriptor() -> *mut JITDescriptor;
fn __jit_debug_register_code();
}
Expand Down
2 changes: 2 additions & 0 deletions crates/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ wasmtime-asm-macros = { workspace = true }
wasmtime-environ = { workspace = true }
wasmtime-fiber = { workspace = true, optional = true }
wasmtime-jit-debug = { workspace = true, features = ["gdb_jit_int"] }
wasmtime-versioned-export-macros = { workspace = true }
libc = { version = "0.2.112", default-features = false }
log = { workspace = true }
memoffset = "0.8.0"
Expand Down Expand Up @@ -50,6 +51,7 @@ once_cell = { workspace = true }

[build-dependencies]
cc = "1.0"
wasmtime-versioned-export-macros = { workspace = true }

[features]
async = ["wasmtime-fiber"]
Expand Down
2 changes: 2 additions & 0 deletions crates/runtime/build.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::env;
use wasmtime_versioned_export_macros::versioned_suffix;

fn main() {
let mut build = cc::Build::new();
Expand All @@ -7,6 +8,7 @@ fn main() {
let os = env::var("CARGO_CFG_TARGET_OS").unwrap();
build.define(&format!("CFG_TARGET_OS_{}", os), None);
build.define(&format!("CFG_TARGET_ARCH_{}", arch), None);
build.define("VERSIONED_SUFFIX", Some(versioned_suffix!()));
if arch == "s390x" {
println!("cargo:rerun-if-changed=src/trampolines/s390x.S");
build.file("src/trampolines/s390x.S");
Expand Down
Loading

0 comments on commit ca90650

Please sign in to comment.