[lld] 4157b60 - [WebAssembly] Fixed LLD generation of 64-bit __wasm_apply_data_relocs

Wouter van Oortmerssen via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 15 10:02:20 PDT 2021


Author: Wouter van Oortmerssen
Date: 2021-07-15T10:02:02-07:00
New Revision: 4157b6033d09d17e8492f3bc7c4e050e63501757

URL: https://github.com/llvm/llvm-project/commit/4157b6033d09d17e8492f3bc7c4e050e63501757
DIFF: https://github.com/llvm/llvm-project/commit/4157b6033d09d17e8492f3bc7c4e050e63501757.diff

LOG: [WebAssembly] Fixed LLD generation of 64-bit __wasm_apply_data_relocs

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

Added: 
    

Modified: 
    lld/test/wasm/shared64.s
    lld/wasm/Driver.cpp
    lld/wasm/InputChunks.cpp
    lld/wasm/SyntheticSections.cpp

Removed: 
    


################################################################################
diff  --git a/lld/test/wasm/shared64.s b/lld/test/wasm/shared64.s
index 14553c349c8a7..36528e1031a65 100644
--- a/lld/test/wasm/shared64.s
+++ b/lld/test/wasm/shared64.s
@@ -17,13 +17,13 @@ data:
 
 .section .data.indirect_func_external,"",@
 indirect_func_external:
-  .int32 func_external
-.size indirect_func_external, 4
+  .int64 func_external
+.size indirect_func_external, 8
 
 .section .data.indirect_func,"",@
 indirect_func:
-  .int32 foo
-  .size indirect_func, 4
+  .int64 foo
+  .size indirect_func, 8
 
 # Test data relocations
 
@@ -68,7 +68,8 @@ foo:
   i32.load  0
   local.set 1
   global.get  indirect_func at GOT
-  i32.load  0
+  i64.load  0
+  i32.wrap_i64
   call_indirect  () -> (i32)
   drop
   local.get 0
@@ -128,7 +129,7 @@ get_local_func_address:
 # CHECK:      Sections:
 # CHECK-NEXT:   - Type:            CUSTOM
 # CHECK-NEXT:     Name:            dylink
-# CHECK-NEXT:     MemorySize:      28
+# CHECK-NEXT:     MemorySize:      36
 # CHECK-NEXT:     MemoryAlignment: 2
 # CHECK-NEXT:     TableSize:       2
 # CHECK-NEXT:     TableAlignment:  0
@@ -180,22 +181,22 @@ get_local_func_address:
 # CHECK-NEXT:       - Module:          GOT.mem
 # CHECK-NEXT:         Field:           indirect_func
 # CHECK-NEXT:         Kind:            GLOBAL
-# CHECK-NEXT:         GlobalType:      I32
+# CHECK-NEXT:         GlobalType:      I64
 # CHECK-NEXT:         GlobalMutable:   true
 # CHECK-NEXT:       - Module:          GOT.func
 # CHECK-NEXT:         Field:           func_external
 # CHECK-NEXT:         Kind:            GLOBAL
-# CHECK-NEXT:         GlobalType:      I32
+# CHECK-NEXT:         GlobalType:      I64
 # CHECK-NEXT:         GlobalMutable:   true
 # CHECK-NEXT:       - Module:          GOT.mem
 # CHECK-NEXT:         Field:           data_external
 # CHECK-NEXT:         Kind:            GLOBAL
-# CHECK-NEXT:         GlobalType:      I32
+# CHECK-NEXT:         GlobalType:      I64
 # CHECK-NEXT:         GlobalMutable:   true
 # CHECK-NEXT:       - Module:          GOT.mem
 # CHECK-NEXT:         Field:           extern_struct
 # CHECK-NEXT:         Kind:            GLOBAL
-# CHECK-NEXT:         GlobalType:      I32
+# CHECK-NEXT:         GlobalType:      I64
 # CHECK-NEXT:         GlobalMutable:   true
 # CHECK-NEXT:   - Type:            FUNCTION
 
@@ -224,7 +225,7 @@ get_local_func_address:
 # CHECK-NEXT:         Body:            10020B
 # CHECK-NEXT:       - Index:           2
 # CHECK-NEXT:         Locals:          []
-# CHECK-NEXT:         Body:            230142047C2305360200230142087C230241016A3602002301420C7C230141006A360200230142107C2306370200230142187C230741046A3602000B
+# CHECK-NEXT:         Body:            230142047C23053702002301420C7C230242017C370200230142147C230141006A360200230142187C2306370200230142207C230741046A3602000B
 
 # check the data segment initialized with __memory_base global as offset
 
@@ -235,4 +236,4 @@ get_local_func_address:
 # CHECK-NEXT:         Offset:
 # CHECK-NEXT:           Opcode:          GLOBAL_GET
 # CHECK-NEXT:           Index:           1
-# CHECK-NEXT:         Content:         '02000000000000000100000000000000000000000000000000000000'
+# CHECK-NEXT:         Content:         '020000000000000000000000010000000000000000000000000000000000000000000000'

diff  --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index 206fde64dabb3..7e0c030482fb9 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -621,6 +621,8 @@ static void createSyntheticSymbols() {
       "__wasm_call_ctors", WASM_SYMBOL_VISIBILITY_HIDDEN,
       make<SyntheticFunction>(nullSignature, "__wasm_call_ctors"));
 
