linkme icon indicating copy to clipboard operation
linkme copied to clipboard

What will it take to get WebAssembly support working?

Open dfoxfranke opened this issue 10 months ago • 3 comments

Getting linkme working under wasm32-unknown-unknown is currently a high priority for me. On a skim of the wasm-ld sources, it looks like the necessary linker support is at least supposed to exist and follow the same conventions as Linux: https://github.com/llvm/llvm-project/blob/d00f65c6acd9f0e1ddae83391f55eb9d232d2f9e/lld/wasm/Writer.cpp#L519-L533. However, I tried modifying linkme simply by adding target_arch = "wasm32" to all the conditionals that currently include target_os = "linux", and this didn't work: my program compiles and links, but then panics at runtime when I try to access the slice because section_start winds up being a null pointer. I currently have no further insight on why this happens. I'm hoping @dtolnay can shed some light on this after having just gotten inventory working on WASM a couple weeks ago.

dfoxfranke avatar Jan 06 '25 17:01 dfoxfranke

IMO this should be handled in a cross-platform way by the compiler, not by wasm-ld. If you are motivated to work on this, here is an outline: https://internals.rust-lang.org/t/from-life-before-main-to-common-life-in-main/16006/25?u=dtolnay

dtolnay avatar Jan 06 '25 17:01 dtolnay

I agree with your position that #[distributed_slice] should be a language built-in, but given the current lack of consensus around that, getting it included, let alone stabilized, in rustc is not going to be compatible with my timeline. For the meantime I just need some working hack that gives the functionality of either linkme or inventory (linkme is more elegant, but I can work with either model) on wasm32-unknown-unknown.

My use case is unusual in that I'm not targeting a web embedding: I'm postprocessing the WebAssembly module through Wasm2Glulx (which I maintain). Since .init_array is already working on WASI and emscripten, I can almost certainly get it working in Wasm2Glulx too if I just have Wasm2Glulx generate some startup code that invokes __wasm_call_ctors at an appropriate point. But I could never ask you to upstream that into inventory because it wouldn't be applicable to anyone's use case but mine. OTOH if I can get linkme working with WebAssembly then I'd expect to work for everyone across all drivers (WASI, emscripten, or unknown), and be suitable for upstreaming. But right now I don't have it working and I don't have enough understanding of wasm-ld internals to track down the problem.

dfoxfranke avatar Jan 06 '25 18:01 dfoxfranke

Well I'll be damned... I just got inventory working on wasm32-unknown-unknown and it required even less effort than I expected. All I did was add the target to the existing conditional compilations for wasi/emscripten, and then it immediately worked. This was very surprising to me because I thought I was also going to have add an explicit call to __wasm_call_ctors at the top of my program's (nonstandard) entrypoint. But it turns out the linker already does this automagically! Before I submit a PR to inventory I'm going to have to dig a little more to understand how this is possible. Since, like I said, my entrypoint is nonstandard, the linker can't possibly know it's the entrypoint, so it must be putting this call at the top of every function that the module exports. But that means it has to be ensuring idempotence somehow, and how it's doing that is not instantly clear to me.

dfoxfranke avatar Jan 06 '25 20:01 dfoxfranke

This is closed as completed, but both the latest release and master branch still don't seem to support wasm.

error: distributed_slice is not implemented for this platform

tqwewe avatar Nov 06 '25 07:11 tqwewe