[lld] r335192 - [WebAssembly] Error on mismatched function signature in final output

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 20 17:12:25 PDT 2018


Author: sbc
Date: Wed Jun 20 17:12:25 2018
New Revision: 335192

URL: http://llvm.org/viewvc/llvm-project?rev=335192&view=rev
Log:
[WebAssembly] Error on mismatched function signature in final output

During symbol resolution, emit warnings for function signature
mismatches.  During GC, if any mismatched symbol is marked as live
then generate an error.

This means that we only error out if the mismatch is written to the
final output.  i.e. if we would generate an invalid wasm file.

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

Modified:
    lld/trunk/test/wasm/fatal-warnings.ll
    lld/trunk/test/wasm/signature-mismatch-weak.ll
    lld/trunk/test/wasm/signature-mismatch.ll
    lld/trunk/wasm/Driver.cpp
    lld/trunk/wasm/MarkLive.cpp
    lld/trunk/wasm/SymbolTable.cpp
    lld/trunk/wasm/Symbols.h

Modified: lld/trunk/test/wasm/fatal-warnings.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/fatal-warnings.ll?rev=335192&r1=335191&r2=335192&view=diff
==============================================================================
--- lld/trunk/test/wasm/fatal-warnings.ll (original)
+++ lld/trunk/test/wasm/fatal-warnings.ll Wed Jun 20 17:12:25 2018
@@ -10,6 +10,11 @@ target triple = "wasm32-unknown-unknown"
 
 define hidden void @_start() local_unnamed_addr #0 {
 entry:
+  ret void
+}
+
+define hidden void @_call_ret32() local_unnamed_addr #0 {
+entry:
   %call = tail call i32 @ret32(i32 1, i64 2, i32 3) #2
   ret void
 }

Modified: lld/trunk/test/wasm/signature-mismatch-weak.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/signature-mismatch-weak.ll?rev=335192&r1=335191&r2=335192&view=diff
==============================================================================
--- lld/trunk/test/wasm/signature-mismatch-weak.ll (original)
+++ lld/trunk/test/wasm/signature-mismatch-weak.ll Wed Jun 20 17:12:25 2018
@@ -1,7 +1,7 @@
 ; RUN: llc -filetype=obj %p/Inputs/weak-symbol1.ll -o %t.weak.o
 ; RUN: llc -filetype=obj %p/Inputs/strong-symbol.ll -o %t.strong.o
 ; RUN: llc -filetype=obj %s -o %t.o
-; RUN: wasm-ld -o %t.wasm %t.o %t.strong.o %t.weak.o 2>&1 | FileCheck %s
+; RUN: not wasm-ld -o %t.wasm %t.o %t.strong.o %t.weak.o 2>&1 | FileCheck %s
 
 target triple = "wasm32-unknown-unknown"
 
@@ -16,3 +16,4 @@ entry:
 ; CHECK: warning: function signature mismatch: weakFn
 ; CHECK-NEXT: >>> defined as () -> I32 in {{.*}}signature-mismatch-weak.ll.tmp.o
 ; CHECK-NEXT: >>> defined as () -> I64 in {{.*}}signature-mismatch-weak.ll.tmp.strong.o
+; CHECK: error: function signature mismatch: weakFn

Modified: lld/trunk/test/wasm/signature-mismatch.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/signature-mismatch.ll?rev=335192&r1=335191&r2=335192&view=diff
==============================================================================
--- lld/trunk/test/wasm/signature-mismatch.ll (original)
+++ lld/trunk/test/wasm/signature-mismatch.ll Wed Jun 20 17:12:25 2018
@@ -1,10 +1,11 @@
 ; RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o
 ; RUN: llc -filetype=obj %s -o %t.main.o
-; RUN: not wasm-ld --fatal-warnings -o %t.wasm %t.main.o %t.ret32.o 2>&1 | FileCheck %s
+; RUN: not wasm-ld -o %t.wasm %t.main.o %t.ret32.o 2>&1 | FileCheck %s
+; RUN: not wasm-ld --no-gc-sections -o %t.wasm %t.main.o %t.ret32.o 2>&1 | FileCheck %s -check-prefix=NO-GC
 ; Run the test again by with the object files in the other order to verify
 ; the check works when the undefined symbol is resolved by an existing defined
 ; one.
-; RUN: not wasm-ld --fatal-warnings -o %t.wasm %t.ret32.o %t.main.o 2>&1 | FileCheck %s -check-prefix=REVERSE
+; RUN: not wasm-ld -o %t.wasm %t.ret32.o %t.main.o 2>&1 | FileCheck %s -check-prefix=REVERSE
 
 target triple = "wasm32-unknown-unknown"
 
@@ -17,10 +18,16 @@ entry:
 
 declare i32 @ret32(i32, i64, i32) local_unnamed_addr #1
 
-; CHECK: error: function signature mismatch: ret32
+; CHECK: warning: function signature mismatch: ret32
 ; CHECK-NEXT: >>> defined as (I32, I64, I32) -> I32 in {{.*}}.main.o
 ; CHECK-NEXT: >>> defined as (F32) -> I32 in {{.*}}.ret32.o
+; CHECK: error: function signature mismatch: ret32
 
