Index: test/wasm/data-layout.ll =================================================================== --- test/wasm/data-layout.ll +++ test/wasm/data-layout.ll @@ -1,6 +1,6 @@ ; RUN: llc -filetype=obj %p/Inputs/hello.ll -o %t.hello.o ; RUN: llc -filetype=obj %s -o %t.o -; RUN: lld -flavor wasm --emit-relocs --allow-undefined --entry '' -o %t.wasm %t.o %t.hello.o +; RUN: lld -flavor wasm --emit-relocs --allow-undefined --no-entry -o %t.wasm %t.o %t.hello.o ; RUN: obj2yaml %t.wasm | FileCheck %s target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" Index: wasm/Driver.cpp =================================================================== --- wasm/Driver.cpp +++ wasm/Driver.cpp @@ -219,6 +219,17 @@ error("no input files"); } +static StringRef getEntry(opt::InputArgList &Args, StringRef def) { + auto *Arg = Args.getLastArg(OPT_entry, OPT_no_entry); + if (!Arg) + return def; + // Apparently the empty string is a valid symbol name in Wasm, so we use a + // null string to mean "no entrypoint", *not* the empty string. + if (Arg->getOption().getID() == OPT_no_entry) + return StringRef(); + return Arg->getValue(); +} + void LinkerDriver::link(ArrayRef ArgsArr) { WasmOptTable Parser; opt::InputArgList Args = Parser.parse(ArgsArr.slice(1)); @@ -248,8 +259,8 @@ Args.hasFlag(OPT_check_signatures, OPT_no_check_signatures, false); Config->EmitRelocs = Args.hasArg(OPT_emit_relocs); Config->Relocatable = Args.hasArg(OPT_relocatable); - Config->Entry = Args.getLastArgValue(OPT_entry, - Config->Relocatable ? "" : "_start"); + Config->Entry = getEntry(Args, Config->Relocatable ? StringRef() + : StringRef("_start")); std::vector Undefined = args::getStrings(Args, OPT_undefined); Config->ImportMemory = Args.hasArg(OPT_import_memory); Config->OutputFile = Args.getLastArgValue(OPT_o); @@ -277,13 +288,13 @@ if (!Args.hasArg(OPT_INPUT)) error("no input files"); - if (Config->Relocatable && !Config->Entry.empty()) + if (Config->Relocatable && Config->Entry.data()) error("entry point specified for relocatable output file"); if (Config->Relocatable && !Undefined.empty()) error("undefined symbols specified for relocatable output file"); if (!Config->Relocatable) { - if (!Config->Entry.empty()) { + if (Config->Entry.data()) { static WasmSignature Signature = {{}, WASM_TYPE_NORESULT}; addSyntheticUndefinedFunction(Config->Entry, &Signature); } @@ -311,12 +322,16 @@ return; } - if (!Config->Entry.empty()) { + if (Config->Entry.data()) { Symbol *Sym = Symtab->find(Config->Entry); - if (!Sym || !Sym->isDefined()) - fatal("entry point not found: " + Config->Entry); - if (!Sym->isFunction()) - fatal("entry point is not a function: " + Sym->getName()); + if (!Sym || !Sym->isDefined()) { + error("entry point not found: " + Config->Entry); + return; + } + if (!Sym->isFunction()) { + error("entry point is not a function: " + Sym->getName()); + return; + } } // Write the result to the file. Index: wasm/Options.td =================================================================== --- wasm/Options.td +++ wasm/Options.td @@ -68,6 +68,9 @@ def entry: S<"entry">, MetaVarName<"">, HelpText<"Name of entry point symbol">; +def no_entry: F<"no-entry">, + HelpText<"Do not output any entry point">; + def error_limit: J<"error-limit=">, HelpText<"Maximum number of errors to emit before stopping (0 = no limit)">; Index: wasm/Writer.cpp =================================================================== --- wasm/Writer.cpp +++ wasm/Writer.cpp @@ -261,7 +261,7 @@ bool ExportMemory = !Config->Relocatable && !Config->ImportMemory; bool ExportOther = true; // ??? TODO Config->Relocatable; bool ExportHidden = Config->Relocatable; - Symbol *EntrySym = !Config->Relocatable ? Symtab->find(Config->Entry) : nullptr; + Symbol *EntrySym = Config->Entry.data() ? Symtab->find(Config->Entry) : nullptr; bool ExportEntry = EntrySym && EntrySym->isDefined(); uint32_t NumExports = 0; @@ -270,11 +270,9 @@ ++NumExports; if (ExportEntry) { + assert(EntrySym->isFunction()); EntrySym->WrittenToSymtab = true; ++NumExports; - - if (!EntrySym->isFunction()) - error("entry point is not a function: " + EntrySym->getName()); } if (ExportOther) { @@ -337,7 +335,7 @@ } void Writer::createStartSection() { - if (Config->Entry.empty()) + if (!Config->Entry.data()) return; const Symbol *Sym = Symtab->find(Config->Entry);