From f44dcf6c5674966cdfbde543cda08334cc09c787 Mon Sep 17 00:00:00 2001 From: SingleAccretion Date: Thu, 3 Jul 2025 22:33:06 +0300 Subject: [PATCH 1/4] Add a test --- llvm/test/MC/WebAssembly/reloc-directive.s | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 llvm/test/MC/WebAssembly/reloc-directive.s 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 From 1e75b9bdb82a450df655b67871d7b691fd0ebab3 Mon Sep 17 00:00:00 2001 From: SingleAccretion Date: Thu, 3 Jul 2025 22:33:28 +0300 Subject: [PATCH 2/4] Implement the .reloc directive for WASM --- llvm/lib/MC/WasmObjectWriter.cpp | 8 ++++++-- .../MCTargetDesc/WebAssemblyAsmBackend.cpp | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) 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); From 798891a5ca2a215c6aa3cff26705ba7b167cb8e4 Mon Sep 17 00:00:00 2001 From: SingleAccretion Date: Mon, 7 Jul 2025 21:45:43 +0300 Subject: [PATCH 3/4] Address feedback --- llvm/test/MC/WebAssembly/reloc-directive.s | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/llvm/test/MC/WebAssembly/reloc-directive.s b/llvm/test/MC/WebAssembly/reloc-directive.s index dbe1d6595a4b4..bc234b928839a 100644 --- a/llvm/test/MC/WebAssembly/reloc-directive.s +++ b/llvm/test/MC/WebAssembly/reloc-directive.s @@ -1,29 +1,28 @@ # 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) +get_addr_func: + .functype get_addr_func () -> (i32) i32.const 0 + nop # 4 NOPs in addition to one zero in i32.const 0 for a canonical 5 byte relocatable [S]LEB. 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 +# PRINT: .reloc get_addr_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 +.reloc get_addr_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 +# PRINT: .reloc function_index_data, R_WASM_FUNCTION_INDEX_I32, get_addr_func # CHECK: Section ({{.*}}) DATA { -# CHECK-NEXT: 0x6 R_WASM_FUNCTION_INDEX_I32 load_function_index_func +# CHECK-NEXT: 0x6 R_WASM_FUNCTION_INDEX_I32 get_addr_func # CHECK-NEXT: } -.reloc function_index_data, R_WASM_FUNCTION_INDEX_I32, load_function_index_func +.reloc function_index_data, R_WASM_FUNCTION_INDEX_I32, get_addr_func From e7c4ba85dd5060a7e84d56de1a9de9e671491f7c Mon Sep 17 00:00:00 2001 From: SingleAccretion Date: Mon, 7 Jul 2025 22:44:45 +0300 Subject: [PATCH 4/4] FK_NONE -> {} --- .../Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp index 0e8198b214879..ad1ee32225422 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp @@ -78,7 +78,7 @@ WebAssemblyAsmBackend::getFixupKindInfo(MCFixupKind Kind) const { // 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); + return {}; if (Kind < FirstTargetFixupKind) return MCAsmBackend::getFixupKindInfo(Kind);