[llvm] r321384 - [WebAssembly] MC: Fix for address taken aliases

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 22 12:31:39 PST 2017


Author: sbc
Date: Fri Dec 22 12:31:39 2017
New Revision: 321384

URL: http://llvm.org/viewvc/llvm-project?rev=321384&view=rev
Log:
[WebAssembly] MC: Fix for address taken aliases

Previously, taking the address for an alias would result in:
 "Symbol not found in table index space"

Increase test coverage for weak aliases.

This code should be more efficient too as it avoids building
the `IsAddressTaken` set.

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

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=321384&r1=321383&r2=321384&view=diff
==============================================================================
--- llvm/trunk/lib/MC/WasmObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/WasmObjectWriter.cpp Fri Dec 22 12:31:39 2017
@@ -553,7 +553,7 @@ uint32_t WasmObjectWriter::getRelocation
   case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
   case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
     if (!IndirectSymbolIndices.count(RelEntry.Symbol))
-      report_fatal_error("symbol not found table index space: " +
+      report_fatal_error("symbol not found in table index space: " +
                          RelEntry.Symbol->getName());
     return IndirectSymbolIndices[RelEntry.Symbol];
   case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
@@ -562,7 +562,7 @@ uint32_t WasmObjectWriter::getRelocation
   case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
   case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
     if (!SymbolIndices.count(RelEntry.Symbol))
-      report_fatal_error("symbol not found function/global index space: " +
+      report_fatal_error("symbol not found in function/global index space: " +
                          RelEntry.Symbol->getName());
     return SymbolIndices[RelEntry.Symbol];
   case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB:
@@ -994,33 +994,10 @@ void WasmObjectWriter::writeObject(MCAss
   SmallVector<WasmExport, 4> Exports;
   SmallVector<std::pair<StringRef, uint32_t>, 4> SymbolFlags;
   SmallVector<std::pair<uint16_t, uint32_t>, 2> InitFuncs;
-  SmallPtrSet<const MCSymbolWasm *, 4> IsAddressTaken;
   unsigned NumFuncImports = 0;
   SmallVector<WasmDataSegment, 4> DataSegments;
   uint32_t DataSize = 0;
 
-  // Populate the IsAddressTaken set.
-  for (const WasmRelocationEntry &RelEntry : CodeRelocations) {
-    switch (RelEntry.Type) {
-    case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
-    case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
-      IsAddressTaken.insert(RelEntry.Symbol);
-      break;
-    default:
-      break;
-    }
-  }
-  for (const WasmRelocationEntry &RelEntry : DataRelocations) {
-    switch (RelEntry.Type) {
-    case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
-    case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
-      IsAddressTaken.insert(RelEntry.Symbol);
-      break;
-    default:
-      break;
-    }
-  }
-
   // In the special .global_variables section, we've encoded global
   // variables used by the function. Translate them into the Globals
   // list.
@@ -1217,14 +1194,7 @@ void WasmObjectWriter::writeObject(MCAss
       }
 
       DEBUG(dbgs() << "  -> function index: " << Index << "\n");
-
-      // If needed, prepare the function to be called indirectly.
-      if (IsAddressTaken.count(&WS) != 0) {
-        IndirectSymbolIndices[&WS] = TableElems.size();
-        DEBUG(dbgs() << "  -> adding to table: " << TableElems.size() << "\n");
-        TableElems.push_back(Index);
-      }
-    } else {
+   } else {
       if (WS.isTemporary() && !WS.getSize())
         continue;
 
@@ -1288,7 +1258,6 @@ void WasmObjectWriter::writeObject(MCAss
     uint32_t Index = SymbolIndices.find(ResolvedSym)->second;
     DEBUG(dbgs() << "  -> index:" << Index << "\n");
 
-    //SymbolIndices[&WS] = Index;
     WasmExport Export;
     Export.FieldName = WS.getName();
     Export.Index = Index;
@@ -1303,12 +1272,34 @@ void WasmObjectWriter::writeObject(MCAss
       SymbolFlags.emplace_back(WS.getName(), wasm::WASM_SYMBOL_BINDING_LOCAL);
   }
 
-  // Add types for indirect function calls.
-  for (const WasmRelocationEntry &Fixup : CodeRelocations) {
-    if (Fixup.Type != wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB)
-      continue;
+  {
+    auto HandleReloc = [&](const WasmRelocationEntry &Rel) {
+      // Functions referenced by a relocation need to prepared to be called
+      // indirectly.
+      const MCSymbolWasm& WS = *Rel.Symbol;
+      if (WS.isFunction() && IndirectSymbolIndices.count(&WS) == 0) {
+        switch (Rel.Type) {
+        case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
+        case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
+        case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
+        case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB: {
+          uint32_t Index = SymbolIndices.find(&WS)->second;
+          IndirectSymbolIndices[&WS] = TableElems.size();
+          DEBUG(dbgs() << "  -> adding to table: " << TableElems.size() << "\n");
+          TableElems.push_back(Index);
+          registerFunctionType(WS);
+          break;
+        }
+        default:
+          break;
+        }
+      }
+    };
 
-    registerFunctionType(*Fixup.Symbol);
+    for (const WasmRelocationEntry &RelEntry : CodeRelocations)
+      HandleReloc(RelEntry);
+    for (const WasmRelocationEntry &RelEntry : DataRelocations)
+      HandleReloc(RelEntry);
   }
 
   // Translate .init_array section contents into start functions.

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=321384&r1=321383&r2=321384&view=diff
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/weak-alias.ll (original)
+++ llvm/trunk/test/MC/WebAssembly/weak-alias.ll Fri Dec 22 12:31:39 2017
@@ -8,21 +8,41 @@
 
 @bar = global i32 7, align 8
 @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
 
+ at direct_address = global i32()* @foo, align 8
+ at alias_address = global i32()* @foo_alias, align 8
+
+define hidden i32 @foo() #0 {
+entry:
+  ret i32 0
+}
+
+define hidden i32 @call_direct() #0 {
+entry:
+  %call = call i32 @foo()
+  ret i32 %call
+}
+
 define hidden i32 @call_alias() #0 {
 entry:
   %call = call i32 @foo_alias()
   ret i32 %call
 }
 
-define hidden i32 @foo() #0 {
+define hidden i32 @call_direct_ptr() #0 {
 entry:
-  ret i32 0
+  %0 = load i32 ()*, i32 ()** @direct_address, align 8
+  %call = call i32 %0()
+  ret i32 %call
 }
 
+define hidden i32 @call_alias_ptr() #0 {
+entry:
+  %0 = load i32 ()*, i32 ()** @alias_address, align 8
+  %call = call i32 %0()
+  ret i32 %call
+}
 
 ; CHECK:        - Type:            TYPE
 ; CHECK-NEXT:     Signatures:      
