diff options
-rw-r--r-- | lld/test/wasm/export.ll | 29 | ||||
-rw-r--r-- | lld/wasm/Driver.cpp | 17 | ||||
-rw-r--r-- | lld/wasm/Options.td | 3 | ||||
-rw-r--r-- | lld/wasm/Symbols.cpp | 8 | ||||
-rw-r--r-- | lld/wasm/Symbols.h | 1 |
5 files changed, 54 insertions, 4 deletions
diff --git a/lld/test/wasm/export.ll b/lld/test/wasm/export.ll new file mode 100644 index 00000000000..f5cc42c332c --- /dev/null +++ b/lld/test/wasm/export.ll @@ -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 diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp index 0173cdc09e5..75c3cb56aa5 100644 --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -296,8 +296,8 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { 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 char *> ArgsArr) { // -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 char *> ArgsArr) { 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()) diff --git a/lld/wasm/Options.td b/lld/wasm/Options.td index df0c6d70807..345417d94ae 100644 --- a/lld/wasm/Options.td +++ b/lld/wasm/Options.td @@ -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">; diff --git a/lld/wasm/Symbols.cpp b/lld/wasm/Symbols.cpp index 8376d220293..3dc88a851b3 100644 --- a/lld/wasm/Symbols.cpp +++ b/lld/wasm/Symbols.cpp @@ -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())) diff --git a/lld/wasm/Symbols.h b/lld/wasm/Symbols.h index af06d9a5c7e..c0e71754438 100644 --- a/lld/wasm/Symbols.h +++ b/lld/wasm/Symbols.h @@ -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; |