Index: test/wasm/alias.ll =================================================================== --- test/wasm/alias.ll +++ test/wasm/alias.ll @@ -53,10 +53,10 @@ ; CHECK-NEXT: - Name: memory ; CHECK-NEXT: Kind: MEMORY ; CHECK-NEXT: Index: 0 -; CHECK-NEXT: - Name: _start +; CHECK-NEXT: - Name: start_alias ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 0 -; CHECK-NEXT: - Name: start_alias +; CHECK-NEXT: - Name: _start ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 0 ; CHECK-NEXT: - Name: __heap_base Index: test/wasm/call-indirect.ll =================================================================== --- test/wasm/call-indirect.ll +++ test/wasm/call-indirect.ll @@ -82,9 +82,6 @@ ; CHECK-NEXT: - Name: memory ; CHECK-NEXT: Kind: MEMORY ; CHECK-NEXT: Index: 0 -; CHECK-NEXT: - Name: _start -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 3 ; CHECK-NEXT: - Name: bar ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 0 @@ -94,6 +91,9 @@ ; CHECK-NEXT: - Name: foo ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 2 +; CHECK-NEXT: - Name: _start +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 3 ; CHECK-NEXT: - Name: call_ptr ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 4 Index: test/wasm/entry.ll =================================================================== --- test/wasm/entry.ll +++ test/wasm/entry.ll @@ -1,19 +1,34 @@ ; RUN: llc -filetype=obj -mtriple=wasm32-unknown-unknown-wasm %s -o %t.o -; RUN: lld -flavor wasm -e entry -o %t.wasm %t.o -; RUN: obj2yaml %t.wasm | FileCheck %s -; RUN: lld -flavor wasm --entry=entry -o %t.wasm %t.o -; RUN: obj2yaml %t.wasm | FileCheck %s -define void @entry() local_unnamed_addr #0 { +define hidden void @entry() local_unnamed_addr #0 { entry: ret void } -; CHECK: - Type: EXPORT -; CHECK: Exports: -; CHECK: - Name: memory -; CHECK: Kind: MEMORY -; CHECK: Index: 0 -; CHECK: - Name: entry -; CHECK: Kind: FUNCTION -; CHECK: Index: 0 +; RUN: lld -flavor wasm -e entry -o %t1.wasm %t.o +; RUN: obj2yaml %t1.wasm | FileCheck %s +; RUN: lld -flavor wasm --entry=entry -o %t2.wasm %t.o +; RUN: obj2yaml %t2.wasm | FileCheck %s + +; CHECK: - Type: EXPORT +; CHECK-NEXT: Exports: +; CHECK-NEXT: - Name: memory +; CHECK-NEXT: Kind: MEMORY +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: - Name: entry +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 0 + +; The __wasm_call_ctors is somewhat special. Make sure we can use it +; as the entry point if we choose +; RUN: lld -flavor wasm --entry=__wasm_call_ctors -o %t3.wasm %t.o +; RUN: obj2yaml %t3.wasm | FileCheck %s -check-prefix=CHECK-CTOR + +; CHECK-CTOR: - Type: EXPORT +; CHECK-CTOR-NEXT: Exports: +; CHECK-CTOR-NEXT: - Name: memory +; CHECK-CTOR-NEXT: Kind: MEMORY +; CHECK-CTOR-NEXT: Index: 0 +; CHECK-CTOR-NEXT: - Name: __wasm_call_ctors +; CHECK-CTOR-NEXT: Kind: FUNCTION +; CHECK-CTOR-NEXT: Index: 1 Index: test/wasm/export.ll =================================================================== --- test/wasm/export.ll +++ test/wasm/export.ll @@ -20,12 +20,12 @@ ; 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: - Name: _start +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Name: __heap_base ; CHECK-NEXT: Kind: GLOBAL ; CHECK-NEXT: Index: 1 Index: test/wasm/stack-pointer.ll =================================================================== --- test/wasm/stack-pointer.ll +++ test/wasm/stack-pointer.ll @@ -52,12 +52,12 @@ ; CHECK-NEXT: - Name: memory ; CHECK-NEXT: Kind: MEMORY ; CHECK-NEXT: Index: 0 -; CHECK-NEXT: - Name: _start -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 0 ; CHECK-NEXT: - Name: __wasm_call_ctors ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: _start +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 0 ; CHECK-NEXT: - Name: __stack_pointer ; CHECK-NEXT: Kind: GLOBAL ; CHECK-NEXT: Index: 0 Index: test/wasm/visibility-hidden.ll =================================================================== --- test/wasm/visibility-hidden.ll +++ test/wasm/visibility-hidden.ll @@ -34,12 +34,12 @@ ; CHECK-NEXT: - Name: memory ; CHECK-NEXT: Kind: MEMORY ; CHECK-NEXT: Index: 0 -; CHECK-NEXT: - Name: _start -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 2 ; CHECK-NEXT: - Name: objectDefault ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: _start +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 2 ; CHECK-NEXT: - Name: archiveDefault ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 4 Index: test/wasm/weak-alias-overide.ll =================================================================== --- test/wasm/weak-alias-overide.ll +++ test/wasm/weak-alias-overide.ll @@ -60,12 +60,12 @@ ; 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: alias_fn ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 0 +; CHECK-NEXT: - Name: _start +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 1 ; CHECK-NEXT: - Name: direct_fn ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 2 Index: test/wasm/weak-undefined.ll =================================================================== --- test/wasm/weak-undefined.ll +++ test/wasm/weak-undefined.ll @@ -67,15 +67,15 @@ ; CHECK-NEXT: - Name: memory ; CHECK-NEXT: Kind: MEMORY ; CHECK-NEXT: Index: 0 -; CHECK-NEXT: - Name: _start -; CHECK-NEXT: Kind: FUNCTION -; CHECK-NEXT: Index: 2 ; CHECK-NEXT: - Name: get_address_of_foo ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 0 ; CHECK-NEXT: - Name: get_address_of_global_var ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Name: _start +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 2 ; CHECK-NEXT: - Name: __heap_base ; CHECK-NEXT: Kind: GLOBAL ; CHECK-NEXT: Index: 1 Index: wasm/Driver.cpp =================================================================== --- wasm/Driver.cpp +++ wasm/Driver.cpp @@ -282,10 +282,11 @@ if (Config->Relocatable && Args.hasArg(OPT_undefined)) error("undefined symbols specified for relocatable output file"); + Symbol *EntrySym = nullptr; if (!Config->Relocatable) { static WasmSignature Signature = {{}, WASM_TYPE_NORESULT}; if (!Config->Entry.empty()) - Symtab->addUndefinedFunction(Config->Entry, &Signature); + EntrySym = Symtab->addUndefinedFunction(Config->Entry, &Signature); // Handle the `--undefined ` options. for (auto* Arg : Args.filtered(OPT_undefined)) @@ -341,6 +342,9 @@ Sym->setHidden(false); } + if (EntrySym) + EntrySym->setHidden(false); + if (errorCount()) return; Index: wasm/SymbolTable.cpp =================================================================== --- wasm/SymbolTable.cpp +++ wasm/SymbolTable.cpp @@ -131,6 +131,9 @@ S->setFunctionType(Type); } else if (!S->isFunction()) { error("symbol type mismatch: " + Name); + } else if (!S->isDefined()) { + DEBUG(dbgs() << "resolving existing undefined function: " << Name << "\n"); + S->update(Symbol::DefinedFunctionKind, nullptr, Flags); } return S; } @@ -140,10 +143,14 @@ Symbol *S; bool WasInserted; std::tie(S, WasInserted) = insert(Name); - if (WasInserted) + if (WasInserted) { S->update(Symbol::DefinedGlobalKind); - else if (!S->isGlobal()) + } else if (!S->isGlobal()) { error("symbol type mismatch: " + Name); + } else { + DEBUG(dbgs() << "resolving existing undefined global: " << Name << "\n"); + S->update(Symbol::DefinedGlobalKind); + } return S; } Index: wasm/Symbols.cpp =================================================================== --- wasm/Symbols.cpp +++ wasm/Symbols.cpp @@ -98,6 +98,7 @@ } void Symbol::setHidden(bool IsHidden) { + DEBUG(dbgs() << "setHidden: " << Name << " -> " << IsHidden << "\n"); Flags &= ~WASM_SYMBOL_VISIBILITY_MASK; if (IsHidden) Flags |= WASM_SYMBOL_VISIBILITY_HIDDEN; Index: wasm/Writer.cpp =================================================================== --- wasm/Writer.cpp +++ wasm/Writer.cpp @@ -617,8 +617,6 @@ } void Writer::calculateExports() { - Symbol *EntrySym = Symtab->find(Config->Entry); - bool ExportEntry = !Config->Relocatable && EntrySym && EntrySym->isDefined(); bool ExportHidden = Config->EmitRelocs; StringSet<> UsedNames; auto BudgeLocalName = [&](const Symbol *Sym) { @@ -640,11 +638,7 @@ } }; - if (ExportEntry) - ExportedSymbols.emplace_back(WasmExportEntry{EntrySym, EntrySym->getName()}); - - if (Config->CtorSymbol && ExportHidden && - !(ExportEntry && Config->CtorSymbol == EntrySym)) + if (Config->CtorSymbol && (!Config->CtorSymbol->isHidden() || ExportHidden)) ExportedSymbols.emplace_back( WasmExportEntry{Config->CtorSymbol, Config->CtorSymbol->getName()}); @@ -659,8 +653,6 @@ if ((Sym->isHidden() || Sym->isLocal()) && !ExportHidden) continue; - if (ExportEntry && Sym == EntrySym) - continue; ExportedSymbols.emplace_back(WasmExportEntry{Sym, BudgeLocalName(Sym)}); } }