Skip to content

Linker error with wasmtime 38 on ARM64 macOS when using ThinLTO #11957

@mkaput

Description

@mkaput

Wasmtime 38.0.3 produces a linker error on ARM64 macOS when building with ThinLTO enabled. The error indicates that wasmtime_fiber_switch symbol is undefined during linking.

error: linking with `cc` failed: exit status: 1
  |
  = note:  "cc" "<426 object files omitted>" "/var/folders/8c/r_zrp9mj12xd414t08zrks940000gn/T/rustc2wYYXA/{libwasmtime-e843f7bbc21927d3,libzstd_sys-7eabaf414ee67d02,libwasmtime_internal_jit_debug-9043bb9a4e496da8}.rlib" "<sysroot>/lib/rustlib/aarch64-apple-darwin/lib/libcompiler_builtins-*.rlib" "-liconv" "-lSystem" "-lc" "-lm" "-arch" "arm64" "-mmacosx-version-min=11.0.0" "-L" "/Users/mk/Developer/software-mansion/scarb/linker-repro/wasmtime-only-test/target/release/build/wasmtime-15671f59b24bbe0f/out" "-L" "/Users/mk/Developer/software-mansion/scarb/linker-repro/wasmtime-only-test/target/release/build/zstd-sys-1ea01473940232bc/out" "-L" "/Users/mk/Developer/software-mansion/scarb/linker-repro/wasmtime-only-test/target/release/build/wasmtime-internal-jit-debug-2aaf81cce8508d62/out" "-o" "/Users/mk/Developer/software-mansion/scarb/linker-repro/wasmtime-only-test/target/release/deps/wasmtime_only_test-69cba5150eff8962" "-Wl,-dead_strip" "-nodefaultlibs"
  = note: some arguments are omitted. use `--verbose` to show all linker arguments
  = note: ld: warning: object file (/private/var/folders/8c/r_zrp9mj12xd414t08zrks940000gn/T/rustc2wYYXA/libwasmtime-e843f7bbc21927d3.rlib[2](242b1992def1ef0b-helpers.o)) was built for newer 'macOS' version (26.0) than being linked (11.0)
          ld: warning: object file (/private/var/folders/8c/r_zrp9mj12xd414t08zrks940000gn/T/rustc2wYYXA/libwasmtime_internal_jit_debug-9043bb9a4e496da8.rlib[2](db3b6bfb95261072-gdbjit.o)) was built for newer 'macOS' version (26.0) than being linked (11.0)
          Undefined symbols for architecture arm64:
            "wasmtime_internal_fiber::stackswitch::aarch64::wasmtime_fiber_switch::h0b241ee887e10750", referenced from:
                wasmtime_internal_fiber::unix::Suspend::switch::hfd4514b4efef3e13 in wasmtime_only_test-69cba5150eff8962.wasmtime-e843f7bbc21927d3.wasmtime.7e3b8021754df0c4-cgu.05.rcgu.o.rcgu.o
          ld: symbol(s) not found for architecture arm64
          clang: error: linker command failed with exit code 1 (use -v to see invocation)
          

This breaks our releases, as seen here: https://github.com/software-mansion/scarb/actions/runs/18924473454/job/54028423511.

Reverting to Wasmtime 37 workarounds this issue. The same happens when we disable LTO or use Fat LTO. This only happens with ThinLTO which is the only thing we can accept in our project due to other reasons.

Steps to Reproduce

  • Architecture: ARM64 (Apple Silicon)
  • OS: macOS 26.0
  • Rust: 1.90.0
  • Wasmtime: 38.0.3
  • Build Profile: release with lto = "thin"

Cargo.toml:

[package]
name = "linker-repro"
version = "0.1.0"
edition = "2021"

[dependencies]
wasmtime = "38"

[profile.release]
lto = "thin"

src/main.rs:

fn main() {
    let engine = wasmtime::Engine::default();
    println!("Engine created: {:?}", engine);
}

Build command:

cargo build --release

This will fail with the linker error shown above.

Thoughts

  • I think this regressed in 3e9eca8.
  • I'm not well versed in these low-level naked functions-LLVM interactions, but prompting llms guided me that there are some issues when you try to combine naked fns with LTO.
  • Getting into guessing mode: could it be that ThinLTO is attempting to inline wasmtime_fiber_switch in some places, but forgets in others?
    • Is it reasonable to attach #[inline(never)] to wasmtime_fiber_switch?

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIncorrect behavior in the current implementation that needs fixing

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions