Skip to content

Commit 285fd29

Browse files
[WebAssembly] Implement the .reloc directive for WASM (llvm#146952)
The implementation follows what is done for ELF on other targets. Fixes llvm#100733.
1 parent ca6b539 commit 285fd29

File tree

3 files changed

+53
-2
lines changed

3 files changed

+53
-2
lines changed

llvm/lib/MC/WasmObjectWriter.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -528,8 +528,12 @@ void WasmObjectWriter::recordRelocation(const MCFragment &F,
528528
// be negative and don't wrap.
529529
FixedValue = 0;
530530

531-
unsigned Type =
532-
TargetObjectWriter->getRelocType(Target, Fixup, FixupSection, IsLocRel);
531+
unsigned Type;
532+
if (mc::isRelocRelocation(Fixup.getKind()))
533+
Type = Fixup.getKind() - FirstLiteralRelocationKind;
534+
else
535+
Type =
536+
TargetObjectWriter->getRelocType(Target, Fixup, FixupSection, IsLocRel);
533537

534538
// Absolute offset within a section or a function.
535539
// Currently only supported for metadata sections.

llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyAsmBackend.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include "MCTargetDesc/WebAssemblyFixupKinds.h"
1515
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
16+
#include "llvm/ADT/StringSwitch.h"
1617
#include "llvm/MC/MCAsmBackend.h"
1718
#include "llvm/MC/MCAssembler.h"
1819
#include "llvm/MC/MCExpr.h"
@@ -36,6 +37,7 @@ class WebAssemblyAsmBackend final : public MCAsmBackend {
3637
: MCAsmBackend(llvm::endianness::little), Is64Bit(Is64Bit),
3738
IsEmscripten(IsEmscripten) {}
3839

40+
std::optional<MCFixupKind> getFixupKind(StringRef Name) const override;
3941
MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override;
4042

4143
void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target,
@@ -48,6 +50,18 @@ class WebAssemblyAsmBackend final : public MCAsmBackend {
4850
const MCSubtargetInfo *STI) const override;
4951
};
5052

53+
std::optional<MCFixupKind>
54+
WebAssemblyAsmBackend::getFixupKind(StringRef Name) const {
55+
unsigned Type = llvm::StringSwitch<unsigned>(Name)
56+
#define WASM_RELOC(NAME, ID) .Case(#NAME, ID)
57+
#include "llvm/BinaryFormat/WasmRelocs.def"
58+
#undef WASM_RELOC
59+
.Default(-1u);
60+
if (Type != -1u)
61+
return static_cast<MCFixupKind>(FirstLiteralRelocationKind + Type);
62+
return std::nullopt;
63+
}
64+
5165
MCFixupKindInfo
5266
WebAssemblyAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
5367
const static MCFixupKindInfo Infos[WebAssembly::NumTargetFixupKinds] = {
@@ -61,6 +75,11 @@ WebAssemblyAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
6175
{"fixup_uleb128_i64", 0, 10 * 8, 0},
6276
};
6377

78+
// Fixup kinds from raw relocation types and .reloc directives force
79+
// relocations and do not use these fields.
80+
if (mc::isRelocation(Kind))
81+
return {};
82+
6483
if (Kind < FirstTargetFixupKind)
6584
return MCAsmBackend::getFixupKindInfo(Kind);
6685

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# RUN: llvm-mc -triple=wasm32 %s | FileCheck --check-prefix=PRINT %s
2+
# RUN: llvm-mc -filetype=obj -triple=wasm32 %s | llvm-readobj -r - | FileCheck %s
3+
4+
get_addr_func:
5+
.functype get_addr_func () -> (i32)
6+
i32.const 0
7+
nop # 4 NOPs in addition to one zero in i32.const 0 for a canonical 5 byte relocatable [S]LEB.
8+
nop
9+
nop
10+
nop
11+
end_function
12+
13+
# PRINT: .reloc get_addr_func+2, R_WASM_MEMORY_ADDR_SLEB, function_index_data+1
14+
# CHECK: Section ({{.*}}) CODE {
15+
# CHECK-NEXT: 0x4 R_WASM_MEMORY_ADDR_SLEB function_index_data 1
16+
# CHECK-NEXT: }
17+
.reloc get_addr_func + 2, R_WASM_MEMORY_ADDR_SLEB, function_index_data + 1
18+
19+
.section .data,"",@
20+
function_index_data:
21+
.int32 0
22+
.size function_index_data, 4
23+
24+
# PRINT: .reloc function_index_data, R_WASM_FUNCTION_INDEX_I32, get_addr_func
25+
# CHECK: Section ({{.*}}) DATA {
26+
# CHECK-NEXT: 0x6 R_WASM_FUNCTION_INDEX_I32 get_addr_func
27+
# CHECK-NEXT: }
28+
.reloc function_index_data, R_WASM_FUNCTION_INDEX_I32, get_addr_func

0 commit comments

Comments
 (0)