summaryrefslogtreecommitdiffstats
path: root/lld/ELF/LinkerScript.cpp
diff options
context:
space:
mode:
authorFangrui Song <maskray@google.com>2019-09-24 11:48:31 +0000
committerFangrui Song <maskray@google.com>2019-09-24 11:48:31 +0000
commite47bbd28f8e9dfea4e019e27e9d371c144c3302e (patch)
tree799459668b1b23aa9f3691564487958ff364ac0c /lld/ELF/LinkerScript.cpp
parent06cdcb5f68b923c7e6e632edd91f49e4f9dd653e (diff)
downloadbcm5719-llvm-e47bbd28f8e9dfea4e019e27e9d371c144c3302e.tar.gz
bcm5719-llvm-e47bbd28f8e9dfea4e019e27e9d371c144c3302e.zip
[ELF] Make MergeInputSection merging aware of output sections
Fixes PR38748 mergeSections() calls getOutputSectionName() to get output section names. Two MergeInputSections may be merged even if they are made different by SECTIONS commands. This patch moves mergeSections() after processSectionCommands() and addOrphanSections() to fix the issue. The new pass is renamed to OutputSection::finalizeInputSections(). processSectionCommands() and addorphanSections() are changed to add sections to InputSectionDescription::sectionBases. finalizeInputSections() merges MergeInputSections and migrates `sectionBases` to `sections`. For the -r case, we drop an optimization that tries keeping sh_entsize non-zero. This is for the simplicity of addOrphanSections(). The updated merge-entsize2.s reflects the change. Reviewed By: grimar Differential Revision: https://reviews.llvm.org/D67504 llvm-svn: 372734
Diffstat (limited to 'lld/ELF/LinkerScript.cpp')
-rw-r--r--lld/ELF/LinkerScript.cpp95
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
OpenPOWER on IntegriCloud