[llvm-branch-commits] [ARM, MC] Support FDPIC relocations (PR #82187)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Feb 18 11:28:24 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mc
@llvm/pr-subscribers-llvm-binary-utilities
@llvm/pr-subscribers-objectyaml
Author: Fangrui Song (MaskRay)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/82187.diff
18 Files Affected:
- (modified) llvm/include/llvm/BinaryFormat/ELF.h (+1)
- (modified) llvm/include/llvm/BinaryFormat/ELFRelocs/ARM.def (+7)
- (modified) llvm/include/llvm/MC/MCExpr.h (+6)
- (modified) llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h (+4)
- (modified) llvm/include/llvm/MC/MCTargetOptions.h (+1)
- (modified) llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h (+2)
- (modified) llvm/lib/MC/MCExpr.cpp (+8-7)
- (modified) llvm/lib/MC/MCParser/AsmParser.cpp (+1-1)
- (modified) llvm/lib/MC/MCTargetOptions.cpp (+1-1)
- (modified) llvm/lib/MC/MCTargetOptionsCommandFlags.cpp (+5)
- (modified) llvm/lib/ObjectYAML/ELFYAML.cpp (+1)
- (modified) llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (+34)
- (modified) llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp (+4-1)
- (modified) llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp (+23)
- (added) llvm/test/MC/ARM/fdpic.s (+31)
- (modified) llvm/test/tools/llvm-readobj/ELF/file-header-os-abi.test (+7)
- (modified) llvm/test/tools/llvm-readobj/ELF/reloc-types-arm.test (+14)
- (modified) llvm/tools/llvm-readobj/ELFDumper.cpp (+2-1)
``````````diff
diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h
index 124bba76c1774c..bace3a92677a82 100644
--- a/llvm/include/llvm/BinaryFormat/ELF.h
+++ b/llvm/include/llvm/BinaryFormat/ELF.h
@@ -362,6 +362,7 @@ enum {
ELFOSABI_AMDGPU_PAL = 65, // AMD PAL runtime
ELFOSABI_AMDGPU_MESA3D = 66, // AMD GCN GPUs (GFX6+) for MESA runtime
ELFOSABI_ARM = 97, // ARM
+ ELFOSABI_ARM_FDPIC = 65, // ARM FDPIC
ELFOSABI_C6000_ELFABI = 64, // Bare-metal TMS320C6000
ELFOSABI_C6000_LINUX = 65, // Linux TMS320C6000
ELFOSABI_STANDALONE = 255, // Standalone (embedded) application
diff --git a/llvm/include/llvm/BinaryFormat/ELFRelocs/ARM.def b/llvm/include/llvm/BinaryFormat/ELFRelocs/ARM.def
index 47084d1eb0aad5..7e9fe965241f25 100644
--- a/llvm/include/llvm/BinaryFormat/ELFRelocs/ARM.def
+++ b/llvm/include/llvm/BinaryFormat/ELFRelocs/ARM.def
@@ -143,3 +143,10 @@ ELF_RELOC(R_ARM_THM_BF16, 0x88)
ELF_RELOC(R_ARM_THM_BF12, 0x89)
ELF_RELOC(R_ARM_THM_BF18, 0x8a)
ELF_RELOC(R_ARM_IRELATIVE, 0xa0)
+ELF_RELOC(R_ARM_GOTFUNCDESC, 0xa1)
+ELF_RELOC(R_ARM_GOTOFFFUNCDESC, 0xa2)
+ELF_RELOC(R_ARM_FUNCDESC, 0xa3)
+ELF_RELOC(R_ARM_FUNCDESC_VALUE, 0xa4)
+ELF_RELOC(R_ARM_TLS_GD32_FDPIC, 0xa5)
+ELF_RELOC(R_ARM_TLS_LDM32_FDPIC, 0xa6)
+ELF_RELOC(R_ARM_TLS_IE32_FDPIC, 0xa7)
diff --git a/llvm/include/llvm/MC/MCExpr.h b/llvm/include/llvm/MC/MCExpr.h
index 67836292874f5f..b3119609372049 100644
--- a/llvm/include/llvm/MC/MCExpr.h
+++ b/llvm/include/llvm/MC/MCExpr.h
@@ -223,6 +223,12 @@ class MCSymbolRefExpr : public MCExpr {
VK_SECREL,
VK_SIZE, // symbol at SIZE
VK_WEAKREF, // The link between the symbols in .weakref foo, bar
+ VK_FUNCDESC,
+ VK_GOTFUNCDESC,
+ VK_GOTOFFFUNCDESC,
+ VK_TLSGD_FDPIC,
+ VK_TLSLDM_FDPIC,
+ VK_GOTTPOFF_FDPIC,
VK_X86_ABS8,
VK_X86_PLTOFF,
diff --git a/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h b/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
index fe905f2c3ba5fe..7edd3f8ce4904c 100644
--- a/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
+++ b/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
@@ -525,6 +525,10 @@ class MCTargetAsmParser : public MCAsmParserExtension {
// Return whether this parser accept star as start of statement
virtual bool starIsStartOfStatement() { return false; };
+ virtual MCSymbolRefExpr::VariantKind
+ getVariantKindForName(StringRef Name) const {
+ return MCSymbolRefExpr::getVariantKindForName(Name);
+ }
virtual const MCExpr *applyModifierToExpr(const MCExpr *E,
MCSymbolRefExpr::VariantKind,
MCContext &Ctx) {
diff --git a/llvm/include/llvm/MC/MCTargetOptions.h b/llvm/include/llvm/MC/MCTargetOptions.h
index e2dd1e0433dbe4..a7295879e15f0f 100644
--- a/llvm/include/llvm/MC/MCTargetOptions.h
+++ b/llvm/include/llvm/MC/MCTargetOptions.h
@@ -51,6 +51,7 @@ class MCTargetOptions {
bool MCNoTypeCheck : 1;
bool MCSaveTempLabels : 1;
bool MCIncrementalLinkerCompatible : 1;
+ bool FDPIC : 1;
bool ShowMCEncoding : 1;
bool ShowMCInst : 1;
bool AsmVerbose : 1;
diff --git a/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h b/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h
index 7f6ee6c8be224a..ba3784cab5b11d 100644
--- a/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h
+++ b/llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h
@@ -29,6 +29,8 @@ std::optional<bool> getExplicitRelaxAll();
bool getIncrementalLinkerCompatible();
+bool getFDPIC();
+
int getDwarfVersion();
bool getDwarf64();
diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp
index 80def6dfc24b1a..485fd1885ddb52 100644
--- a/llvm/lib/MC/MCExpr.cpp
+++ b/llvm/lib/MC/MCExpr.cpp
@@ -220,6 +220,7 @@ const MCSymbolRefExpr *MCSymbolRefExpr::create(StringRef Name, VariantKind Kind,
StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
switch (Kind) {
+ // clang-format off
case VK_Invalid: return "<<invalid>>";
case VK_None: return "<<none>>";
@@ -232,13 +233,16 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_GOTPCREL: return "GOTPCREL";
case VK_GOTPCREL_NORELAX: return "GOTPCREL_NORELAX";
case VK_GOTTPOFF: return "GOTTPOFF";
+ case VK_GOTTPOFF_FDPIC: return "gottpoff_fdpic";
case VK_INDNTPOFF: return "INDNTPOFF";
case VK_NTPOFF: return "NTPOFF";
case VK_GOTNTPOFF: return "GOTNTPOFF";
case VK_PLT: return "PLT";
case VK_TLSGD: return "TLSGD";
+ case VK_TLSGD_FDPIC: return "tlsgd_fdpic";
case VK_TLSLD: return "TLSLD";
case VK_TLSLDM: return "TLSLDM";
+ case VK_TLSLDM_FDPIC: return "tlsldm_fdpic";
case VK_TPOFF: return "TPOFF";
case VK_TPREL: return "TPREL";
case VK_TLSCALL: return "tlscall";
@@ -253,6 +257,9 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_SECREL: return "SECREL32";
case VK_SIZE: return "SIZE";
case VK_WEAKREF: return "WEAKREF";
+ case VK_FUNCDESC: return "FUNCDESC";
+ case VK_GOTFUNCDESC: return "GOTFUNCDESC";
+ case VK_GOTOFFFUNCDESC: return "GOTOFFFUNCDESC";
case VK_X86_ABS8: return "ABS8";
case VK_X86_PLTOFF: return "PLTOFF";
case VK_ARM_NONE: return "none";
@@ -386,6 +393,7 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
case VK_VE_TLS_GD_LO32: return "tls_gd_lo";
case VK_VE_TPOFF_HI32: return "tpoff_hi";
case VK_VE_TPOFF_LO32: return "tpoff_lo";
+ // clang-format on
}
llvm_unreachable("Invalid variant kind");
}
@@ -493,13 +501,6 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
.Case("ie", VK_Hexagon_IE)
.Case("ldgot", VK_Hexagon_LD_GOT)
.Case("ldplt", VK_Hexagon_LD_PLT)
- .Case("none", VK_ARM_NONE)
- .Case("got_prel", VK_ARM_GOT_PREL)
- .Case("target1", VK_ARM_TARGET1)
- .Case("target2", VK_ARM_TARGET2)
- .Case("prel31", VK_ARM_PREL31)
- .Case("sbrel", VK_ARM_SBREL)
- .Case("tlsldo", VK_ARM_TLSLDO)
.Case("lo8", VK_AVR_LO8)
.Case("hi8", VK_AVR_HI8)
.Case("hlo8", VK_AVR_HLO8)
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index 8e508dbdb1c69b..a1c32eee328643 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -1237,7 +1237,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
// Lookup the symbol variant if used.
if (!Split.second.empty()) {
- Variant = MCSymbolRefExpr::getVariantKindForName(Split.second);
+ Variant = getTargetParser().getVariantKindForName(Split.second);
if (Variant != MCSymbolRefExpr::VK_Invalid) {
SymbolName = Split.first;
} else if (MAI.doesAllowAtInName() && !MAI.useParensForSymbolVariant()) {
diff --git a/llvm/lib/MC/MCTargetOptions.cpp b/llvm/lib/MC/MCTargetOptions.cpp
index 07c6e752cb613d..bff4b8da2fb1b0 100644
--- a/llvm/lib/MC/MCTargetOptions.cpp
+++ b/llvm/lib/MC/MCTargetOptions.cpp
@@ -15,7 +15,7 @@ MCTargetOptions::MCTargetOptions()
: MCRelaxAll(false), MCNoExecStack(false), MCFatalWarnings(false),
MCNoWarn(false), MCNoDeprecatedWarn(false), MCNoTypeCheck(false),
MCSaveTempLabels(false), MCIncrementalLinkerCompatible(false),
- ShowMCEncoding(false), ShowMCInst(false), AsmVerbose(false),
+ FDPIC(false), ShowMCEncoding(false), ShowMCInst(false), AsmVerbose(false),
PreserveAsmComments(true), Dwarf64(false),
EmitDwarfUnwind(EmitDwarfUnwindType::Default),
MCUseDwarfDirectory(DefaultDwarfDirectory),
diff --git a/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp b/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp
index 8a4923e4792fb5..fb8334d626cb8b 100644
--- a/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp
+++ b/llvm/lib/MC/MCTargetOptionsCommandFlags.cpp
@@ -36,6 +36,7 @@ using namespace llvm;
MCOPT_EXP(bool, RelaxAll)
MCOPT(bool, IncrementalLinkerCompatible)
+MCOPT(bool, FDPIC)
MCOPT(int, DwarfVersion)
MCOPT(bool, Dwarf64)
MCOPT(EmitDwarfUnwindType, EmitDwarfUnwind)
@@ -66,6 +67,9 @@ llvm::mc::RegisterMCTargetOptionsFlags::RegisterMCTargetOptionsFlags() {
"emit an object file which can be used with an incremental linker"));
MCBINDOPT(IncrementalLinkerCompatible);
+ static cl::opt<bool> FDPIC("fdpic", cl::desc("Use the FDPIC ABI"));
+ MCBINDOPT(FDPIC);
+
static cl::opt<int> DwarfVersion("dwarf-version", cl::desc("Dwarf version"),
cl::init(0));
MCBINDOPT(DwarfVersion);
@@ -135,6 +139,7 @@ MCTargetOptions llvm::mc::InitMCTargetOptionsFromFlags() {
MCTargetOptions Options;
Options.MCRelaxAll = getRelaxAll();
Options.MCIncrementalLinkerCompatible = getIncrementalLinkerCompatible();
+ Options.FDPIC = getFDPIC();
Options.Dwarf64 = getDwarf64();
Options.DwarfVersion = getDwarfVersion();
Options.ShowMCInst = getShowMCInst();
diff --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp
index de1ef2458152c8..9c1a28db592a1c 100644
--- a/llvm/lib/ObjectYAML/ELFYAML.cpp
+++ b/llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -406,6 +406,7 @@ void ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI>::enumeration(
ECase(ELFOSABI_AMDGPU_PAL);
ECase(ELFOSABI_AMDGPU_MESA3D);
ECase(ELFOSABI_ARM);
+ ECase(ELFOSABI_ARM_FDPIC);
ECase(ELFOSABI_C6000_ELFABI);
ECase(ELFOSABI_C6000_LINUX);
ECase(ELFOSABI_STANDALONE);
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index c82ab57bdf80f1..37bfb76a494dee 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -737,6 +737,9 @@ class ARMAsmParser : public MCTargetAsmParser {
void ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses, SMLoc IDLoc,
OperandVector &Operands);
+ MCSymbolRefExpr::VariantKind
+ getVariantKindForName(StringRef Name) const override;
+
void doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc) override;
void onLabelParsed(MCSymbol *Symbol) override;
@@ -11358,6 +11361,37 @@ bool ARMAsmParser::parseDirectiveARM(SMLoc L) {
return false;
}
+MCSymbolRefExpr::VariantKind
+ARMAsmParser::getVariantKindForName(StringRef Name) const {
+ return StringSwitch<MCSymbolRefExpr::VariantKind>(Name.lower())
+ .Case("funcdesc", MCSymbolRefExpr::VK_FUNCDESC)
+ .Case("got", MCSymbolRefExpr::VK_GOT)
+ .Case("got_prel", MCSymbolRefExpr::VK_ARM_GOT_PREL)
+ .Case("gotfuncdesc", MCSymbolRefExpr::VK_GOTFUNCDESC)
+ .Case("gotoff", MCSymbolRefExpr::VK_GOTOFF)
+ .Case("gotofffuncdesc", MCSymbolRefExpr::VK_GOTOFFFUNCDESC)
+ .Case("gottpoff", MCSymbolRefExpr::VK_GOTTPOFF)
+ .Case("gottpoff_fdpic", MCSymbolRefExpr::VK_GOTTPOFF_FDPIC)
+ .Case("imgrel", MCSymbolRefExpr::VK_COFF_IMGREL32)
+ .Case("none", MCSymbolRefExpr::VK_ARM_NONE)
+ .Case("plt", MCSymbolRefExpr::VK_PLT)
+ .Case("prel31", MCSymbolRefExpr::VK_ARM_PREL31)
+ .Case("sbrel", MCSymbolRefExpr::VK_ARM_SBREL)
+ .Case("secrel32", MCSymbolRefExpr::VK_SECREL)
+ .Case("target1", MCSymbolRefExpr::VK_ARM_TARGET1)
+ .Case("target2", MCSymbolRefExpr::VK_ARM_TARGET2)
+ .Case("tlscall", MCSymbolRefExpr::VK_TLSCALL)
+ .Case("tlsdesc", MCSymbolRefExpr::VK_TLSDESC)
+ .Case("tlsgd", MCSymbolRefExpr::VK_TLSGD)
+ .Case("tlsgd_fdpic", MCSymbolRefExpr::VK_TLSGD_FDPIC)
+ .Case("tlsld", MCSymbolRefExpr::VK_TLSLD)
+ .Case("tlsldm", MCSymbolRefExpr::VK_TLSLDM)
+ .Case("tlsldm_fdpic", MCSymbolRefExpr::VK_TLSLDM_FDPIC)
+ .Case("tlsldo", MCSymbolRefExpr::VK_ARM_TLSLDO)
+ .Case("tpoff", MCSymbolRefExpr::VK_TPOFF)
+ .Default(MCSymbolRefExpr::VK_Invalid);
+}
+
void ARMAsmParser::doBeforeLabelEmit(MCSymbol *Symbol, SMLoc IDLoc) {
// We need to flush the current implicit IT block on a label, because it is
// not legal to branch into an IT block.
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
index 1d17bb349f24ba..6cd4badb7704b7 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
@@ -29,6 +29,7 @@
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/EndianStream.h"
@@ -1349,7 +1350,9 @@ static MCAsmBackend *createARMAsmBackend(const Target &T,
return new ARMAsmBackendWinCOFF(T, STI.getTargetTriple().isThumb());
case Triple::ELF:
assert(TheTriple.isOSBinFormatELF() && "using ELF for non-ELF target");
- uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
+ uint8_t OSABI = Options.FDPIC
+ ? ELF::ELFOSABI_ARM_FDPIC
+ : MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
return new ARMAsmBackendELF(T, STI.getTargetTriple().isThumb(), OSABI,
Endian);
}
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
index 44695a86c4e36c..baec4a5cb5215a 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp
@@ -84,6 +84,11 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
if (Kind >= FirstLiteralRelocationKind)
return Kind - FirstLiteralRelocationKind;
MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
+ auto CheckFDPIC = [&]() {
+ if (getOSABI() != ELF::ELFOSABI_ARM_FDPIC)
+ Ctx.reportError(Fixup.getLoc(),
+ "relocation only supported in FDPIC mode");
+ };
if (IsPCRel) {
switch (Fixup.getTargetKind()) {
@@ -240,6 +245,24 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
return ELF::R_ARM_TLS_LDM32;
case MCSymbolRefExpr::VK_ARM_TLSDESCSEQ:
return ELF::R_ARM_TLS_DESCSEQ;
+ case MCSymbolRefExpr::VK_FUNCDESC:
+ CheckFDPIC();
+ return ELF::R_ARM_FUNCDESC;
+ case MCSymbolRefExpr::VK_GOTFUNCDESC:
+ CheckFDPIC();
+ return ELF::R_ARM_GOTFUNCDESC;
+ case MCSymbolRefExpr::VK_GOTOFFFUNCDESC:
+ CheckFDPIC();
+ return ELF::R_ARM_GOTOFFFUNCDESC;
+ case MCSymbolRefExpr::VK_TLSGD_FDPIC:
+ CheckFDPIC();
+ return ELF::R_ARM_TLS_GD32_FDPIC;
+ case MCSymbolRefExpr::VK_TLSLDM_FDPIC:
+ CheckFDPIC();
+ return ELF::R_ARM_TLS_LDM32_FDPIC;
+ case MCSymbolRefExpr::VK_GOTTPOFF_FDPIC:
+ CheckFDPIC();
+ return ELF::R_ARM_TLS_IE32_FDPIC;
}
case ARM::fixup_arm_condbranch:
case ARM::fixup_arm_uncondbranch:
diff --git a/llvm/test/MC/ARM/fdpic.s b/llvm/test/MC/ARM/fdpic.s
new file mode 100644
index 00000000000000..4f36393d9110e8
--- /dev/null
+++ b/llvm/test/MC/ARM/fdpic.s
@@ -0,0 +1,31 @@
+# RUN: llvm-mc -triple=armv7-linux-gnueabi %s | FileCheck %s --check-prefix=ASM
+# RUN: llvm-mc -filetype=obj -triple=armv7-linux-gnueabi --fdpic %s | llvm-readelf -h -r - | FileCheck %s
+
+# RUN: not llvm-mc -filetype=obj -triple=armv7-linux-gnueabi %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR
+
+# ASM: .long f(FUNCDESC)
+# ASM-NEXT: .long f(GOTFUNCDESC)
+# ASM-NEXT: .long f(GOTOFFFUNCDESC)
+
+# CHECK: OS/ABI: ARM FDPIC
+# CHECK: Machine: ARM
+# CHECK: Flags: 0x5000000
+
+# CHECK: R_ARM_FUNCDESC 00000000 f
+# CHECK-NEXT: R_ARM_GOTFUNCDESC 00000000 f
+# CHECK-NEXT: R_ARM_GOTOFFFUNCDESC 00000000 f
+# CHECK-NEXT: R_ARM_TLS_GD32_FDPIC 00000000 tls
+# CHECK-NEXT: R_ARM_TLS_LDM32_FDPIC 00000000 tls
+# CHECK-NEXT: R_ARM_TLS_IE32_FDPIC 00000000 tls
+
+.data
+# ERR: [[#@LINE+1]]:7: error: relocation only supported in FDPIC mode
+.long f(FUNCDESC)
+# ERR: [[#@LINE+1]]:7: error: relocation only supported in FDPIC mode
+.long f(GOTFUNCDESC)
+# ERR: [[#@LINE+1]]:7: error: relocation only supported in FDPIC mode
+.long f(GOTOFFFUNCDESC)
+# ERR: [[#@LINE+1]]:7: error: relocation only supported in FDPIC mode
+.long tls(tlsgd_fdpic)
+.long tls(tlsldm_fdpic)
+.long tls(gottpoff_fdpic)
diff --git a/llvm/test/tools/llvm-readobj/ELF/file-header-os-abi.test b/llvm/test/tools/llvm-readobj/ELF/file-header-os-abi.test
index eb60d2a021af63..a48346d6b9c85e 100644
--- a/llvm/test/tools/llvm-readobj/ELF/file-header-os-abi.test
+++ b/llvm/test/tools/llvm-readobj/ELF/file-header-os-abi.test
@@ -192,6 +192,13 @@ FileHeader:
# OSABI-ARM-LLVM: OS/ABI: ARM (0x61)
# OSABI-ARM-GNU: OS/ABI: ARM
+# RUN: yaml2obj %s -DOSABI=ELFOSABI_ARM_FDPIC -DMACHINE=EM_ARM -o %t.osabi.arm_fdpic
+# RUN: llvm-readobj --file-headers %t.osabi.arm_fdpic | FileCheck %s --match-full-lines --check-prefix=OSABI-ARMFDPIC-LLVM
+# RUN: llvm-readelf --file-headers %t.osabi.arm_fdpic | FileCheck %s --match-full-lines --check-prefix=OSABI-ARMFDPIC-GNU
+
+# OSABI-ARMFDPIC-LLVM: OS/ABI: ARM FDPIC (0x41)
+# OSABI-ARMFDPIC-GNU: OS/ABI: ARM FDPIC
+
## Check all EM_TI_C6000 specific values.
# RUN: yaml2obj %s -DOSABI=ELFOSABI_C6000_ELFABI -DMACHINE=EM_TI_C6000 -o %t.osabi.c6000.elfabi
diff --git a/llvm/test/tools/llvm-readobj/ELF/reloc-types-arm.test b/llvm/test/tools/llvm-readobj/ELF/reloc-types-arm.test
index 96d6cfed4df3e1..dafe01ba36afb1 100644
--- a/llvm/test/tools/llvm-readobj/ELF/reloc-types-arm.test
+++ b/llvm/test/tools/llvm-readobj/ELF/reloc-types-arm.test
@@ -135,6 +135,13 @@
# CHECK: Type: R_ARM_THM_TLS_DESCSEQ16 (129)
# CHECK: Type: R_ARM_THM_TLS_DESCSEQ32 (130)
# CHECK: Type: R_ARM_IRELATIVE (160)
+# CHECK: Type: R_ARM_GOTFUNCDESC (161)
+# CHECK: Type: R_ARM_GOTOFFFUNCDESC (162)
+# CHECK: Type: R_ARM_FUNCDESC (163)
+# CHECK: Type: R_ARM_FUNCDESC_VALUE (164)
+# CHECK: Type: R_ARM_TLS_GD32_FDPIC (165)
+# CHECK: Type: R_ARM_TLS_LDM32_FDPIC (166)
+# CHECK: Type: R_ARM_TLS_IE32_FDPIC (167)
--- !ELF
FileHeader:
@@ -278,3 +285,10 @@ Sections:
- Type: R_ARM_THM_TLS_DESCSEQ16
- Type: R_ARM_THM_TLS_DESCSEQ32
- Type: R_ARM_IRELATIVE
+ - Type: R_ARM_GOTFUNCDESC
+ - Type: R_ARM_GOTOFFFUNCDESC
+ - Type: R_ARM_FUNCDESC
+ - Type: R_ARM_FUNCDESC_VALUE
+ - Type: R_ARM_TLS_GD32_FDPIC
+ - Type: R_ARM_TLS_LDM32_FDPIC
+ - Type: R_ARM_TLS_IE32_FDPIC
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index fa39e04f4ce9c0..8b8c4aa8d842b5 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -1095,7 +1095,8 @@ const EnumEntry<unsigned> AMDGPUElfOSABI[] = {
};
const EnumEntry<unsigned> ARMElfOSABI[] = {
- {"ARM", "ARM", ELF::ELFOSABI_ARM}
+ {"ARM", "ARM", ELF::ELFOSABI_ARM},
+ {"ARM FDPIC", "ARM FDPIC", ELF::ELFOSABI_ARM_FDPIC},
};
const EnumEntry<unsigned> C6000ElfOSABI[] = {
``````````
</details>
https://github.com/llvm/llvm-project/pull/82187
More information about the llvm-branch-commits
mailing list