diff --git a/contrib/llvm-project/lld/ELF/LinkerScript.cpp b/contrib/llvm-project/lld/ELF/LinkerScript.cpp index 9da1e807b103..57e0e1e8acbf 100644 --- a/contrib/llvm-project/lld/ELF/LinkerScript.cpp +++ b/contrib/llvm-project/lld/ELF/LinkerScript.cpp @@ -1020,17 +1020,13 @@ static uint64_t computeBase(uint64_t min, bool allocateHeaders) { return alignDown(min, config->maxPageSize); } -// Try to find an address for the file and program headers output sections, -// which were unconditionally added to the first PT_LOAD segment earlier. +// When the SECTIONS command is used, try to find an address for the file and +// program headers output sections, which can be added to the first PT_LOAD +// segment when program headers are created. // -// When using the default layout, we check if the headers fit below the first -// allocated section. When using a linker script, we also check if the headers -// are covered by the output section. This allows omitting the headers by not -// leaving enough space for them in the linker script; this pattern is common -// in embedded systems. -// -// If there isn't enough space for these sections, we'll remove them from the -// PT_LOAD segment, and we'll also remove the PT_PHDR segment. +// We check if the headers fit below the first allocated section. If there isn't +// enough space for these sections, we'll remove them from the PT_LOAD segment, +// and we'll also remove the PT_PHDR segment. void LinkerScript::allocateHeaders(std::vector &phdrs) { uint64_t min = std::numeric_limits::max(); for (OutputSection *sec : outputSections) @@ -1076,28 +1072,23 @@ LinkerScript::AddressState::AddressState() { } } -static uint64_t getInitialDot() { - // By default linker scripts use an initial value of 0 for '.', - // but prefer -image-base if set. - if (script->hasSectionsCommand) - return config->imageBase ? *config->imageBase : 0; - - uint64_t startAddr = UINT64_MAX; - // The sections with -T
have been sorted in order of ascending - // address. We must lower startAddr if the lowest -T
as - // calls to setDot() must be monotonically increasing. - for (auto &kv : config->sectionStartMap) - startAddr = std::min(startAddr, kv.second); - return std::min(startAddr, target->getImageBase() + elf::getHeaderSize()); -} - // Here we assign addresses as instructed by linker script SECTIONS // sub-commands. Doing that allows us to use final VA values, so here // we also handle rest commands like symbol assignments and ASSERTs. // Returns a symbol that has changed its section or value, or nullptr if no // symbol has changed. const Defined *LinkerScript::assignAddresses() { - dot = getInitialDot(); + if (script->hasSectionsCommand) { + // With a linker script, assignment of addresses to headers is covered by + // allocateHeaders(). + dot = config->imageBase.getValueOr(0); + } else { + // Assign addresses to headers right now. + dot = target->getImageBase(); + Out::elfHeader->addr = dot; + Out::programHeaders->addr = dot + Out::elfHeader->size; + dot += getHeaderSize(); + } auto deleter = std::make_unique(); ctx = deleter.get(); diff --git a/contrib/llvm-project/lld/ELF/Writer.cpp b/contrib/llvm-project/lld/ELF/Writer.cpp index 2434dc5fb5d8..ac332de2a057 100644 --- a/contrib/llvm-project/lld/ELF/Writer.cpp +++ b/contrib/llvm-project/lld/ELF/Writer.cpp @@ -569,7 +569,8 @@ template void Writer::run() { for (OutputSection *sec : outputSections) sec->maybeCompress(); - script->allocateHeaders(mainPart->phdrs); + if (script->hasSectionsCommand) + script->allocateHeaders(mainPart->phdrs); // Remove empty PT_LOAD to avoid causing the dynamic linker to try to mmap a // 0 sized region. This has to be done late since only after assignAddresses