[lld] b34ec59 - [lld][WebAssembly] Handle weakly referenced symbols when lazy (archive) version is see first

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 10 08:17:07 PDT 2020


Author: Sam Clegg
Date: 2020-08-10T08:16:55-07:00
New Revision: b34ec5969f1ad27f48ebc0d35a3fe37e810a8a32

URL: https://github.com/llvm/llvm-project/commit/b34ec5969f1ad27f48ebc0d35a3fe37e810a8a32
DIFF: https://github.com/llvm/llvm-project/commit/b34ec5969f1ad27f48ebc0d35a3fe37e810a8a32.diff

LOG: [lld][WebAssembly] Handle weakly referenced symbols when lazy (archive) version is see first

When a weak reference of a lazy symbol occurs we were not correctly
updating the lazy symbol.  We need to tag the existing lazy symbol
as weak and, in the case of a function symbol, give it a signature.

Without the signature we can't then create the dummy function which
is needed when an weakly undefined function is called.

We had tests for weakly referenced lazy symbols but we were only
tests in the case where the reference was seen before the lazy
symbol.

See: https://github.com/WebAssembly/wasi-libc/pull/214

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

Added: 
    

Modified: 
    lld/test/wasm/archive-weak-undefined.ll
    lld/wasm/SymbolTable.cpp
    lld/wasm/Symbols.cpp
    lld/wasm/Symbols.h

Removed: 
    


################################################################################
diff  --git a/lld/test/wasm/archive-weak-undefined.ll b/lld/test/wasm/archive-weak-undefined.ll
index 530ff8aeb6183..9539cf91af36a 100644
--- a/lld/test/wasm/archive-weak-undefined.ll
+++ b/lld/test/wasm/archive-weak-undefined.ll
@@ -1,4 +1,4 @@
-; Test that weak undefined symbols do not fetch members from archive files.
+;; Test that weak undefined symbols do not fetch members from archive files.
 ; RUN: llc -filetype=obj %s -o %t.o
 ; RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %p/Inputs/ret32.s -o %t.ret32.o
 ; RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %p/Inputs/hello.s -o %t.hello.o
@@ -8,6 +8,10 @@
 ; RUN: wasm-ld %t.o %t.a -o %t.wasm
 ; RUN: obj2yaml %t.wasm | FileCheck %s
 
+;; Also test with the library symbols being read first
+; RUN: wasm-ld %t.a %t.o -o %t2.wasm
+; RUN: obj2yaml %t2.wasm | FileCheck %s
+
 ; RUN: wasm-ld -u hello_str %t.o %t.a -o %t2.wasm
 ; RUN: obj2yaml %t2.wasm | FileCheck %s -check-prefix=CHECK-DATA
 

diff  --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp
index f233646cbb651..b3cb87c8ef174 100644
--- a/lld/wasm/SymbolTable.cpp
+++ b/lld/wasm/SymbolTable.cpp
@@ -458,11 +458,16 @@ Symbol *SymbolTable::addUndefinedFunction(StringRef name,
                                      file, sig, isCalledDirectly);
   };
 
-  if (wasInserted)
+  if (wasInserted) {
     replaceSym();
-  else if (auto *lazy = dyn_cast<LazySymbol>(s))
-    lazy->fetch();
-  else {
+  } else if (auto *lazy = dyn_cast<LazySymbol>(s)) {
+    if ((flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK) {
+      lazy->setWeak();
+      lazy->signature = sig;
+    } else {
+      lazy->fetch();
+    }
+  } else {
     auto existingFunction = dyn_cast<FunctionSymbol>(s);
     if (!existingFunction) {
       reportTypeError(s, file, WASM_SYMBOL_TYPE_FUNCTION);
@@ -499,12 +504,16 @@ Symbol *SymbolTable::addUndefinedData(StringRef name, uint32_t flags,
   if (s->traced)
     printTraceSymbolUndefined(name, file);
 
-  if (wasInserted)
+  if (wasInserted) {
     replaceSymbol<UndefinedData>(s, name, flags, file);
-  else if (auto *lazy = dyn_cast<LazySymbol>(s))
-    lazy->fetch();
-  else if (s->isDefined())
+  } else if (auto *lazy = dyn_cast<LazySymbol>(s)) {
+    if ((flags & WASM_SYMBOL_BINDING_MASK) == WASM_SYMBOL_BINDING_WEAK)
+      lazy->setWeak();
+    else
+      lazy->fetch();
+  } else if (s->isDefined()) {
     checkDataType(s, file);
+  }
   return s;
 }
 

diff  --git a/lld/wasm/Symbols.cpp b/lld/wasm/Symbols.cpp
index 33923fb3e9f4b..4b40f95ed52db 100644
--- a/lld/wasm/Symbols.cpp
+++ b/lld/wasm/Symbols.cpp
@@ -339,6 +339,10 @@ const OutputSectionSymbol *SectionSymbol::getOutputSectionSymbol() const {
 
 void LazySymbol::fetch() { cast<ArchiveFile>(file)->addMember(&archiveSymbol); }
 
+void LazySymbol::setWeak() {
+  flags |= (flags & ~WASM_SYMBOL_BINDING_MASK) | WASM_SYMBOL_BINDING_WEAK;
+}
+
 MemoryBufferRef LazySymbol::getMemberBuffer() {
   Archive::Child c =
       CHECK(archiveSymbol.getMember(),

diff  --git a/lld/wasm/Symbols.h b/lld/wasm/Symbols.h
index 9588a5595206c..73f555217f260 100644
--- a/lld/wasm/Symbols.h
+++ b/lld/wasm/Symbols.h
@@ -411,6 +411,7 @@ class LazySymbol : public Symbol {
 
   static bool classof(const Symbol *s) { return s->kind() == LazyKind; }
   void fetch();
+  void setWeak();
   MemoryBufferRef getMemberBuffer();
 
   // Lazy symbols can have a signature because they can replace an


        


More information about the llvm-commits mailing list