-; REVERSE: error: function signature mismatch: ret32
+; NO-GC: error: function signature mismatch: ret32
+; NO-GC-NEXT: >>> defined as (I32, I64, I32) -> I32 in {{.*}}.main.o
+; NO-GC-NEXT: >>> defined as (F32) -> I32 in {{.*}}.ret32.o
+
+; REVERSE: warning: function signature mismatch: ret32
 ; REVERSE-NEXT: >>> defined as (F32) -> I32 in {{.*}}.ret32.o
 ; REVERSE-NEXT: >>> defined as (I32, I64, I32) -> I32 in {{.*}}.main.o
+; REVERSE: error: function signature mismatch: ret32

Modified: lld/trunk/wasm/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Driver.cpp?rev=335192&r1=335191&r2=335192&view=diff
==============================================================================
--- lld/trunk/wasm/Driver.cpp (original)
+++ lld/trunk/wasm/Driver.cpp Wed Jun 20 17:12:25 2018
@@ -483,7 +483,8 @@ void LinkerDriver::link(ArrayRef<const c
     return;
 
   // Do size optimizations: garbage collection
-  markLive();
+  if (Config->GcSections)
+    markLive();
 
   // Write the result to the file.
   writeResult();

Modified: lld/trunk/wasm/MarkLive.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/MarkLive.cpp?rev=335192&r1=335191&r2=335192&view=diff
==============================================================================
--- lld/trunk/wasm/MarkLive.cpp (original)
+++ lld/trunk/wasm/MarkLive.cpp Wed Jun 20 17:12:25 2018
@@ -34,9 +34,6 @@ using namespace lld;
 using namespace lld::wasm;
 
 void lld::wasm::markLive() {
-  if (!Config->GcSections)
-    return;
-
   LLVM_DEBUG(dbgs() << "markLive\n");
   SmallVector<InputChunk *, 256> Q;
 
@@ -44,6 +41,8 @@ void lld::wasm::markLive() {
     if (!Sym || Sym->isLive())
       return;
     Sym->markLive();
+    if (Sym->SignatureMismatch)
+      error("function signature mismatch: " + Sym->getName());
     if (InputChunk *Chunk = Sym->getChunk())
       Q.push_back(Chunk);
   };

Modified: lld/trunk/wasm/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/SymbolTable.cpp?rev=335192&r1=335191&r2=335192&view=diff
==============================================================================
--- lld/trunk/wasm/SymbolTable.cpp (original)
+++ lld/trunk/wasm/SymbolTable.cpp Wed Jun 20 17:12:25 2018
@@ -106,7 +106,7 @@ static void reportTypeError(const Symbol
         " in " + toString(File));
 }
 
-static void checkFunctionType(const Symbol *Existing, const InputFile *File,
+static void checkFunctionType(Symbol *Existing, const InputFile *File,
                               const WasmSignature *NewSig) {
   auto ExistingFunction = dyn_cast<FunctionSymbol>(Existing);
   if (!ExistingFunction) {
@@ -114,12 +114,27 @@ static void checkFunctionType(const Symb
     return;
   }
 
+
   const WasmSignature *OldSig = ExistingFunction->getFunctionType();
   if (OldSig && NewSig && *NewSig != *OldSig) {
-    warn("function signature mismatch: " + Existing->getName() +
-         "\n>>> defined as " + toString(*OldSig) + " in " +
-         toString(Existing->getFile()) + "\n>>> defined as " +
-         toString(*NewSig) + " in " + toString(File));
+    // Don't generate more than one warning per symbol.
+    if (Existing->SignatureMismatch)
+      return;
+    Existing->SignatureMismatch = true;
+
+    std::string msg = ("function signature mismatch: " + Existing->getName() +
+                       "\n>>> defined as " + toString(*OldSig) + " in " +
+                       toString(Existing->getFile()) + "\n>>> defined as " +
+                       toString(*NewSig) + " in " + toString(File))
+                          .str();
+    // A function signature mismatch is only really problem if the mismatched
+    // symbol is included in the final output, and gc-sections can remove the
+    // offending uses.  Therefore we delay reporting this as an error when
+    // section GC is enabled.
+    if (Config->GcSections)
+      warn(msg);
+    else
+      error(msg);
   }
 }
 

Modified: lld/trunk/wasm/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Symbols.h?rev=335192&r1=335191&r2=335192&view=diff
==============================================================================
--- lld/trunk/wasm/Symbols.h (original)
+++ lld/trunk/wasm/Symbols.h Wed Jun 20 17:12:25 2018
@@ -93,11 +93,12 @@ public:
 
   // True if this symbol was referenced by a regular (non-bitcode) object.
   unsigned IsUsedInRegularObj : 1;
+  unsigned SignatureMismatch : 1;
 
 protected:
   Symbol(StringRef Name, Kind K, uint32_t Flags, InputFile *F)
-      : IsUsedInRegularObj(false), Name(Name), SymbolKind(K), Flags(Flags),
-        File(F), Referenced(!Config->GcSections) {}
+      : IsUsedInRegularObj(false), SignatureMismatch(false), Name(Name),
+        SymbolKind(K), Flags(Flags), File(F), Referenced(!Config->GcSections) {}
 
   StringRef Name;
   Kind SymbolKind;
@@ -340,6 +341,7 @@ T *replaceSymbol(Symbol *S, ArgT &&... A
 
   T *S2 = new (S) T(std::forward<ArgT>(Arg)...);
   S2->IsUsedInRegularObj = SymCopy.IsUsedInRegularObj;
+  S2->SignatureMismatch = SymCopy.SignatureMismatch;
   return S2;
 }
 




More information about the llvm-commits mailing list