-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[lld][WebAssembly] Use writePtrConst helper function #166228
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@llvm/pr-subscribers-lld-wasm @llvm/pr-subscribers-lld Author: Sam Clegg (sbc100) ChangesThis 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 Full diff: https://github.com/llvm/llvm-project/pull/166228.diff 2 Files Affected:
diff --git a/lld/wasm/InputChunks.cpp b/lld/wasm/InputChunks.cpp
index 44927e7a432bc..a08e80dcae1c8 100644
--- a/lld/wasm/InputChunks.cpp
+++ b/lld/wasm/InputChunks.cpp
@@ -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;
@@ -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) {
@@ -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 =
@@ -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 {
@@ -491,8 +485,7 @@ 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");
}
diff --git a/lld/wasm/SyntheticSections.cpp b/lld/wasm/SyntheticSections.cpp
index e1192706ea913..399a5084e6595 100644
--- a/lld/wasm/SyntheticSections.cpp
+++ b/lld/wasm/SyntheticSections.cpp
@@ -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;
@@ -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;
@@ -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;
|
|
Writing a test for this is a little tricky.. but I'm trying |
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
Maybe a use case for the aforementioned assembler features that can create huge BSS segments or constants? |
dschuff
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change LGTM though if you want to land it even before we can reduce a test. I assume this would also fix the emscripten testsuite >2G tests on the Chromium CI.
|
I came up with test using |
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
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