Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -897,13 +897,27 @@ return nullptr; } -static uint64_t computeBase(uint64_t Min, bool AllocateHeaders) { +static bool hasExplicitHeaders(ArrayRef Phdrs) { + return llvm::any_of(Phdrs, [](const PhdrsCommand &Cmd) { + return Cmd.HasPhdrs || Cmd.HasFilehdr; + }); +} + +static Optional getHeadersVA(uint64_t MinVA, uint64_t HeaderSize, + ArrayRef Phdrs) { + // Unable to allocate headers when their size is greater than minimal VA. + if (HeaderSize > MinVA) + return None; + // If there is no SECTIONS or if the linkerscript is explicit about program // headers, do our best to allocate them. - if (!Script->HasSectionsCommand || AllocateHeaders) - return 0; + if (!Script->HasSectionsCommand || hasExplicitHeaders(Phdrs)) + return alignDown(MinVA - HeaderSize, Config->MaxPageSize); + // Otherwise only allocate program headers if that would not add a page. - return alignDown(Min, Config->MaxPageSize); + if (HeaderSize <= MinVA - alignDown(MinVA, Config->MaxPageSize)) + return alignDown(MinVA - HeaderSize, Config->MaxPageSize); + return None; } // Try to find an address for the file and program headers output sections, @@ -927,24 +941,19 @@ Phdrs, [](const PhdrEntry *E) { return E->p_type == PT_LOAD; }); if (It == Phdrs.end()) return; - PhdrEntry *FirstPTLoad = *It; - bool HasExplicitHeaders = - llvm::any_of(PhdrsCommands, [](const PhdrsCommand &Cmd) { - return Cmd.HasPhdrs || Cmd.HasFilehdr; - }); - uint64_t HeaderSize = getHeaderSize(); - if (HeaderSize <= Min - computeBase(Min, HasExplicitHeaders)) { - Min = alignDown(Min - HeaderSize, Config->MaxPageSize); - Out::ElfHeader->Addr = Min; - Out::ProgramHeaders->Addr = Min + Out::ElfHeader->Size; + if (Optional VA = + getHeadersVA(Min, getHeaderSize(), PhdrsCommands)) { + Out::ElfHeader->Addr = *VA; + Out::ProgramHeaders->Addr = *VA + Out::ElfHeader->Size; return; } // Error if we were explicitly asked to allocate headers. - if (HasExplicitHeaders) + if (hasExplicitHeaders(PhdrsCommands)) error("could not allocate headers"); + PhdrEntry *FirstPTLoad = *It; Out::ElfHeader->PtLoad = nullptr; Out::ProgramHeaders->PtLoad = nullptr; FirstPTLoad->FirstSec = findFirstSection(FirstPTLoad);