+    bool is64 = config->is64.getValueOr(false);
+
   if (config->isPic) {
     WasmSym::stackPointer =
         createUndefinedGlobal("__stack_pointer", config->is64.getValueOr(false)
@@ -631,7 +633,6 @@ static void createSyntheticSymbols() {
     // which to load our static data and function table.
     // See:
     // https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
-    bool is64 = config->is64.getValueOr(false);
     auto *globalType = is64 ? &globalTypeI64 : &globalTypeI32;
     WasmSym::memoryBase = createUndefinedGlobal("__memory_base", globalType);
     WasmSym::tableBase = createUndefinedGlobal("__table_base", globalType);
@@ -657,7 +658,7 @@ static void createSyntheticSymbols() {
     WasmSym::initTLS = symtab->addSyntheticFunction(
         "__wasm_init_tls", WASM_SYMBOL_VISIBILITY_HIDDEN,
         make<SyntheticFunction>(
-            config->is64.getValueOr(false) ? i64ArgSignature : i32ArgSignature,
+            is64 ? i64ArgSignature : i32ArgSignature,
             "__wasm_init_tls"));
   }
 }

diff  --git a/lld/wasm/InputChunks.cpp b/lld/wasm/InputChunks.cpp
index 6912fcda0ba3f..cfd1f56104087 100644
--- a/lld/wasm/InputChunks.cpp
+++ b/lld/wasm/InputChunks.cpp
@@ -39,6 +39,10 @@ bool relocIs64(uint8_t relocType) {
   case R_WASM_MEMORY_ADDR_SLEB64:
   case R_WASM_MEMORY_ADDR_REL_SLEB64:
   case R_WASM_MEMORY_ADDR_I64:
+  case R_WASM_TABLE_INDEX_SLEB64:
+  case R_WASM_TABLE_INDEX_I64:
+  case R_WASM_FUNCTION_OFFSET_I64:
+  case R_WASM_TABLE_INDEX_REL_SLEB64:
     return true;
   default:
     return false;
@@ -355,12 +359,11 @@ void InputChunk::generateRelocationCode(raw_ostream &os) const {
   LLVM_DEBUG(dbgs() << "generating runtime relocations: " << getName()
                     << " count=" << relocations.size() << "\n");
 
-  unsigned opcode_ptr_const = config->is64.getValueOr(false)
-                                  ? WASM_OPCODE_I64_CONST
-                                  : WASM_OPCODE_I32_CONST;
-  unsigned opcode_ptr_add = config->is64.getValueOr(false)
-                                ? WASM_OPCODE_I64_ADD
-                                : WASM_OPCODE_I32_ADD;
+  bool is64 = config->is64.getValueOr(false);
+  unsigned opcode_ptr_const = is64 ? WASM_OPCODE_I64_CONST
+                                   : WASM_OPCODE_I32_CONST;
+  unsigned opcode_ptr_add = is64 ? WASM_OPCODE_I64_ADD
+                                 : WASM_OPCODE_I32_ADD;
 
   uint64_t tombstone = getTombstone();
   // TODO(sbc): Encode the relocations in the data section and write a loop

diff  --git a/lld/wasm/SyntheticSections.cpp b/lld/wasm/SyntheticSections.cpp
index a3d6207bbe61b..96f7f30553161 100644
--- a/lld/wasm/SyntheticSections.cpp
+++ b/lld/wasm/SyntheticSections.cpp
@@ -125,6 +125,8 @@ void ImportSection::writeBody() {
 
   writeUleb128(os, getNumImports(), "import count");
 
+  bool is64 = config->is64.getValueOr(false);
+
   if (config->importMemory) {
     WasmImport import;
     import.Module = defaultModule;
@@ -138,7 +140,7 @@ void ImportSection::writeBody() {
     }
     if (config->sharedMemory)
       import.Memory.Flags |= WASM_LIMITS_FLAG_IS_SHARED;
-    if (config->is64.getValueOr(false))
+    if (is64)
       import.Memory.Flags |= WASM_LIMITS_FLAG_IS_64;
     writeImport(os, import);
   }
@@ -180,7 +182,8 @@ void ImportSection::writeBody() {
   for (const Symbol *sym : gotSymbols) {
     WasmImport import;
     import.Kind = WASM_EXTERNAL_GLOBAL;
-    import.Global = {WASM_TYPE_I32, true};
+    auto ptrType = is64 ? WASM_TYPE_I64 : WASM_TYPE_I32;
+    import.Global = {static_cast<uint8_t>(ptrType), true};
     if (isa<DataSymbol>(sym))
       import.Module = "GOT.mem";
     else
@@ -317,12 +320,11 @@ void GlobalSection::addInternalGOTEntry(Symbol *sym) {
 }
 
 void GlobalSection::generateRelocationCode(raw_ostream &os) const {
-  unsigned opcode_ptr_const = config->is64.getValueOr(false)
-                                  ? WASM_OPCODE_I64_CONST
-                                  : WASM_OPCODE_I32_CONST;
-  unsigned opcode_ptr_add = config->is64.getValueOr(false)
-                                ? WASM_OPCODE_I64_ADD
-                                : WASM_OPCODE_I32_ADD;
+  bool is64 = config->is64.getValueOr(false);
+  unsigned opcode_ptr_const = is64 ? WASM_OPCODE_I64_CONST
+                                   : WASM_OPCODE_I32_CONST;
+  unsigned opcode_ptr_add = is64 ? WASM_OPCODE_I64_ADD
+                                 : WASM_OPCODE_I32_ADD;
 
   for (const Symbol *sym : internalGotSymbols) {
     if (auto *d = dyn_cast<DefinedData>(sym)) {


        


More information about the llvm-commits mailing list