summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Clegg <sbc@chromium.org>2019-03-16 01:18:12 +0000
committerSam Clegg <sbc@chromium.org>2019-03-16 01:18:12 +0000
commit632c217921c094b983bc54b5b18e3cd9b9a7fb1a (patch)
tree65dfb497cdd2b14a3a7ea043d620393c4399745e
parent7097e83dab7af66b02408df656afeae014e46711 (diff)
downloadbcm5719-llvm-632c217921c094b983bc54b5b18e3cd9b9a7fb1a.tar.gz
bcm5719-llvm-632c217921c094b983bc54b5b18e3cd9b9a7fb1a.zip
[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 llvm-svn: 356310
-rw-r--r--lld/test/wasm/shared.ll24
-rw-r--r--lld/test/wasm/undefined-data.ll16
-rw-r--r--lld/wasm/Writer.cpp66
3 files changed, 70 insertions, 36 deletions
diff --git a/lld/test/wasm/shared.ll b/lld/test/wasm/shared.ll
index b83e61ed1a8..a40cfbe3051 100644
--- a/lld/test/wasm/shared.ll
+++ b/lld/test/wasm/shared.ll
@@ -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'
diff --git a/lld/test/wasm/undefined-data.ll b/lld/test/wasm/undefined-data.ll
new file mode 100644
index 00000000000..8063d333efa
--- /dev/null
+++ b/lld/test/wasm/undefined-data.ll
@@ -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"
+
+@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
diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp
index 42affb4168a..96c473629cf 100644
--- a/lld/wasm/Writer.cpp
+++ b/lld/wasm/Writer.cpp
@@ -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());
OpenPOWER on IntegriCloud