forked from OSchip/llvm-project
parent
8629752c04
commit
02551abdca
|
@ -545,7 +545,6 @@ void EhFrameSection::finalizeContents() {
|
|||
// Returns data for .eh_frame_hdr. .eh_frame_hdr is a binary search table
|
||||
// to get an FDE from an address to which FDE is applied. This function
|
||||
// returns a list of such pairs.
|
||||
template <class ELFT>
|
||||
std::vector<EhFrameSection::FdeData> EhFrameSection::getFdeData() const {
|
||||
uint8_t *Buf = getParent()->Loc + OutSecOff;
|
||||
std::vector<FdeData> Ret;
|
||||
|
@ -1953,19 +1952,17 @@ void GdbIndexSection::writeTo(uint8_t *Buf) {
|
|||
|
||||
bool GdbIndexSection::empty() const { return !Out::DebugInfo; }
|
||||
|
||||
template <class ELFT>
|
||||
EhFrameHeader<ELFT>::EhFrameHeader()
|
||||
EhFrameHeader::EhFrameHeader()
|
||||
: SyntheticSection(SHF_ALLOC, SHT_PROGBITS, 1, ".eh_frame_hdr") {}
|
||||
|
||||
// .eh_frame_hdr contains a binary search table of pointers to FDEs.
|
||||
// Each entry of the search table consists of two values,
|
||||
// the starting PC from where FDEs covers, and the FDE's address.
|
||||
// It is sorted by PC.
|
||||
template <class ELFT> void EhFrameHeader<ELFT>::writeTo(uint8_t *Buf) {
|
||||
void EhFrameHeader::writeTo(uint8_t *Buf) {
|
||||
typedef EhFrameSection::FdeData FdeData;
|
||||
const endianness E = ELFT::TargetEndianness;
|
||||
|
||||
std::vector<FdeData> Fdes = InX::EhFrame->getFdeData<ELFT>();
|
||||
std::vector<FdeData> Fdes = InX::EhFrame->getFdeData();
|
||||
|
||||
// Sort the FDE list by their PC and uniqueify. Usually there is only
|
||||
// one FDE for a PC (i.e. function), but if ICF merges two functions
|
||||
|
@ -1979,26 +1976,25 @@ template <class ELFT> void EhFrameHeader<ELFT>::writeTo(uint8_t *Buf) {
|
|||
Buf[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4;
|
||||
Buf[2] = DW_EH_PE_udata4;
|
||||
Buf[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4;
|
||||
write32<E>(Buf + 4, InX::EhFrame->getParent()->Addr - this->getVA() - 4);
|
||||
write32<E>(Buf + 8, Fdes.size());
|
||||
write32(Buf + 4, InX::EhFrame->getParent()->Addr - this->getVA() - 4,
|
||||
Config->Endianness);
|
||||
write32(Buf + 8, Fdes.size(), Config->Endianness);
|
||||
Buf += 12;
|
||||
|
||||
uint64_t VA = this->getVA();
|
||||
for (FdeData &Fde : Fdes) {
|
||||
write32<E>(Buf, Fde.Pc - VA);
|
||||
write32<E>(Buf + 4, Fde.FdeVA - VA);
|
||||
write32(Buf, Fde.Pc - VA, Config->Endianness);
|
||||
write32(Buf + 4, Fde.FdeVA - VA, Config->Endianness);
|
||||
Buf += 8;
|
||||
}
|
||||
}
|
||||
|
||||
template <class ELFT> size_t EhFrameHeader<ELFT>::getSize() const {
|
||||
size_t EhFrameHeader::getSize() const {
|
||||
// .eh_frame_hdr has a 12 bytes header followed by an array of FDEs.
|
||||
return 12 + InX::EhFrame->NumFdes * 8;
|
||||
}
|
||||
|
||||
template <class ELFT> bool EhFrameHeader<ELFT>::empty() const {
|
||||
return InX::EhFrame->empty();
|
||||
}
|
||||
bool EhFrameHeader::empty() const { return InX::EhFrame->empty(); }
|
||||
|
||||
template <class ELFT>
|
||||
VersionDefinitionSection<ELFT>::VersionDefinitionSection()
|
||||
|
@ -2402,6 +2398,7 @@ InputSection *InX::ARMAttributes;
|
|||
BssSection *InX::Bss;
|
||||
BssSection *InX::BssRelRo;
|
||||
BuildIdSection *InX::BuildId;
|
||||
EhFrameHeader *InX::EhFrameHdr;
|
||||
EhFrameSection *InX::EhFrame;
|
||||
SyntheticSection *InX::Dynamic;
|
||||
StringTableSection *InX::DynStrTab;
|
||||
|
@ -2476,11 +2473,6 @@ template class elf::SymbolTableSection<ELF32BE>;
|
|||
template class elf::SymbolTableSection<ELF64LE>;
|
||||
template class elf::SymbolTableSection<ELF64BE>;
|
||||
|
||||
template class elf::EhFrameHeader<ELF32LE>;
|
||||
template class elf::EhFrameHeader<ELF32BE>;
|
||||
template class elf::EhFrameHeader<ELF64LE>;
|
||||
template class elf::EhFrameHeader<ELF64BE>;
|
||||
|
||||
template class elf::VersionTableSection<ELF32LE>;
|
||||
template class elf::VersionTableSection<ELF32BE>;
|
||||
template class elf::VersionTableSection<ELF64LE>;
|
||||
|
|
|
@ -80,7 +80,7 @@ public:
|
|||
uint32_t FdeVA;
|
||||
};
|
||||
|
||||
template <class ELFT> std::vector<FdeData> getFdeData() const;
|
||||
std::vector<FdeData> getFdeData() const;
|
||||
|
||||
private:
|
||||
uint64_t Size = 0;
|
||||
|
@ -572,7 +572,7 @@ template <class ELFT> GdbIndexSection *createGdbIndex();
|
|||
// Detailed info about internals can be found in Ian Lance Taylor's blog:
|
||||
// http://www.airs.com/blog/archives/460 (".eh_frame")
|
||||
// http://www.airs.com/blog/archives/462 (".eh_frame_hdr")
|
||||
template <class ELFT> class EhFrameHeader final : public SyntheticSection {
|
||||
class EhFrameHeader final : public SyntheticSection {
|
||||
public:
|
||||
EhFrameHeader();
|
||||
void writeTo(uint8_t *Buf) override;
|
||||
|
@ -811,6 +811,7 @@ struct InX {
|
|||
static BssSection *Bss;
|
||||
static BssSection *BssRelRo;
|
||||
static BuildIdSection *BuildId;
|
||||
static EhFrameHeader *EhFrameHdr;
|
||||
static EhFrameSection *EhFrame;
|
||||
static SyntheticSection *Dynamic;
|
||||
static StringTableSection *DynStrTab;
|
||||
|
@ -832,7 +833,6 @@ struct InX {
|
|||
};
|
||||
|
||||
template <class ELFT> struct In {
|
||||
static EhFrameHeader<ELFT> *EhFrameHdr;
|
||||
static RelocationSection<ELFT> *RelaDyn;
|
||||
static RelocationSection<ELFT> *RelaPlt;
|
||||
static RelocationSection<ELFT> *RelaIplt;
|
||||
|
@ -841,7 +841,6 @@ template <class ELFT> struct In {
|
|||
static VersionNeedSection<ELFT> *VerNeed;
|
||||
};
|
||||
|
||||
template <class ELFT> EhFrameHeader<ELFT> *In<ELFT>::EhFrameHdr;
|
||||
template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaDyn;
|
||||
template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaPlt;
|
||||
template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaIplt;
|
||||
|
|
|
@ -373,8 +373,8 @@ template <class ELFT> void Writer<ELFT>::createSyntheticSections() {
|
|||
|
||||
if (!Config->Relocatable) {
|
||||
if (Config->EhFrameHdr) {
|
||||
In<ELFT>::EhFrameHdr = make<EhFrameHeader<ELFT>>();
|
||||
Add(In<ELFT>::EhFrameHdr);
|
||||
InX::EhFrameHdr = make<EhFrameHeader>();
|
||||
Add(InX::EhFrameHdr);
|
||||
}
|
||||
InX::EhFrame = make<EhFrameSection>();
|
||||
Add(InX::EhFrame);
|
||||
|
@ -1335,18 +1335,14 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
|
|||
|
||||
// Dynamic section must be the last one in this list and dynamic
|
||||
// symbol table section (DynSymTab) must be the first one.
|
||||
applySynthetic({InX::DynSymTab, InX::Bss,
|
||||
InX::BssRelRo, InX::GnuHashTab,
|
||||
InX::HashTab, InX::SymTab,
|
||||
InX::ShStrTab, InX::StrTab,
|
||||
In<ELFT>::VerDef, InX::DynStrTab,
|
||||
InX::Got, InX::MipsGot,
|
||||
InX::IgotPlt, InX::GotPlt,
|
||||
In<ELFT>::RelaDyn, In<ELFT>::RelaIplt,
|
||||
In<ELFT>::RelaPlt, InX::Plt,
|
||||
InX::Iplt, In<ELFT>::EhFrameHdr,
|
||||
In<ELFT>::VerSym, In<ELFT>::VerNeed,
|
||||
InX::Dynamic},
|
||||
applySynthetic({InX::DynSymTab, InX::Bss, InX::BssRelRo,
|
||||
InX::GnuHashTab, InX::HashTab, InX::SymTab,
|
||||
InX::ShStrTab, InX::StrTab, In<ELFT>::VerDef,
|
||||
InX::DynStrTab, InX::Got, InX::MipsGot,
|
||||
InX::IgotPlt, InX::GotPlt, In<ELFT>::RelaDyn,
|
||||
In<ELFT>::RelaIplt, In<ELFT>::RelaPlt, InX::Plt,
|
||||
InX::Iplt, InX::EhFrameHdr, In<ELFT>::VerSym,
|
||||
In<ELFT>::VerNeed, InX::Dynamic},
|
||||
[](SyntheticSection *SS) { SS->finalizeContents(); });
|
||||
|
||||
if (!Script->HasSectionsCommand && !Config->Relocatable)
|
||||
|
@ -1532,10 +1528,10 @@ template <class ELFT> std::vector<PhdrEntry *> Writer<ELFT>::createPhdrs() {
|
|||
Ret.push_back(RelRo);
|
||||
|
||||
// PT_GNU_EH_FRAME is a special section pointing on .eh_frame_hdr.
|
||||
if (!InX::EhFrame->empty() && In<ELFT>::EhFrameHdr &&
|
||||
InX::EhFrame->getParent() && In<ELFT>::EhFrameHdr->getParent())
|
||||
AddHdr(PT_GNU_EH_FRAME, In<ELFT>::EhFrameHdr->getParent()->getPhdrFlags())
|
||||
->add(In<ELFT>::EhFrameHdr->getParent());
|
||||
if (!InX::EhFrame->empty() && InX::EhFrameHdr && InX::EhFrame->getParent() &&
|
||||
InX::EhFrameHdr->getParent())
|
||||
AddHdr(PT_GNU_EH_FRAME, InX::EhFrameHdr->getParent()->getPhdrFlags())
|
||||
->add(InX::EhFrameHdr->getParent());
|
||||
|
||||
// PT_OPENBSD_RANDOMIZE is an OpenBSD-specific feature. That makes
|
||||
// the dynamic linker fill the segment with random data.
|
||||
|
@ -1888,10 +1884,9 @@ template <class ELFT> void Writer<ELFT>::writeSections() {
|
|||
OpdCmd->template writeTo<ELFT>(Buf + Out::Opd->Offset);
|
||||
}
|
||||
|
||||
OutputSection *EhFrameHdr =
|
||||
(In<ELFT>::EhFrameHdr && !In<ELFT>::EhFrameHdr->empty())
|
||||
? In<ELFT>::EhFrameHdr->getParent()
|
||||
: nullptr;
|
||||
OutputSection *EhFrameHdr = nullptr;
|
||||
if (InX::EhFrameHdr && !InX::EhFrameHdr->empty())
|
||||
EhFrameHdr = InX::EhFrameHdr->getParent();
|
||||
|
||||
// In -r or -emit-relocs mode, write the relocation sections first as in
|
||||
// ELf_Rel targets we might find out that we need to modify the relocated
|
||||
|
|
Loading…
Reference in New Issue