[lld] d65ed8c - [lld][WebAssembly] Fix handling of mixed strong and weak references

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 27 14:22:28 PST 2023


Author: Sam Clegg
Date: 2023-02-27T14:20:01-08:00
New Revision: d65ed8cde0a2b595a36f031d65158b08e6421b4f

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

LOG: [lld][WebAssembly] Fix handling of mixed strong and weak references

When adding a undefined symbols to the symbol table, if the existing
reference is weak replace the symbol flags with (potentially) non-weak
binding.

Fixes: https://github.com/llvm/llvm-project/issues/60829

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

Added: 
    lld/test/wasm/Inputs/strong-refs.s

Modified: 
    lld/test/wasm/weak-undefined.s
    lld/wasm/SymbolTable.cpp
    llvm/lib/Object/WasmObjectFile.cpp

Removed: 
    


################################################################################
diff  --git a/lld/test/wasm/Inputs/strong-refs.s b/lld/test/wasm/Inputs/strong-refs.s
new file mode 100644
index 0000000000000..bbf04e1e218ff
--- /dev/null
+++ b/lld/test/wasm/Inputs/strong-refs.s
@@ -0,0 +1,5 @@
+.globl  f2
+f2:
+  .functype f2 () -> (i32)
+  i32.const global_var
+  end_function

diff  --git a/lld/test/wasm/weak-undefined.s b/lld/test/wasm/weak-undefined.s
index 5b8b9775fcea1..e1f551d6d30b6 100644
--- a/lld/test/wasm/weak-undefined.s
+++ b/lld/test/wasm/weak-undefined.s
@@ -1,9 +1,18 @@
+# Test that undefined weak externals (global_var) and (foo) don't cause
+# link failures and resolve to zero.
+
 # RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
 # RUN: wasm-ld -strip-all %t.o -o %t.wasm
 # RUN: obj2yaml %t.wasm | FileCheck %s
 
-# Test that undefined weak externals (global_var) and (foo) don't cause
-# link failures and resolve to zero.
+# Also verify test that strong references in another file do cause link
+# failure (See https://github.com/llvm/llvm-project/issues/60806)
+
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %p/Inputs/strong-refs.s -o %t-strong.o
+# RUN: not wasm-ld -strip-all %t.o %t-strong.o -o %t.wasm 2>&1 | FileCheck --check-prefix=ERROR %s
+# RUN: not wasm-ld -strip-all %t-strong.o %t.o -o %t.wasm 2>&1 | FileCheck --check-prefix=ERROR %s
+
+# ERROR: undefined symbol: global_var
 
 .functype foo () -> (i32)
 
@@ -33,7 +42,6 @@ _start:
 .weak foo
 .weak global_var
 
-
 # CHECK:      --- !WASM
 # CHECK-NEXT: FileHeader:
 # CHECK-NEXT:   Version:         0x1

diff  --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp
index 8ca5e94a2a2a9..d14e9d5c010f1 100644
--- a/lld/wasm/SymbolTable.cpp
+++ b/lld/wasm/SymbolTable.cpp
@@ -548,6 +548,8 @@ Symbol *SymbolTable::addUndefinedFunction(StringRef name,
                           file);
       if (isCalledDirectly)
         existingUndefined->isCalledDirectly = true;
+      if (s->isWeak())
+        s->flags = flags;
     }
   }
 
@@ -574,6 +576,8 @@ Symbol *SymbolTable::addUndefinedData(StringRef name, uint32_t flags,
       lazy->fetch();
   } else if (s->isDefined()) {
     checkDataType(s, file);
+  } else if (s->isWeak()) {
+    s->flags = flags;
   }
   return s;
 }
@@ -599,6 +603,8 @@ Symbol *SymbolTable::addUndefinedGlobal(StringRef name,
     lazy->fetch();
   else if (s->isDefined())
     checkGlobalType(s, file, type);
+  else if (s->isWeak())
+    s->flags = flags;
   return s;
 }
 
@@ -623,6 +629,8 @@ Symbol *SymbolTable::addUndefinedTable(StringRef name,
     lazy->fetch();
   else if (s->isDefined())
     checkTableType(s, file, type);
+  else if (s->isWeak())
+    s->flags = flags;
   return s;
 }
 
@@ -647,6 +655,8 @@ Symbol *SymbolTable::addUndefinedTag(StringRef name,
     lazy->fetch();
   else if (s->isDefined())
     checkTagType(s, file, sig);
+  else if (s->isWeak())
+    s->flags = flags;
   return s;
 }
 

diff  --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp
index 400911d242540..471b68fee432a 100644
--- a/llvm/lib/Object/WasmObjectFile.cpp
+++ b/llvm/lib/Object/WasmObjectFile.cpp
@@ -38,7 +38,18 @@ using namespace object;
 void WasmSymbol::print(raw_ostream &Out) const {
   Out << "Name=" << Info.Name
       << ", Kind=" << toString(wasm::WasmSymbolType(Info.Kind)) << ", Flags=0x"
-      << Twine::utohexstr(Info.Flags);
+      << Twine::utohexstr(Info.Flags) << " [";
+  switch (getBinding()) {
+    case wasm::WASM_SYMBOL_BINDING_GLOBAL: Out << "global"; break;
+    case wasm::WASM_SYMBOL_BINDING_LOCAL: Out << "local"; break;
+    case wasm::WASM_SYMBOL_BINDING_WEAK: Out << "weak"; break;
+  }
+  if (isHidden()) {
+    Out << ", hidden";
+  } else {
+    Out << ", default";
+  }
+  Out << "]";
   if (!isTypeData()) {
     Out << ", ElemIndex=" << Info.ElementIndex;
   } else if (isDefined()) {


        


More information about the llvm-commits mailing list