Skip to content

Commit

Permalink
[WebAssembly] Added R_WASM_FUNCTION_OFFSET_I64 for use with DWARF DW_…
Browse files Browse the repository at this point in the history
…AT_low_pc

Needed for wasm64, see discussion in https://reviews.llvm.org/D91203

Differential Revision: https://reviews.llvm.org/D91395
  • Loading branch information
aardappel committed Nov 13, 2020
1 parent e11195d commit 16f0243
Show file tree
Hide file tree
Showing 12 changed files with 330 additions and 28 deletions.
2 changes: 2 additions & 0 deletions lld/wasm/InputChunks.cpp
Expand Up @@ -97,6 +97,7 @@ void InputChunk::verifyRelocTargets() const {
break;
case R_WASM_TABLE_INDEX_I64:
case R_WASM_MEMORY_ADDR_I64:
case R_WASM_FUNCTION_OFFSET_I64:
existingValue = read64le(loc);
break;
default:
Expand Down Expand Up @@ -176,6 +177,7 @@ void InputChunk::writeTo(uint8_t *buf) const {
break;
case R_WASM_TABLE_INDEX_I64:
case R_WASM_MEMORY_ADDR_I64:
case R_WASM_FUNCTION_OFFSET_I64:
write64le(loc, value);
break;
default:
Expand Down
7 changes: 5 additions & 2 deletions lld/wasm/InputFiles.cpp
Expand Up @@ -124,6 +124,7 @@ uint64_t ObjFile::calcNewAddend(const WasmRelocation &reloc) const {
case R_WASM_MEMORY_ADDR_I32:
case R_WASM_MEMORY_ADDR_I64:
case R_WASM_FUNCTION_OFFSET_I32:
case R_WASM_FUNCTION_OFFSET_I64:
return reloc.Addend;
case R_WASM_SECTION_OFFSET_I32:
return getSectionSymbol(reloc.Index)->section->outputOffset + reloc.Addend;
Expand Down Expand Up @@ -171,7 +172,8 @@ uint64_t ObjFile::calcExpectedValue(const WasmRelocation &reloc) const {
else
llvm_unreachable("unknown init expr opcode");
}
case R_WASM_FUNCTION_OFFSET_I32: {
case R_WASM_FUNCTION_OFFSET_I32:
case R_WASM_FUNCTION_OFFSET_I64: {
const WasmSymbol &sym = wasmObj->syms()[reloc.Index];
InputFunction *f =
functions[sym.Info.ElementIndex - wasmObj->getNumImportedFunctions()];
Expand Down Expand Up @@ -258,7 +260,8 @@ uint64_t ObjFile::calcNewValue(const WasmRelocation &reloc) const {
return sym->getGOTIndex();
case R_WASM_EVENT_INDEX_LEB:
return getEventSymbol(reloc.Index)->getEventIndex();
case R_WASM_FUNCTION_OFFSET_I32: {
case R_WASM_FUNCTION_OFFSET_I32:
case R_WASM_FUNCTION_OFFSET_I64: {
auto *f = cast<DefinedFunction>(sym);
return f->function->outputOffset +
(f->function->getFunctionCodeOffset() + reloc.Addend);
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/BinaryFormat/WasmRelocs.def
Expand Up @@ -24,3 +24,4 @@ WASM_RELOC(R_WASM_TABLE_INDEX_SLEB64, 18)
WASM_RELOC(R_WASM_TABLE_INDEX_I64, 19)
WASM_RELOC(R_WASM_TABLE_NUMBER_LEB, 20)
WASM_RELOC(R_WASM_MEMORY_ADDR_TLS_SLEB, 21)
WASM_RELOC(R_WASM_FUNCTION_OFFSET_I64, 22)
1 change: 1 addition & 0 deletions llvm/lib/BinaryFormat/Wasm.cpp
Expand Up @@ -50,6 +50,7 @@ bool llvm::wasm::relocTypeHasAddend(uint32_t Type) {
case R_WASM_MEMORY_ADDR_I64:
case R_WASM_MEMORY_ADDR_TLS_SLEB:
case R_WASM_FUNCTION_OFFSET_I32:
case R_WASM_FUNCTION_OFFSET_I64:
case R_WASM_SECTION_OFFSET_I32:
return true;
default:
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/MC/WasmObjectWriter.cpp
Expand Up @@ -478,6 +478,7 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm,
// Currently only supported for for metadata sections.
// See: test/MC/WebAssembly/blockaddress.ll
if (Type == wasm::R_WASM_FUNCTION_OFFSET_I32 ||
Type == wasm::R_WASM_FUNCTION_OFFSET_I64 ||
Type == wasm::R_WASM_SECTION_OFFSET_I32) {
if (!FixupSection.getKind().isMetadata())
report_fatal_error("relocations for function or section offsets are "
Expand Down Expand Up @@ -564,6 +565,7 @@ WasmObjectWriter::getProvisionalValue(const WasmRelocationEntry &RelEntry,
assert(WasmIndices.count(RelEntry.Symbol) > 0 && "symbol not found in wasm index space");
return WasmIndices[RelEntry.Symbol];
case wasm::R_WASM_FUNCTION_OFFSET_I32:
case wasm::R_WASM_FUNCTION_OFFSET_I64:
case wasm::R_WASM_SECTION_OFFSET_I32: {
const auto &Section =
static_cast<const MCSectionWasm &>(RelEntry.Symbol->getSection());
Expand Down Expand Up @@ -680,6 +682,7 @@ void WasmObjectWriter::applyRelocations(
break;
case wasm::R_WASM_TABLE_INDEX_I64:
case wasm::R_WASM_MEMORY_ADDR_I64:
case wasm::R_WASM_FUNCTION_OFFSET_I64:
patchI64(Stream, Value, Offset);
break;
case wasm::R_WASM_TABLE_INDEX_SLEB:
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Object/RelocationResolver.cpp
Expand Up @@ -566,6 +566,7 @@ static bool supportsWasm64(uint64_t Type) {
case wasm::R_WASM_MEMORY_ADDR_I64:
case wasm::R_WASM_TABLE_INDEX_SLEB64:
case wasm::R_WASM_TABLE_INDEX_I64:
case wasm::R_WASM_FUNCTION_OFFSET_I64:
return true;
default:
return supportsWasm32(Type);
Expand Down Expand Up @@ -601,6 +602,7 @@ static uint64_t resolveWasm64(RelocationRef R, uint64_t S, uint64_t A) {
case wasm::R_WASM_MEMORY_ADDR_I64:
case wasm::R_WASM_TABLE_INDEX_SLEB64:
case wasm::R_WASM_TABLE_INDEX_I64:
case wasm::R_WASM_FUNCTION_OFFSET_I64:
// For wasm section, its offset at 0 -- ignoring Value
return A;
default:
Expand Down
9 changes: 8 additions & 1 deletion llvm/lib/Object/WasmObjectFile.cpp
Expand Up @@ -876,6 +876,12 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
object_error::parse_failed);
Reloc.Addend = readVarint32(Ctx);
break;
case wasm::R_WASM_FUNCTION_OFFSET_I64:
if (!isValidFunctionSymbol(Reloc.Index))
return make_error<GenericBinaryError>("Bad relocation function index",
object_error::parse_failed);
Reloc.Addend = readVarint64(Ctx);
break;
case wasm::R_WASM_SECTION_OFFSET_I32:
if (!isValidSectionSymbol(Reloc.Index))
return make_error<GenericBinaryError>("Bad relocation section index",
Expand Down Expand Up @@ -903,7 +909,8 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, ReadContext &Ctx) {
Reloc.Type == wasm::R_WASM_GLOBAL_INDEX_I32)
Size = 4;
if (Reloc.Type == wasm::R_WASM_TABLE_INDEX_I64 ||
Reloc.Type == wasm::R_WASM_MEMORY_ADDR_I64)
Reloc.Type == wasm::R_WASM_MEMORY_ADDR_I64 ||
Reloc.Type == wasm::R_WASM_FUNCTION_OFFSET_I64)
Size = 8;
if (Reloc.Offset + Size > EndOffset)
return make_error<GenericBinaryError>("Bad relocation offset",
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/ObjectYAML/WasmEmitter.cpp
Expand Up @@ -547,6 +547,7 @@ void WasmWriter::writeRelocSection(raw_ostream &OS, WasmYAML::Section &Sec,
case wasm::R_WASM_MEMORY_ADDR_I32:
case wasm::R_WASM_MEMORY_ADDR_I64:
case wasm::R_WASM_FUNCTION_OFFSET_I32:
case wasm::R_WASM_FUNCTION_OFFSET_I64:
case wasm::R_WASM_SECTION_OFFSET_I32:
encodeULEB128(Reloc.Addend, OS);
}
Expand Down
Expand Up @@ -23,9 +23,7 @@ WebAssemblyMCAsmInfo::~WebAssemblyMCAsmInfo() = default; // anchor.

WebAssemblyMCAsmInfo::WebAssemblyMCAsmInfo(const Triple &T,
const MCTargetOptions &Options) {
CalleeSaveStackSlotSize = T.isArch64Bit() ? 8 : 4;
// So far this is used for DWARF DW_AT_low_pc which is always 32-bit in Wasm.
CodePointerSize = 4;
CodePointerSize = CalleeSaveStackSlotSize = T.isArch64Bit() ? 8 : 4;

// TODO: What should MaxInstLength be?

Expand Down
Expand Up @@ -131,7 +131,7 @@ unsigned WebAssemblyWasmObjectWriter::getRelocType(const MCValue &Target,
if (auto Section = static_cast<const MCSectionWasm *>(
getFixupSection(Fixup.getValue()))) {
if (Section->getKind().isText())
llvm_unreachable("unimplemented R_WASM_FUNCTION_OFFSET_I64");
return wasm::R_WASM_FUNCTION_OFFSET_I64;
else if (!Section->isWasmData())
llvm_unreachable("unimplemented R_WASM_SECTION_OFFSET_I64");
}
Expand Down

0 comments on commit 16f0243

Please sign in to comment.