summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2024-02-18 11:27:48 -0800
committerFangrui Song <i@maskray.me>2024-02-18 11:27:48 -0800
commit4f33d4ee689b7d5e4a127fa2eb9af16834df9991 (patch)
treead4e8643d7a7c10d529a9d85cda11d6add8299ef
parentcc2fe7b516c1dbf1f8747ade0f17891f9990dede (diff)
parentedc62542da29f027c89dff1a7a9c18cada4343de (diff)
Created using spr 1.3.4
-rw-r--r--clang/include/clang/Driver/Options.td2
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp4
-rw-r--r--clang/test/Driver/arm-ias-Wa.s2
-rw-r--r--clang/test/Misc/cc1as-arm-fdpic.s10
-rw-r--r--clang/tools/driver/cc1as_main.cpp4
-rw-r--r--llvm/include/llvm/BinaryFormat/ELF.h1
-rw-r--r--llvm/include/llvm/BinaryFormat/ELFRelocs/ARM.def7
-rw-r--r--llvm/include/llvm/MC/MCExpr.h6
-rw-r--r--llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h4
-rw-r--r--llvm/include/llvm/MC/MCTargetOptions.h1
-rw-r--r--llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h2
-rw-r--r--llvm/lib/MC/MCExpr.cpp15
-rw-r--r--llvm/lib/MC/MCParser/AsmParser.cpp2
-rw-r--r--llvm/lib/MC/MCTargetOptions.cpp2
-rw-r--r--llvm/lib/MC/MCTargetOptionsCommandFlags.cpp5
-rw-r--r--llvm/lib/ObjectYAML/ELFYAML.cpp1
-rw-r--r--llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp34
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp5
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp23
-rw-r--r--llvm/test/MC/ARM/fdpic.s31
-rw-r--r--llvm/test/tools/llvm-readobj/ELF/file-header-os-abi.test9
-rw-r--r--llvm/test/tools/llvm-readobj/ELF/reloc-types-arm.test14
-rw-r--r--llvm/tools/llvm-readobj/ELFDumper.cpp6
23 files changed, 178 insertions, 12 deletions
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 53f23f9abb4c..da0ebbc1f0b6 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -7954,6 +7954,8 @@ def dwarf_debug_producer : Separate<["-"], "dwarf-debug-producer">,
def defsym : Separate<["-"], "defsym">,
HelpText<"Define a value for a symbol">;
+def fdpic : Flag<["--"], "fdpic">, HelpText<"Enable FDPIC ABI (ARM only)">;
+
} // let Visibility = [CC1AsOption]
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 47305f798c5f..b4cc79df8dab 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -2530,6 +2530,10 @@ static void CollectArgsForIntegratedAssembler(Compilation &C,
case llvm::Triple::thumbeb:
case llvm::Triple::arm:
case llvm::Triple::armeb:
+ if (Value == "--fdpic") {
+ CmdArgs.push_back("--fdpic");
+ continue;
+ }
if (Value.starts_with("-mimplicit-it=")) {
// Only store the value; the last value set takes effect.
ImplicitIt = Value.split("=").second;
diff --git a/clang/test/Driver/arm-ias-Wa.s b/clang/test/Driver/arm-ias-Wa.s
index b82ce8dfb31a..73d6bb880451 100644
--- a/clang/test/Driver/arm-ias-Wa.s
+++ b/clang/test/Driver/arm-ias-Wa.s
@@ -79,3 +79,5 @@
// RUN: | FileCheck -check-prefix=CHECK-M-PROFILE %s
// CHECK-M-PROFILE: "-triple" "thumbv7m-{{.*}}"
+// RUN: %clang --target=arm-unknown-linuxfdpiceabi -Wa,--fdpic -c %s -### 2>&1 | FileCheck --check-prefix=FDPIC %s
+// FDPIC: "--fdpic"
diff --git a/clang/test/Misc/cc1as-arm-fdpic.s b/clang/test/Misc/cc1as-arm-fdpic.s
new file mode 100644
index 000000000000..cc6438558eeb
--- /dev/null
+++ b/clang/test/Misc/cc1as-arm-fdpic.s
@@ -0,0 +1,10 @@
+// REQUIRES: arm-registered-target
+
+// RUN: %clang -cc1as -triple armv7-unknown-linuxfdpiceabi -filetype obj --fdpic %s -o %t
+// RUN: llvm-readelf -h -r %t | FileCheck %s
+
+// CHECK: OS/ABI: ARM FDPIC
+// CHECK: R_ARM_FUNCDESC
+
+.data
+.word f(FUNCDESC)
diff --git a/clang/tools/driver/cc1as_main.cpp b/clang/tools/driver/cc1as_main.cpp
index a55e06500d9d..2d97769b7862 100644
--- a/clang/tools/driver/cc1as_main.cpp
+++ b/clang/tools/driver/cc1as_main.cpp
@@ -154,6 +154,8 @@ struct AssemblerInvocation {
LLVM_PREFERRED_TYPE(bool)
unsigned IncrementalLinkerCompatible : 1;
LLVM_PREFERRED_TYPE(bool)
+ unsigned FDPIC : 1;
+ LLVM_PREFERRED_TYPE(bool)
unsigned EmbedBitcode : 1;
/// Whether to emit DWARF unwind info.
@@ -346,6 +348,7 @@ bool AssemblerInvocation::CreateFromArgs(AssemblerInvocation &Opts,
Opts.FatalWarnings = Args.hasArg(OPT_massembler_fatal_warnings);
Opts.NoWarn = Args.hasArg(OPT_massembler_no_warn);
Opts.NoTypeCheck = Args.hasArg(OPT_mno_type_check);
+ Opts.FDPIC = Args.hasArg(OPT_fdpic);
Opts.RelocationModel =
std::string(Args.getLastArgValue(OPT_mrelocation_model, "pic"));
Opts.TargetABI = std::string(Args.getLastArgValue(OPT_target_abi));
@@ -520,6 +523,7 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts,
MCOptions.MCNoWarn = Opts.NoWarn;
MCOptions.MCFatalWarnings = Opts.FatalWarnings;
MCOptions.MCNoTypeCheck = Opts.NoTypeCheck;
+ MCOptions.FDPIC = Opts.FDPIC;
MCOptions.ABIName = Opts.TargetABI;
// FIXME: There is a bit of code duplication with addPassesToEmitFile.
diff --git a/llvm/include/llvm/BinaryFormat/ELF.h b/llvm/include/llvm/BinaryFormat/ELF.h
index 124bba76c177..bace3a92677a 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 47084d1eb0aa..7e9fe965241f 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 67836292874f..b31196093720 100644
--- a/llvm/include/llvm/MC/MCExpr.h
+++ b/llvm/include/llvm/MC/MCExpr.h
@@ -223,6 +223,12 @@ public:
VK_SECREL,
VK_SIZE, // symbol@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 fe905f2c3ba5..7edd3f8ce490 100644
--- a/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
+++ b/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
@@ -525,6 +525,10 @@ public:
// 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 e2dd1e0433db..a7295879e15f 100644
--- a/llvm/include/llvm/MC/MCTargetOptions.h
+++ b/llvm/include/llvm/MC/MCTargetOptions.h
@@ -51,6 +51,7 @@ public:
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 7f6ee6c8be22..ba3784cab5b1 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 80def6dfc24b..485fd1885ddb 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 8e508dbdb1c6..a1c32eee3286 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 07c6e752cb61..bff4b8da2fb1 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 8a4923e4792f..fb8334d626cb 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 de1ef2458152..9c1a28db592a 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 c82ab57bdf80..37bfb76a494d 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -737,6 +737,9 @@ public:
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 1d17bb349f24..6cd4badb7704 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 44695a86c4e3..baec4a5cb521 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 000000000000..4f36393d9110
--- /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 f815e78e0c54..a48346d6b9c8 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
@@ -190,7 +190,14 @@ FileHeader:
# RUN: llvm-readelf --file-headers %t.osabi.arm | FileCheck %s --match-full-lines --check-prefix=OSABI-ARM-GNU
# OSABI-ARM-LLVM: OS/ABI: ARM (0x61)
-# OSABI-ARM-GNU: OS/ABI: 61
+# 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.
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 96d6cfed4df3..dafe01ba36af 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 50ea63e87a43..8b8c4aa8d842 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[] = {
@@ -3553,6 +3554,9 @@ template <class ELFT> void GNUELFDumper<ELFT>::printFileHeaders() {
if (e.e_ident[ELF::EI_OSABI] >= ELF::ELFOSABI_FIRST_ARCH &&
e.e_ident[ELF::EI_OSABI] <= ELF::ELFOSABI_LAST_ARCH) {
switch (e.e_machine) {
+ case ELF::EM_ARM:
+ OSABI = ArrayRef(ARMElfOSABI);
+ break;
case ELF::EM_AMDGPU:
OSABI = ArrayRef(AMDGPUElfOSABI);
break;