Skip to content

Commit c389526

Browse files
committed
[MC][ARM] Make .reloc support arbitrary relocation types
Generalizes D61992. In GNU as, the .reloc directive supports arbitrary relocation types. A MCFixupKind value `V` larger than or equal to FirstLiteralRelocationKind is used to represent the relocation type whose number is V-FirstLiteralRelocationKind. This is useful for linker tests. Without the feature the assembler cannot produce certain relocation records (e.g. R_ARM_ALU_PC_G0/R_ARM_LDR_PC_G0) This helps move forward D75349 and D76575. Differential Revision: https://reviews.llvm.org/D76746
1 parent ee7510d commit c389526

File tree

5 files changed

+51
-21
lines changed

5 files changed

+51
-21
lines changed

llvm/include/llvm/MC/MCFixup.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,14 @@ enum MCFixupKind {
5555

5656
FirstTargetFixupKind = 128,
5757

58-
// Limit range of target fixups, in case we want to pack more efficiently
59-
// later.
60-
MaxTargetFixupKind = (1 << 8)
58+
/// The range [FirstLiteralRelocationKind, MaxTargetFixupKind) is used for
59+
/// relocations coming from .reloc directive. Fixup kind
60+
/// FirstLiteralRelocationKind+V represents the relocation type with number V.
61+
FirstLiteralRelocationKind = 256,
62+
63+
/// Set limit to accommodate the highest reloc type in use for all Targets,
64+
/// currently R_AARCH64_IRELATIVE at 1032, including room for expansion.
65+
MaxFixupKind = FirstLiteralRelocationKind + 1032 + 32,
6166
};
6267

