[lld] r356310 - [WebAssembly] Error on R_WASM_MEMORY_ADDR relocations against undefined data symbols.

Sam Clegg via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 15 18:18:12 PDT 2019


Author: sbc
Date: Fri Mar 15 18:18:12 2019
New Revision: 356310

URL: http://llvm.org/viewvc/llvm-project?rev=356310&view=rev
Log:
[WebAssembly] Error on R_WASM_MEMORY_ADDR relocations against undefined data symbols.

For these types of relocations an absolute memory address is
required which is not possible for undefined data symbols.  For symbols
that can be undefined at link time (i.e. external data symbols in
shared libraries) a different type of relocation (i.e. via a GOT) will
be needed.

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

Added:
    lld/trunk/test/wasm/undefined-data.ll
Modified:
    lld/trunk/test/wasm/shared.ll
    lld/trunk/wasm/Writer.cpp

Modified: lld/trunk/test/wasm/shared.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/shared.ll?rev=356310&r1=356309&r2=356310&view=diff
==============================================================================
--- lld/trunk/test/wasm/shared.ll (original)
+++ lld/trunk/test/wasm/shared.ll Fri Mar 15 18:18:12 2019
@@ -13,10 +13,12 @@ entry:
   ; To ensure we use __stack_pointer
   %ptr = alloca i32
   %0 = load i32, i32* @data, align 4
-  %1 = load i32, i32* @data_external, align 4
-  %2 = load i32 ()*, i32 ()** @indirect_func, align 4
-  call i32 %2()
-  ret i32 %1
+  ; TODO(sbc): Re-enable once the codegen supports generating the correct
+  ; relocation type when referencing external data in shared libraries.
+  ; %1 = load i32, i32* @data_external, align 4
+  %1 = load i32 ()*, i32 ()** @indirect_func, align 4
+  call i32 %1()
+  ret i32 %0
 }
 
 declare void @func_external()
@@ -29,7 +31,7 @@ declare void @func_external()
 ; CHECK:      Sections:
 ; CHECK-NEXT:   - Type:            CUSTOM
 ; CHECK-NEXT:     Name:            dylink
-; CHECK-NEXT:     MemorySize:      8
+; CHECK-NEXT:     MemorySize:      12
 ; CHECK-NEXT:     MemoryAlignment: 2
 ; CHECK-NEXT:     TableSize:       2
 ; CHECK-NEXT:     TableAlignment:  0
@@ -62,11 +64,11 @@ declare void @func_external()
 ; CHECK-NEXT:         Kind:            GLOBAL
 ; CHECK-NEXT:         GlobalType:      I32
 ; CHECK-NEXT:         GlobalMutable:   false
-; CHECK-NEXT:       - Module:          env
-; CHECK-NEXT:         Field:           data_external
-; CHECK-NEXT:         Kind:            GLOBAL
-; CHECK-NEXT:         GlobalType:      I32
-; CHECK-NEXT:         GlobalMutable:   true
+; XCHECK-NEXT:       - Module:          env
+; XCHECK-NEXT:         Field:           data_external
+; XCHECK-NEXT:         Kind:            GLOBAL
+; XCHECK-NEXT:         GlobalType:      I32
+; XCHECK-NEXT:         GlobalMutable:   true
 ; CHECK-NEXT:       - Module:          env
 ; CHECK-NEXT:         Field:           func_external
 ; CHECK-NEXT:         Kind:            FUNCTION
@@ -90,4 +92,4 @@ declare void @func_external()
 ; CHECK-NEXT:         Offset:
 ; CHECK-NEXT:           Opcode:          GLOBAL_GET
 ; CHECK-NEXT:           Index:           1
-; CHECK-NEXT:         Content:         '0000000001000000'
+; CHECK-NEXT:         Content:         '020000000000000001000000'

Added: lld/trunk/test/wasm/undefined-data.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/wasm/undefined-data.ll?rev=356310&view=auto
==============================================================================
--- lld/trunk/test/wasm/undefined-data.ll (added)
+++ lld/trunk/test/wasm/undefined-data.ll Fri Mar 15 18:18:12 2019
@@ -0,0 +1,16 @@
+; RUN: llc -filetype=obj %s -o %t.o
+; RUN: not wasm-ld -o %t.wasm %t.o 2>&1 | FileCheck %s -check-prefix=UNDEF
+; RUN: not wasm-ld --allow-undefined -o %t.wasm %t.o 2>&1 | FileCheck %s -check-prefix=BADRELOC
+
+target triple = "wasm32-unknown-unknown"
+
+ at data_external = external global i32
+
+define i32 @_start() {
+entry:
+    %0 = load i32, i32* @data_external, align 4
+    ret i32 %0
+}
+
+; UNDEF: undefined symbol: data_external
+; BADRELOC: undefined-data.ll.tmp.o: relocation of type R_WASM_MEMORY_ADDR_* against undefined data symbol: data_external

