diff options
-rw-r--r-- | lld/ELF/LinkerScript.cpp | 38 | ||||
-rw-r--r-- | lld/ELF/LinkerScript.h | 1 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 20 | ||||
-rw-r--r-- | lld/test/ELF/linkerscript/implicit-program-header.s | 2 | ||||
-rw-r--r-- | lld/test/ELF/linkerscript/orphan-phdrs.s | 1 |
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 |