6368
/// Encode information on a single operation to perform on a byte
@@ -92,7 +97,7 @@ class MCFixup {
9297
public:
9398
static MCFixup create(uint32_t Offset, const MCExpr *Value,
9499
MCFixupKind Kind, SMLoc Loc = SMLoc()) {
95-
assert(Kind < MaxTargetFixupKind && "Kind out of range!");
100+
assert(Kind <= MaxFixupKind && "Kind out of range!");
96101
MCFixup FI;
97102
FI.Value = Value;
98103
FI.Offset = Offset;

llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,17 @@ class ARMELFObjectWriter : public MCELFObjectTargetWriter {
4848
} // end anonymous namespace
4949

5050
Optional<MCFixupKind> ARMAsmBackend::getFixupKind(StringRef Name) const {
51-
if (STI.getTargetTriple().isOSBinFormatELF() && Name == "R_ARM_NONE")
52-
return FK_NONE;
53-
54-
return MCAsmBackend::getFixupKind(Name);
51+
if (!STI.getTargetTriple().isOSBinFormatELF())
52+
return None;
53+
54+
unsigned Type = llvm::StringSwitch<unsigned>(Name)
55+
#define ELF_RELOC(X, Y) .Case(#X, Y)
56+
#include "llvm/BinaryFormat/ELFRelocs/ARM.def"
57+
#undef ELF_RELOC
58+
.Default(-1u);
59+
if (Type == -1u)
60+
return None;
61+
return static_cast<MCFixupKind>(FirstLiteralRelocationKind + Type);
5562
}
5663

5764
const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
@@ -172,6 +179,11 @@ const MCFixupKindInfo &ARMAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
172179
{"fixup_le", 0, 32, MCFixupKindInfo::FKF_IsPCRel}
173180
};
174181

182+
// Fixup kinds from .reloc directive are like R_ARM_NONE. They do not require
183+
// any extra processing.
184+
if (Kind >= FirstLiteralRelocationKind)
185+
return MCAsmBackend::getFixupKindInfo(FK_NONE);
186+
175187
if (Kind < FirstTargetFixupKind)
176188
return MCAsmBackend::getFixupKindInfo(Kind);
177189

@@ -438,7 +450,6 @@ unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm,
438450
default:
439451
Ctx.reportError(Fixup.getLoc(), "bad relocation fixup type");
440452
return 0;
441-
case FK_NONE:
442453
case FK_Data_1:
443454
case FK_Data_2:
444455
case FK_Data_4:
@@ -871,7 +882,7 @@ bool ARMAsmBackend::shouldForceRelocation(const MCAssembler &Asm,
871882
const MCSymbolRefExpr *A = Target.getSymA();
872883
const MCSymbol *Sym = A ? &A->getSymbol() : nullptr;
873884
const unsigned FixupKind = Fixup.getKind();
874-
if (FixupKind == FK_NONE)
885+
if (FixupKind >= FirstLiteralRelocationKind)
875886
return true;
876887
if (FixupKind == ARM::fixup_arm_thumb_bl) {
877888
assert(Sym && "How did we resolve this?");
@@ -915,9 +926,6 @@ static unsigned getFixupKindNumBytes(unsigned Kind) {
915926
default:
916927
llvm_unreachable("Unknown fixup kind!");
917928

918-
case FK_NONE:
919-
return 0;
920-
921929
case FK_Data_1:
922930
case ARM::fixup_arm_thumb_bcc:
923931
case ARM::fixup_arm_thumb_cp:
@@ -979,9 +987,6 @@ static unsigned getFixupKindContainerSizeBytes(unsigned Kind) {
979987
default:
980988
llvm_unreachable("Unknown fixup kind!");
981989

982-
case FK_NONE:
983-
return 0;
984-
985990
case FK_Data_1:
986991
return 1;
987992
case FK_Data_2:
@@ -1037,7 +1042,10 @@ void ARMAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
10371042
MutableArrayRef<char> Data, uint64_t Value,
10381043
bool IsResolved,
10391044
const MCSubtargetInfo* STI) const {
1040-
unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
1045+
unsigned Kind = Fixup.getKind();
1046+
if (Kind >= FirstLiteralRelocationKind)
1047+
return;
1048+
unsigned NumBytes = getFixupKindNumBytes(Kind);
10411049
MCContext &Ctx = Asm.getContext();
10421050
Value = adjustFixupValue(Asm, Fixup, Target, Value, IsResolved, Ctx, STI);
10431051
if (!Value)
@@ -1049,7 +1057,7 @@ void ARMAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
10491057
// Used to point to big endian bytes.
10501058
unsigned FullSizeBytes;
10511059
if (Endian == support::big) {
1052-
FullSizeBytes = getFixupKindContainerSizeBytes(Fixup.getKind());
1060+
FullSizeBytes = getFixupKindContainerSizeBytes(Kind);
10531061
assert((Offset + FullSizeBytes) <= Data.size() && "Invalid fixup size!");
10541062
assert(NumBytes <= FullSizeBytes && "Invalid fixup size!");
10551063
}

llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
7979
const MCFixup &Fixup,
8080
bool IsPCRel,
8181
MCContext &Ctx) const {
82+
unsigned Kind = Fixup.getTargetKind();
83+
if (Kind >= FirstLiteralRelocationKind)
84+
return Kind - FirstLiteralRelocationKind;
8285
MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
8386

8487
if (IsPCRel) {
@@ -152,12 +155,10 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
152155
return ELF::R_ARM_THM_BF18;
153156
}
154157
}
155-
switch (Fixup.getTargetKind()) {
158+
switch (Kind) {
156159
default:
157160
Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol");
158161
return ELF::R_ARM_NONE;
159-
case FK_NONE:
160-
return ELF::R_ARM_NONE;
161162
case FK_Data_1:
162163
switch (Modifier) {
163164
default:
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# RUN: llvm-mc -triple=armv7 %s 2>&1 | FileCheck --check-prefix=PRINT %s
2+
# RUN: not llvm-mc -filetype=obj -triple=armv7 %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/ARM/reloc-directive.s

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
.reloc 4, R_ARM_NONE, foo+4
1818
.reloc 0, R_ARM_NONE, 8
1919

20+
.reloc 0, R_ARM_ALU_PC_G0, .data+2
21+
.reloc 0, R_ARM_LDR_PC_G0, foo+3
22+
.reloc 0, R_ARM_THM_ALU_PREL_11_0, 5
23+
2024
.data
2125
.globl foo
2226
foo:
@@ -27,11 +31,17 @@ foo:
2731
# PRINT: .reloc 8, R_ARM_NONE, .data
2832
# PRINT: .reloc 4, R_ARM_NONE, foo+4
2933
# PRINT: .reloc 0, R_ARM_NONE, 8
34+
# PRINT: .reloc 0, R_ARM_ALU_PC_G0, .data+2
35+
# PRINT: .reloc 0, R_ARM_LDR_PC_G0, foo+3
36+
# PRINT: .reloc 0, R_ARM_THM_ALU_PREL_11_0, 5
3037

3138
# ARM relocations use the Elf32_Rel format. Addends are neither stored in the
3239
# relocation entries nor applied in the referenced locations.
3340
# CHECK: 0x8 R_ARM_NONE .data 0x0
3441
# CHECK-NEXT: 0x4 R_ARM_NONE foo 0x0
3542
# CHECK-NEXT: 0x0 R_ARM_NONE - 0x0
43+
# CHECK-NEXT: 0x0 R_ARM_ALU_PC_G0 .data 0x0
44+
# CHECK-NEXT: 0x0 R_ARM_LDR_PC_G0 foo 0x0
45+
# CHECK-NEXT: 0x0 R_ARM_THM_ALU_PREL_11_0 - 0x0
3646

3747
# HEX: 0x00000000 00000000 00000000

0 commit comments

Comments
 (0)