diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp index 3b82fb782f888..7e07d163b8869 100644 --- a/llvm/lib/MC/WasmObjectWriter.cpp +++ b/llvm/lib/MC/WasmObjectWriter.cpp @@ -530,8 +530,12 @@ void WasmObjectWriter::recordRelocation(const MCFragment &F, // be negative and don't wrap. FixedValue = 0; - unsigned Type = - TargetObjectWriter->getRelocType(Target, Fixup, FixupSection, IsLocRel); + unsigned Type; + if (mc::isRelocRelocation(Fixup.getKind())) + Type = Fixup.getKind() - FirstLiteralRelocationKind; + else + Type = + TargetObjectWriter->getRelocType(Target, Fixup, FixupSection, IsLocRel); // Absolute offset within a section or a function. // Currently only supported for metadata sections. diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp index 7bc672c069476..0e8198b214879 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp @@ -13,6 +13,7 @@ #include "MCTargetDesc/WebAssemblyFixupKinds.h" #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCExpr.h" @@ -36,6 +37,7 @@ class WebAssemblyAsmBackend final : public MCAsmBackend { : MCAsmBackend(llvm::endianness::little), Is64Bit(Is64Bit), IsEmscripten(IsEmscripten) {} + std::optional getFixupKind(StringRef Name) const override; MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override; void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target, @@ -48,6 +50,18 @@ class WebAssemblyAsmBackend final : public MCAsmBackend { const MCSubtargetInfo *STI) const override; }; +std::optional +WebAssemblyAsmBackend::getFixupKind(StringRef Name) const { + unsigned Type = llvm::StringSwitch(Name) +#define WASM_RELOC(NAME, ID) .Case(#NAME, ID) +#include "llvm/BinaryFormat/WasmRelocs.def" +#undef WASM_RELOC + .Default(-1u); + if (Type != -1u) + return static_cast(FirstLiteralRelocationKind + Type); + return std::nullopt; +} + MCFixupKindInfo WebAssemblyAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { const static MCFixupKindInfo Infos[WebAssembly::NumTargetFixupKinds] = { @@ -61,6 +75,11 @@ WebAssemblyAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { {"fixup_uleb128_i64", 0, 10 * 8, 0}, }; + // Fixup kinds from raw relocation types and .reloc directives force + // relocations and do not use these fields. + if (mc::isRelocation(Kind)) + return MCAsmBackend::getFixupKindInfo(FK_NONE); + if (Kind < FirstTargetFixupKind) return MCAsmBackend::getFixupKindInfo(Kind); diff --git a/llvm/test/MC/WebAssembly/reloc-directive.s b/llvm/test/MC/WebAssembly/reloc-directive.s new file mode 100644 index 0000000000000..dbe1d6595a4b4 --- /dev/null +++ b/llvm/test/MC/WebAssembly/reloc-directive.s @@ -0,0 +1,29 @@ +# RUN: llvm-mc -triple=wasm32 %s | FileCheck --check-prefix=PRINT %s +# RUN: llvm-mc -filetype=obj -triple=wasm32 %s | llvm-readobj -r - | FileCheck %s + +load_function_index_func: + .functype load_function_index_func () -> (i32) + i32.const 0 + nop + nop + nop + nop + i32.load 0 + end_function + +# PRINT: .reloc load_function_index_func+2, R_WASM_MEMORY_ADDR_SLEB, function_index_data+1 +# CHECK: Section ({{.*}}) CODE { +# CHECK-NEXT: 0x4 R_WASM_MEMORY_ADDR_SLEB function_index_data 1 +# CHECK-NEXT: } +.reloc load_function_index_func + 2, R_WASM_MEMORY_ADDR_SLEB, function_index_data + 1 + +.section .data,"",@ +function_index_data: + .int32 0 +.size function_index_data, 4 + +# PRINT: .reloc function_index_data, R_WASM_FUNCTION_INDEX_I32, load_function_index_func +# CHECK: Section ({{.*}}) DATA { +# CHECK-NEXT: 0x6 R_WASM_FUNCTION_INDEX_I32 load_function_index_func +# CHECK-NEXT: } +.reloc function_index_data, R_WASM_FUNCTION_INDEX_I32, load_function_index_func