[lld] r322408 - [WebAssembly] Add --export flag to force a symbol to be exported

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 12 14:10:35 PST 2018


Author: sbc
Date: Fri Jan 12 14:10:35 2018
New Revision: 322408

URL: http://llvm.org/viewvc/llvm-project?rev=322408&view=rev
Log:
[WebAssembly] Add --export flag to force a symbol to be exported

This is useful for emscripten or other tools that want to
selectively exports symbols without necessarily changing the
source code.

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

Added:
    lld/trunk/test/wasm/export.ll
Modified:
    lld/trunk/wasm/Driver.cpp
    lld/trunk/wasm/Options.td
    lld/trunk/wasm/Symbols.cpp
    lld/trunk/wasm/Symbols.h

Added: lld/trunk/test/wasm/export.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/export.ll?rev=322408&view=auto
==============================================================================
--- lld/trunk/test/wasm/export.ll (added)
+++ lld/trunk/test/wasm/export.ll Fri Jan 12 14:10:35 2018
@@ -0,0 +1,29 @@
+; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o
+; RUN: not lld -flavor wasm --export=missing -o %t.wasm %t.o 2>&1 | FileCheck -check-prefix=CHECK-ERROR %s
+; RUN: lld -flavor wasm --export=hidden_function -o %t.wasm %t.o
+; RUN: obj2yaml %t.wasm | FileCheck %s
+
+define hidden i32 @hidden_function() local_unnamed_addr {
+entry:
+  ret i32 0
+}
+
+define i32 @_start() local_unnamed_addr {
+entry:
+  ret i32 0
+}
+
+; CHECK-ERROR: error: symbol exported via --export not found: missing
+
+; CHECK:        - Type:            EXPORT
+; CHECK-NEXT:     Exports:         
+; CHECK-NEXT:       - Name:            memory
+; CHECK-NEXT:         Kind:            MEMORY
+; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:       - Name:            _start
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Index:           1
+; CHECK-NEXT:       - Name:            hidden_function
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:   - Type:            CODE

Modified: lld/trunk/wasm/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Driver.cpp?rev=322408&r1=322407&r2=322408&view=diff
==============================================================================
--- lld/trunk/wasm/Driver.cpp (original)
+++ lld/trunk/wasm/Driver.cpp Fri Jan 12 14:10:35 2018
@@ -296,8 +296,8 @@ void LinkerDriver::link(ArrayRef<const c
       addSyntheticUndefinedFunction(Config->Entry, &Signature);
 
     // Handle the `--undefined <sym>` options.
-    for (StringRef S : args::getStrings(Args, OPT_undefined))
-      addSyntheticUndefinedFunction(S, nullptr);
+    for (auto* Arg : Args.filtered(OPT_undefined))
+      addSyntheticUndefinedFunction(Arg->getValue(), nullptr);
 
     Config->CtorSymbol = Symtab->addDefinedFunction(
         "__wasm_call_ctors", &Signature, WASM_SYMBOL_VISIBILITY_HIDDEN);
@@ -321,8 +321,8 @@ void LinkerDriver::link(ArrayRef<const c
     // -u/--undefined since these undefined symbols have only names and no
     // function signature, which means they cannot be written to the final
     // output.
-    for (StringRef S : args::getStrings(Args, OPT_undefined)) {
-      Symbol *Sym = Symtab->find(S);
+    for (auto* Arg : Args.filtered(OPT_undefined)) {
+      Symbol *Sym = Symtab->find(Arg->getValue());
       if (!Sym->isDefined())
         error("function forced with --undefined not found: " + Sym->getName());
     }
@@ -330,6 +330,15 @@ void LinkerDriver::link(ArrayRef<const c
   if (errorCount())
     return;
 
+  for (auto *Arg : Args.filtered(OPT_export)) {
+    Symbol *Sym = Symtab->find(Arg->getValue());
+    if (!Sym || !Sym->isDefined())
+      error("symbol exported via --export not found: " +
+            Twine(Arg->getValue()));
+    else
+      Sym->setHidden(false);
+  }
+
   if (!Config->Entry.empty() && !Symtab->find(Config->Entry)->isDefined())
     error("entry point not found: " + Config->Entry);
   if (errorCount())

Modified: lld/trunk/wasm/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Options.td?rev=322408&r1=322407&r2=322408&view=diff
==============================================================================
--- lld/trunk/wasm/Options.td (original)
+++ lld/trunk/wasm/Options.td Fri Jan 12 14:10:35 2018
@@ -74,6 +74,9 @@ def error_limit: J<"error-limit=">,
 
 // The follow flags are unique to wasm
 
+defm export: Eq<"export">,
+  HelpText<"Force a symbol to be exported">;
+
 def global_base: J<"global-base=">,
   HelpText<"Where to start to place global data">;
 

Modified: lld/trunk/wasm/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Symbols.cpp?rev=322408&r1=322407&r2=322408&view=diff
==============================================================================
--- lld/trunk/wasm/Symbols.cpp (original)
+++ lld/trunk/wasm/Symbols.cpp Fri Jan 12 14:10:35 2018
@@ -97,6 +97,14 @@ bool Symbol::isHidden() const {
   return (Flags & WASM_SYMBOL_VISIBILITY_MASK) == WASM_SYMBOL_VISIBILITY_HIDDEN;
 }
 
+void Symbol::setHidden(bool IsHidden) {
+  Flags &= ~WASM_SYMBOL_VISIBILITY_MASK;
+  if (IsHidden)
+    Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN;
+  else
+    Flags |= WASM_SYMBOL_VISIBILITY_DEFAULT;
+}
+
 std::string lld::toString(const wasm::Symbol &Sym) {
   if (Config->Demangle)
     if (Optional<std::string> S = demangleItanium(Sym.getName()))

Modified: lld/trunk/wasm/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Symbols.h?rev=322408&r1=322407&r2=322408&view=diff
==============================================================================
--- lld/trunk/wasm/Symbols.h (original)
+++ lld/trunk/wasm/Symbols.h Fri Jan 12 14:10:35 2018
@@ -67,6 +67,7 @@ public:
   bool hasFunctionType() const { return FunctionType != nullptr; }
   const WasmSignature &getFunctionType() const;
   void setFunctionType(const WasmSignature *Type);
+  void setHidden(bool IsHidden);
 
   uint32_t getOutputIndex() const;
 




More information about the llvm-commits mailing list