Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -28,10 +28,6 @@ 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 @@ void assignAddresses(); void assignFileOffsets(); void setPhdrs(); + void fixHeaders(); void fixSectionAlignments(); void fixAbsoluteSymbols(); void openFile(); @@ -103,14 +100,6 @@ 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 @@ assignFileOffsets(); } else { createPhdrs(); + fixHeaders(); fixSectionAlignments(); assignAddresses(); assignFileOffsets(); @@ -983,10 +973,6 @@ // 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 @@ } } - for (OutputSectionBase *Sec : getSections()) + for (OutputSectionBase *Sec : OutputSections) Sec->assignOffsets(); // Now that we have defined all possible symbols including linker- @@ -1112,11 +1098,11 @@ 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 @@ 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 @@ } } +// 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 @@ // 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 @@ 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 @@ 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 @@ // 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); }