@@ -42,7 +62,7 @@ entry:
 ; CHECK-NEXT:         Table:
 ; CHECK-NEXT:           ElemType:        ANYFUNC
 ; CHECK-NEXT:           Limits:
-; CHECK-NEXT:             Initial:         0x00000000
+; CHECK-NEXT:             Initial:         0x00000002
 ; CHECK-NEXT:       - Module:          env
 ; CHECK-NEXT:         Field:           foo_alias
 ; CHECK-NEXT:         Kind:            FUNCTION
@@ -53,54 +73,101 @@ entry:
 ; CHECK-NEXT:         GlobalType:      I32
 ; CHECK-NEXT:         GlobalMutable:   false
 ; CHECK-NEXT:   - Type:            FUNCTION
-; CHECK-NEXT:     FunctionTypes:   [ 0, 0 ]
+; CHECK-NEXT:     FunctionTypes:   [ 0, 0, 0, 0, 0 ]
 ; CHECK-NEXT:   - Type:            GLOBAL
 ; CHECK-NEXT:     Globals:         
 ; CHECK-NEXT:       - Type:            I32
 ; CHECK-NEXT:         Mutable:         false
 ; CHECK-NEXT:         InitExpr:        
 ; CHECK-NEXT:           Opcode:          I32_CONST
-; CHECK-NEXT:           Value:           0
+; CHECK-NEXT:           Value:           8
 ; CHECK-NEXT:       - Type:            I32
 ; CHECK-NEXT:         Mutable:         false
 ; CHECK-NEXT:         InitExpr:        
 ; CHECK-NEXT:           Opcode:          I32_CONST
-; CHECK-NEXT:           Value:           8
+; CHECK-NEXT:           Value:           16
+; CHECK-NEXT:       - Type:            I32
+; CHECK-NEXT:         Mutable:         false
+; CHECK-NEXT:         InitExpr:        
+; CHECK-NEXT:           Opcode:          I32_CONST
+; CHECK-NEXT:           Value:           0
 ; CHECK-NEXT:   - Type:            EXPORT
 ; CHECK-NEXT:     Exports:         
-; CHECK-NEXT:       - Name:            call_alias
+; CHECK-NEXT:       - Name:            foo
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Index:           1
-; CHECK-NEXT:       - Name:            foo
+; CHECK-NEXT:       - Name:            call_direct
 ; CHECK-NEXT:         Kind:            FUNCTION
 ; CHECK-NEXT:         Index:           2
