[llvm] [WebAssembly] Implement the `.reloc` directive for WASM (PR #146952)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 3 13:29:15 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mc

@llvm/pr-subscribers-backend-webassembly

Author: None (SingleAccretion)

<details>
<summary>Changes</summary>

The implementation follows what is done for ELF on other targets.

Fixed #<!-- -->100733.

---
Full diff: https://github.com/llvm/llvm-project/pull/146952.diff


3 Files Affected:

- (modified) llvm/lib/MC/WasmObjectWriter.cpp (+6-2) 
- (modified) llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp (+19) 
- (added) llvm/test/MC/WebAssembly/reloc-directive.s (+29) 


``````````diff
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);
 
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

``````````

</details>


https://github.com/llvm/llvm-project/pull/146952


More information about the llvm-commits mailing list