[lld] r338938 - [WebAssembly] Don't error when --undefined symbols are not found

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 3 17:04:06 PDT 2018


Author: sbc
Date: Fri Aug  3 17:04:06 2018
New Revision: 338938

URL: http://llvm.org/viewvc/llvm-project?rev=338938&view=rev
Log:
[WebAssembly] Don't error when --undefined symbols are not found

This matches the behavior of the ELF linker where -u/--undefined
means symbols will get pulled in from archives but won't result
in link error if they are missing.

Also, don't actually great symbol table entries for the undefined
symbols, again matching more closely the ELF linker.

This also results in simplification of the code.

Differential Revision: https://reviews.llvm.org/D50279

Modified:
    lld/trunk/test/wasm/call-indirect.ll
    lld/trunk/test/wasm/cxx-mangling.ll
    lld/trunk/test/wasm/demangle.ll
    lld/trunk/test/wasm/export-all.ll
    lld/trunk/test/wasm/export.ll
    lld/trunk/test/wasm/load-undefined.test
    lld/trunk/test/wasm/lto/export.ll
    lld/trunk/test/wasm/undefined-entry.test
    lld/trunk/test/wasm/undefined.ll
    lld/trunk/test/wasm/visibility-hidden.ll
    lld/trunk/test/wasm/weak-alias-overide.ll
    lld/trunk/test/wasm/weak-undefined.ll
    lld/trunk/wasm/Driver.cpp
    lld/trunk/wasm/SymbolTable.cpp

