[lld] r270445 - Make .eh_frame a singleton output object.
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Mon May 23 09:24:19 PDT 2016
Author: ruiu
Date: Mon May 23 11:24:16 2016
New Revision: 270445
URL: http://llvm.org/viewvc/llvm-project?rev=270445&view=rev
Log:
Make .eh_frame a singleton output object.
.eh_frame_hdr assumes that there is only one .eh_frame and
ensures it by assertions. This patch makes .eh_frame a real
singleton object to simplify.
Modified:
lld/trunk/ELF/OutputSections.cpp
lld/trunk/ELF/OutputSections.h
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=270445&r1=270444&r2=270445&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Mon May 23 11:24:16 2016
@@ -739,7 +739,7 @@ template <class ELFT> void EhFrameHeader
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, Sec->getVA() - this->getVA() - 4);
+ write32<E>(Buf + 4, Out<ELFT>::EhFrame->getVA() - this->getVA() - 4);
write32<E>(Buf + 8, Fdes.size());
Buf += 12;
@@ -752,14 +752,6 @@ template <class ELFT> void EhFrameHeader
}
template <class ELFT>
-void EhFrameHeader<ELFT>::add(EhOutputSection<ELFT> *Sec) {
- assert((!this->Sec || this->Sec == Sec) &&
- "multiple .eh_frame sections not supported for .eh_frame_hdr");
- Live = Config->EhFrameHdr;
- this->Sec = Sec;
-}
-
-template <class ELFT>
void EhFrameHeader<ELFT>::addFde(uint32_t Pc, uint32_t FdeVA) {
Fdes.push_back({Pc, FdeVA});
}
@@ -922,9 +914,7 @@ template <class ELFT> void OutputSection
template <class ELFT>
EhOutputSection<ELFT>::EhOutputSection()
- : OutputSectionBase<ELFT>(".eh_frame", SHT_PROGBITS, SHF_ALLOC) {
- Out<ELFT>::EhFrameHdr->add(this);
-}
+ : OutputSectionBase<ELFT>(".eh_frame", SHT_PROGBITS, SHF_ALLOC) {}
template <class ELFT>
void EhOutputSection<ELFT>::forEachInputSection(
@@ -1118,7 +1108,8 @@ void EhOutputSection<ELFT>::addSectionAu
if (!isFdeLive(FdePiece, Sec, Rels))
continue;
Cie->FdePieces.push_back(&FdePiece);
- Out<ELFT>::EhFrameHdr->reserveFde();
+ if (Out<ELFT>::EhFrameHdr)
+ Out<ELFT>::EhFrameHdr->reserveFde();
}
}
@@ -1229,11 +1220,13 @@ template <class ELFT> void EhOutputSecti
// Construct .eh_frame_hdr. .eh_frame_hdr is a binary search table
// to get a FDE from an address to which FDE is applied to. So here
// we obtain two addresses and pass them to EhFrameHdr object.
- for (CieRecord *Cie : Cies) {
- for (SectionPiece *Fde : Cie->FdePieces) {
- uintX_t Pc = getFdePc(Buf, Fde->OutputOff, Cie->FdeEncoding);
- uintX_t FdeVA = this->getVA() + Fde->OutputOff;
- Out<ELFT>::EhFrameHdr->addFde(Pc, FdeVA);
+ if (Out<ELFT>::EhFrameHdr) {
+ for (CieRecord *Cie : Cies) {
+ for (SectionPiece *Fde : Cie->FdePieces) {
+ uintX_t Pc = getFdePc(Buf, Fde->OutputOff, Cie->FdeEncoding);
+ uintX_t FdeVA = this->getVA() + Fde->OutputOff;
+ Out<ELFT>::EhFrameHdr->addFde(Pc, FdeVA);
+ }
}
}
}
Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=270445&r1=270444&r2=270445&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Mon May 23 11:24:16 2016
@@ -343,6 +343,7 @@ public:
EhOutputSection();
void writeTo(uint8_t *Buf) override;
void finalize() override;
+ bool empty() const { return Sections.empty(); }
void
forEachInputSection(std::function<void(InputSectionBase<ELFT> *)> F) override;
@@ -543,10 +544,6 @@ public:
void add(EhOutputSection<ELFT> *Sec);
void reserveFde();
- bool Live = false;
-
- EhOutputSection<ELFT> *Sec = nullptr;
-
private:
struct FdeData {
uint32_t Pc;
@@ -603,6 +600,7 @@ template <class ELFT> struct Out {
static BuildIdSection<ELFT> *BuildId;
static DynamicSection<ELFT> *Dynamic;
static EhFrameHeader<ELFT> *EhFrameHdr;
+ static EhOutputSection<ELFT> *EhFrame;
static GnuHashTableSection<ELFT> *GnuHashTab;
static GotPltSection<ELFT> *GotPlt;
static GotSection<ELFT> *Got;
@@ -630,6 +628,7 @@ template <class ELFT> struct Out {
template <class ELFT> BuildIdSection<ELFT> *Out<ELFT>::BuildId;
template <class ELFT> DynamicSection<ELFT> *Out<ELFT>::Dynamic;
template <class ELFT> EhFrameHeader<ELFT> *Out<ELFT>::EhFrameHdr;
+template <class ELFT> EhOutputSection<ELFT> *Out<ELFT>::EhFrame;
template <class ELFT> GnuHashTableSection<ELFT> *Out<ELFT>::GnuHashTab;
template <class ELFT> GotPltSection<ELFT> *Out<ELFT>::GotPlt;
template <class ELFT> GotSection<ELFT> *Out<ELFT>::Got;
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=270445&r1=270444&r2=270445&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Mon May 23 11:24:16 2016
@@ -130,7 +130,7 @@ template <class ELFT> void elf::writeRes
// Create singleton output sections.
DynamicSection<ELFT> Dynamic(*Symtab);
- EhFrameHeader<ELFT> EhFrameHdr;
+ EhOutputSection<ELFT> EhFrame;
GotSection<ELFT> Got;
InterpSection<ELFT> Interp;
PltSection<ELFT> Plt;
@@ -149,6 +149,7 @@ template <class ELFT> void elf::writeRes
// Instantiate optional output sections if they are needed.
std::unique_ptr<BuildIdSection<ELFT>> BuildId;
+ std::unique_ptr<EhFrameHeader<ELFT>> EhFrameHdr;
std::unique_ptr<GnuHashTableSection<ELFT>> GnuHashTab;
std::unique_ptr<GotPltSection<ELFT>> GotPlt;
std::unique_ptr<HashTableSection<ELFT>> HashTab;
@@ -166,6 +167,9 @@ template <class ELFT> void elf::writeRes
else if (Config->BuildId == BuildIdKind::Hexstring)
BuildId.reset(new BuildIdHexstring<ELFT>);
+ if (Config->EhFrameHdr)
+ EhFrameHdr.reset(new EhFrameHeader<ELFT>);
+
if (Config->GnuHash)
GnuHashTab.reset(new GnuHashTableSection<ELFT>);
if (Config->SysvHash)
@@ -192,7 +196,8 @@ template <class ELFT> void elf::writeRes
Out<ELFT>::DynStrTab = &DynStrTab;
Out<ELFT>::DynSymTab = &DynSymTab;
Out<ELFT>::Dynamic = &Dynamic;
- Out<ELFT>::EhFrameHdr = &EhFrameHdr;
+ Out<ELFT>::EhFrame = &EhFrame;
+ Out<ELFT>::EhFrameHdr = EhFrameHdr.get();
Out<ELFT>::GnuHashTab = GnuHashTab.get();
Out<ELFT>::Got = &Got;
Out<ELFT>::GotPlt = GotPlt.get();
@@ -1174,8 +1179,7 @@ OutputSectionFactory<ELFT>::create(Input
Sec = new OutputSection<ELFT>(Key.Name, Key.Type, Key.Flags);
break;
case InputSectionBase<ELFT>::EHFrame:
- Sec = new EhOutputSection<ELFT>;
- break;
+ return {Out<ELFT>::EhFrame, false};
case InputSectionBase<ELFT>::Merge:
Sec = new MergeOutputSection<ELFT>(Key.Name, Key.Type, Key.Flags,
Key.Alignment);
@@ -1368,8 +1372,10 @@ template <class ELFT> void Writer<ELFT>:
// Define __rel[a]_iplt_{start,end} symbols if needed.
addRelIpltSymbols();
- if (Out<ELFT>::EhFrameHdr->Sec)
- Out<ELFT>::EhFrameHdr->Sec->finalize();
+ if (!Out<ELFT>::EhFrame->empty()) {
+ OutputSections.push_back(Out<ELFT>::EhFrame);
+ Out<ELFT>::EhFrame->finalize();
+ }
// Scan relocations. This must be done after every symbol is declared so that
// we can correctly decide if a dynamic relocation is needed.
@@ -1515,7 +1521,7 @@ template <class ELFT> void Writer<ELFT>:
Add(Out<ELFT>::GotPlt);
if (!Out<ELFT>::Plt->empty())
Add(Out<ELFT>::Plt);
- if (Out<ELFT>::EhFrameHdr->Live)
+ if (!Out<ELFT>::EhFrame->empty())
Add(Out<ELFT>::EhFrameHdr);
}
@@ -1662,7 +1668,7 @@ template <class ELFT> void Writer<ELFT>:
Phdrs.push_back(std::move(RelRo));
// PT_GNU_EH_FRAME is a special section pointing on .eh_frame_hdr.
- if (Out<ELFT>::EhFrameHdr->Live) {
+ if (!Out<ELFT>::EhFrame->empty() && Out<ELFT>::EhFrameHdr) {
Phdr &Hdr = *AddHdr(PT_GNU_EH_FRAME,
toPhdrFlags(Out<ELFT>::EhFrameHdr->getFlags()));
AddSec(Hdr, Out<ELFT>::EhFrameHdr);
More information about the llvm-commits
mailing list