[lld] r359207 - [WebAssembly] Always take into account added when applying runtime relocations

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 25 10:11:54 PDT 2019


Author: sbc
Date: Thu Apr 25 10:11:54 2019
New Revision: 359207

URL: http://llvm.org/viewvc/llvm-project?rev=359207&view=rev
Log:
[WebAssembly] Always take into account added when applying runtime relocations

The code we generate for applying data relocations at runtime omitted
the symbols with GOT entries.

Also refactor the code to reduce duplication.

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

Modified:
    lld/trunk/test/wasm/shared.ll
    lld/trunk/wasm/InputChunks.cpp
    lld/trunk/wasm/Symbols.cpp

Modified: lld/trunk/test/wasm/shared.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/shared.ll?rev=359207&r1=359206&r2=359207&view=diff
==============================================================================
--- lld/trunk/test/wasm/shared.ll (original)
+++ lld/trunk/test/wasm/shared.ll Thu Apr 25 10:11:54 2019
@@ -9,8 +9,14 @@ target triple = "wasm32-unknown-unknown"
 @indirect_func = local_unnamed_addr global i32 ()* @foo, align 4
 @indirect_func_external = local_unnamed_addr global void ()* @func_external, align 4
 
+; Test data relocations
 @data_addr = local_unnamed_addr global i32* @data, align 4
+; .. against external symbols
 @data_addr_external = local_unnamed_addr global i32* @data_external, align 4
