summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Clegg <sbc@chromium.org>2018-04-19 22:48:03 +0000
committerSam Clegg <sbc@chromium.org>2018-04-19 22:48:03 +0000
commit0dbe57e7523b531374a96982a69b7a0fcb71db36 (patch)
tree4bba850a59ce73066c611e7bfe9f7dc1018ea0a2
parent1eca23bdd88e9357477d198f6dd922e1fcba9d77 (diff)
downloadbcm5719-llvm-0dbe57e7523b531374a96982a69b7a0fcb71db36.tar.gz
bcm5719-llvm-0dbe57e7523b531374a96982a69b7a0fcb71db36.zip
[WebAssembly] Fix bug where reloc addends were written as unsigned
Relocation addends can be negative so should be written as signed LEBs. This bug meant that writing value between 64 and 128 would be incorrectly interpreted as negative by the object file readers. Differential Revision: https://reviews.llvm.org/D45825 llvm-svn: 330374
-rw-r--r--lld/test/wasm/reloc-addend.ll19
-rw-r--r--lld/wasm/InputChunks.cpp2
2 files changed, 20 insertions, 1 deletions
diff --git a/lld/test/wasm/reloc-addend.ll b/lld/test/wasm/reloc-addend.ll
new file mode 100644
index 00000000000..630bd868916
--- /dev/null
+++ b/lld/test/wasm/reloc-addend.ll
@@ -0,0 +1,19 @@
+; RUN: llc -filetype=obj %s -o %t.o
+; RUN: wasm-ld --check-signatures -r -o %t.wasm %t.o
+; RUN: obj2yaml %t.wasm | FileCheck %s
+
+target triple = "wasm32-unknown-unknown-wasm"
+
+@foo = hidden global [76 x i32] zeroinitializer, align 16
+
+; bar points to the 16th element, which happens to be 64 bytes
+; This generates an addend of 64 which, is the value at which
+; signed and unsigned LEB encodes will differ.
+@bar = hidden local_unnamed_addr global i32* getelementptr inbounds ([76 x i32], [76 x i32]* @foo, i32 0, i32 16), align 4
+
+; CHECK: - Type: DATA
+; CHECK-NEXT: Relocations:
+; CHECK-NEXT: - Type: R_WEBASSEMBLY_MEMORY_ADDR_I32
+; CHECK-NEXT: Index: 0
+; CHECK-NEXT: Offset: 0x0000013D
+; CHECK-NEXT: Addend: 64
diff --git a/lld/wasm/InputChunks.cpp b/lld/wasm/InputChunks.cpp
index 0cac19b3d4e..1f11bde4a67 100644
--- a/lld/wasm/InputChunks.cpp
+++ b/lld/wasm/InputChunks.cpp
@@ -124,7 +124,7 @@ void InputChunk::writeRelocations(raw_ostream &OS) const {
case R_WEBASSEMBLY_MEMORY_ADDR_LEB:
case R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
case R_WEBASSEMBLY_MEMORY_ADDR_I32:
- writeUleb128(OS, Rel.Addend, "reloc addend");
+ writeSleb128(OS, Rel.Addend, "reloc addend");
break;
}
}
OpenPOWER on IntegriCloud