Skip to content

Commit a7aaaf7

Browse files
committed
[MC][RISCV] Make .reloc support arbitrary relocation types
Similar to D76746 (ARM), D76754 (AArch64) and llvmorg-11-init-6967-g152d14da64c (x86) Differential Revision: https://reviews.llvm.org/D77018
1 parent 4593e41 commit a7aaaf7

File tree

5 files changed

+114
-42
lines changed

5 files changed

+114
-42
lines changed

llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,75 @@
2323

2424
using namespace llvm;
2525

26+
Optional<MCFixupKind> RISCVAsmBackend::getFixupKind(StringRef Name) const {
27+
if (STI.getTargetTriple().isOSBinFormatELF()) {
28+
unsigned Type;
29+
Type = llvm::StringSwitch<unsigned>(Name)
30+
#define ELF_RELOC(X, Y) .Case(#X, Y)
31+
#include "llvm/BinaryFormat/ELFRelocs/RISCV.def"
32+
#undef ELF_RELOC
33+
.Default(-1u);
34+
if (Type != -1u)
35+
return static_cast<MCFixupKind>(FirstLiteralRelocationKind + Type);
36+
}
37+
return None;
38+
}
39+
40+
const MCFixupKindInfo &
41+
RISCVAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
42+
const static MCFixupKindInfo Infos[] = {
43+
// This table *must* be in the order that the fixup_* kinds are defined in
44+
// RISCVFixupKinds.h.
45+
//
46+
// name offset bits flags
47+
{"fixup_riscv_hi20", 12, 20, 0},
48+
{"fixup_riscv_lo12_i", 20, 12, 0},
49+
{"fixup_riscv_lo12_s", 0, 32, 0},
50+
{"fixup_riscv_pcrel_hi20", 12, 20,
51+
MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsTarget},
52+
{"fixup_riscv_pcrel_lo12_i", 20, 12,
53+
MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsTarget},
54+
{"fixup_riscv_pcrel_lo12_s", 0, 32,
55+
MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsTarget},
56+
{"fixup_riscv_got_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel},
57+
{"fixup_riscv_tprel_hi20", 12, 20, 0},
58+
{"fixup_riscv_tprel_lo12_i", 20, 12, 0},
59+
{"fixup_riscv_tprel_lo12_s", 0, 32, 0},
60+
{"fixup_riscv_tprel_add", 0, 0, 0},
61+
{"fixup_riscv_tls_got_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel},
62+
{"fixup_riscv_tls_gd_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel},
63+
{"fixup_riscv_jal", 12, 20, MCFixupKindInfo::FKF_IsPCRel},
64+
{"fixup_riscv_branch", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
65+
{"fixup_riscv_rvc_jump", 2, 11, MCFixupKindInfo::FKF_IsPCRel},
66+
{"fixup_riscv_rvc_branch", 0, 16, MCFixupKindInfo::FKF_IsPCRel},
67+
{"fixup_riscv_call", 0, 64, MCFixupKindInfo::FKF_IsPCRel},
68+
{"fixup_riscv_call_plt", 0, 64, MCFixupKindInfo::FKF_IsPCRel},
69+
{"fixup_riscv_relax", 0, 0, 0},
70+
{"fixup_riscv_align", 0, 0, 0}};
71+
static_assert((array_lengthof(Infos)) == RISCV::NumTargetFixupKinds,
72+
"Not all fixup kinds added to Infos array");
73+
74+
// Fixup kinds from .reloc directive are like R_RISCV_NONE. They
75+
// do not require any extra processing.
76+
if (Kind >= FirstLiteralRelocationKind)
77+
return MCAsmBackend::getFixupKindInfo(FK_NONE);
78+
79+
if (Kind < FirstTargetFixupKind)
80+
return MCAsmBackend::getFixupKindInfo(Kind);
81+
82+
assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
83+
"Invalid kind!");
84+
return Infos[Kind - FirstTargetFixupKind];
85+
}
86+
2687
// If linker relaxation is enabled, or the relax option had previously been
2788
// enabled, always emit relocations even if the fixup can be resolved. This is
2889
// necessary for correctness as offsets may change during relaxation.
2990
bool RISCVAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
3091
const MCFixup &Fixup,
3192
const MCValue &Target) {
93+
if (Fixup.getKind() >= FirstLiteralRelocationKind)
94+
return true;
3295
switch (Fixup.getTargetKind()) {
3396
default:
3497
break;
@@ -318,8 +381,11 @@ void RISCVAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
318381
MutableArrayRef<char> Data, uint64_t Value,
319382
bool IsResolved,
320383
const MCSubtargetInfo *STI) const {
384+
MCFixupKind Kind = Fixup.getKind();
385+
if (Kind >= FirstLiteralRelocationKind)
386+
return;
321387
MCContext &Ctx = Asm.getContext();
322-
MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind());
388+
MCFixupKindInfo Info = getFixupKindInfo(Kind);
323389
if (!Value)
324390
return; // Doesn't change encoding.
325391
// Apply any target-specific value adjustments.

llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h

Lines changed: 3 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -97,47 +97,9 @@ class RISCVAsmBackend : public MCAsmBackend {
9797
return RISCV::NumTargetFixupKinds;
9898
}
9999

100-
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
101-
const static MCFixupKindInfo Infos[] = {
102-
// This table *must* be in the order that the fixup_* kinds are defined in
103-
// RISCVFixupKinds.h.
104-
//
105-
// name offset bits flags
106-
{ "fixup_riscv_hi20", 12, 20, 0 },
107-
{ "fixup_riscv_lo12_i", 20, 12, 0 },
108-
{ "fixup_riscv_lo12_s", 0, 32, 0 },
109-
{ "fixup_riscv_pcrel_hi20", 12, 20,
110-
MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsTarget },
111-
{ "fixup_riscv_pcrel_lo12_i", 20, 12,
112-
MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsTarget },
113-
{ "fixup_riscv_pcrel_lo12_s", 0, 32,
114-
MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsTarget },
115-
{ "fixup_riscv_got_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel },
116-
{ "fixup_riscv_tprel_hi20", 12, 20, 0 },
117-
{ "fixup_riscv_tprel_lo12_i", 20, 12, 0 },
118-
{ "fixup_riscv_tprel_lo12_s", 0, 32, 0 },
119-
{ "fixup_riscv_tprel_add", 0, 0, 0 },
120-
{ "fixup_riscv_tls_got_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel },
121-
{ "fixup_riscv_tls_gd_hi20", 12, 20, MCFixupKindInfo::FKF_IsPCRel },
122-
{ "fixup_riscv_jal", 12, 20, MCFixupKindInfo::FKF_IsPCRel },
123-
{ "fixup_riscv_branch", 0, 32, MCFixupKindInfo::FKF_IsPCRel },
124-
{ "fixup_riscv_rvc_jump", 2, 11, MCFixupKindInfo::FKF_IsPCRel },
125-
{ "fixup_riscv_rvc_branch", 0, 16, MCFixupKindInfo::FKF_IsPCRel },
126-
{ "fixup_riscv_call", 0, 64, MCFixupKindInfo::FKF_IsPCRel },
127-
{ "fixup_riscv_call_plt", 0, 64, MCFixupKindInfo::FKF_IsPCRel },
128-
{ "fixup_riscv_relax", 0, 0, 0 },
129-
{ "fixup_riscv_align", 0, 0, 0 }
130-
};
131-
static_assert((array_lengthof(Infos)) == RISCV::NumTargetFixupKinds,
132-
"Not all fixup kinds added to Infos array");
133-
134-
if (Kind < FirstTargetFixupKind)
135-
return MCAsmBackend::getFixupKindInfo(Kind);
136-
137-
assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
138-
"Invalid kind!");
139-
return Infos[Kind - FirstTargetFixupKind];
140-
}
100+
Optional<MCFixupKind> getFixupKind(StringRef Name) const override;
101+
102+
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
141103

142104
bool mayNeedRelaxation(const MCInst &Inst,
143105
const MCSubtargetInfo &STI) const override;

llvm/lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx,
5252
const MCExpr *Expr = Fixup.getValue();
5353
// Determine the type of the relocation
5454
unsigned Kind = Fixup.getTargetKind();
55+
if (Kind >= FirstLiteralRelocationKind)
56+
return Kind - FirstLiteralRelocationKind;
5557
if (IsPCRel) {
5658
switch (Kind) {
5759
default:
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# RUN: llvm-mc -triple=riscv64 %s 2>&1 | FileCheck --check-prefix=PRINT %s
2+
# RUN: not llvm-mc -filetype=obj -triple=riscv64 %s -o /dev/null 2>&1 | FileCheck %s
3+
4+
# PRINT: .reloc 0, R_INVALID, 0
5+
# CHECK: {{.*}}.s:[[# @LINE+1]]:11: error: unknown relocation name
6+
.reloc 0, R_INVALID, 0

llvm/test/MC/RISCV/reloc-directive.s

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# RUN: llvm-mc -triple=riscv32 %s | FileCheck --check-prefix=PRINT %s
2+
# RUN: llvm-mc -triple=riscv64 %s | FileCheck --check-prefix=PRINT %s
3+
# RUN: llvm-mc -filetype=obj -triple=riscv32 %s | llvm-readobj -r | FileCheck %s
4+
# RUN: llvm-mc -filetype=obj -triple=riscv64 %s | llvm-readobj -r | FileCheck %s
5+
6+
# PRINT: .reloc 8, R_RISCV_NONE, .data
7+
# PRINT: .reloc 4, R_RISCV_NONE, foo+4
8+
# PRINT: .reloc 0, R_RISCV_NONE, 8
9+
# PRINT: .reloc 0, R_RISCV_32, .data+2
10+
# PRINT: .reloc 0, R_RISCV_SET32, foo+3
11+
# PRINT: .reloc 0, R_RISCV_32_PCREL, 5
12+
13+
# CHECK: 0x8 R_RISCV_NONE .data 0x0
14+
# CHECK-NEXT: 0x4 R_RISCV_NONE foo 0x4
15+
# CHECK-NEXT: 0x0 R_RISCV_NONE - 0x8
16+
# CHECK-NEXT: 0x0 R_RISCV_32 .data 0x2
17+
# CHECK-NEXT: 0x0 R_RISCV_SET32 foo 0x3
18+
# CHECK-NEXT: 0x0 R_RISCV_32_PCREL - 0x5
19+
.text
20+
ret
21+
nop
22+
nop
23+
.reloc 8, R_RISCV_NONE, .data
24+
.reloc 4, R_RISCV_NONE, foo+4
25+
.reloc 0, R_RISCV_NONE, 8
26+
27+
.reloc 0, R_RISCV_32, .data+2
28+
.reloc 0, R_RISCV_SET32, foo+3
29+
.reloc 0, R_RISCV_32_PCREL, 5
30+
31+
.data
32+
.globl foo
33+
foo:
34+
.word 0
35+
.word 0
36+
.word 0

0 commit comments

Comments
 (0)