aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lld/ELF/LinkerScript.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/lld/ELF/LinkerScript.cpp')
-rw-r--r--contrib/llvm-project/lld/ELF/LinkerScript.cpp88
1 files changed, 39 insertions, 49 deletions
diff --git a/contrib/llvm-project/lld/ELF/LinkerScript.cpp b/contrib/llvm-project/lld/ELF/LinkerScript.cpp
index e8f2ce4fdf1f..bfb583453735 100644
--- a/contrib/llvm-project/lld/ELF/LinkerScript.cpp
+++ b/contrib/llvm-project/lld/ELF/LinkerScript.cpp
@@ -19,7 +19,7 @@
#include "SyntheticSections.h"
#include "Target.h"
#include "Writer.h"
-#include "lld/Common/Memory.h"
+#include "lld/Common/CommonLinkerContext.h"
#include "lld/Common/Strings.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
@@ -64,8 +64,8 @@ static StringRef getOutputSectionName(const InputSectionBase *s) {
if (InputSectionBase *rel = isec->getRelocatedSection()) {
OutputSection *out = rel->getOutputSection();
if (s->type == SHT_RELA)
- return saver.save(".rela" + out->name);
- return saver.save(".rel" + out->name);
+ return saver().save(".rela" + out->name);
+ return saver().save(".rel" + out->name);
}
}
@@ -135,7 +135,7 @@ uint64_t ExprValue::getSectionOffset() const {
OutputSection *LinkerScript::createOutputSection(StringRef name,
StringRef location) {
- OutputSection *&secRef = nameToOutputSection[name];
+ OutputSection *&secRef = nameToOutputSection[CachedHashStringRef(name)];
OutputSection *sec;
if (secRef && secRef->location.empty()) {
// There was a forward reference.
@@ -150,7 +150,7 @@ OutputSection *LinkerScript::createOutputSection(StringRef name,
}
OutputSection *LinkerScript::getOrCreateOutputSection(StringRef name) {
- OutputSection *&cmdRef = nameToOutputSection[name];
+ OutputSection *&cmdRef = nameToOutputSection[CachedHashStringRef(name)];
if (!cmdRef)
cmdRef = make<OutputSection>(name, SHT_PROGBITS, 0);
return cmdRef;
@@ -270,8 +270,8 @@ using SymbolAssignmentMap =
// Collect section/value pairs of linker-script-defined symbols. This is used to
// check whether symbol values converge.
-static SymbolAssignmentMap getSymbolAssignmentValues(
- const std::vector<SectionCommand *> &sectionCommands) {
+static SymbolAssignmentMap
+getSymbolAssignmentValues(ArrayRef<SectionCommand *> sectionCommands) {
SymbolAssignmentMap ret;
for (SectionCommand *cmd : sectionCommands) {
if (auto *assign = dyn_cast<SymbolAssignment>(cmd)) {
@@ -306,7 +306,7 @@ getChangedSymbolAssignment(const SymbolAssignmentMap &oldValues) {
// Process INSERT [AFTER|BEFORE] commands. For each command, we move the
// specified output section to the designated place.
void LinkerScript::processInsertCommands() {
- std::vector<OutputSection *> moves;
+ SmallVector<OutputSection *, 0> moves;
for (const InsertCommand &cmd : insertCommands) {
for (StringRef name : cmd.names) {
// If base is empty, it may have been discarded by
@@ -486,11 +486,11 @@ static void sortInputSections(MutableArrayRef<InputSectionBase *> vec,
}
// Compute and remember which sections the InputSectionDescription matches.
-std::vector<InputSectionBase *>
+SmallVector<InputSectionBase *, 0>
LinkerScript::computeInputSections(const InputSectionDescription *cmd,
ArrayRef<InputSectionBase *> sections) {
- std::vector<InputSectionBase *> ret;
- std::vector<size_t> indexes;
+ SmallVector<InputSectionBase *, 0> ret;
+ SmallVector<size_t, 0> indexes;
DenseSet<size_t> seen;
auto sortByPositionThenCommandLine = [&](size_t begin, size_t end) {
llvm::sort(MutableArrayRef<size_t>(indexes).slice(begin, end - begin));
@@ -561,17 +561,9 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd,
}
void LinkerScript::discard(InputSectionBase &s) {
- if (&s == in.shStrTab || &s == mainPart->relrDyn)
+ if (&s == in.shStrTab.get())
error("discarding " + s.name + " section is not allowed");
- // You can discard .hash and .gnu.hash sections by linker scripts. Since
- // they are synthesized sections, we need to handle them differently than
- // other regular sections.
- if (&s == mainPart->gnuHashTab)
- mainPart->gnuHashTab = nullptr;
- if (&s == mainPart->hashTab)
- mainPart->hashTab = nullptr;
-
s.markDead();
s.parent = nullptr;
for (InputSection *sec : s.dependentSections)
@@ -582,21 +574,19 @@ void LinkerScript::discardSynthetic(OutputSection &outCmd) {
for (Partition &part : partitions) {
if (!part.armExidx || !part.armExidx->isLive())
continue;
- std::vector<InputSectionBase *> secs(part.armExidx->exidxSections.begin(),
- part.armExidx->exidxSections.end());
+ SmallVector<InputSectionBase *, 0> secs(
+ part.armExidx->exidxSections.begin(),
+ part.armExidx->exidxSections.end());
for (SectionCommand *cmd : outCmd.commands)
- if (auto *isd = dyn_cast<InputSectionDescription>(cmd)) {
- std::vector<InputSectionBase *> matches =
- computeInputSections(isd, secs);
- for (InputSectionBase *s : matches)
+ if (auto *isd = dyn_cast<InputSectionDescription>(cmd))
+ for (InputSectionBase *s : computeInputSections(isd, secs))
discard(*s);
- }
}
}
-std::vector<InputSectionBase *>
+SmallVector<InputSectionBase *, 0>
LinkerScript::createInputSectionList(OutputSection &outCmd) {
- std::vector<InputSectionBase *> ret;
+ SmallVector<InputSectionBase *, 0> ret;
for (SectionCommand *cmd : outCmd.commands) {
if (auto *isd = dyn_cast<InputSectionDescription>(cmd)) {
@@ -612,7 +602,7 @@ LinkerScript::createInputSectionList(OutputSection &outCmd) {
// Create output sections described by SECTIONS commands.
void LinkerScript::processSectionCommands() {
auto process = [this](OutputSection *osec) {
- std::vector<InputSectionBase *> v = createInputSectionList(*osec);
+ SmallVector<InputSectionBase *, 0> v = createInputSectionList(*osec);
// The output section name `/DISCARD/' is special.
// Any input section assigned to it is discarded.
@@ -656,14 +646,16 @@ void LinkerScript::processSectionCommands() {
// Process OVERWRITE_SECTIONS first so that it can overwrite the main script
// or orphans.
- DenseMap<StringRef, OutputSection *> map;
+ DenseMap<CachedHashStringRef, OutputSection *> map;
size_t i = 0;
for (OutputSection *osec : overwriteSections)
- if (process(osec) && !map.try_emplace(osec->name, osec).second)
+ if (process(osec) &&
+ !map.try_emplace(CachedHashStringRef(osec->name), osec).second)
warn("OVERWRITE_SECTIONS specifies duplicate " + osec->name);
for (SectionCommand *&base : sectionCommands)
if (auto *osec = dyn_cast<OutputSection>(base)) {
- if (OutputSection *overwrite = map.lookup(osec->name)) {
+ if (OutputSection *overwrite =
+ map.lookup(CachedHashStringRef(osec->name))) {
log(overwrite->location + " overwrites " + osec->name);
overwrite->sectionIndex = i++;
base = overwrite;
@@ -830,10 +822,9 @@ addInputSec(StringMap<TinyPtrVector<OutputSection *>> &map,
// Add sections that didn't match any sections command.
void LinkerScript::addOrphanSections() {
StringMap<TinyPtrVector<OutputSection *>> map;
- std::vector<OutputSection *> v;
+ SmallVector<OutputSection *, 0> v;
- std::function<void(InputSectionBase *)> add;
- add = [&](InputSectionBase *s) {
+ auto add = [&](InputSectionBase *s) {
if (s->isLive() && !s->parent) {
orphanSections.push_back(s);
@@ -849,11 +840,6 @@ void LinkerScript::addOrphanSections() {
s->getOutputSection()->sectionIndex == UINT32_MAX);
}
}
-
- if (config->relocatable)
- for (InputSectionBase *depSec : s->dependentSections)
- if (depSec->flags & SHF_LINK_ORDER)
- add(depSec);
};
// For further --emit-reloc handling code we need target output section
@@ -872,6 +858,10 @@ void LinkerScript::addOrphanSections() {
if (auto *relIS = dyn_cast_or_null<InputSectionBase>(rel->parent))
add(relIS);
add(isec);
+ if (config->relocatable)
+ for (InputSectionBase *depSec : isec->dependentSections)
+ if (depSec->flags & SHF_LINK_ORDER)
+ add(depSec);
}
// If no SECTIONS command was given, we should insert sections commands
@@ -1113,7 +1103,7 @@ bool LinkerScript::isDiscarded(const OutputSection *sec) const {
}
static void maybePropagatePhdrs(OutputSection &sec,
- std::vector<StringRef> &phdrs) {
+ SmallVector<StringRef, 0> &phdrs) {
if (sec.phdrs.empty()) {
// To match the bfd linker script behaviour, only propagate program
// headers to sections that are allocated.
@@ -1147,7 +1137,7 @@ void LinkerScript::adjustSectionsBeforeSorting() {
// the previous sections. Only a few flags are needed to keep the impact low.
uint64_t flags = SHF_ALLOC;
- std::vector<StringRef> defPhdrs;
+ SmallVector<StringRef, 0> defPhdrs;
for (SectionCommand *&cmd : sectionCommands) {
auto *sec = dyn_cast<OutputSection>(cmd);
if (!sec)
@@ -1218,7 +1208,7 @@ void LinkerScript::adjustSectionsAfterSorting() {
// Below is an example of such linker script:
// PHDRS { seg PT_LOAD; }
// SECTIONS { .aaa : { *(.aaa) } }
- std::vector<StringRef> defPhdrs;
+ SmallVector<StringRef, 0> defPhdrs;
auto firstPtLoad = llvm::find_if(phdrsCommands, [](const PhdrsCommand &cmd) {
return cmd.type == PT_LOAD;
});
@@ -1248,7 +1238,7 @@ static uint64_t computeBase(uint64_t min, bool allocateHeaders) {
// 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) {
+void LinkerScript::allocateHeaders(SmallVector<PhdrEntry *, 0> &phdrs) {
uint64_t min = std::numeric_limits<uint64_t>::max();
for (OutputSection *sec : outputSections)
if (sec->flags & SHF_ALLOC)
@@ -1332,8 +1322,8 @@ const Defined *LinkerScript::assignAddresses() {
}
// Creates program headers as instructed by PHDRS linker script command.
-std::vector<PhdrEntry *> LinkerScript::createPhdrs() {
- std::vector<PhdrEntry *> ret;
+SmallVector<PhdrEntry *, 0> LinkerScript::createPhdrs() {
+ SmallVector<PhdrEntry *, 0> ret;
// Process PHDRS and FILEHDR keywords because they are not
// real output sections and cannot be added in the following loop.
@@ -1415,8 +1405,8 @@ static Optional<size_t> getPhdrIndex(ArrayRef<PhdrsCommand> vec,
// Returns indices of ELF headers containing specific section. Each index is a
// zero based number of ELF header listed within PHDRS {} script block.
-std::vector<size_t> LinkerScript::getPhdrIndices(OutputSection *cmd) {
- std::vector<size_t> ret;
+SmallVector<size_t, 0> LinkerScript::getPhdrIndices(OutputSection *cmd) {
+ SmallVector<size_t, 0> ret;
for (StringRef s : cmd->phdrs) {
if (Optional<size_t> idx = getPhdrIndex(phdrsCommands, s))