From: Sam Clegg Date: Fri, 29 May 2020 01:39:27 +0000 (-0700) Subject: [WebAssembly] Add placeholders for R_WASM_TABLE_INDEX_REL_SLEB relocations X-Git-Tag: llvmorg-12-init~4670 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=81443ac1bc710c89565ea1bce0eb566bf2cacd0d;p=platform%2Fupstream%2Fllvm.git [WebAssembly] Add placeholders for R_WASM_TABLE_INDEX_REL_SLEB relocations Previously in the object format we punted on this and simply wrote zeros (and didn't include the function in the elem segment). With this change we write a meaningful value which is the segment relative table index of the associated function. This matches the that wasm-ld produces in `-r` mode. This inconsistency between the output the MC object writer and the wasm-ld object writer could cause warnings to be emitted when reading back in the output of `wasm-ld -r`. See: https://github.com/emscripten-core/emscripten/issues/11217 This only applies to this one relocation type which is only generated when compiling in PIC mode. Differential Revision: https://reviews.llvm.org/D80774 --- diff --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp index b7d90fe..7390575 100644 --- a/lld/wasm/InputFiles.cpp +++ b/lld/wasm/InputFiles.cpp @@ -122,11 +122,14 @@ uint32_t ObjFile::calcNewAddend(const WasmRelocation &reloc) const { uint32_t ObjFile::calcExpectedValue(const WasmRelocation &reloc) const { switch (reloc.Type) { case R_WASM_TABLE_INDEX_I32: - case R_WASM_TABLE_INDEX_SLEB: - case R_WASM_TABLE_INDEX_REL_SLEB: { + case R_WASM_TABLE_INDEX_SLEB: { const WasmSymbol &sym = wasmObj->syms()[reloc.Index]; return tableEntries[sym.Info.ElementIndex]; } + case R_WASM_TABLE_INDEX_REL_SLEB: { + const WasmSymbol &sym = wasmObj->syms()[reloc.Index]; + return tableEntriesRel[sym.Info.ElementIndex]; + } case R_WASM_MEMORY_ADDR_SLEB: case R_WASM_MEMORY_ADDR_I32: case R_WASM_MEMORY_ADDR_LEB: @@ -266,6 +269,7 @@ void ObjFile::parse(bool ignoreComdats) { // verifying the existing table index relocations uint32_t totalFunctions = wasmObj->getNumImportedFunctions() + wasmObj->functions().size(); + tableEntriesRel.resize(totalFunctions); tableEntries.resize(totalFunctions); for (const WasmElemSegment &seg : wasmObj->elements()) { if (seg.Offset.Opcode != WASM_OPCODE_I32_CONST) @@ -274,6 +278,7 @@ void ObjFile::parse(bool ignoreComdats) { for (uint32_t index = 0; index < seg.Functions.size(); index++) { uint32_t functionIndex = seg.Functions[index]; + tableEntriesRel[functionIndex] = index; tableEntries[functionIndex] = offset + index; } } diff --git a/lld/wasm/InputFiles.h b/lld/wasm/InputFiles.h index bf4a4ec..661aa89 100644 --- a/lld/wasm/InputFiles.h +++ b/lld/wasm/InputFiles.h @@ -118,6 +118,7 @@ public: std::vector typeIsUsed; // Maps function indices to table indices std::vector tableEntries; + std::vector tableEntriesRel; std::vector keptComdats; std::vector segments; std::vector functions; diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp index 0c09f99..c6a2789 100644 --- a/llvm/lib/MC/WasmObjectWriter.cpp +++ b/llvm/lib/MC/WasmObjectWriter.cpp @@ -565,7 +565,10 @@ WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry) { // Provisional value is table address of the resolved symbol itself const MCSymbolWasm *Sym = resolveSymbol(*RelEntry.Symbol); assert(Sym->isFunction()); - return TableIndices[Sym]; + if (RelEntry.Type == wasm::R_WASM_TABLE_INDEX_REL_SLEB) + return TableIndices[Sym] - InitialTableOffset; + else + return TableIndices[Sym]; } case wasm::R_WASM_TYPE_INDEX_LEB: // Provisional value is same as the index @@ -1559,7 +1562,8 @@ uint64_t WasmObjectWriter::writeObject(MCAssembler &Asm, // purely to make the object file's provisional values readable, and is // ignored by the linker, which re-calculates the relocations itself. if (Rel.Type != wasm::R_WASM_TABLE_INDEX_I32 && - Rel.Type != wasm::R_WASM_TABLE_INDEX_SLEB) + Rel.Type != wasm::R_WASM_TABLE_INDEX_SLEB && + Rel.Type != wasm::R_WASM_TABLE_INDEX_REL_SLEB) return; assert(Rel.Symbol->isFunction()); const MCSymbolWasm &WS = *resolveSymbol(*Rel.Symbol); diff --git a/llvm/test/MC/WebAssembly/reloc-pic.s b/llvm/test/MC/WebAssembly/reloc-pic.s index 626f8d9..4732b7e 100644 --- a/llvm/test/MC/WebAssembly/reloc-pic.s +++ b/llvm/test/MC/WebAssembly/reloc-pic.s @@ -68,7 +68,7 @@ hidden_func: # CHECK-NEXT: Table: # CHECK-NEXT: ElemType: FUNCREF # CHECK-NEXT: Limits: -# CHECK-NEXT: Initial: 0x00000000 +# CHECK-NEXT: Initial: 0x00000001 # CHECK-NEXT: - Module: env # CHECK-NEXT: Field: default_func # CHECK-NEXT: Kind: FUNCTION @@ -85,6 +85,12 @@ hidden_func: # CHECK-NEXT: GlobalMutable: true # CHECK-NEXT: - Type: FUNCTION # CHECK-NEXT: FunctionTypes: [ 0, 0, 0, 0, 0 ] +# CHECK-NEXT: - Type: ELEM +# CHECK-NEXT: Segments: +# CHECK-NEXT: Offset: +# CHECK-NEXT: Opcode: I32_CONST +# CHECK-NEXT: Value: 1 +# CHECK-NEXT: Functions: [ 5 ] # CHECK-NEXT: - Type: DATACOUNT # CHECK-NEXT: Count: 1 # CHECK-NEXT: - Type: CODE