diff options
Diffstat (limited to 'contrib/llvm-project/lld/ELF/LinkerScript.cpp')
-rw-r--r-- | contrib/llvm-project/lld/ELF/LinkerScript.cpp | 88 |
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 *> §ionCommands) { +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)) |