-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
[wasm] WebAssembly CodeGen disables PIC #7796
Comments
...I don't remember :-) Try changing it and see what breaks? |
Okay, will do ... lemme see if things go boom. |
Just enabling the flag doesn't seem to be enough to enable relocation ... the LLVM module gets created with the correct halide_use_pic flag, and PIC level flags, but I still get errors emitted from wasm-ld:
There may be some other LLVM feature flags that may need to get set to make this work. I'll keep investigating. |
This seems relevant: Which would imply that the triple flag needs to have the |
I believe that bug was fixed in https://reviews.llvm.org/D153293. I just closes the corresponding github issue: llvm/llvm-project#42059 |
Note that if you want you could unconditionally enable PIC code generation. It does at a little bloat to the object files, due to the extra indirection, but when linked into a static binary 100% of this can be removed by |
That sounds like the simplest option, TBH -- is there a reason this isn't done in general? (Is (Thanks for commenting, BTW, didn't realize you were watching these issues/PRs :-) |
I was pointed here by an emscripten who uses halide |
Maybe you can just remove the |
Here's an idea: could we just always set PIC everywhere, and then have a Halide target flag (e.g., |
It not quite that simple, alas, since Halide codegen isn't always (or even usually) directly invoked from the command line, but rather, indirectly from build rules.
That would probably be a much more tractable approach. It looks like we (currently) default to using PIC for all LLVM-based backends, with no way to override them; WebAssembly is the only backend that changes this (to false, also with no way to override it.) So, strawman:
|
Thanks very much for the reply! It appears just setting use_pic() isn’t enough … we still get linking errors when trying to use the static libraries or object files create by Halide in a shared object created by emcc. In the link you provided it appears that the target triple includes wasm32-wasi … is wasi required for dynamic linking? |
OK, we should clearly hold off until we know the entire scope of the issue. What are the linking errors? |
A bit of a threadjack here, but: it's been a minute since I've done more than minor fixes to our wasm backend... which was written when WASI was still mostly just a proposal. Looking at the link, it seems likely that upgrading our codegen to be WASI-compliant (if needed) would be highly desirable (to allow for easier use in a runtime env that doesn't include JS support)... and I don't know anything at all about the Component Model proposal. Unfortunately, our team is fairly understaffed right now, and there's ~no way that I'm likely to get any bandwidth to look into this anytime soon (unless my manager(s) make it a priority for me), but the Halide team would absolutely welcome any community contribution that could be made here. |
wasm-ld: error: relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol.Lstr; recompile with -fPIC |
@steven-johnson. Note that both wasi and the component model as still very early in the standard process. Its likely worth supporting the different target triples but I think that is all you would need to do. I would imagine you could even target |
I attempted to override the llvm::triple inside of LLVM_Runtime_Linker.cpp: Halide/src/LLVM_Runtime_Linker.cpp Line 492 in acc9413
I tried |
FWIW, I just stumbled upon this (from 2019): |
Not a different format, no. But the relocation types used are different. In PIC code generatation you should shouldn't get any |
Okay, good to know. It looks like the generated object files can be inspected with wabt. From the HelloWasm app:
|
As @sbc100 indicated, the above object file contains R_WASM_MEMORY_ADDR_SLEB entries which shouldn't exist if PIC was enabled. I've scrutinized the WebAssembly clang driver and noticed that "mutable-globals" appear to be required for the linker: So I added this to Halide's CodeGen_WebAssembly::mattrs() so that emits "+mutable-globals" and verified this shows up in the generated object files:
But the linker still complains and we still have R_WASM_MEMORY_ADDR_SLEB symbols being generated. I'll keep digging .... |
I haven't found anything concrete ... my guess is we may be missing one or more LLVM passes that may transform the module into a PIC compatible layout for wasm and/or are missing attributes on global values or functions (ie We don't use the standard llvm Anyone have any other ideas? @steven-johnson @abadams @sbc100 |
The relevant code is in https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp. You can see that |
@derek-gerstmann, also are you using llvm tip-of-tree? Because llvm/llvm-project#42059 only recently landed. |
Ah, thanks! So far I've been testing with LLVM releases 15-17. I'll pull llvm from main and rebuild. |
Okay, fix confirmed. Testing against LLVM main (18.x), with the following changes to Halide enabled me to produce wasm object files that could be relocated with emcc:
Optional, but likely needed (based on comments from LLVM devs):
Symbols in the wasm object files now appear as I'll open a PR, and we can iron out the details of the proposed strawman. Thanks everyone! @slomp @sbc100 @steven-johnson |
It appears that the WebAssembly CodeGen explicitly disables PIC, which means that objects and modules being generated for wasm cannot be linked into a shared object and dynamically loaded (eg
emcc -s SIDE_MODULE=2
).Is this necessary?
The text was updated successfully, but these errors were encountered: