-
Notifications
You must be signed in to change notification settings - Fork 503
Warn when target is wasm32-not-wasi
#715
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
It's not like nothing works, right? If you know how to play your cards, you can have Rust's wasm32-unknown interoperate with clang. So the question is really about identifying the incompatibilities and the assertion is that the toolchain will let you through without so much as a warning. Well, it doesn't seem to hold upon inspection. I've tried to trigger the problem that would be a result of the said incompatibility and have got a very informative error message from rust-lld which in fact illuminated the incompatibility. Just in case for reference. Here is the example. On the C side:
On the Rust side (which is the right way to go about on all platforms but wasm32-unknown):
The error message from rust-lld:
|
BTW
It's actually "[all] but wasm32-unknown-unknown." I mean among the three Rust wasm targets, wasm32-unknown-emscripten, wasm32-unknown-unknown and wasm32-wasi, only one [in the middle] appears to be problematic. [As opposed to the originally suggested "all are problematic but wasm32-wasi".] |
Right, I believe some crates have thought about this and do theoretically support it, so you're right it shouldn't be a hard-error, or at least should have an override.
I don't think that was quite my assertion, but a few notes: |
Ah, right, it's a bit more subtle, I believe, in that 'em scripted and wasi have different ABIs, but both are compatible with their respective C compilers. |
This is not something that cc-rs would be able to pull off. It would be the job for the Rust compiler, one that passes structures by value.
It wasn't a warning, but a hard failure. As for parameter mismatches. Concern essentially is that it won't catch the cases when the size of the structure argument is not larger than 32 bits, right? Well, this actually seems to work out. As it turns out, if the structure is not larger than 32 bits, then C expects it to be passed by value, and Rust does exactly that. In other words the linker should arguably catch all the mismatches...
As already mentioned, it was a hard failure, so there was no obfuscation on cargo part or ambiguity. |
Oh! That's the source of a lot of confusion here, I think. What version of wasm-ld are you using? Locally that's a warning, not a failure.
Ah, I had understood that the clang wasm ABI did not have that behavior. If that's true then indeed as long as wasm-ld hard-fails then it seems like there should be no issue. |
As mentioned, it was rust-lld that failed on me. The one that is part of the stock Rust 1.6x(*) installation. For example mine is called (*) I'm writing 1.6x, because I'm relatively sure that it's not something that was introduced in the most recent 1.63. But I don't really know how far back does it go. |
I've tried to configure wasm-ld as linker through .cargo/config.toml and the compilation fails with "error: unknown argument: --rsp-quoting=posix" [from wasm-ld]. So wasm-ld does not appear to be a viable option, at least not for 1.63. |
Ah, I missed that, thanks for calling it out. IIUC rust-lld is the same as system-lld, but built from the same LLVM version as rust, rather than whatever system LLVM version is built into system lld. I could be wrong here, though.
lld is a thing wrapper around relevant ld's, and calls out to wasm-ld if the target is wasm, or at least that's what it does for my system lld. In any case, given the latest rust-lld hard-errors on these issues, and we believe its not possible to have the two ABIs generate the same function signature in an incompatible way, I think we can close this. It'd be nice to dig into it more, but it sounds like maybe newer LLVM simply changed the behavior and now errors. |
Hmm... I can't confirm this. If I |
Its possible rust-lld is actually completely different, then, or its just |
It can't be just "or wasm-ld", because as far as I understand it's used for all bare-metal/no-std platforms. And if I run |
There might be an explanation for why our experiences appear to differ. I'm experimenting directly with |
I was actually using I agree if wasm-ld can 100% detect this issue the correct path is to have it fail, not to have cc try to work around it. Because it sounds like it can, and it sounds like at least in default configurations things will already fail, I agree this issus is likely not necessary. It'd be nice to test wasm-pack to double-check (since that was my original concern), but if it fails, we can probably close and move on. |
An additional bit of information. wasm32-unknown-emscripten does call wasm-ld, and it still treats mismatching signatures as a warning, not an error. But it's not a problem in the context of this query. Because there is no ABI mismatch in emscripten target. So that if wasm-ld issues the warning, then it's for an unrelated reason. One can make a case for having cc-rs always pass |
I think a warning would be appropriate. There are a couple cases where this is fine ("I don't plan on calling it from Rust", "I've manually ensured the ABI issues are avoided", ...), but that's fine for warnings. |
To summarize. This is about matching ABIs on the Rust and clang sides, and the only problematic target is wasm32-unknown-unknown. And for this target Rust invokes rust-lld which refuses to link problematic code with an informative message. With this in mind it's argued that a general vague warning is not actually necessary. |
Ah, right, thanks. That's not really enough in all cases, as the linker does not see everything -- for example, there still would be issues in the case of C APIs which take/return function pointers (possibly indirectly e.g. via a vtable or something). I don't see how the linker could detect this, but maybe there's some way. Thinking more though, I guess libraries with APIs that use function pointers with problematic signatures are fairly likely to have the same patterns occur in their public APIs too, so it might be very rare. That is, the question isn't "how many C APIs have function pointers that would hit this ABI issue", it's "how many C APIs have function poijnters that would hit this ABI issue, and don't also have functions that would". I tend to think a warning couldn't hurt, to help ensure people doing this are at least aware of this issue. |
No, linker won't detect this. However! The [said] signature mismatches would be caught at run time. How informative the message is naturally depends on the vm, but at least
If cc-rs maintainers choose this path, I'd advocate |
Because of the ABI incompatibility between Rust's
wasm32-unknown
target and upstream LLVM/clang'swasm32
target, linking Rust and C code (on Rust targets other thanwasm32-wasi
) may be unsafe (see rustwasm/team#291 for more details). However, in many cases there are no warnings at all and undefined behavior may instead simply be invoked. It is likely prudent for cc-rs to generate such a warning, given its in the best position to "see" the issue, simply printing something tostderr
if the target iswasm32
and notwasi
.The text was updated successfully, but these errors were encountered: