From 02ed7575e7c0dacb6eb36a5893817fcb967905b1 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 4 May 2017 19:34:17 +0000 Subject: Simplify the header allocation. In the non linker script case we would try very early to find out if we could allocate the headers. Failing to do that would add extra alignment to the first ro section, since we would set PageAlign thinking it was the first section in the PT_LOAD. In the linker script case the header allocation must be done in the end, causing some duplication. We now tentatively add the headers to the first PT_LOAD and if it turns out they don't fit, remove them. With this we only need to allocate the headers in one place in the code. llvm-svn: 302186 --- lld/ELF/LinkerScript.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) (limited to 'lld/ELF/LinkerScript.cpp') diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 35b88254304..2620e699053 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -420,13 +420,11 @@ void LinkerScript::processCommands(OutputSectionFactory &Factory) { CurOutSec = nullptr; } -void LinkerScript::fabricateDefaultCommands(bool AllocateHeader) { +void LinkerScript::fabricateDefaultCommands() { std::vector Commands; // Define start address - uint64_t StartAddr = Config->ImageBase; - if (AllocateHeader) - StartAddr += elf::getHeaderSize(); + uint64_t StartAddr = Config->ImageBase + elf::getHeaderSize(); // The Sections with -T
have been sorted in order of ascending // address. We must lower StartAddr if the lowest -T
as @@ -892,6 +890,48 @@ void LinkerScript::synchronize() { } } +static bool allocateHeaders(std::vector &Phdrs, + ArrayRef OutputSections, + uint64_t Min) { + auto FirstPTLoad = + std::find_if(Phdrs.begin(), Phdrs.end(), + [](const PhdrEntry &E) { return E.p_type == PT_LOAD; }); + if (FirstPTLoad == Phdrs.end()) + return false; + + uint64_t HeaderSize = getHeaderSize(); + if (HeaderSize <= Min || Script->hasPhdrsCommands()) { + Min = alignDown(Min - HeaderSize, Config->MaxPageSize); + Out::ElfHeader->Addr = Min; + Out::ProgramHeaders->Addr = Min + Out::ElfHeader->Size; + return true; + } + + assert(FirstPTLoad->First == Out::ElfHeader); + OutputSection *ActualFirst = nullptr; + for (OutputSection *Sec : OutputSections) { + if (Sec->FirstInPtLoad == Out::ElfHeader) { + ActualFirst = Sec; + break; + } + } + if (ActualFirst) { + for (OutputSection *Sec : OutputSections) + if (Sec->FirstInPtLoad == Out::ElfHeader) + Sec->FirstInPtLoad = ActualFirst; + FirstPTLoad->First = ActualFirst; + } else { + Phdrs.erase(FirstPTLoad); + } + + auto PhdrI = std::find_if(Phdrs.begin(), Phdrs.end(), [](const PhdrEntry &E) { + return E.p_type == PT_PHDR; + }); + if (PhdrI != Phdrs.end()) + Phdrs.erase(PhdrI); + return false; +} + void LinkerScript::assignAddresses(std::vector &Phdrs) { // Assign addresses as instructed by linker script SECTIONS sub-commands. Dot = 0; -- cgit v1.2.3