[llvm] r305253 - [WebAssembly] MC: Fix value of R_WEBASSEMBLY_TABLE_INDEX relocations

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 12 16:52:44 PDT 2017


Author: sbc
Date: Mon Jun 12 18:52:44 2017
New Revision: 305253

URL: http://llvm.org/viewvc/llvm-project?rev=305253&view=rev
Log:
[WebAssembly] MC: Fix value of R_WEBASSEMBLY_TABLE_INDEX relocations

Previously we were writing the value function index space
value but for these types of relocations we want to be
writing the table element index space value.

Add a test case for these relocation types that fails
without this change.

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

Added:
    llvm/trunk/test/MC/WebAssembly/func-address.ll
Modified:
    llvm/trunk/lib/MC/WasmObjectWriter.cpp

Modified: llvm/trunk/lib/MC/WasmObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/WasmObjectWriter.cpp?rev=305253&r1=305252&r2=305253&view=diff
==============================================================================
--- llvm/trunk/lib/MC/WasmObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/WasmObjectWriter.cpp Mon Jun 12 18:52:44 2017
@@ -181,7 +181,10 @@ class WasmObjectWriter : public MCObject
   // Index values to use for fixing up call_indirect type indices.
   // Maps function symbols to the index of the type of the function
   DenseMap<const MCSymbolWasm *, uint32_t> TypeIndices;
-
+  // Maps function symbols to the table element index space. Used
+  // for TABLE_INDEX relocation types (i.e. address taken functions).
+  DenseMap<const MCSymbolWasm *, uint32_t> IndirectSymbolIndices;
+  // Maps function/global symbols to the function/global index space.
   DenseMap<const MCSymbolWasm *, uint32_t> SymbolIndices;
 
   DenseMap<WasmFunctionType, int32_t, WasmFunctionTypeDenseMapInfo>
@@ -210,6 +213,7 @@ private:
     DataRelocations.clear();
     TypeIndices.clear();
     SymbolIndices.clear();
+    IndirectSymbolIndices.clear();
     FunctionTypeIndices.clear();
     MCObjectWriter::reset();
   }
@@ -233,7 +237,7 @@ private:
   void writeTypeSection(const SmallVector<WasmFunctionType, 4> &FunctionTypes);
   void writeImportSection(const SmallVector<WasmImport, 4> &Imports);
   void writeFunctionSection(const SmallVector<WasmFunction, 4> &Functions);
-  void writeTableSection(const SmallVector<uint32_t, 4> &TableElems);
+  void writeTableSection(uint32_t NumElements);
   void writeMemorySection(const SmallVector<char, 0> &DataBytes);
   void writeGlobalSection(const SmallVector<WasmGlobal, 4> &Globals);
   void writeExportSection(const SmallVector<WasmExport, 4> &Exports);
@@ -464,9 +468,11 @@ static uint32_t ProvisionalValue(const W
 uint32_t WasmObjectWriter::getRelocationIndexValue(
     const WasmRelocationEntry &RelEntry) {
   switch (RelEntry.Type) {
-  case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
   case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
   case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
+    assert(IndirectSymbolIndices.count(RelEntry.Symbol));
+    return IndirectSymbolIndices[RelEntry.Symbol];
+  case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
   case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_LEB:
   case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_SLEB:
   case wasm::R_WEBASSEMBLY_GLOBAL_ADDR_I32:
@@ -617,21 +623,19 @@ void WasmObjectWriter::writeFunctionSect
   endSection(Section);
 }
 
-void WasmObjectWriter::writeTableSection(
-    const SmallVector<uint32_t, 4> &TableElems) {
+void WasmObjectWriter::writeTableSection(uint32_t NumElements) {
   // For now, always emit the table section, since indirect calls are not
   // valid without it. In the future, we could perhaps be more clever and omit
   // it if there are no indirect calls.
+
   SectionBookkeeping Section;
   startSection(Section, wasm::WASM_SEC_TABLE);
 
-  // The number of tables, fixed to 1 for now.
-  encodeULEB128(1, getStream());
-
-  encodeSLEB128(wasm::WASM_TYPE_ANYFUNC, getStream());
-
-  encodeULEB128(0, getStream());                 // flags
-  encodeULEB128(TableElems.size(), getStream()); // initial
+  encodeULEB128(1, getStream());                       // The number of tables.
+                                                       // Fixed to 1 for now.
+  encodeSLEB128(wasm::WASM_TYPE_ANYFUNC, getStream()); // Type of table
+  encodeULEB128(0, getStream());                       // flags
+  encodeULEB128(NumElements, getStream());             // initial
 
   endSection(Section);
 }
@@ -1072,8 +1076,10 @@ void WasmObjectWriter::writeObject(MCAss
       }
 
       // If needed, prepare the function to be called indirectly.
-      if (IsAddressTaken.count(&WS))
+      if (IsAddressTaken.count(&WS)) {
+        IndirectSymbolIndices[&WS] = TableElems.size();
         TableElems.push_back(Index);
+      }
     } else {
       if (WS.isTemporary() && !WS.getSize())
         continue;
@@ -1180,7 +1186,7 @@ void WasmObjectWriter::writeObject(MCAss
   writeTypeSection(FunctionTypes);
   writeImportSection(Imports);
   writeFunctionSection(Functions);
-  writeTableSection(TableElems);
+  writeTableSection(TableElems.size());
   writeMemorySection(DataBytes);
   writeGlobalSection(Globals);
   writeExportSection(Exports);

Added: llvm/trunk/test/MC/WebAssembly/func-address.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/WebAssembly/func-address.ll?rev=305253&view=auto
==============================================================================
--- llvm/trunk/test/MC/WebAssembly/func-address.ll (added)
+++ llvm/trunk/test/MC/WebAssembly/func-address.ll Mon Jun 12 18:52:44 2017
@@ -0,0 +1,48 @@
+; RUN: llc -mtriple wasm32-unknown-unknown-wasm -O2 -filetype=obj %s -o - | llvm-readobj -r -s -expand-relocs | FileCheck %s
+
+declare i32 @import1()
+declare i32 @import2()
+declare i32 @import3()
+
+; call the imports to make sure they are included in the imports section
+define hidden void @call_imports() #0 {
+entry:
+  %call = call i32 @import1()
+  %call1 = call i32 @import2()
+  ret void
+}
+
+; take the address of the third import.  This should generate a TABLE_INDEX
+; relocation with index of 0 since its the first and only address taken
+; function.
+define hidden void @call_indirect() #0 {
+entry:
+  %adr = alloca i32 ()*, align 4
+  store i32 ()* @import3, i32 ()** %adr, align 4
+  ret void
+}
+
+; CHECK:   Section {
+; CHECK:     Type: ELEM (0x9)
+; CHECK:     Size: 7
+; CHECK:     Offset: 165
+; CHECK:   }
+
+; CHECK: Relocations [
+; CHECK:   Section (9) CODE {
+; CHECK:     Relocation {
+; CHECK:       Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB (0)
+; CHECK:       Offset: 0x4
+; CHECK:       Index: 0x0
+; CHECK:     }
+; CHECK:     Relocation {
+; CHECK:       Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB (0)
+; CHECK:       Offset: 0xB
+; CHECK:       Index: 0x1
+; CHECK:     }
+; CHECK:     Relocation {
+; CHECK:       Type: R_WEBASSEMBLY_TABLE_INDEX_SLEB (1)
+; CHECK:       Offset: 0x1A
+; CHECK:       Index: 0x0
+; CHECK:     }
+; CHECK:   }




More information about the llvm-commits mailing list