-; CHECK-NEXT:       - Name:            bar
+; CHECK-NEXT:       - Name:            call_alias
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Index:           3
+; CHECK-NEXT:       - Name:            call_direct_ptr
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Index:           4
+; CHECK-NEXT:       - Name:            direct_address
 ; CHECK-NEXT:         Kind:            GLOBAL
 ; CHECK-NEXT:         Index:           1
-; CHECK-NEXT:       - Name:            bar_alias_address
+; CHECK-NEXT:       - Name:            call_alias_ptr
+; CHECK-NEXT:         Kind:            FUNCTION
+; CHECK-NEXT:         Index:           5
+; CHECK-NEXT:       - Name:            alias_address
 ; CHECK-NEXT:         Kind:            GLOBAL
 ; CHECK-NEXT:         Index:           2
+; CHECK-NEXT:       - Name:            bar
+; CHECK-NEXT:         Kind:            GLOBAL
+; CHECK-NEXT:         Index:           3
 ; CHECK-NEXT:       - Name:            foo_alias
 ; CHECK-NEXT:         Kind:            FUNCTION
-; CHECK-NEXT:         Index:           2
+; CHECK-NEXT:         Index:           1
 ; CHECK-NEXT:       - Name:            bar_alias
 ; CHECK-NEXT:         Kind:            GLOBAL
-; CHECK-NEXT:         Index:           1
+; CHECK-NEXT:         Index:           3
+; CHECK-NEXT:   - Type:            ELEM
+; CHECK-NEXT:     Segments:        
+; CHECK-NEXT:       - Offset:          
+; CHECK-NEXT:           Opcode:          I32_CONST
+; CHECK-NEXT:           Value:           0
+; CHECK-NEXT:         Functions:       [ 1, 0 ]
 ; CHECK-NEXT:   - Type:            CODE
 ; CHECK-NEXT:     Relocations:     
 ; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_FUNCTION_INDEX_LEB
+; CHECK-NEXT:         Index:           1
+; CHECK-NEXT:         Offset:          0x00000009
+; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_FUNCTION_INDEX_LEB
+; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Offset:          0x00000012
+; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:         Index:           1
+; CHECK-NEXT:         Offset:          0x0000001E
+; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_TYPE_INDEX_LEB
 ; CHECK-NEXT:         Index:           0
-; CHECK-NEXT:         Offset:          0x00000004
+; CHECK-NEXT:         Offset:          0x00000024
+; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_LEB
+; CHECK-NEXT:         Index:           2
+; CHECK-NEXT:         Offset:          0x00000031
+; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_TYPE_INDEX_LEB
+; CHECK-NEXT:         Index:           0
+; CHECK-NEXT:         Offset:          0x00000037
 ; CHECK-NEXT:     Functions:       
 ; CHECK-NEXT:       - Locals:          
+; CHECK-NEXT:         Body:            41000B
+; CHECK-NEXT:       - Locals:          
+; CHECK-NEXT:         Body:            1081808080000B
+; CHECK-NEXT:       - Locals:          
 ; CHECK-NEXT:         Body:            1080808080000B
 ; CHECK-NEXT:       - Locals:          
-; CHECK-NEXT:         Body:            41000B
+; CHECK-NEXT:         Body:            410028028880808000118080808000000B
+; CHECK-NEXT:       - Locals:          
+; CHECK-NEXT:         Body:            410028029080808000118080808000000B
 ; CHECK-NEXT:   - Type:            DATA
 ; CHECK-NEXT:     Relocations:     
-; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_MEMORY_ADDR_I32
+; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_TABLE_INDEX_I32
 ; CHECK-NEXT:         Index:           0
 ; CHECK-NEXT:         Offset:          0x0000000F
+; CHECK-NEXT:       - Type:            R_WEBASSEMBLY_TABLE_INDEX_I32
+; CHECK-NEXT:         Index:           1
+; CHECK-NEXT:         Offset:          0x00000018
 ; CHECK-NEXT:     Segments:        
 ; CHECK-NEXT:       - SectionOffset:   6
 ; CHECK-NEXT:         MemoryIndex:     0
@@ -121,20 +188,32 @@ entry:
 ; CHECK-NEXT:       - Index:           0
 ; CHECK-NEXT:         Name:            foo_alias
 ; CHECK-NEXT:       - Index:           1
-; CHECK-NEXT:         Name:            call_alias
-; CHECK-NEXT:       - Index:           2
 ; CHECK-NEXT:         Name:            foo
