summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/LinkerScript.cpp38
-rw-r--r--lld/ELF/LinkerScript.h1
-rw-r--r--lld/ELF/Writer.cpp20
-rw-r--r--lld/test/ELF/linkerscript/implicit-program-header.s2
-rw-r--r--lld/test/ELF/linkerscript/orphan-phdrs.s1
5 files changed, 25 insertions, 37 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 0426c503df0..63738d88d8d 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -752,21 +752,12 @@ void LinkerScript::assignOffsets(OutputSection *Sec) {
}
}
-void LinkerScript::removeEmptyCommands() {
- // It is common practice to use very generic linker scripts. So for any
- // given run some of the output sections in the script will be empty.
- // We could create corresponding empty output sections, but that would
- // clutter the output.
- // We instead remove trivially empty sections. The bfd linker seems even
- // more aggressive at removing them.
- llvm::erase_if(SectionCommands, [&](BaseCommand *Base) {
- if (auto *Sec = dyn_cast<OutputSection>(Base))
- return !Sec->Live;
+static bool isAllSectionDescription(const OutputSection &Cmd) {
+ // We do not remove empty sections that are explicitly
+ // assigned to any segment.
+ if (!Cmd.Phdrs.empty())
return false;
- });
-}
-static bool isAllSectionDescription(const OutputSection &Cmd) {
// We do not want to remove sections that have custom address or align
// expressions set even if them are empty. We keep them because we
// want to be sure that any expressions can be evaluated and report
@@ -803,7 +794,7 @@ void LinkerScript::adjustSectionsBeforeSorting() {
// the previous sections. Only a few flags are needed to keep the impact low.
uint64_t Flags = SHF_ALLOC;
- for (BaseCommand *Cmd : SectionCommands) {
+ for (BaseCommand *&Cmd : SectionCommands) {
auto *Sec = dyn_cast<OutputSection>(Cmd);
if (!Sec)
continue;
@@ -812,20 +803,25 @@ void LinkerScript::adjustSectionsBeforeSorting() {
continue;
}
- if (isAllSectionDescription(*Sec))
- continue;
-
- Sec->Live = true;
- Sec->Flags = Flags;
+ if (!isAllSectionDescription(*Sec))
+ Sec->Flags = Flags;
+ else
+ Cmd = nullptr;
}
+
+ // It is common practice to use very generic linker scripts. So for any
+ // given run some of the output sections in the script will be empty.
+ // We could create corresponding empty output sections, but that would
+ // clutter the output.
+ // We instead remove trivially empty sections. The bfd linker seems even
+ // more aggressive at removing them.
+ llvm::erase_if(SectionCommands, [&](BaseCommand *Base) { return !Base; });
}
void LinkerScript::adjustSectionsAfterSorting() {
// Try and find an appropriate memory region to assign offsets in.
for (BaseCommand *Base : SectionCommands) {
if (auto *Sec = dyn_cast<OutputSection>(Base)) {
- if (!Sec->Live)
- continue;
if (!Sec->LMARegionName.empty()) {
if (MemoryRegion *M = MemoryRegions.lookup(Sec->LMARegionName))
Sec->LMARegion = M;
diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h
index 1ff07ffb0d7..6aa859124be 100644
--- a/lld/ELF/LinkerScript.h
+++ b/lld/ELF/LinkerScript.h
@@ -254,7 +254,6 @@ public:
ExprValue getSymbolValue(StringRef Name, const Twine &Loc);
void addOrphanSections();
- void removeEmptyCommands();
void adjustSectionsBeforeSorting();
void adjustSectionsAfterSorting();
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 173acbf4dea..df03f8ae531 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -937,8 +937,7 @@ static int getRankProximityAux(OutputSection *A, OutputSection *B) {
static int getRankProximity(OutputSection *A, BaseCommand *B) {
if (auto *Sec = dyn_cast<OutputSection>(B))
- if (Sec->Live)
- return getRankProximityAux(A, Sec);
+ return getRankProximityAux(A, Sec);
return -1;
}
@@ -984,20 +983,16 @@ findOrphanPos(std::vector<BaseCommand *>::iterator B,
int Proximity = getRankProximity(Sec, *I);
for (; I != E; ++I) {
auto *CurSec = dyn_cast<OutputSection>(*I);
- if (!CurSec || !CurSec->Live)
+ if (!CurSec)
continue;
if (getRankProximity(Sec, CurSec) != Proximity ||
Sec->SortRank < CurSec->SortRank)
break;
}
- auto IsLiveSection = [](BaseCommand *Cmd) {
- auto *OS = dyn_cast<OutputSection>(Cmd);
- return OS && OS->Live;
- };
-
+ auto IsOutputSec = [](BaseCommand *Cmd) { return isa<OutputSection>(Cmd); };
auto J = std::find_if(llvm::make_reverse_iterator(I),
- llvm::make_reverse_iterator(B), IsLiveSection);
+ llvm::make_reverse_iterator(B), IsOutputSec);
I = J.base();
// As a special case, if the orphan section is the last section, put
@@ -1005,7 +1000,7 @@ findOrphanPos(std::vector<BaseCommand *>::iterator B,
// This matches bfd's behavior and is convenient when the linker script fully
// specifies the start of the file, but doesn't care about the end (the non
// alloc sections for example).
- auto NextSec = std::find_if(I, E, IsLiveSection);
+ auto NextSec = std::find_if(I, E, IsOutputSec);
if (NextSec == E)
return E;
@@ -1077,8 +1072,6 @@ static DenseMap<const InputSectionBase *, int> buildSectionOrder() {
static void sortSection(OutputSection *Sec,
const DenseMap<const InputSectionBase *, int> &Order) {
- if (!Sec->Live)
- return;
StringRef Name = Sec->Name;
// Sort input sections by section name suffixes for
@@ -1186,7 +1179,7 @@ template <class ELFT> void Writer<ELFT>::sortSections() {
auto E = Script->SectionCommands.end();
auto NonScriptI = std::find_if(I, E, [](BaseCommand *Base) {
if (auto *Sec = dyn_cast<OutputSection>(Base))
- return Sec->Live && Sec->SectionIndex == INT_MAX;
+ return Sec->SectionIndex == INT_MAX;
return false;
});
@@ -1498,7 +1491,6 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
removeUnusedSyntheticSections();
sortSections();
- Script->removeEmptyCommands();
// Now that we have the final list, create a list of all the
// OutputSections for convenience.
diff --git a/lld/test/ELF/linkerscript/implicit-program-header.s b/lld/test/ELF/linkerscript/implicit-program-header.s
index 36379a9cf6c..682f2024558 100644
--- a/lld/test/ELF/linkerscript/implicit-program-header.s
+++ b/lld/test/ELF/linkerscript/implicit-program-header.s
@@ -15,7 +15,7 @@
# CHECK: Segment Sections...
# CHECK-NEXT: 00 .text .dynsym .hash .dynstr .dynamic
-# CHECK-NEXT: 01 .foo
+# CHECK-NEXT: 01 .bar .foo
.quad 0
.section .foo,"ax"
diff --git a/lld/test/ELF/linkerscript/orphan-phdrs.s b/lld/test/ELF/linkerscript/orphan-phdrs.s
index 648911162e9..2d5f4aa4f75 100644
--- a/lld/test/ELF/linkerscript/orphan-phdrs.s
+++ b/lld/test/ELF/linkerscript/orphan-phdrs.s
@@ -18,6 +18,7 @@
# CHECK: Section Headers
# CHECK: .text
# CHECK-NEXT: .orphan
+# CHECK-NEXT: .empty
# CHECK-NEXT: .rw
# CHECK: Segment Sections
OpenPOWER on IntegriCloud