Modified: lld/trunk/wasm/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/wasm/Writer.cpp?rev=356310&r1=356309&r2=356310&view=diff
==============================================================================
--- lld/trunk/wasm/Writer.cpp (original)
+++ lld/trunk/wasm/Writer.cpp Fri Mar 15 18:18:12 2019
@@ -66,6 +66,7 @@ private:
 
   void createCtorFunction();
   void calculateInitFunctions();
+  void processRelocations(InputChunk *Chunk);
   void assignIndexes();
   void calculateImports();
   void calculateExports();
@@ -1018,6 +1019,43 @@ void Writer::calculateTypes() {
     registerType(E->Signature);
 }
 
+void Writer::processRelocations(InputChunk *Chunk) {
+  if (!Chunk->Live)
+    return;
+  ObjFile *File = Chunk->File;
+  ArrayRef<WasmSignature> Types = File->getWasmObj()->types();
+  for (const WasmRelocation &Reloc : Chunk->getRelocations()) {
+    switch (Reloc.Type) {
+    case R_WASM_TABLE_INDEX_I32:
+    case R_WASM_TABLE_INDEX_SLEB: {
+      FunctionSymbol *Sym = File->getFunctionSymbol(Reloc.Index);
+      if (Sym->hasTableIndex() || !Sym->hasFunctionIndex())
+        continue;
+      Sym->setTableIndex(TableBase + IndirectFunctions.size());
+      IndirectFunctions.emplace_back(Sym);
+      break;
+    }
+    case R_WASM_TYPE_INDEX_LEB:
+      // Mark target type as live
+      File->TypeMap[Reloc.Index] = registerType(Types[Reloc.Index]);
+      File->TypeIsUsed[Reloc.Index] = true;
+      break;
+    case R_WASM_MEMORY_ADDR_SLEB:
+    case R_WASM_MEMORY_ADDR_I32:
+    case R_WASM_MEMORY_ADDR_LEB: {
+      DataSymbol *DataSym = File->getDataSymbol(Reloc.Index);
+      if (!Config->Relocatable && !isa<DefinedData>(DataSym) &&
+          !DataSym->isWeak())
+        error(File->getName() +
+              ": relocation of type R_WASM_MEMORY_ADDR_* "
+              "against undefined data symbol: " +
+              DataSym->getName());
+      break;
+    }
+    }
+  }
+}
+
 void Writer::assignIndexes() {
   assert(InputFunctions.empty());
   uint32_t FunctionIndex = NumImportedFunctions;
@@ -1037,36 +1075,14 @@ void Writer::assignIndexes() {
       AddDefinedFunction(Func);
   }
 
-  uint32_t TableIndex = TableBase;
-  auto HandleRelocs = [&](InputChunk *Chunk) {
-    if (!Chunk->Live)
-      return;
-    ObjFile *File = Chunk->File;
-    ArrayRef<WasmSignature> Types = File->getWasmObj()->types();
-    for (const WasmRelocation &Reloc : Chunk->getRelocations()) {
-      if (Reloc.Type == R_WASM_TABLE_INDEX_I32 ||
-          Reloc.Type == R_WASM_TABLE_INDEX_SLEB) {
-        FunctionSymbol *Sym = File->getFunctionSymbol(Reloc.Index);
-        if (Sym->hasTableIndex() || !Sym->hasFunctionIndex())
-          continue;
-        Sym->setTableIndex(TableIndex++);
-        IndirectFunctions.emplace_back(Sym);
-      } else if (Reloc.Type == R_WASM_TYPE_INDEX_LEB) {
-        // Mark target type as live
-        File->TypeMap[Reloc.Index] = registerType(Types[Reloc.Index]);
-        File->TypeIsUsed[Reloc.Index] = true;
-      }
-    }
-  };
-
   for (ObjFile *File : Symtab->ObjectFiles) {
     LLVM_DEBUG(dbgs() << "Handle relocs: " << File->getName() << "\n");
     for (InputChunk *Chunk : File->Functions)
-      HandleRelocs(Chunk);
+      processRelocations(Chunk);
     for (InputChunk *Chunk : File->Segments)
-      HandleRelocs(Chunk);
+      processRelocations(Chunk);
     for (auto &P : File->CustomSections)
-      HandleRelocs(P);
+      processRelocations(P);
   }
 
   assert(InputGlobals.empty());




More information about the llvm-commits mailing list