forked from OSchip/llvm-project
LLD/ELF: Allow targets to set e_flags
Differential Revision: https://reviews.llvm.org/D39139 llvm-svn: 316460
This commit is contained in:
parent
983fa9bf23
commit
e7f1734f1a
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue