From 7ca0627c51b31650281654dbadf080f1ec6d46ec Mon Sep 17 00:00:00 2001 From: George Rimar Date: Wed, 6 Apr 2016 07:20:45 +0000 Subject: [PATCH] [ELF] - Do not handle ELF and program header as dummy sections. ELF and program header are not part of OutputSections list anymore. That helps to avoid having and working with functions like dummySectionsNum(). Still keeping them as sections helps to simplify the code. Differential revision: http://reviews.llvm.org/D18743 llvm-svn: 265522 --- lld/ELF/Writer.cpp | 55 +++++++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 4e6b368..e3601f4 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -28,10 +28,6 @@ using namespace llvm::object; using namespace lld; using namespace lld::elf; -// Usually there are 2 dummies sections: ELF header and program header. -// Relocatable output does not require program headers to be created. -static unsigned dummySectionsNum() { return Config->Relocatable ? 1 : 2; } - namespace { // The writer writes a SymbolTable result to a file. template class Writer { @@ -75,6 +71,7 @@ private: void assignAddresses(); void assignFileOffsets(); void setPhdrs(); + void fixHeaders(); void fixSectionAlignments(); void fixAbsoluteSymbols(); void openFile(); @@ -103,14 +100,6 @@ private: std::vector *> OutputSections; std::vector>> OwningSections; - // We create a section for the ELF header and one for the program headers. - ArrayRef *> getSections() const { - return makeArrayRef(OutputSections).slice(dummySectionsNum()); - } - unsigned getNumSections() const { - return OutputSections.size() + 1 - dummySectionsNum(); - } - void addRelIpltSymbols(); void addStartEndSymbols(); void addStartStopSymbols(OutputSectionBase *Sec); @@ -223,6 +212,7 @@ template void Writer::run() { assignFileOffsets(); } else { createPhdrs(); + fixHeaders(); fixSectionAlignments(); assignAddresses(); assignFileOffsets(); @@ -983,10 +973,6 @@ template static void sortCtorsDtors(OutputSectionBase *S) { // Create output section objects and add them to OutputSections. template void Writer::createSections() { - OutputSections.push_back(Out::ElfHeader); - if (!Config->Relocatable) - OutputSections.push_back(Out::ProgramHeaders); - // Add .interp first because some loaders want to see that section // on the first page of the executable file when loaded into memory. if (needsInterpSection()) @@ -1075,7 +1061,7 @@ template void Writer::createSections() { } } - for (OutputSectionBase *Sec : getSections()) + for (OutputSectionBase *Sec : OutputSections) Sec->assignOffsets(); // Now that we have defined all possible symbols including linker- @@ -1112,11 +1098,11 @@ template void Writer::createSections() { std::stable_sort(OutputSections.begin(), OutputSections.end(), compareSections); - for (unsigned I = dummySectionsNum(), N = OutputSections.size(); I < N; ++I) - OutputSections[I]->SectionIndex = I + 1 - dummySectionsNum(); - - for (OutputSectionBase *Sec : getSections()) + unsigned I = 1; + for (OutputSectionBase *Sec : OutputSections) { + Sec->SectionIndex = I++; Sec->setSHName(Out::ShStrTab->addString(Sec->getName())); + } // Finalizers fix each section's size. // .dynsym is finalized early since that may fill up .gnu.hash. @@ -1284,6 +1270,7 @@ template void Writer::createPhdrs() { uintX_t Flags = PF_R; Phdr *Load = AddHdr(PT_LOAD, Flags); AddSec(*Load, Out::ElfHeader); + AddSec(*Load, Out::ProgramHeaders); Phdr TlsHdr(PT_TLS, PF_R); Phdr RelRo(PT_GNU_RELRO, PF_R); @@ -1371,11 +1358,23 @@ template void Writer::fixSectionAlignments() { } } +// We should set file offsets and VAs for elf header and program headers +// sections. These are special, we do not include them into output sections +// list, but have them to simplify the code. +template void Writer::fixHeaders() { + Out::ElfHeader->setVA(Target->getVAStart()); + Out::ElfHeader->setFileOffset(0); + uintX_t Off = Out::ElfHeader->getSize(); + Out::ProgramHeaders->setVA(Off + Target->getVAStart()); + Out::ProgramHeaders->setFileOffset(Off); +} + // Assign VAs (addresses at run-time) to output sections. template void Writer::assignAddresses() { - uintX_t ThreadBssOffset = 0; - uintX_t VA = Target->getVAStart(); + uintX_t VA = Target->getVAStart() + Out::ElfHeader->getSize() + + Out::ProgramHeaders->getSize(); + uintX_t ThreadBssOffset = 0; for (OutputSectionBase *Sec : OutputSections) { uintX_t Align = Sec->getAlign(); if (Sec->PageAlign) @@ -1397,7 +1396,9 @@ template void Writer::assignAddresses() { // Assign file offsets to output sections. template void Writer::assignFileOffsets() { - uintX_t Off = 0; + uintX_t Off = + Out::ElfHeader->getSize() + Out::ProgramHeaders->getSize(); + for (OutputSectionBase *Sec : OutputSections) { if (Sec->getType() == SHT_NOBITS) { Sec->setFileOffset(Off); @@ -1411,7 +1412,7 @@ template void Writer::assignFileOffsets() { Off += Sec->getSize(); } SectionHeaderOff = alignTo(Off, sizeof(uintX_t)); - FileSize = SectionHeaderOff + getNumSections() * sizeof(Elf_Shdr); + FileSize = SectionHeaderOff + (OutputSections.size() + 1) * sizeof(Elf_Shdr); } // Finalize the program headers. We call this function after we assign @@ -1541,7 +1542,7 @@ template void Writer::writeHeader() { EHdr->e_ehsize = sizeof(Elf_Ehdr); EHdr->e_phnum = Phdrs.size(); EHdr->e_shentsize = sizeof(Elf_Shdr); - EHdr->e_shnum = getNumSections(); + EHdr->e_shnum = OutputSections.size() + 1; EHdr->e_shstrndx = Out::ShStrTab->SectionIndex; if (Config->EMachine == EM_MIPS) @@ -1559,7 +1560,7 @@ template void Writer::writeHeader() { // Write the section header table. Note that the first table entry is null. auto *SHdrs = reinterpret_cast(Buf + EHdr->e_shoff); - for (OutputSectionBase *Sec : getSections()) + for (OutputSectionBase *Sec : OutputSections) Sec->writeHeaderTo(++SHdrs); } -- 2.7.4