aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-03-05 18:09:19 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-03-05 18:09:19 +0000
commit69660011c6637bc32c9b5ff25f285de3e1209225 (patch)
treef62ca9bb05a2f4b61022e17cb46d343cfc0cb97e
parente43d33d286a1aa41b6fc6a209f28a18e8cd7437a (diff)
Notes
-rw-r--r--contrib/llvm-project/lld/ELF/LinkerScript.cpp43
-rw-r--r--contrib/llvm-project/lld/ELF/Writer.cpp3
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