[PATCH] D85567: Handle undefined weak sumbols even when lazy version is loaded first

Sam Clegg via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 7 16:15:49 PDT 2020


sbc100 created this revision.
Herald added subscribers: llvm-commits, sunfish, dschuff.
Herald added a project: LLVM.
sbc100 requested review of this revision.
Herald added a subscriber: aheejin.

When a weak reference of a lazy synmbol 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


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D85567

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


Index: lld/wasm/Symbols.h
===================================================================
--- lld/wasm/Symbols.h
+++ lld/wasm/Symbols.h
@@ -411,6 +411,7 @@
 
   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
Index: lld/wasm/Symbols.cpp
===================================================================
--- lld/wasm/Symbols.cpp
+++ lld/wasm/Symbols.cpp
@@ -339,6 +339,10 @@
 
 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(),
Index: lld/wasm/SymbolTable.cpp
===================================================================
--- lld/wasm/SymbolTable.cpp
+++ lld/wasm/SymbolTable.cpp
@@ -458,11 +458,16 @@
                                      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 @@
   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;
 }
 
Index: lld/test/wasm/archive-weak-undefined.ll
===================================================================
--- lld/test/wasm/archive-weak-undefined.ll
+++ 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
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D85567.284086.patch
Type: text/x-patch
Size: 3137 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200807/aee078fd/attachment.bin>


More information about the llvm-commits mailing list