Modified: lld/trunk/test/wasm/call-indirect.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/call-indirect.ll?rev=338938&r1=338937&r2=338938&view=diff
==============================================================================
--- lld/trunk/test/wasm/call-indirect.ll (original)
+++ lld/trunk/test/wasm/call-indirect.ll Fri Aug  3 17:04:06 2018
@@ -105,9 +105,6 @@ define void @call_ptr(i64 (i64)* %arg) {
 ; CHECK-NEXT:       - Name:            __data_end
 ; CHECK-NEXT:         Kind:            GLOBAL
 ; CHECK-NEXT:         Index:           2
-; CHECK-NEXT:       - Name:            _start
-; CHECK-NEXT:         Kind:            FUNCTION
-; CHECK-NEXT:         Index:           4
 ; CHECK-NEXT:       - Name:            bar
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Index:           1
@@ -117,6 +114,9 @@ define void @call_ptr(i64 (i64)* %arg) {
 ; CHECK-NEXT:       - Name:            foo
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Index:           3
+; CHECK-NEXT:       - Name:            _start
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Index:           4
 ; CHECK-NEXT:       - Name:            indirect_func
 ; CHECK-NEXT:         Kind:            GLOBAL
 ; CHECK-NEXT:         Index:           3

Modified: lld/trunk/test/wasm/cxx-mangling.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/cxx-mangling.ll?rev=338938&r1=338937&r2=338938&view=diff
==============================================================================
--- lld/trunk/test/wasm/cxx-mangling.ll (original)
+++ lld/trunk/test/wasm/cxx-mangling.ll Fri Aug  3 17:04:06 2018
@@ -32,12 +32,12 @@ define void @_start() {
 ; CHECK-NEXT:       - Name:            __data_end
 ; CHECK-NEXT:         Kind:            GLOBAL
 ; CHECK-NEXT:         Index:           2
-; CHECK-NEXT:       - Name:            _start
-; CHECK-NEXT:         Kind:            FUNCTION
-; CHECK-NEXT:         Index:           3
 ; CHECK-NEXT:       - Name:            _Z3fooi
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Index:           2
+; CHECK-NEXT:       - Name:            _start
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Index:           3
 ; CHECK-NEXT:   - Type:            CODE
 ; CHECK-NEXT:     Functions:
 ; CHECK-NEXT:       - Index:           0

Modified: lld/trunk/test/wasm/demangle.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/demangle.ll?rev=338938&r1=338937&r2=338938&view=diff
==============================================================================
--- lld/trunk/test/wasm/demangle.ll (original)
+++ lld/trunk/test/wasm/demangle.ll Fri Aug  3 17:04:06 2018
@@ -1,17 +1,19 @@
 ; RUN: llc -filetype=obj %s -o %t.o
-; RUN: not wasm-ld --undefined _Z3fooi \
-; RUN:     -o %t.wasm %t.o 2>&1 | FileCheck %s
+; RUN: not wasm-ld -o %t.wasm %t.o 2>&1 | FileCheck %s
 
-; CHECK: error: undefined symbol: foo(int)
+; CHECK: error: {{.*}}.o: undefined symbol: foo(int)
 
-; RUN: not wasm-ld --no-demangle --undefined _Z3fooi \
-; RUN:     -o %t.wasm %t.o 2>&1 |  FileCheck -check-prefix=CHECK-NODEMANGLE %s
+; RUN: not wasm-ld --no-demangle \
+; RUN:     -o %t.wasm %t.o 2>&1 | FileCheck -check-prefix=CHECK-NODEMANGLE %s
 
-; CHECK-NODEMANGLE: error: undefined symbol: _Z3fooi
+; CHECK-NODEMANGLE: error: {{.*}}.o: undefined symbol: _Z3fooi
 
 target triple = "wasm32-unknown-unknown"
 
+declare void @_Z3fooi(i32);
+
 define hidden void @_start() local_unnamed_addr {
 entry:
+    call void @_Z3fooi(i32 1)
     ret void
 }

Modified: lld/trunk/test/wasm/export-all.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/export-all.ll?rev=338938&r1=338937&r2=338938&view=diff
==============================================================================
--- lld/trunk/test/wasm/export-all.ll (original)
+++ lld/trunk/test/wasm/export-all.ll Fri Aug  3 17:04:06 2018
@@ -42,7 +42,7 @@ entry:
 ; CHECK-NOT:     - Name:            internal_func
 
 ; EXPORT:     - Type:            EXPORT
-; EXPORT:        - Name:            _start
 ; EXPORT:        - Name:            bar
 ; EXPORT:        - Name:            foo
+; EXPORT:        - Name:            _start
 ; EXPORT-NOT:    - Name:            internal_func

Modified: lld/trunk/test/wasm/export.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/export.ll?rev=338938&r1=338937&r2=338938&view=diff
==============================================================================
--- lld/trunk/test/wasm/export.ll (original)
+++ lld/trunk/test/wasm/export.ll Fri Aug  3 17:04:06 2018
@@ -28,10 +28,10 @@ entry:
 ; CHECK-NEXT:       - Name:            __data_end
 ; CHECK-NEXT:         Kind:            GLOBAL
 ; CHECK-NEXT:         Index:           2
-; CHECK-NEXT:       - Name:            _start
-; CHECK-NEXT:         Kind:            FUNCTION
-; CHECK-NEXT:         Index:           2
 ; CHECK-NEXT:       - Name:            hidden_function
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Index:           1
+; CHECK-NEXT:       - Name:            _start
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Index:           2
 ; CHECK-NEXT:   - Type:            CODE

Modified: lld/trunk/test/wasm/load-undefined.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/load-undefined.test?rev=338938&r1=338937&r2=338938&view=diff
==============================================================================
--- lld/trunk/test/wasm/load-undefined.test (original)
+++ lld/trunk/test/wasm/load-undefined.test Fri Aug  3 17:04:06 2018
@@ -18,9 +18,9 @@
 ; CHECK-NEXT:      - Index:           1
 ; CHECK-NEXT:        Name:            _start
 ; CHECK-NEXT:      - Index:           2
-; CHECK-NEXT:        Name:            ret32
-; CHECK-NEXT:      - Index:           3
 ; CHECK-NEXT:        Name:            ret64
+; CHECK-NEXT:      - Index:           3
+; CHECK-NEXT:        Name:            ret32
 ; CHECK-NEXT: ...
 
 ; NO-LOAD:         Name:            name
@@ -33,9 +33,6 @@
 ; NO-LOAD-NEXT:        Name:            ret64
 ; NO-LOAD-NEXT: ...
 
-; Verify that referencing a symbol that doesn't exist won't work
-; RUN: not wasm-ld %t.start.o -o %t.wasm -u symboldoesnotexist 2>&1 | FileCheck -check-prefix=CHECK-UNDEFINED1 %s
-; CHECK-UNDEFINED1: error: undefined symbol: symboldoesnotexist
-
-; RUN: not wasm-ld %t.start.o -o %t.wasm --undefined symboldoesnotexist --allow-undefined 2>&1 | FileCheck -check-prefix=CHECK-UNDEFINED2 %s
-; CHECK-UNDEFINED2: symbol forced with --undefined not found: symboldoesnotexist
+; Verify that referencing a symbol that is not found doesn't result in a link
+; failure.  This matches the behaviour of the ELF linker.
+; RUN: wasm-ld %t.start.o -o %t.wasm -u symboldoesnotexist

Modified: lld/trunk/test/wasm/lto/export.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/lto/export.ll?rev=338938&r1=338937&r2=338938&view=diff
==============================================================================
--- lld/trunk/test/wasm/lto/export.ll (original)
+++ lld/trunk/test/wasm/lto/export.ll Fri Aug  3 17:04:06 2018
@@ -29,10 +29,10 @@ entry:
 ; CHECK-NEXT:       - Name:            __data_end
 ; CHECK-NEXT:         Kind:            GLOBAL
 ; CHECK-NEXT:         Index:           2
-; CHECK-NEXT:       - Name:            _start
-; CHECK-NEXT:         Kind:            FUNCTION
-; CHECK-NEXT:         Index:           2
 ; CHECK-NEXT:       - Name:            hidden_function
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Index:           1
+; CHECK-NEXT:       - Name:            _start
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Index:           2
 ; CHECK-NEXT:   - Type:            CODE

Modified: lld/trunk/test/wasm/undefined-entry.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/undefined-entry.test?rev=338938&r1=338937&r2=338938&view=diff
==============================================================================
--- lld/trunk/test/wasm/undefined-entry.test (original)
+++ lld/trunk/test/wasm/undefined-entry.test Fri Aug  3 17:04:06 2018
@@ -1,11 +1,9 @@
 RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o
 RUN: not wasm-ld -o %t.wasm %t.ret32.o 2>&1 | FileCheck %s
+RUN: not wasm-ld --allow-undefined -o %t.wasm %t.ret32.o 2>&1 | FileCheck %s
 RUN: not wasm-ld -entry=foo -o %t.wasm %t.ret32.o 2>&1 | FileCheck %s -check-prefix=CHECK-CUSTOM
-RUN: not wasm-ld --allow-undefined -o %t.wasm %t.ret32.o 2>&1 | FileCheck %s -check-prefix=CHECK-ALLOW
 
-CHECK: error: undefined symbol: _start
-CHECK-CUSTOM: error: undefined symbol: foo
-CHECK-ALLOW: error: entry symbol not defined (pass --no-entry to supress):
-_start
+CHECK: error: entry symbol not defined (pass --no-entry to supress): _start
+CHECK-CUSTOM: error: entry symbol not defined (pass --no-entry to supress): foo
 
 RUN: wasm-ld --no-entry -o %t.wasm %t.ret32.o

Modified: lld/trunk/test/wasm/undefined.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/undefined.ll?rev=338938&r1=338937&r2=338938&view=diff
==============================================================================
--- lld/trunk/test/wasm/undefined.ll (original)
+++ lld/trunk/test/wasm/undefined.ll Fri Aug  3 17:04:06 2018
@@ -1,10 +1,10 @@
 ; RUN: llc -filetype=obj %s -o %t.o
 ; RUN: wasm-ld --allow-undefined -o %t.wasm %t.o
 
-; Fails due to undefined 'foo' and also 'baz'
+; Fails due to undefined 'foo' 
 ; RUN: not wasm-ld --undefined=baz -o %t.wasm %t.o 2>&1 | FileCheck %s
 ; CHECK: error: {{.*}}.o: undefined symbol: foo
-; CHECK: error: undefined symbol: baz
+; CHECK-NOT: undefined symbol: baz
 
 ; Succeeds if we pass a file containing 'foo' as --allow-undefined-file.
 ; RUN: echo 'foo' > %t.txt

Modified: lld/trunk/test/wasm/visibility-hidden.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/visibility-hidden.ll?rev=338938&r1=338937&r2=338938&view=diff
==============================================================================
--- lld/trunk/test/wasm/visibility-hidden.ll (original)
+++ lld/trunk/test/wasm/visibility-hidden.ll Fri Aug  3 17:04:06 2018
@@ -43,12 +43,12 @@ entry:
 ; CHECK-NEXT:       - Name:            __data_end
 ; CHECK-NEXT:         Kind:            GLOBAL
 ; CHECK-NEXT:         Index:           2
-; CHECK-NEXT:       - Name:            _start
-; CHECK-NEXT:         Kind:            FUNCTION
-; CHECK-NEXT:         Index:           3
 ; CHECK-NEXT:       - Name:            objectDefault
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Index:           2
+; CHECK-NEXT:       - Name:            _start
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Index:           3
 ; CHECK-NEXT:       - Name:            archiveDefault
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Index:           5

Modified: lld/trunk/test/wasm/weak-alias-overide.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/weak-alias-overide.ll?rev=338938&r1=338937&r2=338938&view=diff
==============================================================================
--- lld/trunk/test/wasm/weak-alias-overide.ll (original)
+++ lld/trunk/test/wasm/weak-alias-overide.ll Fri Aug  3 17:04:06 2018
@@ -74,12 +74,12 @@ entry:
 ; CHECK-NEXT:       - Name:            __data_end
 ; CHECK-NEXT:         Kind:            GLOBAL
 ; CHECK-NEXT:         Index:           2
-; CHECK-NEXT:       - Name:            _start
-; CHECK-NEXT:         Kind:            FUNCTION
-; CHECK-NEXT:         Index:           2
 ; CHECK-NEXT:       - Name:            alias_fn
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Index:           1
+; CHECK-NEXT:       - Name:            _start
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Index:           2
 ; CHECK-NEXT:       - Name:            direct_fn
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Index:           3

Modified: lld/trunk/test/wasm/weak-undefined.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/weak-undefined.ll?rev=338938&r1=338937&r2=338938&view=diff
==============================================================================
--- lld/trunk/test/wasm/weak-undefined.ll (original)
+++ lld/trunk/test/wasm/weak-undefined.ll Fri Aug  3 17:04:06 2018
@@ -81,15 +81,15 @@ entry:
 ; CHECK-NEXT:       - Name:            __data_end
 ; CHECK-NEXT:         Kind:            GLOBAL
 ; CHECK-NEXT:         Index:           2
-; CHECK-NEXT:       - Name:            _start
-; CHECK-NEXT:         Kind:            FUNCTION
-; CHECK-NEXT:         Index:           3
 ; CHECK-NEXT:       - Name:            get_address_of_foo
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:       - Name:            get_address_of_global_var
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Index:           2
+; CHECK-NEXT:       - Name:            _start
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Index:           3
 ; CHECK-NEXT:   - Type:            CODE
 ; CHECK-NEXT:     Functions:
 ; CHECK-NEXT:       - Index:           0

Modified: lld/trunk/wasm/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Driver.cpp?rev=338938&r1=338937&r2=338938&view=diff
==============================================================================
--- lld/trunk/wasm/Driver.cpp (original)
+++ lld/trunk/wasm/Driver.cpp Fri Aug  3 17:04:06 2018
@@ -329,14 +329,19 @@ static void handleWeakUndefines() {
 }
 
 // Force Sym to be entered in the output. Used for -u or equivalent.
-static Symbol *addUndefined(StringRef Name) {
-  Symbol *S = Symtab->addUndefinedFunction(Name, 0, nullptr, nullptr);
+static Symbol *handleUndefined(StringRef Name) {
+  Symbol *Sym = Symtab->find(Name);
+  if (!Sym)
+    return nullptr;
 
   // Since symbol S may not be used inside the program, LTO may
   // eliminate it. Mark the symbol as "used" to prevent it.
-  S->IsUsedInRegularObj = true;
+  Sym->IsUsedInRegularObj = true;
 
-  return S;
+  if (auto *LazySym = dyn_cast<LazySymbol>(Sym))
+    LazySym->fetch();
+
+  return Sym;
 }
 
 void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
@@ -462,15 +467,6 @@ void LinkerDriver::link(ArrayRef<const c
     WasmSym::DsoHandle = Symtab->addSyntheticDataSymbol(
         "__dso_handle", WASM_SYMBOL_VISIBILITY_HIDDEN);
     WasmSym::DataEnd = Symtab->addSyntheticDataSymbol("__data_end", 0);
-
-    // For now, since we don't actually use the start function as the
-    // wasm start symbol, we don't need to care about it signature.
-    if (!Config->Entry.empty())
-      EntrySym = addUndefined(Config->Entry);
-
-    // Handle the `--undefined <sym>` options.
-    for (auto *Arg : Args.filtered(OPT_undefined))
-      addUndefined(Arg->getValue());
   }
 
   createFiles(Args);
@@ -484,10 +480,29 @@ void LinkerDriver::link(ArrayRef<const c
   if (errorCount())
     return;
 
-  // Add synthetic dummies for weak undefined functions.
-  if (!Config->Relocatable)
+  // Handle the `--undefined <sym>` options.
+  for (auto *Arg : Args.filtered(OPT_undefined))
+    handleUndefined(Arg->getValue());
+
+  if (!Config->Relocatable) {
+    // Add synthetic dummies for weak undefined functions.
     handleWeakUndefines();
 
+    if (!Config->Entry.empty()) {
+      EntrySym = handleUndefined(Config->Entry);
+      if (!EntrySym)
+        error("entry symbol not defined (pass --no-entry to supress): " +
+              Config->Entry);
+    }
+
+    // Make sure we have resolved all symbols.
+    if (!Config->AllowUndefined)
+      Symtab->reportRemainingUndefines();
+  }
+
+  if (errorCount())
+    return;
+
   // Handle --export.
   for (auto *Arg : Args.filtered(OPT_export)) {
     StringRef Name = Arg->getValue();
@@ -504,27 +519,6 @@ void LinkerDriver::link(ArrayRef<const c
   if (errorCount())
     return;
 
-  // Make sure we have resolved all symbols.
-  if (!Config->Relocatable && !Config->AllowUndefined) {
-    Symtab->reportRemainingUndefines();
-  } else {
-    // Even when using --allow-undefined we still want to report the absence of
-    // our initial set of undefined symbols (i.e. the entry point and symbols
-    // specified via --undefined).
-    // Part of the reason for this is that these function don't have signatures
-    // so which means they cannot be written as wasm function imports.
-    for (auto *Arg : Args.filtered(OPT_undefined)) {
-      Symbol *Sym = Symtab->find(Arg->getValue());
-      if (!Sym->isDefined())
-        error("symbol forced with --undefined not found: " + Sym->getName());
-    }
-    if (EntrySym && !EntrySym->isDefined())
-      error("entry symbol not defined (pass --no-entry to supress): " +
-            EntrySym->getName());
-  }
-  if (errorCount())
-    return;
-
   if (EntrySym)
     EntrySym->setHidden(false);
 

Modified: lld/trunk/wasm/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/SymbolTable.cpp?rev=338938&r1=338937&r2=338938&view=diff
==============================================================================
--- lld/trunk/wasm/SymbolTable.cpp (original)
+++ lld/trunk/wasm/SymbolTable.cpp Fri Aug  3 17:04:06 2018
@@ -60,7 +60,6 @@ void SymbolTable::addCombinedLTOObject()
 }
 
 void SymbolTable::reportRemainingUndefines() {
-  SetVector<Symbol *> Undefs;
   for (Symbol *Sym : SymVector) {
     if (!Sym->isUndefined() || Sym->isWeak())
       continue;
@@ -68,20 +67,8 @@ void SymbolTable::reportRemainingUndefin
       continue;
     if (!Sym->IsUsedInRegularObj)
       continue;
-    Undefs.insert(Sym);
+    error(toString(Sym->getFile()) + ": undefined symbol: " + toString(*Sym));
   }
-
-  if (Undefs.empty())
-    return;
-
-  for (ObjFile *File : ObjectFiles)
-    for (Symbol *Sym : File->getSymbols())
-      if (Undefs.count(Sym))
-        error(toString(File) + ": undefined symbol: " + toString(*Sym));
-
-  for (Symbol *Sym : Undefs)
-    if (!Sym->getFile())
-      error("undefined symbol: " + toString(*Sym));
 }
 
 Symbol *SymbolTable::find(StringRef Name) {




More information about the llvm-commits mailing list