[lld] r249955 - ELF2: Remove ProgramHeader class and use Elf_Phdr directly. NFC.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Sat Oct 10 15:34:31 PDT 2015


Author: ruiu
Date: Sat Oct 10 17:34:30 2015
New Revision: 249955

URL: http://llvm.org/viewvc/llvm-project?rev=249955&view=rev
Log:
ELF2: Remove ProgramHeader class and use Elf_Phdr directly. NFC.

Modified:
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=249955&r1=249954&r2=249955&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Sat Oct 10 17:34:30 2015
@@ -14,6 +14,7 @@
 #include "Target.h"
 
 #include "llvm/Support/FileOutputBuffer.h"
+#include <unordered_set>
 
 using namespace llvm;
 using namespace llvm::ELF;
@@ -24,7 +25,7 @@ using namespace lld::elf2;
 
 namespace {
 
-static uint32_t toPHDRFlags(uint64_t Flags) {
+static uint32_t toPhdrFlags(uint64_t Flags) {
   uint32_t Ret = PF_R;
   if (Flags & SHF_WRITE)
     Ret |= PF_W;
@@ -33,34 +34,6 @@ static uint32_t toPHDRFlags(uint64_t Fla
   return Ret;
 }
 
-template <class ELFT> struct ProgramHeader {
-  typedef typename ELFFile<ELFT>::uintX_t uintX_t;
-  typedef typename ELFFile<ELFT>::Elf_Phdr Elf_Phdr;
-
-  ProgramHeader(uintX_t Type, uintX_t Flags, uintX_t FileOff, uintX_t VA) {
-    std::memset(&Header, 0, sizeof(Elf_Phdr));
-    Header.p_type = Type;
-    Header.p_flags = Flags;
-    Header.p_align = Target->getPageSize();
-    Header.p_offset = FileOff;
-    Header.p_vaddr = VA;
-    Header.p_paddr = VA;
-  }
-
-  void setValuesFromSection(OutputSectionBase<ELFT::Is64Bits> *Sec) {
-    Header.p_flags = toPHDRFlags(Sec->getFlags());
-    Header.p_offset = Sec->getFileOff();
-    Header.p_vaddr = Sec->getVA();
-    Header.p_paddr = Header.p_vaddr;
-    Header.p_filesz = Sec->getSize();
-    Header.p_memsz = Header.p_filesz;
-    Header.p_align = Sec->getAlign();
-  }
-
-  Elf_Phdr Header;
-  bool Closed = false;
-};
-
 // The writer writes a SymbolTable result to a file.
 template <class ELFT> class Writer {
 public:
@@ -100,13 +73,17 @@ private:
   std::vector<OutputSectionBase<ELFT::Is64Bits> *> OutputSections;
   unsigned getNumSections() const { return OutputSections.size() + 1; }
 
+  void phdrSet(Elf_Phdr *PH, uint32_t Type, uint32_t Flags, uintX_t FileOff,
+               uintX_t VA, uintX_t Align);
+  void phdrCopy(Elf_Phdr *PH, OutputSectionBase<ELFT::Is64Bits> *From);
+
   llvm::BumpPtrAllocator PAlloc;
   SymbolTable<ELFT> &Symtab;
-  std::vector<ProgramHeader<ELFT> *> PHDRs;
-  ProgramHeader<ELFT> PhdrPHDR{PT_PHDR, PF_R, 0, 0};
-  ProgramHeader<ELFT> FileHeaderPHDR{PT_LOAD, PF_R, 0, 0};
-  ProgramHeader<ELFT> InterpPHDR{PT_INTERP, 0, 0, 0};
-  ProgramHeader<ELFT> DynamicPHDR{PT_DYNAMIC, 0, 0, 0};
+  std::vector<Elf_Phdr *> Phdrs;
+  Elf_Phdr PhdrPhdr;
+  Elf_Phdr FileHeaderPhdr;
+  Elf_Phdr InterpPhdr;
+  Elf_Phdr DynamicPhdr;
 
   uintX_t FileSize;
   uintX_t ProgramHeaderOff;
@@ -473,7 +450,7 @@ template <class ELFT> void Writer<ELFT>:
 }
 
 template <class ELFT>
-static bool needsPHDR(OutputSectionBase<ELFT::Is64Bits> *Sec) {
+static bool needsPhdr(OutputSectionBase<ELFT::Is64Bits> *Sec) {
   return Sec->getFlags() & SHF_ALLOC;
 }
 
@@ -481,50 +458,44 @@ static bool needsPHDR(OutputSectionBase<
 // file offsets.
 template <class ELFT> void Writer<ELFT>::assignAddresses() {
   assert(!OutputSections.empty() && "No output sections to layout!");
-  uintX_t VA = getVAStart();
-  uintX_t FileOff = 0;
-
-  FileOff += sizeof(Elf_Ehdr);
-  VA += sizeof(Elf_Ehdr);
+  uintX_t VA = getVAStart() + sizeof(Elf_Ehdr);
+  uintX_t FileOff = sizeof(Elf_Ehdr);
 
-  // The first PHDR entry is PT_PHDR which describes the program header itself.
-  PHDRs.push_back(&PhdrPHDR);
-  PhdrPHDR.Header.p_align = 8;
-  PhdrPHDR.Header.p_offset = FileOff;
-  PhdrPHDR.Header.p_vaddr = VA;
-  PhdrPHDR.Header.p_paddr = VA;
+  // The first Phdr entry is PT_PHDR which describes the program header itself.
+  Phdrs.push_back(&PhdrPhdr);
+  phdrSet(&PhdrPhdr, PT_PHDR, PF_R, FileOff, VA, /*Align=*/8);
 
-  // Reserve space for PHDRs.
+  // Reserve space for Phdrs.
   ProgramHeaderOff = FileOff;
   FileOff = RoundUpToAlignment(FileOff, Target->getPageSize());
   VA = RoundUpToAlignment(VA, Target->getPageSize());
 
   if (needsInterpSection())
-    PHDRs.push_back(&InterpPHDR);
+    Phdrs.push_back(&InterpPhdr);
 
-  // Create a PHDR for the file header.
-  PHDRs.push_back(&FileHeaderPHDR);
-  FileHeaderPHDR.Header.p_vaddr = getVAStart();
-  FileHeaderPHDR.Header.p_paddr = getVAStart();
-  FileHeaderPHDR.Header.p_align = Target->getPageSize();
+  // Create a Phdr for the file header.
+  Phdrs.push_back(&FileHeaderPhdr);
+  phdrSet(&FileHeaderPhdr, PT_LOAD, PF_R, 0, getVAStart(),
+          Target->getPageSize());
 
+  std::unordered_set<Elf_Phdr *> Closed;
   for (OutputSectionBase<ELFT::Is64Bits> *Sec : OutputSections) {
     if (Sec->getSize()) {
-      uintX_t Flags = toPHDRFlags(Sec->getFlags());
-      ProgramHeader<ELFT> *Last = PHDRs.back();
-      if (Last->Header.p_flags != Flags || !needsPHDR<ELFT>(Sec)) {
-        // Flags changed. End current PHDR and potentially create a new one.
-        if (!Last->Closed) {
-          Last->Header.p_filesz = FileOff - Last->Header.p_offset;
-          Last->Header.p_memsz = VA - Last->Header.p_vaddr;
-          Last->Closed = true;
+      uintX_t Flags = toPhdrFlags(Sec->getFlags());
+      Elf_Phdr *Last = Phdrs.back();
+      if (Last->p_flags != Flags || !needsPhdr<ELFT>(Sec)) {
+        // Flags changed. End current Phdr and potentially create a new one.
+        if (Closed.insert(Last).second) {
+          Last->p_filesz = FileOff - Last->p_offset;
+          Last->p_memsz = VA - Last->p_vaddr;
         }
 
-        if (needsPHDR<ELFT>(Sec)) {
+        if (needsPhdr<ELFT>(Sec)) {
           VA = RoundUpToAlignment(VA, Target->getPageSize());
           FileOff = RoundUpToAlignment(FileOff, Target->getPageSize());
-          PHDRs.push_back(new (PAlloc)
-                              ProgramHeader<ELFT>(PT_LOAD, Flags, FileOff, VA));
+          auto *PH = new (PAlloc) Elf_Phdr;
+          phdrSet(PH, PT_LOAD, Flags, FileOff, VA, Target->getPageSize());
+          Phdrs.push_back(PH);
         }
       }
     }
@@ -542,17 +513,22 @@ template <class ELFT> void Writer<ELFT>:
       FileOff += Size;
   }
 
-  // Add a PHDR for the dynamic table.
-  if (needsDynamicSections())
-    PHDRs.push_back(&DynamicPHDR);
-
-  FileOff += OffsetToAlignment(FileOff, ELFT::Is64Bits ? 8 : 4);
+  if (needsInterpSection()) {
+    InterpPhdr.p_type = PT_INTERP;
+    phdrCopy(&InterpPhdr, Out<ELFT>::Interp);
+  }
+  if (needsDynamicSections()) {
+    Phdrs.push_back(&DynamicPhdr);
+    DynamicPhdr.p_type = PT_DYNAMIC;
+    phdrCopy(&DynamicPhdr, Out<ELFT>::Dynamic);
+  }
 
   // Fix up the first entry's size.
-  PhdrPHDR.Header.p_filesz = sizeof(Elf_Phdr) * PHDRs.size();
-  PhdrPHDR.Header.p_memsz = sizeof(Elf_Phdr) * PHDRs.size();
+  PhdrPhdr.p_filesz = sizeof(Elf_Phdr) * Phdrs.size();
+  PhdrPhdr.p_memsz = sizeof(Elf_Phdr) * Phdrs.size();
 
   // Add space for section headers.
+  FileOff = RoundUpToAlignment(FileOff, ELFT::Is64Bits ? 8 : 4);
   SectionHeaderOff = FileOff;
   FileOff += getNumSections() * sizeof(Elf_Shdr);
   FileSize = FileOff;
@@ -587,26 +563,21 @@ template <class ELFT> void Writer<ELFT>:
   EHdr->e_shoff = SectionHeaderOff;
   EHdr->e_ehsize = sizeof(Elf_Ehdr);
   EHdr->e_phentsize = sizeof(Elf_Phdr);
-  EHdr->e_phnum = PHDRs.size();
+  EHdr->e_phnum = Phdrs.size();
   EHdr->e_shentsize = sizeof(Elf_Shdr);
   EHdr->e_shnum = getNumSections();
   EHdr->e_shstrndx = Out<ELFT>::StrTab->getSectionIndex();
 
   // If nothing was merged into the file header PT_LOAD, set the size correctly.
-  if (FileHeaderPHDR.Header.p_filesz == Target->getPageSize()) {
-    uint64_t Size = sizeof(Elf_Ehdr) + sizeof(Elf_Phdr) * PHDRs.size();
-    FileHeaderPHDR.Header.p_filesz = Size;
-    FileHeaderPHDR.Header.p_memsz = Size;
+  if (FileHeaderPhdr.p_filesz == Target->getPageSize()) {
+    uint64_t Size = sizeof(Elf_Ehdr) + sizeof(Elf_Phdr) * Phdrs.size();
+    FileHeaderPhdr.p_filesz = Size;
+    FileHeaderPhdr.p_memsz = Size;
   }
 
-  if (needsInterpSection())
-    InterpPHDR.setValuesFromSection(Out<ELFT>::Interp);
-  if (needsDynamicSections())
-    DynamicPHDR.setValuesFromSection(Out<ELFT>::Dynamic);
-
   auto PHdrs = reinterpret_cast<Elf_Phdr *>(Buf + EHdr->e_phoff);
-  for (ProgramHeader<ELFT> *PHDR : PHDRs)
-    *PHdrs++ = PHDR->Header;
+  for (Elf_Phdr *PH : Phdrs)
+    *PHdrs++ = *PH;
 
   auto SHdrs = reinterpret_cast<Elf_Shdr *>(Buf + EHdr->e_shoff);
   // First entry is null.
@@ -631,6 +602,29 @@ template <class ELFT> void Writer<ELFT>:
     Sec->writeTo(Buf + Sec->getFileOff());
 }
 
+template <class ELFT>
+void Writer<ELFT>::phdrSet(Elf_Phdr *PH, uint32_t Type, uint32_t Flags,
+                           uintX_t FileOff, uintX_t VA, uintX_t Align) {
+  PH->p_type = Type;
+  PH->p_flags = Flags;
+  PH->p_offset = FileOff;
+  PH->p_vaddr = VA;
+  PH->p_paddr = VA;
+  PH->p_align = Align;
+}
+
+template <class ELFT>
+void Writer<ELFT>::phdrCopy(Elf_Phdr *PH,
+                            OutputSectionBase<ELFT::Is64Bits> *From) {
+  PH->p_flags = toPhdrFlags(From->getFlags());
+  PH->p_offset = From->getFileOff();
+  PH->p_vaddr = From->getVA();
+  PH->p_paddr = From->getVA();
+  PH->p_filesz = From->getSize();
+  PH->p_memsz = From->getSize();
+  PH->p_align = From->getAlign();
+}
+
 template void lld::elf2::writeResult<ELF32LE>(SymbolTable<ELF32LE> *Symtab);
 template void lld::elf2::writeResult<ELF32BE>(SymbolTable<ELF32BE> *Symtab);
 template void lld::elf2::writeResult<ELF64LE>(SymbolTable<ELF64LE> *Symtab);




More information about the llvm-commits mailing list