Skip to content

Commit a017343

Browse files
committed
[lld][WebAssembly] Use writePtrConst helper function
This is especially important for writing i32 values larger than 2gb which need to be encoded as negative SLEB vales in the binary. Without this change offsets over 2gb are wrongly encoded and cause validation errors. Fixes: emscripten-core/emscripten#25706
1 parent dccced2 commit a017343

File tree

2 files changed

+6
-16
lines changed

2 files changed

+6
-16
lines changed

lld/wasm/InputChunks.cpp

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -423,8 +423,6 @@ bool InputChunk::generateRelocationCode(raw_ostream &os) const {
423423

424424
bool is64 = ctx.arg.is64.value_or(false);
425425
bool generated = false;
426-
unsigned opcode_ptr_const = is64 ? WASM_OPCODE_I64_CONST
427-
: WASM_OPCODE_I32_CONST;
428426
unsigned opcode_ptr_add = is64 ? WASM_OPCODE_I64_ADD
429427
: WASM_OPCODE_I32_ADD;
430428

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

453451
// Calculate the address at which to apply the relocation
454-
writeU8(os, opcode_ptr_const, "CONST");
455-
writeSleb128(os, offset, "offset");
452+
writePtrConst(os, offset, is64, "offset");
456453

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

467464
// Now figure out what we want to store at this location
468465
bool is64 = relocIs64(rel.Type);
469-
unsigned opcode_reloc_const =
470-
is64 ? WASM_OPCODE_I64_CONST : WASM_OPCODE_I32_CONST;
471466
unsigned opcode_reloc_add =
472467
is64 ? WASM_OPCODE_I64_ADD : WASM_OPCODE_I32_ADD;
473468
unsigned opcode_reloc_store =
@@ -477,8 +472,7 @@ bool InputChunk::generateRelocationCode(raw_ostream &os) const {
477472
writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
478473
writeUleb128(os, sym->getGOTIndex(), "global index");
479474
if (rel.Addend) {
480-
writeU8(os, opcode_reloc_const, "CONST");
481-
writeSleb128(os, rel.Addend, "addend");
475+
writePtrConst(os, rel.Addend, is64, "addend");
482476
writeU8(os, opcode_reloc_add, "ADD");
483477
}
484478
} else {
@@ -491,8 +485,8 @@ bool InputChunk::generateRelocationCode(raw_ostream &os) const {
491485
baseSymbol = ctx.sym.tlsBase;
492486
writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
493487
writeUleb128(os, baseSymbol->getGlobalIndex(), "base");
494-
writeU8(os, opcode_reloc_const, "CONST");
495-
writeSleb128(os, file->calcNewValue(rel, tombstone, this), "offset");
488+
writePtrConst(os, file->calcNewValue(rel, tombstone, this), is64,
489+
"offset");
496490
writeU8(os, opcode_reloc_add, "ADD");
497491
}
498492

lld/wasm/SyntheticSections.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -434,8 +434,6 @@ void GlobalSection::addInternalGOTEntry(Symbol *sym) {
434434
void GlobalSection::generateRelocationCode(raw_ostream &os, bool TLS) const {
435435
assert(!ctx.arg.extendedConst);
436436
bool is64 = ctx.arg.is64.value_or(false);
437-
unsigned opcode_ptr_const = is64 ? WASM_OPCODE_I64_CONST
438-
: WASM_OPCODE_I32_CONST;
439437
unsigned opcode_ptr_add = is64 ? WASM_OPCODE_I64_ADD
440438
: WASM_OPCODE_I32_ADD;
441439

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

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

464461
// Add the table index to __table_base
465-
writeU8(os, opcode_ptr_const, "CONST");
466-
writeSleb128(os, f->getTableIndex(), "offset");
462+
writePtrConst(os, f->getTableIndex(), is64, "offset");
467463
} else {
468464
assert(isa<UndefinedData>(sym) || isa<SharedData>(sym));
469465
continue;

0 commit comments

Comments
 (0)