Index: lld/trunk/test/wasm/data-layout.ll =================================================================== --- lld/trunk/test/wasm/data-layout.ll +++ lld/trunk/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: lld/trunk/wasm/Driver.cpp =================================================================== --- lld/trunk/wasm/Driver.cpp +++ lld/trunk/wasm/Driver.cpp @@ -202,6 +202,15 @@ error("no input files"); } +static const char *getEntry(opt::InputArgList &Args, const char *def) { + auto *Arg = Args.getLastArg(OPT_entry, OPT_no_entry); + if (!Arg) + return def; + if (Arg->getOption().getID() == OPT_no_entry) + return ""; + return Arg->getValue(); +} + void LinkerDriver::link(ArrayRef ArgsArr) { WasmOptTable Parser; opt::InputArgList Args = Parser.parse(ArgsArr.slice(1)); @@ -230,10 +239,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); @@ -265,10 +274,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)) @@ -301,15 +310,12 @@ 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 (!Config->Entry.empty() && !Symtab->find(Config->Entry)->isDefined()) + error("entry point not found: " + Config->Entry); + if (errorCount()) + return; // Write the result to the file. writeResult(); Index: lld/trunk/wasm/Options.td =================================================================== --- lld/trunk/wasm/Options.td +++ lld/trunk/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)">;