Author: Joel Dice
Date: 2023-06-26T10:31:40-07:00
New Revision: 55e199a2c9f4b218499733d60129deffa0a025fe

URL: 
https://github.com/llvm/llvm-project/commit/55e199a2c9f4b218499733d60129deffa0a025fe
DIFF: 
https://github.com/llvm/llvm-project/commit/55e199a2c9f4b218499733d60129deffa0a025fe.diff

LOG: [clang][WebAssembly] Support wasm32-wasi shared libraries

This adds support for Emscripten-style shared libraries [1] to
non-emscripten targets, such as `wasm32-wasi`.  Previously, only static
linking was supported, and the `-shared` and `-fPIC` flags were simply
ignored.  Now both flags are honored.

Since WASI runtimes do not necessarily include JavaScript support, we
cannot rely on the JS-based Emscripten linker to link shared libraries.
Instead, we link them using the Component Model proposal [2].

We have prototyped shared library support in `wasi-sdk` [3] and put
together a demo [4] which uses a patched version of `wit-component` [5]
to link libraries using the Component Model.  We plan to submit the
required changes upstream to the respective repositories in the next
week or two.

[1] https://github.com/WebAssembly/tool-conventions/blob/main/DynamicLinking.md
[2] 
https://github.com/WebAssembly/component-model/blob/main/design/mvp/examples/SharedEverythingDynamicLinking.md
[3] https://github.com/dicej/wasi-sdk/tree/dynamic-linking
[4] https://github.com/dicej/component-linking-demo
[5] 
https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wit-component

Signed-off-by: Joel Dice <joel.d...@fermyon.com>

Reviewed By: sbc100

Differential Revision: https://reviews.llvm.org/D153293

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Driver/ToolChains/WebAssembly.cpp
    clang/test/Driver/wasm-toolchain.c
    llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 055aa9008b03b..c022e9ffb6604 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -727,6 +727,12 @@ AIX Support
 
 WebAssembly Support
 ^^^^^^^^^^^^^^^^^^^
+- Shared library support (and PIC code generation) for WebAssembly is no longer
+  limited to the Emscripten target OS and now works with other targets such as
+  wasm32-wasi.  Note that the `format
+  
<https://github.com/WebAssembly/tool-conventions/blob/main/DynamicLinking.md>`_
+  is not yet stable and may change between LLVM versions.  Also, WASI does not
+  yet have facilities to load dynamic libraries.
 
 AVR Support
 ^^^^^^^^^^^

diff  --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp 
b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 016b70b1c2ede..fb9c8e4910e8b 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -101,13 +101,16 @@ void wasm::Linker::ConstructJob(Compilation &C, const 
JobAction &JA,
           << CM << A->getOption().getName();
     }
   }
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles))
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles, 
options::OPT_shared))
     CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(Crt1)));
   if (Entry) {
     CmdArgs.push_back(Args.MakeArgString("--entry"));
     CmdArgs.push_back(Args.MakeArgString(Entry));
   }
 
+  if (Args.hasArg(options::OPT_shared))
+    CmdArgs.push_back(Args.MakeArgString("-shared"));
+
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {

diff  --git a/clang/test/Driver/wasm-toolchain.c 
b/clang/test/Driver/wasm-toolchain.c
index bfe696d7846e7..909d27f0f2d9c 100644
--- a/clang/test/Driver/wasm-toolchain.c
+++ b/clang/test/Driver/wasm-toolchain.c
@@ -33,6 +33,20 @@
 // LINK_KNOWN: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
 // LINK_KNOWN: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi" "crt1.o" "[[temp]]" 
"-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
 
+// -shared should be passed through to `wasm-ld` and not include crt1.o with a 
known OS.
+
+// RUN: %clang -### -shared --target=wasm32-wasi --sysroot=/foo %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=LINK_KNOWN_SHARED %s
+// LINK_KNOWN_SHARED: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
+// LINK_KNOWN_SHARED: wasm-ld{{.*}}" "-L/foo/lib/wasm32-wasi" "-shared" 
"[[temp]]" "-lc" "{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
+
+// -shared should be passed through to `wasm-ld` and not include crt1.o with 
an unknown OS.
+
+// RUN: %clang -### -shared --target=wasm32-unknown-unknown --sysroot=/foo %s 
2>&1 \
+// RUN:   | FileCheck -check-prefix=LINK_UNKNOWN_SHARED %s
+// LINK_UNKNOWN_SHARED: "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
+// LINK_UNKNOWN_SHARED: wasm-ld{{.*}}" "-shared" "[[temp]]" "-lc" 
"{{.*[/\\]}}libclang_rt.builtins-wasm32.a" "-o" "a.out"
+
 // A basic C link command-line with optimization with known OS.
 
 // RUN: %clang -### -O2 --target=wasm32-wasi --sysroot=/foo %s 2>&1 \
@@ -46,6 +60,18 @@
 // RUN:   | FileCheck -check-prefix=COMPILE %s
 // COMPILE: "-cc1" {{.*}} "-internal-isystem" "/foo/include/wasm32-wasi" 
"-internal-isystem" "/foo/include"
 
+// -fPIC should work on a known OS
+
+// RUN: %clang -### -fPIC --target=wasm32-wasi --sysroot=/foo %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=COMPILE_KNOWN_PIC %s
+// COMPILE_KNOWN_PIC: "-cc1" {{.*}} "-mrelocation-model" "pic" "-pic-level" 
"2" {{.*}} "-internal-isystem" "/foo/include/wasm32-wasi" "-internal-isystem" 
"/foo/include"
+
+// -fPIC should work on an unknown OS
+
+// RUN: %clang -### -fPIC --target=wasm32-unknown-unknown --sysroot=/foo %s 
2>&1 \
+// RUN:   | FileCheck -check-prefix=COMPILE_UNKNOWN_PIC %s
+// COMPILE_UNKNOWN_PIC: "-cc1" {{.*}} "-mrelocation-model" "pic" "-pic-level" 
"2"
+
 // Thread-related command line tests.
 
 // '-pthread' sets +atomics, +bulk-memory, +mutable-globals, +sign-ext, and 
--shared-memory

diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp 
b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
index c10f07018878b..6ef219f216a3b 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp
@@ -99,13 +99,6 @@ static Reloc::Model 
getEffectiveRelocModel(std::optional<Reloc::Model> RM,
     return Reloc::Static;
   }
 
-  if (!TT.isOSEmscripten()) {
-    // Relocation modes other than static are currently implemented in a way
-    // that only works for Emscripten, so disable them if we aren't targeting
-    // Emscripten.
-    return Reloc::Static;
-  }
-
   return *RM;
 }
 


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to