From 8a427459520128e76d307ffa25dc59f166d0252f Mon Sep 17 00:00:00 2001 From: Wouter van Oortmerssen Date: Thu, 15 Jul 2021 13:24:28 -0700 Subject: [PATCH] [WebAssembly] Support R_WASM_MEMORY_ADDR_TLS_SLEB64 for wasm64 Also fixed TLS tests swapping addr & value in store op Differential Revision: https://reviews.llvm.org/D106096 --- include/llvm/BinaryFormat/WasmRelocs.def | 1 + lib/BinaryFormat/Wasm.cpp | 1 + lib/MC/WasmObjectWriter.cpp | 2 + lib/Object/WasmObjectFile.cpp | 1 + .../WebAssemblyWasmObjectWriter.cpp | 3 +- test/MC/WebAssembly/tls.s | 7 +- test/MC/WebAssembly/tls64.s | 76 +++++++++++++++++++ 7 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 test/MC/WebAssembly/tls64.s diff --git a/include/llvm/BinaryFormat/WasmRelocs.def b/include/llvm/BinaryFormat/WasmRelocs.def index a78a76f5778..2913f20dfd2 100644 --- a/include/llvm/BinaryFormat/WasmRelocs.def +++ b/include/llvm/BinaryFormat/WasmRelocs.def @@ -27,3 +27,4 @@ WASM_RELOC(R_WASM_MEMORY_ADDR_TLS_SLEB, 21) WASM_RELOC(R_WASM_FUNCTION_OFFSET_I64, 22) WASM_RELOC(R_WASM_MEMORY_ADDR_LOCREL_I32, 23) WASM_RELOC(R_WASM_TABLE_INDEX_REL_SLEB64, 24) +WASM_RELOC(R_WASM_MEMORY_ADDR_TLS_SLEB64, 25) diff --git a/lib/BinaryFormat/Wasm.cpp b/lib/BinaryFormat/Wasm.cpp index 4192622d2d2..55efe31f266 100644 --- a/lib/BinaryFormat/Wasm.cpp +++ b/lib/BinaryFormat/Wasm.cpp @@ -49,6 +49,7 @@ bool llvm::wasm::relocTypeHasAddend(uint32_t Type) { case R_WASM_MEMORY_ADDR_I32: case R_WASM_MEMORY_ADDR_I64: case R_WASM_MEMORY_ADDR_TLS_SLEB: + case R_WASM_MEMORY_ADDR_TLS_SLEB64: case R_WASM_FUNCTION_OFFSET_I32: case R_WASM_FUNCTION_OFFSET_I64: case R_WASM_SECTION_OFFSET_I32: diff --git a/lib/MC/WasmObjectWriter.cpp b/lib/MC/WasmObjectWriter.cpp index 4832cd3ff54..b86604d54f4 100644 --- a/lib/MC/WasmObjectWriter.cpp +++ b/lib/MC/WasmObjectWriter.cpp @@ -633,6 +633,7 @@ WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry, case wasm::R_WASM_MEMORY_ADDR_I32: case wasm::R_WASM_MEMORY_ADDR_I64: case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB: + case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB64: case wasm::R_WASM_MEMORY_ADDR_LOCREL_I32: { // Provisional value is address of the global plus the offset // For undefined symbols, use zero @@ -748,6 +749,7 @@ void WasmObjectWriter::applyRelocations( case wasm::R_WASM_TABLE_INDEX_REL_SLEB64: case wasm::R_WASM_MEMORY_ADDR_SLEB64: case wasm::R_WASM_MEMORY_ADDR_REL_SLEB64: + case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB64: writePatchableSLEB<10>(Stream, Value, Offset); break; default: diff --git a/lib/Object/WasmObjectFile.cpp b/lib/Object/WasmObjectFile.cpp index 518803792f5..a08c648358c 100644 --- a/lib/Object/WasmObjectFile.cpp +++ b/lib/Object/WasmObjectFile.cpp @@ -919,6 +919,7 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) { case wasm::R_WASM_MEMORY_ADDR_SLEB64: case wasm::R_WASM_MEMORY_ADDR_I64: case wasm::R_WASM_MEMORY_ADDR_REL_SLEB64: + case wasm::R_WASM_MEMORY_ADDR_TLS_SLEB64: if (!isValidDataSymbol(Reloc.Index)) return make_error("invalid relocation data index", object_error::parse_failed); diff --git a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp index cd3465a1b37..48e86544149 100644 --- a/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp +++ b/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyWasmObjectWriter.cpp @@ -79,7 +79,8 @@ unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target, return is64Bit() ? wasm::R_WASM_TABLE_INDEX_REL_SLEB64 : wasm::R_WASM_TABLE_INDEX_REL_SLEB; case MCSymbolRefExpr::VK_WASM_TLSREL: - return wasm::R_WASM_MEMORY_ADDR_TLS_SLEB; + return is64Bit() ? wasm::R_WASM_MEMORY_ADDR_TLS_SLEB64 + : wasm::R_WASM_MEMORY_ADDR_TLS_SLEB; case MCSymbolRefExpr::VK_WASM_MBREL: assert(SymA.isData()); return is64Bit() ? wasm::R_WASM_MEMORY_ADDR_REL_SLEB64 diff --git a/test/MC/WebAssembly/tls.s b/test/MC/WebAssembly/tls.s index 0f5a5a394c3..542273c339c 100644 --- a/test/MC/WebAssembly/tls.s +++ b/test/MC/WebAssembly/tls.s @@ -9,11 +9,12 @@ tls_store: # CHECK: global.get __tls_base # CHECK-NEXT: i32.const tls1@TLSREL # CHECK-NEXT: i32.add + # CHECK-NEXT: local.get 0 # CHECK-NEXT: i32.store 0 - local.get 0 global.get __tls_base i32.const tls1@TLSREL i32.add + local.get 0 i32.store 0 end_function @@ -33,10 +34,10 @@ tls2: # CHECK-OBJ-NEXT: Relocations: # CHECK-OBJ-NEXT: - Type: R_WASM_GLOBAL_INDEX_LEB # CHECK-OBJ-NEXT: Index: 1 -# CHECK-OBJ-NEXT: Offset: 0x6 +# CHECK-OBJ-NEXT: Offset: 0x4 # CHECK-OBJ-NEXT: - Type: R_WASM_MEMORY_ADDR_TLS_SLEB # CHECK-OBJ-NEXT: Index: 2 -# CHECK-OBJ-NEXT: Offset: 0xC +# CHECK-OBJ-NEXT: Offset: 0xA # CHECK-OBJ: - Type: CUSTOM # CHECK-OBJ-NEXT: Name: linking diff --git a/test/MC/WebAssembly/tls64.s b/test/MC/WebAssembly/tls64.s new file mode 100644 index 00000000000..f066fd29424 --- /dev/null +++ b/test/MC/WebAssembly/tls64.s @@ -0,0 +1,76 @@ +# RUN: llvm-mc -triple=wasm64-unknown-unknown < %s | FileCheck %s +# RUN: llvm-mc -triple=wasm64-unknown-unknown -filetype=obj -o %t.o < %s +# RUN: obj2yaml %t.o | FileCheck %s --check-prefix=CHECK-OBJ --match-full-lines + +.globaltype __tls_base, i64 + +tls_store: + .functype tls_store (i32) -> () + # CHECK: global.get __tls_base + # CHECK-NEXT: i64.const tls1@TLSREL + # CHECK-NEXT: i64.add + # CHECK-NEXT: local.get 0 + # CHECK-NEXT: i32.store 0 + global.get __tls_base + i64.const tls1@TLSREL + i64.add + local.get 0 + i32.store 0 + end_function + +.section .tls.foo,"T",@ +# CHECK: .tls.foo,"T",@ +tls1: + .int32 42 + .size tls1, 4 + +.section custom_tls,"T",@ +# CHECK: custom_tls,"T",@ +tls2: + .int32 43 + .size tls2, 4 + +# CHECK-OBJ: - Type: CODE +# CHECK-OBJ-NEXT: Relocations: +# CHECK-OBJ-NEXT: - Type: R_WASM_GLOBAL_INDEX_LEB +# CHECK-OBJ-NEXT: Index: 1 +# CHECK-OBJ-NEXT: Offset: 0x4 +# CHECK-OBJ-NEXT: - Type: R_WASM_MEMORY_ADDR_TLS_SLEB64 +# CHECK-OBJ-NEXT: Index: 2 +# CHECK-OBJ-NEXT: Offset: 0xA + +# CHECK-OBJ: - Type: CUSTOM +# CHECK-OBJ-NEXT: Name: linking +# CHECK-OBJ-NEXT: Version: 2 +# CHECK-OBJ-NEXT: SymbolTable: +# CHECK-OBJ-NEXT: - Index: 0 +# CHECK-OBJ-NEXT: Kind: FUNCTION +# CHECK-OBJ-NEXT: Name: tls_store +# CHECK-OBJ-NEXT: Flags: [ BINDING_LOCAL ] +# CHECK-OBJ-NEXT: Function: 0 +# CHECK-OBJ-NEXT: - Index: 1 +# CHECK-OBJ-NEXT: Kind: GLOBAL +# CHECK-OBJ-NEXT: Name: __tls_base +# CHECK-OBJ-NEXT: Flags: [ UNDEFINED ] +# CHECK-OBJ-NEXT: Global: 0 +# CHECK-OBJ-NEXT: - Index: 2 +# CHECK-OBJ-NEXT: Kind: DATA +# CHECK-OBJ-NEXT: Name: tls1 +# CHECK-OBJ-NEXT: Flags: [ BINDING_LOCAL ] +# CHECK-OBJ-NEXT: Segment: 0 +# CHECK-OBJ-NEXT: Size: 4 +# CHECK-OBJ-NEXT: - Index: 3 +# CHECK-OBJ-NEXT: Kind: DATA +# CHECK-OBJ-NEXT: Name: tls2 +# CHECK-OBJ-NEXT: Flags: [ BINDING_LOCAL ] +# CHECK-OBJ-NEXT: Segment: 1 +# CHECK-OBJ-NEXT: Size: 4 +# CHECK-OBJ-NEXT: SegmentInfo: +# CHECK-OBJ-NEXT: - Index: 0 +# CHECK-OBJ-NEXT: Name: .tls.foo +# CHECK-OBJ-NEXT: Alignment: 0 +# CHECK-OBJ-NEXT: Flags: [ TLS ] +# CHECK-OBJ-NEXT: - Index: 1 +# CHECK-OBJ-NEXT: Name: custom_tls +# CHECK-OBJ-NEXT: Alignment: 0 +# CHECK-OBJ-NEXT: Flags: [ TLS ]