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 --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: test/wasm/entry.ll =================================================================== --- test/wasm/entry.ll +++ test/wasm/entry.ll @@ -12,11 +12,13 @@ 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 +; 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 +; CHECK-NEXT: - Type: START +; CHECK-NEXT: StartFunction: 0 Index: test/wasm/load-undefined.ll =================================================================== --- /dev/null +++ test/wasm/load-undefined.ll @@ -0,0 +1,22 @@ +; Verify that the -u / --undefined option is able to pull in symbols from +; an archive, and doesn't error when uses to pull in a symbol already loaded. +; +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %S/Inputs/ret64.ll -o %t.o +; RUN: llc -filetype=obj -mtriple=wasm32-unknown-uknown-wasm %S/Inputs/ret32.ll -o %t2.o +; RUN: llvm-ar rcs %t2.a %t2.o +; RUN: lld -flavor wasm %t2.a %t.o -o %t.wasm --entry '' -u ret32 --undefined ret64 +; RUN: obj2yaml %t.wasm | FileCheck %s + + +; CHECK: - Type: EXPORT +; CHECK-NEXT: Exports: +; CHECK-NEXT: - Name: memory +; CHECK-NEXT: Kind: MEMORY +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: - Name: ret32 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 0 +; CHECK-NEXT: - Name: ret64 +; CHECK-NEXT: Kind: FUNCTION +; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Type: Index: test/wasm/local-symbols.ll =================================================================== --- test/wasm/local-symbols.ll +++ test/wasm/local-symbols.ll @@ -54,6 +54,8 @@ ; CHECK-NEXT: - Name: _start ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 1 +; CHECK-NEXT: - Type: START +; CHECK-NEXT: StartFunction: 1 ; CHECK-NEXT: - Type: CODE ; CHECK-NEXT: Functions: ; CHECK-NEXT: - Locals: Index: test/wasm/weak-alias-overide.ll =================================================================== --- test/wasm/weak-alias-overide.ll +++ test/wasm/weak-alias-overide.ll @@ -65,6 +65,8 @@ ; CHECK-NEXT: - Name: call_bar ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 3 +; CHECK-NEXT: - Type: START +; CHECK-NEXT: StartFunction: 1 ; CHECK-NEXT: - Type: CODE ; CHECK-NEXT: Functions: ; CHECK-NEXT: - Locals: Index: test/wasm/weak-alias.ll =================================================================== --- test/wasm/weak-alias.ll +++ test/wasm/weak-alias.ll @@ -59,6 +59,8 @@ ; CHECK-NEXT: - Name: call_bar ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 2 +; CHECK-NEXT: - Type: START +; CHECK-NEXT: StartFunction: 0 ; CHECK-NEXT: - Type: CODE ; CHECK-NEXT: Functions: ; CHECK-NEXT: - Locals: Index: test/wasm/weak-external.ll =================================================================== --- test/wasm/weak-external.ll +++ test/wasm/weak-external.ll @@ -66,6 +66,8 @@ ; CHECK-NEXT: - Name: _start ; CHECK-NEXT: Kind: FUNCTION ; CHECK-NEXT: Index: 2 +; CHECK-NEXT: - Type: START +; CHECK-NEXT: StartFunction: 2 ; CHECK-NEXT: - Type: ELEM ; CHECK-NEXT: Segments: ; CHECK-NEXT: - Offset: Index: wasm/Config.h =================================================================== --- wasm/Config.h +++ wasm/Config.h @@ -39,6 +39,7 @@ llvm::StringRef OutputFile; std::vector SearchPaths; + std::vector Undefined; std::set AllowUndefinedSymbols; std::vector> SyntheticGlobals; }; Index: wasm/Driver.cpp =================================================================== --- wasm/Driver.cpp +++ wasm/Driver.cpp @@ -292,11 +292,13 @@ Config->AllowUndefined = Args.hasArg(OPT_allow_undefined); Config->EmitRelocs = Args.hasArg(OPT_emit_relocs); - Config->Entry = Args.getLastArgValue(OPT_entry); + Config->Relocatable = Args.hasArg(OPT_relocatable); + Config->Entry = Args.getLastArgValue(OPT_entry, + Config->Relocatable ? "" : "_start"); Config->ImportMemory = Args.hasArg(OPT_import_memory); Config->OutputFile = Args.getLastArgValue(OPT_o); - Config->Relocatable = Args.hasArg(OPT_relocatable); Config->SearchPaths = getArgs(Args, OPT_L); + Config->Undefined = getArgs(Args, OPT_undefined); Config->StripAll = Args.hasArg(OPT_strip_all); Config->StripDebug = Args.hasArg(OPT_strip_debug); Config->Sysroot = Args.getLastArgValue(OPT_sysroot); @@ -323,9 +325,11 @@ error("entry point specified for relocatable output file"); if (!Config->Relocatable) { - if (Config->Entry.empty()) - Config->Entry = "_start"; - addSyntheticUndefinedFunction(Config->Entry); + if (!Config->Entry.empty()) + addSyntheticUndefinedFunction(Config->Entry); + // Handle the `--undefined ` options. + for (StringRef S : Config->Undefined) + addSyntheticUndefinedFunction(S); addSyntheticGlobal("__stack_pointer", 0); } @@ -348,6 +352,8 @@ if (!Config->Entry.empty()) { 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()); } Index: wasm/Options.td =================================================================== --- wasm/Options.td +++ wasm/Options.td @@ -6,6 +6,11 @@ class J: Joined<["--", "-"], name>; class S: Separate<["--", "-"], name>; +multiclass Eq { + def "": Separate<["--", "-"], name>; + def _eq: Joined<["--", "-"], name # "=">, Alias(NAME)>; +} + def L: JoinedOrSeparate<["-"], "L">, MetaVarName<"">, HelpText<"Add a directory to the library search path">; @@ -50,6 +55,9 @@ def sysroot: J<"sysroot=">, HelpText<"Set the system root">; +defm undefined: Eq<"undefined">, + HelpText<"Force undefined symbol during linking">; + def z: JoinedOrSeparate<["-"], "z">, MetaVarName<"