llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.69k stars 11.87k forks source link

wasm-ld: support -shared flag #63207

Open anuraaga opened 1 year ago

anuraaga commented 1 year ago

This is a strawman's proposal, it's not obvious whether these two flags are equivalent, but I think in all the usages I've seen wasm-ld ignores the -shared flag and complains about not finding main until adding the exec-model. Would this translation make sense? It would make building existing projects for wasi simpler (similar intent as #62931)

llvmbot commented 1 year ago

@llvm/issue-subscribers-lld-wasm

sbc100 commented 1 year ago

IIUC -shared is a fairly different to -mexec-model=reactor. I think we should reserved -shared for more traditional "shared everything" linking, whereas -mexec-model=reactor implies self-contained wasm module that happens to have multiple entry points.

-shared is currently usable but you also need to pass --experimental-pic .. if you pass -shared to wasm-ld today you should see wasm-ld: warning: creating shared libraries, with -shared, is not yet stable, but its just a warning.

Also, all the inputs to wasm-ld must be compiled with -fPIC if you want to link with -shared.. just like on a native platforms, but PIC code generatation is only currently available with the wasm32-unknown-emscripten target. There are plans to extent this to wasm32-wasi too: https://hackmd.io/IlY4lICRRNy9wQbNLdb2Wg

anuraaga commented 1 year ago

Thanks for the extra context @sbc100 - IIUC, it's true that the reactor model may be needed for -shared to avoid the requirement on main, but there are other aspects to -shared than just that. Indeed, now that I think about it, exports seem to currently need to be manually defined with wasm-ld invocation and should presumably be controlled by source for the -shared flag.

I went ahead and changed the issue title to be more generic, if it seems infeasible no worries closing it

sbc100 commented 1 year ago

If you build with -fPIC and -fvisibility=default you should see all your symbols being exporting when building a -shared object. You can also mark individual symbols with default visibility in the source code instead of passing -fvisibility=default.

The point of --experimental-pic is that let folks know that current model for shared everything linking is still a being worked on. See https://github.com/WebAssembly/tool-conventions/blob/main/DynamicLinking.md.

sbc100 commented 1 year ago

-mexec-model=reactor is something you pass when linking an executable, not something you would use when building a shared library.

anuraaga commented 1 year ago

Ah ok - I think I have a mental model of reactor being similar to shared libraries because when loading into a wasm runtime, it is invoking individual functions in a way that feels like invoking into a shared DLL, but I suspect the actual machinery must be quite different compared to normal shared libraries, thanks for clarfiying that.

sbc100 commented 1 year ago

Yes shared librarys and reactors both export multiple symbols. But I don't think we should think of them as the same just for that reason. Shared libraries use shared everything linkage whereas reactors are self contained module that happen to export more than one entry point.

Note that a reactor could be composed on multple shared libraries (e.g. IIUC, in the component module reactors would be component and shared libraries would live within a component).