From e044e9cf80236c85e93b40e274b067e6f9dbaf39 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Fri, 1 Apr 2016 17:07:17 +0000 Subject: [PATCH] Tidy up address and file offset assignments in the Writer. assignAddressesRelocatable function did not set addresses to sections despite its name. What it actually did is to set file offsets to sections. assignAddresses function assigned addresses and file offsets to sections. So there was a confusion what they were doing, and they had duplicate code. This patch separates file offset assignments from address assignments. A new function, assignFileOffsets assign file offsets. assignAddresses do not care about file offsets anymore. llvm-svn: 265151 --- lld/ELF/Writer.cpp | 63 +++++++++++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index b814adf..fa0bff2 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -74,8 +74,8 @@ private: void scanRelocs(InputSectionBase &S, const Elf_Shdr &RelSec); void createPhdrs(); void assignAddresses(); - void assignAddressesRelocatable(); - void assignPhdrs(); + void assignFileOffsets(); + void setPhdrs(); void fixSectionAlignments(); void fixAbsoluteSymbols(); bool openFile(); @@ -216,14 +216,18 @@ template void Writer::run() { addReservedSymbols(); if (!createSections()) return; - if (!Config->Relocatable) { + + if (Config->Relocatable) { + assignFileOffsets(); + } else { createPhdrs(); fixSectionAlignments(); assignAddresses(); - } else { - assignAddressesRelocatable(); + assignFileOffsets(); + setPhdrs(); } fixAbsoluteSymbols(); + if (!openFile()) return; writeHeader(); @@ -1351,28 +1355,9 @@ template void Writer::fixSectionAlignments() { template static uintX_t fixFileOff(uintX_t FileOff, uintX_t Align, OutputSectionBase *Sec) { - if (Sec->getType() != SHT_NOBITS) - FileOff = alignTo(FileOff, Align); - Sec->setFileOffset(FileOff); - if (Sec->getType() != SHT_NOBITS) - FileOff += Sec->getSize(); - return FileOff; } -// Used for relocatable output (-r). In this case we create only ELF file -// header, do not create program headers. Also assign of section addresses -// is very straightforward: we just put all sections sequentually to the file. -template void Writer::assignAddressesRelocatable() { - Out::ElfHeader->setSize(sizeof(Elf_Ehdr)); - uintX_t FileOff = 0; - for (OutputSectionBase *Sec : OutputSections) - FileOff = fixFileOff(FileOff, Sec->getAlign(), Sec); - SectionHeaderOff = alignTo(FileOff, sizeof(uintX_t)); - FileSize = SectionHeaderOff + getNumSections() * sizeof(Elf_Shdr); -} - -// Visits all headers in PhdrTable and assigns the adresses to -// the output sections. Also creates common and special headers. +// Assign VAs (addresses at run-time) to output sections. template void Writer::assignAddresses() { Out::ElfHeader->setSize(sizeof(Elf_Ehdr)); size_t PhdrSize = sizeof(Elf_Phdr) * Phdrs.size(); @@ -1380,13 +1365,11 @@ template void Writer::assignAddresses() { uintX_t ThreadBssOffset = 0; uintX_t VA = Target->getVAStart(); - uintX_t FileOff = 0; for (OutputSectionBase *Sec : OutputSections) { uintX_t Align = Sec->getAlign(); if (Sec->PageAlign) Align = std::max(Align, Target->PageSize); - FileOff = fixFileOff(FileOff, Align, Sec); // We only assign VAs to allocated sections. if (needsPtLoad(Sec)) { @@ -1400,15 +1383,31 @@ template void Writer::assignAddresses() { ThreadBssOffset = TVA - VA + Sec->getSize(); } } +} - // Add space for section headers. - SectionHeaderOff = alignTo(FileOff, sizeof(uintX_t)); +// Assign file offsets to output sections. +template void Writer::assignFileOffsets() { + Out::ElfHeader->setSize(sizeof(Elf_Ehdr)); + uintX_t Off = 0; + for (OutputSectionBase *Sec : OutputSections) { + if (Sec->getType() == SHT_NOBITS) { + Sec->setFileOffset(Off); + continue; + } + uintX_t Align = Sec->getAlign(); + if (Sec->PageAlign) + Align = std::max(Align, Target->PageSize); + Off = alignTo(Off, Align); + Sec->setFileOffset(Off); + Off += Sec->getSize(); + } + SectionHeaderOff = alignTo(Off, sizeof(uintX_t)); FileSize = SectionHeaderOff + getNumSections() * sizeof(Elf_Shdr); - - assignPhdrs(); } -template void Writer::assignPhdrs() { +// Finalize the program headers. We call this function after we assign +// file offsets and VAs to all sections. +template void Writer::setPhdrs() { for (Phdr &PHdr : Phdrs) { Elf_Phdr &H = PHdr.H; if (PHdr.First) { -- 2.7.4