forked from bytecodealliance/wit-bindgen
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
rust: Define
cabi_realloc
as a weak symbol (bytecodealliance#851)
* rust: Define `cabi_realloc` as a weak symbol This commit updates the `wit-bindgen` Rust crate to define the `cabi_realloc` symbol as a weak symbol. This is not easy because Rust does not offer a stable means by which to do this. Despite this through a combination of shell scripts and CI it should be possible to get this all working together by using C to define a weak symbol calling a known Rust symbol. Closes bytecodealliance#849 * Fix typo in yml * More yml changes * Regenerate cabi_realloc files * Strip custom sections * Install wasm-tools on CI as well * Pin to slightly older wasm-tools * Fix native tests * Subvert rate limiting
- Loading branch information
1 parent
c7f4fe7
commit b98e460
Showing
11 changed files
with
224 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
name: 'Install the wasi-sdk' | ||
description: 'Install the wasi-sdk toolchain' | ||
|
||
runs: | ||
using: composite | ||
steps: | ||
- run: | | ||
curl https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-linux.tar.gz -L | tar xzvf - | ||
echo "WASI_SDK_PATH=`pwd`/wasi-sdk-20.0" >> $GITHUB_ENV | ||
if: runner.os == 'Linux' | ||
shell: bash | ||
- run: | | ||
curl https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-macos.tar.gz -L | tar xzvf - | ||
echo "WASI_SDK_PATH=`pwd`/wasi-sdk-20.0" >> $GITHUB_ENV | ||
if: runner.os == 'macOS' | ||
shell: bash | ||
- run: | | ||
curl https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0.m-mingw.tar.gz -L | tar xzvf - | ||
echo "WASI_SDK_PATH=`pwd`/wasi-sdk-20.0+m" >> $GITHUB_ENV | ||
if: runner.os == 'Windows' | ||
shell: bash | ||
- name: Setup `wasm-tools` | ||
uses: bytecodealliance/actions/wasm-tools/setup@v1 | ||
with: | ||
version: "1.0.60" | ||
github_token: ${{ github.token }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,3 +7,4 @@ ace | |
*.wasm | ||
!wasi_snapshot_preview1.reactor.wasm | ||
__pycache__ | ||
crates/guest-rust/src/cabi_realloc.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
#!/bin/sh | ||
|
||
# This script, and various infrastructure, is a hack to work around the lack of | ||
# stable support in Rust to generate a weak symbol. | ||
# | ||
# The basic problem here is that the Rust `wit-bindgen` crate wants to export | ||
# the `cabi_realloc` symbol from the final binary. This library, however, | ||
# is not stable which means that we're publishing new versions of `wit-bindgen` | ||
# over its development. This means that if `wit-bindgen`-the-crate were to | ||
# export a `#[no_mangle]` symbol of `cabi_realloc` then it wouldn't work to | ||
# have two versions of `wit-bindgen` in the same project. This can arise | ||
# relatively quickly, however, so this is something we want to solve. | ||
# | ||
# The general idea of the solution here is to ensure that the `cabi_realloc` | ||
# symbol itself is declared as a weak symbol. A weakly-defined symbol means | ||
# that if the linker sees multiple copies it can discard all but one. This is | ||
# the semantics we want where some `wit-bindgen` needs to define `cabi_realloc` | ||
# but it doesn't matter much which one. | ||
# | ||
# Stable Rust can't define weak symbols as of the time of this writing. C, | ||
# however, can. Unfortunately users of this crate do not always have a C | ||
# compiler on-hand for wasm, nor do we want to require one. That's where all | ||
# these hacks come into play. With that intro, the purpose of this script is to: | ||
# | ||
# * Generate a `cabi_realloc.rs` file with a "mangled" Rust symbol that's | ||
# unique per-major-version of the crate. | ||
# * Generate a `cabi_realloc.c` file that defines a weak `cabi_realloc` symbol | ||
# that calls the above Rust symbol | ||
# * Compile `cabi_realloc.c` into an object and place it into an archive and | ||
# check that archive into this repo. | ||
# | ||
# This all leads up to the point where we're distributing binary artifacts with | ||
# this crate. These artifacts are verified in CI to ensure what this script | ||
# generates. | ||
# | ||
# Overall this is intended to provide `cabi_realloc` as a weak symbol, | ||
# everything works on stable Rust, and users don't need a C compiler when they | ||
# use this crate. | ||
|
||
set -ex | ||
|
||
version=$(grep '^version =' ./Cargo.toml | sed 's/.*"\(.*\)"/\1/' | sed 's/\./_/g') | ||
|
||
sym=cabi_realloc_wit_bindgen_$version | ||
|
||
cat >./crates/guest-rust/src/cabi_realloc.rs <<-EOF | ||
// This file is generated by $0 | ||
#[no_mangle] | ||
pub unsafe extern "C" fn $sym( | ||
old_ptr: *mut u8, | ||
old_len: usize, | ||
align: usize, | ||
new_len: usize, | ||
) -> *mut u8 { | ||
crate::rt::cabi_realloc(old_ptr, old_len, align, new_len) | ||
} | ||
EOF | ||
|
||
cat >./crates/guest-rust/src/cabi_realloc.c <<-EOF | ||
// This file is generated by $0 | ||
#include <stdint.h> | ||
extern void *$sym(void *ptr, size_t old_size, size_t align, size_t new_size); | ||
__attribute__((__weak__, __export_name__("cabi_realloc"))) | ||
void *cabi_realloc(void *ptr, size_t old_size, size_t align, size_t new_size) { | ||
return $sym(ptr, old_size, align, new_size); | ||
} | ||
EOF | ||
|
||
rm -f crates/guest-rust/src/cabi_realloc.o | ||
$WASI_SDK_PATH/bin/clang crates/guest-rust/src/cabi_realloc.c \ | ||
-O -c -o crates/guest-rust/src/cabi_realloc.o | ||
|
||
# Remove the `producers` section. This appears to differ whether the host for | ||
# clang is either macOS or Linux. Not needed here anyway, so discard it to help | ||
# either host produce the same object. | ||
wasm-tools strip -d producers ./crates/guest-rust/src/cabi_realloc.o \ | ||
-o ./crates/guest-rust/src/cabi_realloc.o | ||
|
||
rm -f crates/guest-rust/src/libwit_bindgen_cabi_realloc.a | ||
$WASI_SDK_PATH/bin/llvm-ar crus crates/guest-rust/src/libwit_bindgen_cabi_realloc.a \ | ||
crates/guest-rust/src/cabi_realloc.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
fn main() { | ||
if !cfg!(feature = "realloc") { | ||
return; | ||
} | ||
|
||
let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap_or(String::new()); | ||
let target_family = std::env::var("CARGO_CFG_TARGET_FAMILY").unwrap_or(String::new()); | ||
|
||
if target_family != "wasm" { | ||
return; | ||
} | ||
|
||
if target_arch != "wasm32" { | ||
panic!("only wasm32 supports cabi-realloc right now"); | ||
} | ||
|
||
println!("cargo:rustc-link-lib=wit_bindgen_cabi_realloc"); | ||
let cwd = std::env::current_dir().unwrap(); | ||
let cwd = cwd.display(); | ||
println!("cargo:rustc-link-search=native={cwd}/src"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
// This file is generated by ./ci/rebuild-libcabi-realloc.sh | ||
|
||
#include <stdint.h> | ||
|
||
extern void *cabi_realloc_wit_bindgen_0_18_0(void *ptr, size_t old_size, size_t align, size_t new_size); | ||
|
||
__attribute__((__weak__, __export_name__("cabi_realloc"))) | ||
void *cabi_realloc(void *ptr, size_t old_size, size_t align, size_t new_size) { | ||
return cabi_realloc_wit_bindgen_0_18_0(ptr, old_size, align, new_size); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// This file is generated by ./ci/rebuild-libcabi-realloc.sh | ||
|
||
#[no_mangle] | ||
pub unsafe extern "C" fn cabi_realloc_wit_bindgen_0_18_0( | ||
old_ptr: *mut u8, | ||
old_len: usize, | ||
align: usize, | ||
new_len: usize, | ||
) -> *mut u8 { | ||
crate::rt::cabi_realloc(old_ptr, old_len, align, new_len) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters