[llvm] [WebAssembly] Implement the `.reloc` directive for WASM (PR #146952)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 7 11:45:57 PDT 2025
https://github.com/SingleAccretion updated https://github.com/llvm/llvm-project/pull/146952
>From f44dcf6c5674966cdfbde543cda08334cc09c787 Mon Sep 17 00:00:00 2001
From: SingleAccretion <AccretionMail at yandex.ru>
Date: Thu, 3 Jul 2025 22:33:06 +0300
Subject: [PATCH 1/3] 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 <AccretionMail at yandex.ru>
Date: Thu, 3 Jul 2025 22:33:28 +0300
Subject: [PATCH 2/3] 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<MCFixupKind> 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<MCFixupKind>
+WebAssemblyAsmBackend::getFixupKind(StringRef Name) const {
+ unsigned Type = llvm::StringSwitch<unsigned>(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<MCFixupKind>(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 <AccretionMail at yandex.ru>
Date: Mon, 7 Jul 2025 21:45:43 +0300
Subject: [PATCH 3/3] 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
More information about the llvm-commits
mailing list