diff options
Diffstat (limited to 'lld/ELF/LinkerScript.cpp')
-rw-r--r-- | lld/ELF/LinkerScript.cpp | 95 |
1 files changed, 41 insertions, 54 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index cd02e779e7a..48f6c38cce6 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -341,19 +341,19 @@ bool LinkerScript::shouldKeep(InputSectionBase *s) { } // A helper function for the SORT() command. -static bool matchConstraints(ArrayRef<InputSection *> sections, +static bool matchConstraints(ArrayRef<InputSectionBase *> sections, ConstraintKind kind) { if (kind == ConstraintKind::NoConstraint) return true; bool isRW = llvm::any_of( - sections, [](InputSection *sec) { return sec->flags & SHF_WRITE; }); + sections, [](InputSectionBase *sec) { return sec->flags & SHF_WRITE; }); return (isRW && kind == ConstraintKind::ReadWrite) || (!isRW && kind == ConstraintKind::ReadOnly); } -static void sortSections(MutableArrayRef<InputSection *> vec, +static void sortSections(MutableArrayRef<InputSectionBase *> vec, SortSectionPolicy k) { auto alignmentComparator = [](InputSectionBase *a, InputSectionBase *b) { // ">" is not a mistake. Sections with larger alignments are placed @@ -392,7 +392,7 @@ static void sortSections(MutableArrayRef<InputSection *> vec, // --sort-section is handled as an inner SORT command. // 3. If one SORT command is given, and if it is SORT_NONE, don't sort. // 4. If no SORT command is given, sort according to --sort-section. -static void sortInputSections(MutableArrayRef<InputSection *> vec, +static void sortInputSections(MutableArrayRef<InputSectionBase *> vec, const SectionPattern &pat) { if (pat.sortOuter == SortSectionPolicy::None) return; @@ -405,9 +405,9 @@ static void sortInputSections(MutableArrayRef<InputSection *> vec, } // Compute and remember which sections the InputSectionDescription matches. -std::vector<InputSection *> +std::vector<InputSectionBase *> LinkerScript::computeInputSections(const InputSectionDescription *cmd) { - std::vector<InputSection *> ret; + std::vector<InputSectionBase *> ret; // Collects all sections that satisfy constraints of Cmd. for (const SectionPattern &pat : cmd->sectionPatterns) { @@ -422,10 +422,8 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd) { // which are common because they are in the default bfd script. // We do not ignore SHT_REL[A] linker-synthesized sections here because // want to support scripts that do custom layout for them. - // - // It is safe to assume that Sec is an InputSection because mergeable or - // EH input sections have already been handled and eliminated. - if (cast<InputSection>(sec)->getRelocatedSection()) + if (isa<InputSection>(sec) && + cast<InputSection>(sec)->getRelocatedSection()) continue; std::string filename = getFilename(sec->file); @@ -434,42 +432,41 @@ LinkerScript::computeInputSections(const InputSectionDescription *cmd) { !pat.sectionPat.match(sec->name)) continue; - ret.push_back(cast<InputSection>(sec)); + ret.push_back(sec); sec->assigned = true; } - sortInputSections(MutableArrayRef<InputSection *>(ret).slice(sizeBefore), - pat); + sortInputSections( + MutableArrayRef<InputSectionBase *>(ret).slice(sizeBefore), pat); } return ret; } -void LinkerScript::discard(ArrayRef<InputSection *> v) { - for (InputSection *s : v) { - if (s == in.shStrTab || s == mainPart->relaDyn || s == mainPart->relrDyn) - 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(); - discard(s->dependentSections); - } +void LinkerScript::discard(InputSectionBase *s) { + if (s == in.shStrTab || s == mainPart->relaDyn || s == mainPart->relrDyn) + 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(); + for (InputSection *ds : s->dependentSections) + discard(ds); } -std::vector<InputSection *> +std::vector<InputSectionBase *> LinkerScript::createInputSectionList(OutputSection &outCmd) { - std::vector<InputSection *> ret; + std::vector<InputSectionBase *> ret; for (BaseCommand *base : outCmd.sectionCommands) { if (auto *cmd = dyn_cast<InputSectionDescription>(base)) { - cmd->sections = computeInputSections(cmd); - ret.insert(ret.end(), cmd->sections.begin(), cmd->sections.end()); + cmd->sectionBases = computeInputSections(cmd); + ret.insert(ret.end(), cmd->sectionBases.begin(), cmd->sectionBases.end()); } } return ret; @@ -480,12 +477,13 @@ void LinkerScript::processSectionCommands() { size_t i = 0; for (BaseCommand *base : sectionCommands) { if (auto *sec = dyn_cast<OutputSection>(base)) { - std::vector<InputSection *> v = createInputSectionList(*sec); + std::vector<InputSectionBase *> v = createInputSectionList(*sec); // The output section name `/DISCARD/' is special. // Any input section assigned to it is discarded. if (sec->name == "/DISCARD/") { - discard(v); + for (InputSectionBase *s : v) + discard(s); sec->sectionCommands.clear(); continue; } @@ -513,15 +511,9 @@ void LinkerScript::processSectionCommands() { s->alignment = subalign; } - // Some input sections may be removed from the list after ICF. - for (InputSection *s : v) - sec->addSection(s); - sec->sectionIndex = i++; - if (sec->noload) - sec->type = SHT_NOBITS; - if (sec->nonAlloc) - sec->flags &= ~(uint64_t)SHF_ALLOC; + for (InputSectionBase *s : v) + s->parent = sec; } } } @@ -565,7 +557,7 @@ static OutputSection *findByName(ArrayRef<BaseCommand *> vec, static OutputSection *createSection(InputSectionBase *isec, StringRef outsecName) { OutputSection *sec = script->createOutputSection(outsecName, "<internal>"); - sec->addSection(cast<InputSection>(isec)); + sec->recordSection(isec); return sec; } @@ -594,7 +586,7 @@ addInputSec(StringMap<TinyPtrVector<OutputSection *>> &map, OutputSection *out = sec->getRelocatedSection()->getOutputSection(); if (out->relocationSection) { - out->relocationSection->addSection(sec); + out->relocationSection->recordSection(sec); return nullptr; } @@ -602,12 +594,6 @@ addInputSec(StringMap<TinyPtrVector<OutputSection *>> &map, return out->relocationSection; } - // When control reaches here, mergeable sections have already been merged into - // synthetic sections. For relocatable case we want to create one output - // section per syntetic section so that they have a valid sh_entsize. - if (config->relocatable && (isec->flags & SHF_MERGE)) - return createSection(isec, outsecName); - // The ELF spec just says // ---------------------------------------------------------------- // In the first phase, input sections that match in name, type and @@ -654,7 +640,7 @@ addInputSec(StringMap<TinyPtrVector<OutputSection *>> &map, for (OutputSection *sec : v) { if (sec->partition != isec->partition) continue; - sec->addSection(cast<InputSection>(isec)); + sec->recordSection(isec); return nullptr; } @@ -680,13 +666,14 @@ void LinkerScript::addOrphanSections() { warn(toString(s) + " is being placed in '" + name + "'"); if (OutputSection *sec = findByName(sectionCommands, name)) { - sec->addSection(cast<InputSection>(s)); + sec->recordSection(s); return; } if (OutputSection *os = addInputSec(map, s, name)) v.push_back(os); - assert(s->getOutputSection()->sectionIndex == UINT32_MAX); + assert(isa<MergeInputSection>(s) || + s->getOutputSection()->sectionIndex == UINT32_MAX); }; // For futher --emit-reloc handling code we need target output section |