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 -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 @@ -213,6 +213,15 @@ 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; + 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)); @@ -241,10 +250,10 @@ Config->CheckSignatures = Args.hasFlag(OPT_check_signatures, OPT_no_check_signatures, false); Config->EmitRelocs = Args.hasArg(OPT_emit_relocs); - Config->Entry = Args.getLastArgValue(OPT_entry); + Config->Relocatable = Args.hasArg(OPT_relocatable); + Config->Entry = getEntry(Args, Config->Relocatable ? "" : "_start"); Config->ImportMemory = Args.hasArg(OPT_import_memory); Config->OutputFile = Args.getLastArgValue(OPT_o); - Config->Relocatable = Args.hasArg(OPT_relocatable); Config->SearchPaths = args::getStrings(Args, OPT_L); Config->StripAll = Args.hasArg(OPT_strip_all); Config->StripDebug = Args.hasArg(OPT_strip_debug); @@ -276,10 +285,10 @@ error("undefined symbols specified for relocatable output file"); if (!Config->Relocatable) { - if (Config->Entry.empty()) - Config->Entry = "_start"; - static WasmSignature Signature = {{}, WASM_TYPE_NORESULT}; - addSyntheticUndefinedFunction(Config->Entry, &Signature); + if (!Config->Entry.empty()) { + static WasmSignature Signature = {{}, WASM_TYPE_NORESULT}; + addSyntheticUndefinedFunction(Config->Entry, &Signature); + } // Handle the `--undefined ` options. for (StringRef S : args::getStrings(Args, OPT_undefined)) @@ -312,15 +321,14 @@ if (!Sym->isDefined()) error("function forced with --undefined not found: " + Sym->getName()); } - if (errorCount()) - return; } if (!Config->Entry.empty()) { - Symbol *Sym = Symtab->find(Config->Entry); - if (!Sym->isFunction()) - fatal("entry point is not a function: " + Sym->getName()); + if (!Symtab->find(Config->Entry)->isDefined()) + error("entry point not found: " + Config->Entry); } + if (errorCount()) + return; // Write the result to the file. writeResult(); Index: wasm/Options.td =================================================================== --- wasm/Options.td +++ wasm/Options.td @@ -66,6 +66,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 @@ -248,7 +248,7 @@ void Writer::createExportSection() { bool ExportMemory = !Config->Relocatable && !Config->ImportMemory; - Symbol *EntrySym = Symtab->find(Config->Entry); + Symbol *EntrySym = !Config->Entry.empty() ? Symtab->find(Config->Entry) : nullptr; bool ExportEntry = !Config->Relocatable && EntrySym && EntrySym->isDefined(); bool ExportHidden = Config->EmitRelocs;