LLD/ELF: Allow targets to set e_flags
authorKonstantin Zhuravlyov <kzhuravl_dev@outlook.com>
Tue, 24 Oct 2017 17:01:40 +0000 (17:01 +0000)
committerKonstantin Zhuravlyov <kzhuravl_dev@outlook.com>
Tue, 24 Oct 2017 17:01:40 +0000 (17:01 +0000)
Differential Revision: https://reviews.llvm.org/D39139

llvm-svn: 316460

lld/ELF/Arch/ARM.cpp
lld/ELF/Arch/Mips.cpp
lld/ELF/Arch/MipsArchTree.cpp
lld/ELF/Config.h
lld/ELF/Driver.cpp
lld/ELF/Target.h
lld/ELF/Writer.cpp

index 3fca467..522911e 100644 (file)
@@ -26,6 +26,7 @@ namespace {
 class ARM final : public TargetInfo {
 public:
   ARM();
+  uint32_t calcEFlags() const override;
   RelExpr getRelExpr(RelType Type, const SymbolBody &S,
                      const uint8_t *Loc) const override;
   bool isPicRel(RelType Type) const override;
@@ -64,6 +65,13 @@ ARM::ARM() {
   NeedsThunks = true;
 }
 
+uint32_t ARM::calcEFlags() const {
+  // We don't currently use any features incompatible with EF_ARM_EABI_VER5,
+  // but we don't have any firm guarantees of conformance. Linux AArch64
+  // kernels (as of 2016) require an EABI version to be set.
+  return EF_ARM_EABI_VER5;
+}
+
 RelExpr ARM::getRelExpr(RelType Type, const SymbolBody &S,
                         const uint8_t *Loc) const {
   switch (Type) {
index 5f232dc..1ffff3f 100644 (file)
@@ -28,6 +28,7 @@ namespace {
 template <class ELFT> class MIPS final : public TargetInfo {
 public:
   MIPS();
+  uint32_t calcEFlags() const override;
   RelExpr getRelExpr(RelType Type, const SymbolBody &S,
                      const uint8_t *Loc) const override;
   int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const override;
@@ -69,6 +70,10 @@ template <class ELFT> MIPS<ELFT>::MIPS() {
   }
 }
 
+template <class ELFT> uint32_t MIPS<ELFT>::calcEFlags() const {
+  return calcMipsEFlags<ELFT>();
+}
+
 template <class ELFT>
 RelExpr MIPS<ELFT>::getRelExpr(RelType Type, const SymbolBody &S,
                                const uint8_t *Loc) const {
@@ -236,7 +241,7 @@ static void writeMicroRelocation16(uint8_t *Loc, uint64_t V, uint8_t BitsSize,
   write16<E>(Loc, Data);
 }
 
-static bool isMicroMips() { return Config->MipsEFlags & EF_MIPS_MICROMIPS; }
+static bool isMicroMips() { return Config->EFlags & EF_MIPS_MICROMIPS; }
 
 template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *Buf) const {
   const endianness E = ELFT::TargetEndianness;
index 017f0c7..6b6d25b 100644 (file)
@@ -365,7 +365,7 @@ bool elf::isMipsN32Abi(const InputFile *F) {
 }
 
 bool elf::isMipsR6() {
-  uint32_t Arch = Config->MipsEFlags & EF_MIPS_ARCH;
+  uint32_t Arch = Config->EFlags & EF_MIPS_ARCH;
   return Arch == EF_MIPS_ARCH_32R6 || Arch == EF_MIPS_ARCH_64R6;
 }
 
index d5d8309..d753af7 100644 (file)
@@ -202,11 +202,8 @@ struct Configuration {
   // if that's true.)
   bool IsMips64EL;
 
-  // Holds set of ELF header flags for MIPS targets. The set calculated
-  // by the `elf::calcMipsEFlags` function and cached in this field. For
-  // the calculation we iterate over all input object files and combine
-  // their ELF flags.
-  uint32_t MipsEFlags = 0;
+  // Holds set of ELF header flags for the target.
+  uint32_t EFlags = 0;
 
   // The ELF spec defines two types of relocation table entries, RELA and
   // REL. RELA is a triplet of (offset, info, addend) while REL is a
index af56b2b..b990af5 100644 (file)
@@ -1087,8 +1087,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
     for (InputSectionBase *S : F->getSections())
       InputSections.push_back(cast<InputSection>(S));
 
-  if (Config->EMachine == EM_MIPS)
-    Config->MipsEFlags = calcMipsEFlags<ELFT>();
+  Config->EFlags = Target->calcEFlags();
 
   // This adds a .comment section containing a version string. We have to add it
   // before decompressAndMergeSections because the .comment section is a
index 957af6a..ef2a3f1 100644 (file)
@@ -23,6 +23,7 @@ class SymbolBody;
 
 class TargetInfo {
 public:
+  virtual uint32_t calcEFlags() const { return 0; }
   virtual bool isPicRel(RelType Type) const { return true; }
   virtual RelType getDynRel(RelType Type) const { return Type; }
   virtual void writeGotPltHeader(uint8_t *Buf) const {}
index 836d36a..3e5bb3b 100644 (file)
@@ -1778,20 +1778,13 @@ template <class ELFT> void Writer<ELFT>::writeHeader() {
   EHdr->e_version = EV_CURRENT;
   EHdr->e_entry = getEntryAddr();
   EHdr->e_shoff = SectionHeaderOff;
+  EHdr->e_flags = Config->EFlags;
   EHdr->e_ehsize = sizeof(Elf_Ehdr);
   EHdr->e_phnum = Phdrs.size();
   EHdr->e_shentsize = sizeof(Elf_Shdr);
   EHdr->e_shnum = OutputSections.size() + 1;
   EHdr->e_shstrndx = InX::ShStrTab->getParent()->SectionIndex;
 
-  if (Config->EMachine == EM_ARM)
-    // We don't currently use any features incompatible with EF_ARM_EABI_VER5,
-    // but we don't have any firm guarantees of conformance. Linux AArch64
-    // kernels (as of 2016) require an EABI version to be set.
-    EHdr->e_flags = EF_ARM_EABI_VER5;
-  else if (Config->EMachine == EM_MIPS)
-    EHdr->e_flags = Config->MipsEFlags;
-
   if (!Config->Relocatable) {
     EHdr->e_phoff = sizeof(Elf_Ehdr);
     EHdr->e_phentsize = sizeof(Elf_Phdr);