diff --git a/lld/test/wasm/bad-data-relocs.s b/lld/test/wasm/bad-data-relocs.s new file mode 100644 index 0000000000000..7e2ef3e1dc3b7 --- /dev/null +++ b/lld/test/wasm/bad-data-relocs.s @@ -0,0 +1,27 @@ +## Certain relocations types are not supported by runtime relocation code +## generated in `-shared/`-pie` binaries. + +# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s +# RUN: not wasm-ld -pie --experimental-pic %t.o -o %t.wasm 2>&1 | FileCheck %s + +# CHECK: wasm-ld: error: invalid runtime relocation type in data section: R_WASM_FUNCTION_INDEX_I32 + +foo: + .functype foo (i32) -> () + end_function + +.globl _start +_start: + .functype _start () -> () + i32.const bar@GOT + call foo@GOT + end_function + +# data section containing relocation type that is not valid in a data section +.section .data,"",@ +.globl bar +bar: + .int32 0 + .size bar, 4 + +.reloc bar, R_WASM_FUNCTION_INDEX_I32, foo diff --git a/lld/wasm/InputChunks.cpp b/lld/wasm/InputChunks.cpp index 181221a77b106..009869f1dcde1 100644 --- a/lld/wasm/InputChunks.cpp +++ b/lld/wasm/InputChunks.cpp @@ -406,6 +406,14 @@ uint64_t InputChunk::getVA(uint64_t offset) const { return (outputSeg ? outputSeg->startVA : 0) + getChunkOffset(offset); } +bool isValidRuntimeRelocation(WasmRelocType type) { + // TODO(https://github.com/llvm/llvm-project/issues/146923): Currently + // this means that R_WASM_FUNCTION_INDEX_I32 is not valid in `-pie` data + // sections. + return type == R_WASM_TABLE_INDEX_I32 || type == R_WASM_TABLE_INDEX_I64 || + type == R_WASM_MEMORY_ADDR_I32 || type == R_WASM_MEMORY_ADDR_I64; +} + // Generate code to apply relocations to the data section at runtime. // This is only called when generating shared libraries (PIC) where address are // not known at static link time. @@ -424,8 +432,6 @@ bool InputChunk::generateRelocationCode(raw_ostream &os) const { // TODO(sbc): Encode the relocations in the data section and write a loop // here to apply them. for (const WasmRelocation &rel : relocations) { - uint64_t offset = getVA(rel.Offset) - getInputSectionOffset(); - Symbol *sym = file->getSymbol(rel); // Runtime relocations are needed when we don't know the address of // a symbol statically. @@ -433,6 +439,11 @@ bool InputChunk::generateRelocationCode(raw_ostream &os) const { if (!requiresRuntimeReloc) continue; + if (!isValidRuntimeRelocation(rel.getType())) + error("invalid runtime relocation type in data section: " + + relocTypetoString(rel.Type)); + + uint64_t offset = getVA(rel.Offset) - getInputSectionOffset(); LLVM_DEBUG(dbgs() << "gen reloc: type=" << relocTypeToString(rel.Type) << " addend=" << rel.Addend << " index=" << rel.Index << " output offset=" << offset << "\n");