From: Rui Ueyama Date: Wed, 30 Mar 2016 19:41:51 +0000 (+0000) Subject: Split Writer::assignAddresses. NFC. X-Git-Tag: llvmorg-3.9.0-rc1~10490 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4709190376d2d29f5b26a69f540feac31444080a;p=platform%2Fupstream%2Fllvm.git Split Writer::assignAddresses. NFC. llvm-svn: 264905 --- diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index a35fa1e..2c1f735 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -83,6 +83,10 @@ public: Header.sh_addralign = Align; } + // If true, this section will be page aligned on disk. + // Typically the first section of each PT_LOAD segment has this flag. + bool PageAlign = false; + virtual void finalize() {} virtual void writeTo(uint8_t *Buf) {} virtual ~OutputSectionBase() = default; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index b9df7cd..2ab47f7 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -71,6 +71,7 @@ private: void createPhdrs(); void assignAddresses(); void assignAddressesRelocatable(); + void fixSectionAlignments(); void fixAbsoluteSymbols(); bool openFile(); void writeHeader(); @@ -212,6 +213,7 @@ template void Writer::run() { return; if (!Config->Relocatable) { createPhdrs(); + fixSectionAlignments(); assignAddresses(); } else { assignAddressesRelocatable(); @@ -1304,6 +1306,28 @@ template void Writer::createPhdrs() { Phdrs.push_back(std::move(Note)); } +// The first section of each PT_LOAD and the first section after PT_GNU_RELRO +// have to be page aligned so that the dynamic linker can set the permissions. +template void Writer::fixSectionAlignments() { + for (const Phdr &P : Phdrs) + if (P.H.p_type == PT_LOAD) + P.First->PageAlign = true; + + for (const Phdr &P : Phdrs) { + if (P.H.p_type != PT_GNU_RELRO) + continue; + // Find the first section after PT_GNU_RELRO. If it is in a PT_LOAD we + // have to align it to a page. + auto End = OutputSections.end(); + auto I = std::find(OutputSections.begin(), End, P.Last); + if (I == End || (I + 1) == End) + continue; + OutputSectionBase *Sec = *(I + 1); + if (needsPtLoad(Sec)) + Sec->PageAlign = true; + } +} + // 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. @@ -1328,30 +1352,13 @@ template void Writer::assignAddresses() { size_t PhdrSize = sizeof(Elf_Phdr) * Phdrs.size(); Out::ProgramHeaders->setSize(PhdrSize); - // The first section of each PT_LOAD and the first section after PT_GNU_RELRO - // have to be page aligned so that the dynamic linker can set the permissions. - SmallPtrSet *, 4> PageAlign; - for (const Phdr &P : Phdrs) { - if (P.H.p_type == PT_GNU_RELRO) { - // Find the first section after PT_GNU_RELRO. If it is in a PT_LOAD we - // have to align it to a page. - auto I = std::find(OutputSections.begin(), OutputSections.end(), P.Last); - ++I; - if (I != OutputSections.end() && needsPtLoad(*I)) - PageAlign.insert(*I); - } - - if (P.H.p_type == PT_LOAD) - PageAlign.insert(P.First); - } - uintX_t ThreadBssOffset = 0; uintX_t VA = Target->getVAStart(); uintX_t FileOff = 0; for (OutputSectionBase *Sec : OutputSections) { uintX_t Align = Sec->getAlign(); - if (PageAlign.count(Sec)) + if (Sec->PageAlign) Align = std::max(Align, Target->PageSize); if (Sec->getType() != SHT_NOBITS)