From: Konstantin Zhuravlyov Date: Tue, 24 Oct 2017 17:01:40 +0000 (+0000) Subject: LLD/ELF: Allow targets to set e_flags X-Git-Tag: llvmorg-6.0.0-rc1~5035 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e7f1734f1aa50dd888f563f84b1265c14a896949;p=platform%2Fupstream%2Fllvm.git LLD/ELF: Allow targets to set e_flags Differential Revision: https://reviews.llvm.org/D39139 llvm-svn: 316460 --- diff --git a/lld/ELF/Arch/ARM.cpp b/lld/ELF/Arch/ARM.cpp index 3fca467..522911e 100644 --- a/lld/ELF/Arch/ARM.cpp +++ b/lld/ELF/Arch/ARM.cpp @@ -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) { diff --git a/lld/ELF/Arch/Mips.cpp b/lld/ELF/Arch/Mips.cpp index 5f232dc..1ffff3f 100644 --- a/lld/ELF/Arch/Mips.cpp +++ b/lld/ELF/Arch/Mips.cpp @@ -28,6 +28,7 @@ namespace { template 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 MIPS::MIPS() { } } +template uint32_t MIPS::calcEFlags() const { + return calcMipsEFlags(); +} + template RelExpr MIPS::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(Loc, Data); } -static bool isMicroMips() { return Config->MipsEFlags & EF_MIPS_MICROMIPS; } +static bool isMicroMips() { return Config->EFlags & EF_MIPS_MICROMIPS; } template void MIPS::writePltHeader(uint8_t *Buf) const { const endianness E = ELFT::TargetEndianness; diff --git a/lld/ELF/Arch/MipsArchTree.cpp b/lld/ELF/Arch/MipsArchTree.cpp index 017f0c7..6b6d25b 100644 --- a/lld/ELF/Arch/MipsArchTree.cpp +++ b/lld/ELF/Arch/MipsArchTree.cpp @@ -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; } diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index d5d8309..d753af7 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -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 diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index af56b2b..b990af5 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -1087,8 +1087,7 @@ template void LinkerDriver::link(opt::InputArgList &Args) { for (InputSectionBase *S : F->getSections()) InputSections.push_back(cast(S)); - if (Config->EMachine == EM_MIPS) - Config->MipsEFlags = calcMipsEFlags(); + 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 diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h index 957af6a..ef2a3f1 100644 --- a/lld/ELF/Target.h +++ b/lld/ELF/Target.h @@ -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 {} diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 836d36a..3e5bb3b 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -1778,20 +1778,13 @@ template void Writer::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);