[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