+; CHECK-NEXT:       - Index:           2
+; CHECK-NEXT:         Name:            call_direct
+; CHECK-NEXT:       - Index:           3
+; CHECK-NEXT:         Name:            call_alias
+; CHECK-NEXT:       - Index:           4
+; CHECK-NEXT:         Name:            call_direct_ptr
+; CHECK-NEXT:       - Index:           5
+; CHECK-NEXT:         Name:            call_alias_ptr
 ; CHECK-NEXT:   - Type:            CUSTOM
 ; CHECK-NEXT:     Name:            linking
-; CHECK-NEXT:     DataSize:        12
+; CHECK-NEXT:     DataSize:        20
 ; CHECK-NEXT:     SymbolInfo:      
 ; CHECK-NEXT:       - Name:            foo_alias
 ; CHECK-NEXT:         Flags:           [ BINDING_WEAK, VISIBILITY_HIDDEN ]
 ; CHECK-NEXT:       - Name:            bar_alias
 ; CHECK-NEXT:         Flags:           [ BINDING_WEAK, VISIBILITY_HIDDEN ]
+; CHECK-NEXT:       - Name:            foo
+; CHECK-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
+; CHECK-NEXT:       - Name:            call_direct
+; CHECK-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
 ; CHECK-NEXT:       - Name:            call_alias
 ; CHECK-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
-; CHECK-NEXT:       - Name:            foo
+; CHECK-NEXT:       - Name:            call_direct_ptr
+; CHECK-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
+; CHECK-NEXT:       - Name:            call_alias_ptr
 ; CHECK-NEXT:         Flags:           [ VISIBILITY_HIDDEN ]
 ; CHECK-NEXT:     SegmentInfo:    
 ; CHECK-NEXT:       - Index:           0
@@ -142,18 +221,29 @@ entry:
 ; CHECK-NEXT:         Alignment:       8
 ; CHECK-NEXT:         Flags:           [ ]
 ; CHECK-NEXT:       - Index:           1
-; CHECK-NEXT:         Name:            .data.bar_alias_address
+; CHECK-NEXT:         Name:            .data.direct_address
+; CHECK-NEXT:         Alignment:       8
+; CHECK-NEXT:         Flags:           [ ]
+; CHECK-NEXT:       - Index:           2
+; CHECK-NEXT:         Name:            .data.alias_address
 ; CHECK-NEXT:         Alignment:       8
 ; CHECK-NEXT:         Flags:           [ ]
 ; CHECK-NEXT: ...
 
 ; CHECK-SYMS: SYMBOL TABLE:
 ; CHECK-SYMS-NEXT: 00000000 g     F name	foo_alias
-; CHECK-SYMS-NEXT: 00000001 g     F name	call_alias
-; CHECK-SYMS-NEXT: 00000002 g     F name	foo
-; CHECK-SYMS-NEXT: 00000002 gw    F EXPORT	.hidden foo_alias
+; CHECK-SYMS-NEXT: 00000001 g     F name	foo
+; CHECK-SYMS-NEXT: 00000002 g     F name	call_direct
+; CHECK-SYMS-NEXT: 00000003 g     F name	call_alias
+; CHECK-SYMS-NEXT: 00000004 g     F name	call_direct_ptr
+; CHECK-SYMS-NEXT: 00000005 g     F name	call_alias_ptr
+; CHECK-SYMS-NEXT: 00000001 gw    F EXPORT	.hidden foo_alias
 ; CHECK-SYMS-NEXT: 00000000 gw      EXPORT	.hidden bar_alias
-; CHECK-SYMS-NEXT: 00000001 g     F EXPORT	.hidden call_alias
-; CHECK-SYMS-NEXT: 00000002 g     F EXPORT	.hidden foo
+; CHECK-SYMS-NEXT: 00000001 g     F EXPORT	.hidden foo
+; CHECK-SYMS-NEXT: 00000002 g     F EXPORT	.hidden call_direct
+; CHECK-SYMS-NEXT: 00000003 g     F EXPORT	.hidden call_alias
+; CHECK-SYMS-NEXT: 00000004 g     F EXPORT	.hidden call_direct_ptr
+; CHECK-SYMS-NEXT: 00000008 g       EXPORT	direct_address
+; CHECK-SYMS-NEXT: 00000005 g     F EXPORT	.hidden call_alias_ptr
+; CHECK-SYMS-NEXT: 00000010 g       EXPORT	alias_address
 ; CHECK-SYMS-NEXT: 00000000 g       EXPORT	bar
-; CHECK-SYMS-NEXT: 00000008 g       EXPORT	bar_alias_address




More information about the llvm-commits mailing list