Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions lld/test/wasm/bad-data-relocs.s
Original file line number Diff line number Diff line change
@@ -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
15 changes: 13 additions & 2 deletions lld/wasm/InputChunks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -424,15 +432,18 @@ 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.
bool requiresRuntimeReloc = ctx.isPic || sym->hasGOTIndex();
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");
Expand Down