diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-03-05 18:09:19 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-03-05 18:09:19 +0000 |
commit | 69660011c6637bc32c9b5ff25f285de3e1209225 (patch) | |
tree | f62ca9bb05a2f4b61022e17cb46d343cfc0cb97e | |
parent | e43d33d286a1aa41b6fc6a209f28a18e8cd7437a (diff) |
Notes
-rw-r--r-- | contrib/llvm-project/lld/ELF/LinkerScript.cpp | 43 | ||||
-rw-r--r-- | contrib/llvm-project/lld/ELF/Writer.cpp | 3 |
2 files changed, 19 insertions, 27 deletions
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<PhdrEntry *> &phdrs) { uint64_t min = std::numeric_limits<uint64_t>::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<section> have been sorted in order of ascending - // address. We must lower startAddr if the lowest -T<section address> 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<AddressState>(); 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 <class ELFT> void Writer<ELFT>::run() { for (OutputSection *sec : outputSections) sec->maybeCompress<ELFT>(); - 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 |