+; .. including addends
+%struct.s = type { i32, i32 }
+ at extern_struct = external global %struct.s
+ at extern_struct_internal_ptr = local_unnamed_addr global i32* getelementptr inbounds (%struct.s, %struct.s* @extern_struct, i32 0, i32 1), align 4
 
 define hidden i32 @foo() {
 entry:
@@ -46,7 +52,7 @@ declare void @func_external()
 ; CHECK:      Sections:
 ; CHECK-NEXT:   - Type:            CUSTOM
 ; CHECK-NEXT:     Name:            dylink
-; CHECK-NEXT:     MemorySize:      20
+; CHECK-NEXT:     MemorySize:      24
 ; CHECK-NEXT:     MemoryAlignment: 2
 ; CHECK-NEXT:     TableSize:       3
 ; CHECK-NEXT:     TableAlignment:  0
@@ -98,6 +104,11 @@ declare void @func_external()
 ; CHECK-NEXT:         Kind:            GLOBAL
 ; CHECK-NEXT:         GlobalType:      I32
 ; CHECK-NEXT:         GlobalMutable:   true
+; CHECK-NEXT:       - Module:          GOT.mem
+; CHECK-NEXT:         Field:           extern_struct
+; CHECK-NEXT:         Kind:            GLOBAL
+; CHECK-NEXT:         GlobalType:      I32
+; CHECK-NEXT:         GlobalMutable:   true
 ; CHECK-NEXT:   - Type:            FUNCTION
 
 ; CHECK:        - Type:            EXPORT
@@ -125,7 +136,7 @@ declare void @func_external()
 ; CHECK-NEXT:         Body:            10020B
 ; CHECK-NEXT:       - Index:           2
 ; CHECK-NEXT:         Locals:          []
-; CHECK-NEXT:         Body:            230141046A230241016A360200230141086A230241026A3602002301410C6A230141006A360200230141106A23033602000B
+; CHECK-NEXT:         Body:            230141046A230241016A360200230141086A23043602002301410C6A230141006A360200230141106A2303360200230141146A230541046A3602000B
 
 ; check the data segment initialized with __memory_base global as offset
 
@@ -136,4 +147,4 @@ declare void @func_external()
 ; CHECK-NEXT:         Offset:
 ; CHECK-NEXT:           Opcode:          GLOBAL_GET
 ; CHECK-NEXT:           Index:           1
-; CHECK-NEXT:         Content:         '0200000001000000020000000000000000000000'
+; CHECK-NEXT:         Content:         '020000000100000002000000000000000000000000000000'

Modified: lld/trunk/wasm/InputChunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/InputChunks.cpp?rev=359207&r1=359206&r2=359207&view=diff
==============================================================================
--- lld/trunk/wasm/InputChunks.cpp (original)
+++ lld/trunk/wasm/InputChunks.cpp Thu Apr 25 10:11:54 2019
@@ -301,10 +301,19 @@ void InputFunction::writeTo(uint8_t *Buf
 // This is only called when generating shared libaries (PIC) where address are
 // not known at static link time.
 void InputSegment::generateRelocationCode(raw_ostream &OS) const {
+  LLVM_DEBUG(dbgs() << "generating runtime relocations: " << getName()
+                    << " count=" << Relocations.size() << "\n");
+
+  // TODO(sbc): Encode the relocations in the data section and write a loop
+  // here to apply them.
   uint32_t SegmentVA = OutputSeg->StartVA + OutputSegmentOffset;
   for (const WasmRelocation &Rel : Relocations) {
     uint32_t Offset = Rel.Offset - getInputSectionOffset();
-    uint32_t OutputVA = SegmentVA + Offset;
+    uint32_t OutputOffset = SegmentVA + Offset;
+
+    LLVM_DEBUG(dbgs() << "gen reloc: type=" << relocTypeToString(Rel.Type)
+                      << " addend=" << Rel.Addend << " index=" << Rel.Index
+                      << " output offset=" << OutputOffset << "\n");
 
     // Get __memory_base
     writeU8(OS, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
@@ -312,38 +321,28 @@ void InputSegment::generateRelocationCod
 
     // Add the offset of the relocation
     writeU8(OS, WASM_OPCODE_I32_CONST, "I32_CONST");
-    writeSleb128(OS, OutputVA, "offset");
+    writeSleb128(OS, OutputOffset, "offset");
     writeU8(OS, WASM_OPCODE_I32_ADD, "ADD");
 
+    Symbol *Sym = File->getSymbol(Rel);
     // Now figure out what we want to store
-    switch (Rel.Type) {
-    case R_WASM_TABLE_INDEX_I32:
-      // Add the table index to the __table_base
+    if (Sym->hasGOTIndex()) {
       writeU8(OS, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
-      writeUleb128(OS, WasmSym::TableBase->getGlobalIndex(), "table_base");
-      writeU8(OS, WASM_OPCODE_I32_CONST, "CONST");
-      writeSleb128(OS, File->calcNewValue(Rel), "new table index");
-      writeU8(OS, WASM_OPCODE_I32_ADD, "ADD");
-      break;
-    case R_WASM_MEMORY_ADDR_I32: {
-      Symbol *Sym = File->getSymbol(Rel);
-      if (Sym->isLocal() || Sym->isHidden()) {
-        // Hidden/Local data symbols are accessed via known offset from
-        // __memory_base
-        writeU8(OS, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
-        writeUleb128(OS, WasmSym::MemoryBase->getGlobalIndex(), "memory_base");
+      writeUleb128(OS, Sym->getGOTIndex(), "global index");
+      if (Rel.Addend) {
         writeU8(OS, WASM_OPCODE_I32_CONST, "CONST");
-        writeSleb128(OS, File->calcNewValue(Rel), "new memory offset");
+        writeSleb128(OS, Rel.Addend, "addend");
         writeU8(OS, WASM_OPCODE_I32_ADD, "ADD");
-      } else {
-        // Default data symbols are accessed via imported GOT globals
-        writeU8(OS, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
-        writeUleb128(OS, Sym->getGOTIndex(), "global index");
       }
-      break;
-    }
-    default:
-      llvm_unreachable("unexpected relocation type in data segment");
+    } else {
+      const GlobalSymbol* BaseSymbol = WasmSym::MemoryBase;
+      if (Rel.Type == R_WASM_TABLE_INDEX_I32)
+        BaseSymbol = WasmSym::TableBase;
+      writeU8(OS, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
+      writeUleb128(OS, BaseSymbol->getGlobalIndex(), "base");
+      writeU8(OS, WASM_OPCODE_I32_CONST, "CONST");
+      writeSleb128(OS, File->calcNewValue(Rel), "offset");
+      writeU8(OS, WASM_OPCODE_I32_ADD, "ADD");
     }
 
     // Store that value at the virtual address

Modified: lld/trunk/wasm/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Symbols.cpp?rev=359207&r1=359206&r2=359207&view=diff
==============================================================================
--- lld/trunk/wasm/Symbols.cpp (original)
+++ lld/trunk/wasm/Symbols.cpp Thu Apr 25 10:11:54 2019
@@ -97,6 +97,9 @@ void Symbol::setOutputSymbolIndex(uint32
 void Symbol::setGOTIndex(uint32_t Index) {
   LLVM_DEBUG(dbgs() << "setGOTIndex " << Name << " -> " << Index << "\n");
   assert(GOTIndex == INVALID_INDEX);
+  // Any symbol that is assigned a GOT entry must be exported othewise the
+  // dynamic linker won't be able create the entry that contains it.
+  ForceExport = true;
   GOTIndex = Index;
 }
 




More information about the llvm-commits mailing list