Skip to content

Commit 2167881

Browse files
committed
[ARM,MC] Support FDPIC relocations
Linux kernel fs/binfmt_elf_fdpic.c supports FDPIC for MMU-less systems. GCC/binutils/qemu support FDPIC ABI for ARM (https://github.com/mickael-guene/fdpic_doc). _ARM FDPIC Toolchain and ABI_ provides a summary. This patch implements FDPIC relocations to the integrated assembler. There are 6 static relocations and 2 dynamic relocations, with R_ARM_FUNCDESC as both static and dynamic. gas requires `--fdpic` to assemble data relocations like `.word f(FUNCDESC)`. This patch adds `MCTargetOptions::FDPIC` and reports an error if FDPIC is not set. Pull Request: #82187
1 parent c5bbf97 commit 2167881

File tree

19 files changed

+153
-11
lines changed

19 files changed

+153
-11
lines changed

llvm/include/llvm/BinaryFormat/ELF.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ enum {
362362
ELFOSABI_AMDGPU_PAL = 65, // AMD PAL runtime
363363
ELFOSABI_AMDGPU_MESA3D = 66, // AMD GCN GPUs (GFX6+) for MESA runtime
364364
ELFOSABI_ARM = 97, // ARM
365+
ELFOSABI_ARM_FDPIC = 65, // ARM FDPIC
365366
ELFOSABI_C6000_ELFABI = 64, // Bare-metal TMS320C6000
366367
ELFOSABI_C6000_LINUX = 65, // Linux TMS320C6000
367368
ELFOSABI_STANDALONE = 255, // Standalone (embedded) application

llvm/include/llvm/BinaryFormat/ELFRelocs/ARM.def

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,10 @@ ELF_RELOC(R_ARM_THM_BF16, 0x88)
143143
ELF_RELOC(R_ARM_THM_BF12, 0x89)
144144
ELF_RELOC(R_ARM_THM_BF18, 0x8a)
145145
ELF_RELOC(R_ARM_IRELATIVE, 0xa0)
146+
ELF_RELOC(R_ARM_GOTFUNCDESC, 0xa1)
147+
ELF_RELOC(R_ARM_GOTOFFFUNCDESC, 0xa2)
148+
ELF_RELOC(R_ARM_FUNCDESC, 0xa3)
149+
ELF_RELOC(R_ARM_FUNCDESC_VALUE, 0xa4)
150+
ELF_RELOC(R_ARM_TLS_GD32_FDPIC, 0xa5)
151+
ELF_RELOC(R_ARM_TLS_LDM32_FDPIC, 0xa6)
152+
ELF_RELOC(R_ARM_TLS_IE32_FDPIC, 0xa7)

llvm/include/llvm/MC/MCExpr.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,12 @@ class MCSymbolRefExpr : public MCExpr {
223223
VK_SECREL,
224224
VK_SIZE, // symbol@SIZE
225225
VK_WEAKREF, // The link between the symbols in .weakref foo, bar
226+
VK_FUNCDESC,
227+
VK_GOTFUNCDESC,
228+
VK_GOTOFFFUNCDESC,
229+
VK_TLSGD_FDPIC,
230+
VK_TLSLDM_FDPIC,
231+
VK_GOTTPOFF_FDPIC,
226232

227233
VK_X86_ABS8,
228234
VK_X86_PLTOFF,

llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,10 @@ class MCTargetAsmParser : public MCAsmParserExtension {
525525
// Return whether this parser accept star as start of statement
526526
virtual bool starIsStartOfStatement() { return false; };
527527

528+
virtual MCSymbolRefExpr::VariantKind
529+
getVariantKindForName(StringRef Name) const {
530+
return MCSymbolRefExpr::getVariantKindForName(Name);
531+
}
528532
virtual const MCExpr *applyModifierToExpr(const MCExpr *E,
529533
MCSymbolRefExpr::VariantKind,
530534
MCContext &Ctx) {

llvm/include/llvm/MC/MCTargetOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class MCTargetOptions {
5151
bool MCNoTypeCheck : 1;
5252
bool MCSaveTempLabels : 1;
5353
bool MCIncrementalLinkerCompatible : 1;
54+
bool FDPIC : 1;
5455
bool ShowMCEncoding : 1;
5556
bool ShowMCInst : 1;
5657
bool AsmVerbose : 1;

llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ std::optional<bool> getExplicitRelaxAll();
2929

3030
bool getIncrementalLinkerCompatible();
3131

32+
bool getFDPIC();
33+
3234
int getDwarfVersion();
3335

3436
bool getDwarf64();

llvm/lib/MC/MCExpr.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ const MCSymbolRefExpr *MCSymbolRefExpr::create(StringRef Name, VariantKind Kind,
220220

221221
StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
222222
switch (Kind) {
223+
// clang-format off
223224
case VK_Invalid: return "<<invalid>>";
224225
case VK_None: return "<<none>>";
225226

@@ -232,13 +233,16 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
232233
case VK_GOTPCREL: return "GOTPCREL";
233234
case VK_GOTPCREL_NORELAX: return "GOTPCREL_NORELAX";
234235
case VK_GOTTPOFF: return "GOTTPOFF";
236+
case VK_GOTTPOFF_FDPIC: return "gottpoff_fdpic";
235237
case VK_INDNTPOFF: return "INDNTPOFF";
236238
case VK_NTPOFF: return "NTPOFF";
237239
case VK_GOTNTPOFF: return "GOTNTPOFF";
238240
case VK_PLT: return "PLT";
239241
case VK_TLSGD: return "TLSGD";
242+
case VK_TLSGD_FDPIC: return "tlsgd_fdpic";
240243
case VK_TLSLD: return "TLSLD";
241244
case VK_TLSLDM: return "TLSLDM";
245+
case VK_TLSLDM_FDPIC: return "tlsldm_fdpic";
242246
case VK_TPOFF: return "TPOFF";
243247
case VK_TPREL: return "TPREL";
244248
case VK_TLSCALL: return "tlscall";
@@ -253,6 +257,9 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
253257
case VK_SECREL: return "SECREL32";
254258
case VK_SIZE: return "SIZE";
255259
case VK_WEAKREF: return "WEAKREF";
260+
case VK_FUNCDESC: return "FUNCDESC";
261+
case VK_GOTFUNCDESC: return "GOTFUNCDESC";
262+
case VK_GOTOFFFUNCDESC: return "GOTOFFFUNCDESC";
256263
case VK_X86_ABS8: return "ABS8";
257264
case VK_X86_PLTOFF: return "PLTOFF";
258265
case VK_ARM_NONE: return "none";
@@ -386,6 +393,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
386393
case VK_VE_TLS_GD_LO32: return "tls_gd_lo";
387394
case VK_VE_TPOFF_HI32: return "tpoff_hi";
388395
case VK_VE_TPOFF_LO32: return "tpoff_lo";
396+
// clang-format on
389397
}
390398
llvm_unreachable("Invalid variant kind");
391399
}
@@ -493,13 +501,6 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
493501
.Case("ie", VK_Hexagon_IE)
494502
.Case("ldgot", VK_Hexagon_LD_GOT)
495503
.Case("ldplt", VK_Hexagon_LD_PLT)
496-
.Case("none", VK_ARM_NONE)
497-
.Case("got_prel", VK_ARM_GOT_PREL)
498-
.Case("target1", VK_ARM_TARGET1)
499-
.Case("target2", VK_ARM_TARGET2)
500-
.Case("prel31", VK_ARM_PREL31)
501-
.Case("sbrel", VK_ARM_SBREL)
502-
.Case("tlsldo", VK_ARM_TLSLDO)
503504
.Case("lo8", VK_AVR_LO8)
504505
.Case("hi8", VK_AVR_HI8)
505506
.Case("hlo8", VK_AVR_HLO8)

llvm/lib/MC/MCParser/AsmParser.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1237,7 +1237,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
12371237

12381238
// Lookup the symbol variant if used.
12391239
if (!Split.second.empty()) {
1240-
Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
1240+
Variant = getTargetParser().getVariantKindForName(Split.second);
12411241
if (Variant != MCSymbolRefExpr::VK_Invalid) {
12421242
SymbolName = Split.first;
12431243
} else if (MAI.doesAllowAtInName() && !MAI.useParensForSymbolVariant()) {

llvm/lib/MC/MCTargetOptions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ MCTargetOptions::MCTargetOptions()
1515
: MCRelaxAll(false), MCNoExecStack(false), MCFatalWarnings(false),
1616
MCNoWarn(false), MCNoDeprecatedWarn(false), MCNoTypeCheck(false),
1717
MCSaveTempLabels(false), MCIncrementalLinkerCompatible(false),
18-
ShowMCEncoding(false), ShowMCInst(false), AsmVerbose(false),
18+
FDPIC(false), ShowMCEncoding(false), ShowMCInst(false), AsmVerbose(false),
1919
PreserveAsmComments(true), Dwarf64(false),
2020
EmitDwarfUnwind(EmitDwarfUnwindType::Default),
2121
MCUseDwarfDirectory(DefaultDwarfDirectory),

llvm/lib/MC/MCTargetOptionsCommandFlags.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ using namespace llvm;
3636

3737
MCOPT_EXP(bool, RelaxAll)
3838
MCOPT(bool, IncrementalLinkerCompatible)
39+
MCOPT(bool, FDPIC)
3940
MCOPT(int, DwarfVersion)
4041
MCOPT(bool, Dwarf64)
4142
MCOPT(EmitDwarfUnwindType, EmitDwarfUnwind)
@@ -66,6 +67,9 @@ llvm::mc::RegisterMCTargetOptionsFlags::RegisterMCTargetOptionsFlags() {
6667
"emit an object file which can be used with an incremental linker"));
6768
MCBINDOPT(IncrementalLinkerCompatible);
6869

70+
static cl::opt<bool> FDPIC("fdpic", cl::desc("Use the FDPIC ABI"));
71+
MCBINDOPT(FDPIC);
72+
6973
static cl::opt<int> DwarfVersion("dwarf-version", cl::desc("Dwarf version"),
7074
cl::init(0));
7175
MCBINDOPT(DwarfVersion);
@@ -135,6 +139,7 @@ MCTargetOptions llvm::mc::InitMCTargetOptionsFromFlags() {
135139
MCTargetOptions Options;
136140
Options.MCRelaxAll = getRelaxAll();
137141
Options.MCIncrementalLinkerCompatible = getIncrementalLinkerCompatible();
142+
Options.FDPIC = getFDPIC();
138143
Options.Dwarf64 = getDwarf64();
139144
Options.DwarfVersion = getDwarfVersion();
140145
Options.ShowMCInst = getShowMCInst();

0 commit comments

Comments
 (0)