Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions lld/test/wasm/runtime-relocations-himem.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
## Verifies runtime relocation code for addresses over 2gb works correctly.
## We have had issues with LEB encoding of address over 2gb in i32.const
## instruction leading to invalid binaries.

# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
# RUN: wasm-ld --global-base=2147483648 --experimental-pic --unresolved-symbols=import-dynamic -no-gc-sections --shared-memory --no-entry -o %t.wasm %t.o
# XUN: obj2yaml %t.wasm | FileCheck %s
# RUN: llvm-objdump -d --no-show-raw-insn --no-leading-addr %t.wasm | FileCheck %s --

.globl tls_sym
.globl data_sym
.globl _start
.globaltype __tls_base, i32

_start:
.functype _start () -> ()
global.get __tls_base
i32.const tls_sym@TLSREL
i32.add
drop
i32.const data_sym
drop
end_function

.section tls_sec,"T",@
.p2align 2
tls_sym:
.int32 0
.int32 extern_sym
.size tls_sym, 8

.section data_sec,"",@
.p2align 2
data_sym:
.int32 0
.int32 extern_sym
.size data_sym, 8

.section .custom_section.target_features,"",@
.int8 2
.int8 43
.int8 7
.ascii "atomics"
.int8 43
.int8 11
.ascii "bulk-memory"

# CHECK: <__wasm_apply_data_relocs>:
# CHECK-EMPTY:
# CHECK-NEXT: i32.const -2147483636
# CHECK-NEXT: global.get 0
# CHECK-NEXT: i32.store 0
# CHECK-NEXT: end

# CHECK: <__wasm_apply_tls_relocs>:
# CHECK-EMPTY:
# CHECK-NEXT: i32.const -2147483644
# CHECK-NEXT: global.get 0
# CHECK-NEXT: i32.store 0
# CHECK-NEXT: end
14 changes: 4 additions & 10 deletions lld/wasm/InputChunks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -423,8 +423,6 @@ bool InputChunk::generateRelocationCode(raw_ostream &os) const {

bool is64 = ctx.arg.is64.value_or(false);
bool generated = 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;

Expand All @@ -451,8 +449,7 @@ bool InputChunk::generateRelocationCode(raw_ostream &os) const {
<< " output offset=" << offset << "\n");

// Calculate the address at which to apply the relocation
writeU8(os, opcode_ptr_const, "CONST");
writeSleb128(os, offset, "offset");
writePtrConst(os, offset, is64, "offset");

// In PIC mode we need to add the __memory_base
if (ctx.isPic) {
Expand All @@ -466,8 +463,6 @@ bool InputChunk::generateRelocationCode(raw_ostream &os) const {

// Now figure out what we want to store at this location
bool is64 = relocIs64(rel.Type);
unsigned opcode_reloc_const =
is64 ? WASM_OPCODE_I64_CONST : WASM_OPCODE_I32_CONST;
unsigned opcode_reloc_add =
is64 ? WASM_OPCODE_I64_ADD : WASM_OPCODE_I32_ADD;
unsigned opcode_reloc_store =
Expand All @@ -477,8 +472,7 @@ bool InputChunk::generateRelocationCode(raw_ostream &os) const {
writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
writeUleb128(os, sym->getGOTIndex(), "global index");
if (rel.Addend) {
writeU8(os, opcode_reloc_const, "CONST");
writeSleb128(os, rel.Addend, "addend");
writePtrConst(os, rel.Addend, is64, "addend");
writeU8(os, opcode_reloc_add, "ADD");
}
} else {
Expand All @@ -491,8 +485,8 @@ bool InputChunk::generateRelocationCode(raw_ostream &os) const {
baseSymbol = ctx.sym.tlsBase;
writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
writeUleb128(os, baseSymbol->getGlobalIndex(), "base");
writeU8(os, opcode_reloc_const, "CONST");
writeSleb128(os, file->calcNewValue(rel, tombstone, this), "offset");
writePtrConst(os, file->calcNewValue(rel, tombstone, this), is64,
"offset");
writeU8(os, opcode_reloc_add, "ADD");
}

Expand Down
8 changes: 2 additions & 6 deletions lld/wasm/SyntheticSections.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -434,8 +434,6 @@ void GlobalSection::addInternalGOTEntry(Symbol *sym) {
void GlobalSection::generateRelocationCode(raw_ostream &os, bool TLS) const {
assert(!ctx.arg.extendedConst);
bool is64 = ctx.arg.is64.value_or(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;

Expand All @@ -452,8 +450,7 @@ void GlobalSection::generateRelocationCode(raw_ostream &os, bool TLS) const {
writeUleb128(os, ctx.sym.memoryBase->getGlobalIndex(), "__memory_base");

// Add the virtual address of the data symbol
writeU8(os, opcode_ptr_const, "CONST");
writeSleb128(os, d->getVA(), "offset");
writePtrConst(os, d->getVA(), is64, "offset");
} else if (auto *f = dyn_cast<FunctionSymbol>(sym)) {
if (f->isStub)
continue;
Expand All @@ -462,8 +459,7 @@ void GlobalSection::generateRelocationCode(raw_ostream &os, bool TLS) const {
writeUleb128(os, ctx.sym.tableBase->getGlobalIndex(), "__table_base");

// Add the table index to __table_base
writeU8(os, opcode_ptr_const, "CONST");
writeSleb128(os, f->getTableIndex(), "offset");
writePtrConst(os, f->getTableIndex(), is64, "offset");
} else {
assert(isa<UndefinedData>(sym) || isa<SharedData>(sym));
continue;
Expand Down
Loading