forked from OSchip/llvm-project
[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 llvm-svn: 322408
This commit is contained in:
parent
6371180cd4
commit
2a06afae16
|
@ -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
|
|
@ -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())
|
||||
|
|
|
@ -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">;
|
||||
|
||||
|
|
|
@ -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()))
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue