[llvm] r313381 - [WebAssembly] MC: Fix crash in getProvitionalValue on weak references

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 15 12:22:02 PDT 2017


Author: sbc
Date: Fri Sep 15 12:22:01 2017
New Revision: 313381

URL: http://llvm.org/viewvc/llvm-project?rev=313381&view=rev
Log:
[WebAssembly] MC: Fix crash in getProvitionalValue on weak references

- Create helper function for resolving weak references.
- Add test that preproduces the crash.

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

Modified:
    llvm/trunk/lib/MC/WasmObjectWriter.cpp
    llvm/trunk/test/MC/WebAssembly/weak-alias.ll

Modified: llvm/trunk/lib/MC/WasmObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/WasmObjectWriter.cpp?rev=313381&r1=313380&r2=313381&view=diff
==============================================================================
--- llvm/trunk/lib/MC/WasmObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/WasmObjectWriter.cpp Fri Sep 15 12:22:01 2017
@@ -477,13 +477,22 @@ static void WriteI32(raw_pwrite_stream &
   Stream.pwrite((char *)Buffer, sizeof(Buffer), Offset);
 }
 
+static const MCSymbolWasm* ResolveSymbol(const MCSymbolWasm& Symbol) {
+  if (Symbol.isVariable()) {
+    const MCExpr *Expr = Symbol.getVariableValue();
+    auto *Inner = cast<MCSymbolRefExpr>(Expr);
+    return cast<MCSymbolWasm>(&Inner->getSymbol());
+  }
+  return &Symbol;
+}
+
 // Compute a value to write into the code at the location covered
 // by RelEntry. This value isn't used by the static linker, since
 // we have addends; it just serves to make the code more readable
 // and to make standalone wasm modules directly usable.
 uint32_t
 WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry) {
-  const MCSymbolWasm *Sym = RelEntry.Symbol;
+  const MCSymbolWasm *Sym = ResolveSymbol(*RelEntry.Symbol);
 
   // For undefined symbols, use a hopefully invalid value.
   if (!Sym->isDefined(/*SetUsed=*/false))
@@ -934,16 +943,9 @@ uint32_t WasmObjectWriter::registerFunct
   assert(Symbol.isFunction());
 
   WasmFunctionType F;
-  if (Symbol.isVariable()) {
-    const MCExpr *Expr = Symbol.getVariableValue();
-    auto *Inner = cast<MCSymbolRefExpr>(Expr);
-    const auto *ResolvedSym = cast<MCSymbolWasm>(&Inner->getSymbol());
-    F.Returns = ResolvedSym->getReturns();
-    F.Params = ResolvedSym->getParams();
-  } else {
-    F.Returns = Symbol.getReturns();
-    F.Params = Symbol.getParams();
-  }
+  const MCSymbolWasm* ResolvedSym = ResolveSymbol(Symbol);
+  F.Returns = ResolvedSym->getReturns();
+  F.Params = ResolvedSym->getParams();
 
   auto Pair =
       FunctionTypeIndices.insert(std::make_pair(F, FunctionTypes.size()));
@@ -1255,11 +1257,9 @@ void WasmObjectWriter::writeObject(MCAss
       continue;
     assert(S.isDefined(/*SetUsed=*/false));
 
-    const auto &WS = static_cast<const MCSymbolWasm &>(S);
     // Find the target symbol of this weak alias and export that index
-    const MCExpr *Expr = WS.getVariableValue();
-    auto *Inner = cast<MCSymbolRefExpr>(Expr);
-    const auto *ResolvedSym = cast<MCSymbolWasm>(&Inner->getSymbol());
+    const auto &WS = static_cast<const MCSymbolWasm &>(S);
+    const MCSymbolWasm *ResolvedSym = ResolveSymbol(WS);
     DEBUG(dbgs() << WS.getName() << ": weak alias of '" << *ResolvedSym << "'\n");
     assert(SymbolIndices.count(ResolvedSym) > 0);
     uint32_t Index = SymbolIndices.find(ResolvedSym)->second;

Modified: llvm/trunk/test/MC/WebAssembly/weak-alias.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/weak-alias.ll?rev=313381&r1=313380&r2=313381&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/weak-alias.ll (original)
+++ llvm/trunk/test/MC/WebAssembly/weak-alias.ll Fri Sep 15 12:22:01 2017
@@ -1,8 +1,13 @@
 ; RUN: llc -mtriple wasm32-unknown-unknown-wasm -filetype=obj %s -o - | obj2yaml | FileCheck %s
 
-; foo_alias() function is weak alias of function foo()
+; 'foo_alias()' is weak alias of function 'foo()'
+; 'bar_alias' is weak alias of global variable 'bar'
 ; Generates two exports of the same function, one of them weak
 
+ at bar = global i32 7, align 8
+ at bar_alias = weak hidden alias i32, i32* @bar
+ at bar_alias_address = global i32* @bar_alias, align 8
+
 @foo_alias = weak hidden alias i32 (), i32 ()* @foo
 
 define hidden i32 @call_alias() #0 {
@@ -29,6 +34,11 @@ entry:
 ; CHECK-NEXT:         Field:           foo_alias
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         SigIndex:        0
+; CHECK-NEXT:       - Module:          env
+; CHECK-NEXT:         Field:           bar_alias
+; CHECK-NEXT:         Kind:            GLOBAL
+; CHECK-NEXT:         GlobalType:      I32
+; CHECK-NEXT:         GlobalMutable:   false
 
 ; CHECK:        - Type:            FUNCTION
 ; CHECK-NEXT:     FunctionTypes:   [ 0, 0 ]
@@ -41,9 +51,37 @@ entry:
 ; CHECK-NEXT:       - Name:            foo
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Index:           2
+; CHECK-NEXT:       - Name:            bar
+; CHECK-NEXT:         Kind:            GLOBAL
+; CHECK-NEXT:         Index:           1
+; CHECK-NEXT:       - Name:            bar_alias_address
+; CHECK-NEXT:         Kind:            GLOBAL
+; CHECK-NEXT:         Index:           2
 ; CHECK-NEXT:       - Name:            foo_alias
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Index:           2
+; CHECK-NEXT:       - Name:            bar_alias
+; CHECK-NEXT:         Kind:            GLOBAL
+; CHECK-NEXT:         Index:           1
+
+; CHECK:        - Type:            DATA
+; CHECK-NEXT:     Relocations:     
+; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_I32
+; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Offset:          0x0000000F
+; CHECK-NEXT:     Segments:        
+; CHECK-NEXT:       - SectionOffset:   6
+; CHECK-NEXT:         MemoryIndex:     0
+; CHECK-NEXT:         Offset:          
+; CHECK-NEXT:           Opcode:          I32_CONST
+; CHECK-NEXT:           Value:           0
+; CHECK-NEXT:         Content:         '07000000'
+; CHECK-NEXT:       - SectionOffset:   15
+; CHECK-NEXT:         MemoryIndex:     0
+; CHECK-NEXT:         Offset:          
+; CHECK-NEXT:           Opcode:          I32_CONST
+; CHECK-NEXT:           Value:           8
+; CHECK-NEXT:         Content:         '00000000'
 
 ; CHECK:        - Type:            CUSTOM
 ; CHECK-NEXT:     Name:            name
@@ -56,9 +94,11 @@ entry:
 ; CHECK-NEXT:         Name:            foo
 ; CHECK-NEXT:   - Type:            CUSTOM
 ; CHECK-NEXT:     Name:            linking
-; CHECK-NEXT:     DataSize:        0
-; CHECK-NEXT:     DataAlignment:   0
+; CHECK-NEXT:     DataSize:        12
+; CHECK-NEXT:     DataAlignment:   8
 ; CHECK-NEXT:     SymbolInfo:      
 ; CHECK-NEXT:       - Name:            foo_alias
 ; CHECK-NEXT:         Flags:           1
+; CHECK-NEXT:       - Name:            bar_alias
+; CHECK-NEXT:         Flags:           1
 ; CHECK-NEXT: ...




More information about the llvm-commits mailing list