diff options
author | Wouter van Oortmerssen <aardappel@gmail.com> | 2020-06-05 09:03:12 -0700 |
---|---|---|
committer | Wouter van Oortmerssen <aardappel@gmail.com> | 2020-06-15 10:07:42 -0700 |
commit | 3b29376e3fca4305ea470ee142cad1296103297b (patch) | |
tree | e7f51eac4ca7de905e4d01a46a53c4125136e964 /llvm/lib/Object/WasmObjectFile.cpp | |
parent | 017969de766287ec6c2fc82128c62d1d1dad7bd8 (diff) | |
download | llvm-3b29376e3fca4305ea470ee142cad1296103297b.zip llvm-3b29376e3fca4305ea470ee142cad1296103297b.tar.gz llvm-3b29376e3fca4305ea470ee142cad1296103297b.tar.bz2 |
[WebAssembly] Adding 64-bit version of R_WASM_MEMORY_ADDR_* relocs
This adds 4 new reloc types.
A lot of code that previously assumed any memory or offset values could be contained in a uint32_t (and often truncated results from functions returning 64-bit values) have been upgraded to uint64_t. This is not comprehensive: it is only the values that come in contact with the new relocation values and their dependents.
A new tablegen mapping was added to automatically upgrade loads/stores in the assembler, which otherwise has no way to select for these instructions (since they are indentical other than for the offset immediate). It follows a similar technique to https://reviews.llvm.org/D53307
Differential Revision: https://reviews.llvm.org/D81704
Diffstat (limited to 'llvm/lib/Object/WasmObjectFile.cpp')
-rw-r--r-- | llvm/lib/Object/WasmObjectFile.cpp | 34 |
1 files changed, 29 insertions, 5 deletions
diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp index 573055b..023948e 100644 --- a/llvm/lib/Object/WasmObjectFile.cpp +++ b/llvm/lib/Object/WasmObjectFile.cpp @@ -156,6 +156,10 @@ static int64_t readVarint64(WasmObjectFile::ReadContext &Ctx) { return readLEB128(Ctx); } +static uint64_t readVaruint64(WasmObjectFile::ReadContext &Ctx) { + return readULEB128(Ctx); +} + static uint8_t readOpcode(WasmObjectFile::ReadContext &Ctx) { return readUint8(Ctx); } @@ -558,12 +562,12 @@ Error WasmObjectFile::parseLinkingSectionSymtab(ReadContext &Ctx) { case wasm::WASM_SYMBOL_TYPE_DATA: Info.Name = readString(Ctx); if (IsDefined) { - uint32_t Index = readVaruint32(Ctx); + auto Index = readVaruint32(Ctx); if (Index >= DataSegments.size()) return make_error<GenericBinaryError>("invalid data symbol index", object_error::parse_failed); - uint32_t Offset = readVaruint32(Ctx); - uint32_t Size = readVaruint32(Ctx); + auto Offset = readVaruint64(Ctx); + auto Size = readVaruint64(Ctx); if (Offset + Size > DataSegments[Index].Data.Content.size()) return make_error<GenericBinaryError>("invalid data symbol offset", object_error::parse_failed); @@ -818,6 +822,15 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) { object_error::parse_failed); Reloc.Addend = readVarint32(Ctx); break; + case wasm::R_WASM_MEMORY_ADDR_LEB64: + case wasm::R_WASM_MEMORY_ADDR_SLEB64: + case wasm::R_WASM_MEMORY_ADDR_I64: + case wasm::R_WASM_MEMORY_ADDR_REL_SLEB64: + if (!isValidDataSymbol(Reloc.Index)) + return make_error<GenericBinaryError>("Bad relocation data index", + object_error::parse_failed); + Reloc.Addend = readVarint64(Ctx); + break; case wasm::R_WASM_FUNCTION_OFFSET_I32: if (!isValidFunctionSymbol(Reloc.Index)) return make_error<GenericBinaryError>("Bad relocation function index", @@ -840,12 +853,18 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) { // also shouldn't overlap a function/element boundary, but we don't bother // to check that. uint64_t Size = 5; + if (Reloc.Type == wasm::R_WASM_MEMORY_ADDR_LEB64 || + Reloc.Type == wasm::R_WASM_MEMORY_ADDR_SLEB64 || + Reloc.Type == wasm::R_WASM_MEMORY_ADDR_REL_SLEB64) + Size = 10; if (Reloc.Type == wasm::R_WASM_TABLE_INDEX_I32 || Reloc.Type == wasm::R_WASM_MEMORY_ADDR_I32 || Reloc.Type == wasm::R_WASM_SECTION_OFFSET_I32 || Reloc.Type == wasm::R_WASM_FUNCTION_OFFSET_I32 || Reloc.Type == wasm::R_WASM_GLOBAL_INDEX_I32) Size = 4; + if (Reloc.Type == wasm::R_WASM_MEMORY_ADDR_I64) + Size = 8; if (Reloc.Offset + Size > EndOffset) return make_error<GenericBinaryError>("Bad relocation offset", object_error::parse_failed); @@ -1331,8 +1350,13 @@ uint64_t WasmObjectFile::getWasmSymbolValue(const WasmSymbol &Sym) const { // offset within the segment. uint32_t SegmentIndex = Sym.Info.DataRef.Segment; const wasm::WasmDataSegment &Segment = DataSegments[SegmentIndex].Data; - assert(Segment.Offset.Opcode == wasm::WASM_OPCODE_I32_CONST); - return Segment.Offset.Value.Int32 + Sym.Info.DataRef.Offset; + if (Segment.Offset.Opcode == wasm::WASM_OPCODE_I32_CONST) { + return Segment.Offset.Value.Int32 + Sym.Info.DataRef.Offset; + } else if (Segment.Offset.Opcode == wasm::WASM_OPCODE_I64_CONST) { + return Segment.Offset.Value.Int64 + Sym.Info.DataRef.Offset; + } else { + llvm_unreachable("unknown init expr opcode"); + } } case wasm::WASM_SYMBOL_TYPE_SECTION: return 0; |