diff options
-rw-r--r-- | lld/ELF/LinkerScript.cpp | 36 | ||||
-rw-r--r-- | lld/ELF/OutputSections.cpp | 19 | ||||
-rw-r--r-- | lld/ELF/OutputSections.h | 2 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 5 |
4 files changed, 30 insertions, 32 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index e82ee3c7879..69a35be858c 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -416,6 +416,7 @@ void LinkerScript::processSectionCommands() { // Any input section assigned to it is discarded. if (Sec->Name == "/DISCARD/") { discard(V); + Sec->SectionCommands.clear(); continue; } @@ -771,6 +772,25 @@ void LinkerScript::assignOffsets(OutputSection *Sec) { } } +static bool isDiscardable(OutputSection &Sec) { + // We do not remove empty sections that are explicitly + // assigned to any segment. + if (!Sec.Phdrs.empty()) + return false; + + // 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 + // an error otherwise. + if (Sec.AddrExpr || Sec.AlignExpr || Sec.LMAExpr) + return false; + + for (BaseCommand *Base : Sec.SectionCommands) + if (!isa<InputSectionDescription>(*Base)) + return false; + return getInputSections(&Sec).empty(); +} + void LinkerScript::adjustSectionsBeforeSorting() { // If the output section contains only symbol assignments, create a // corresponding output section. The issue is what to do with linker script @@ -798,15 +818,19 @@ void LinkerScript::adjustSectionsBeforeSorting() { auto *Sec = dyn_cast<OutputSection>(Cmd); if (!Sec) continue; - if (Sec->Live) { - Flags = Sec->Flags & (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR); - continue; - } - if (!Sec->isAllSectionDescription()) - Sec->Flags = Flags; + // A live output section means that some input section was added to it. It + // might have been removed (gc, or empty synthetic section), but we at least + // know the flags. + if (Sec->Live) + Flags = Sec->Flags & (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR); else + Sec->Flags = Flags; + + if (isDiscardable(*Sec)) { + Sec->Live = false; Cmd = nullptr; + } } // It is common practice to use very generic linker scripts. So for any diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 9b8ea2bb461..9d5ebe5fea7 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -78,25 +78,6 @@ OutputSection::OutputSection(StringRef Name, uint32_t Type, uint64_t Flags) Live = false; } -bool OutputSection::isAllSectionDescription() const { - // We do not remove empty sections that are explicitly - // assigned to any segment. - if (!Phdrs.empty()) - return false; - - // 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 - // an error otherwise. - if (AddrExpr || AlignExpr || LMAExpr) - return false; - - for (BaseCommand *Base : SectionCommands) - if (!isa<InputSectionDescription>(*Base)) - return false; - return true; -} - // We allow sections of types listed below to merged into a // single progbits section. This is typically done by linker // scripts. Merging nobits and progbits will force disk space diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index 597fd065a21..35a873488f2 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -42,8 +42,6 @@ class OutputSection final : public BaseCommand, public SectionBase { public: OutputSection(StringRef Name, uint32_t Type, uint64_t Flags); - bool isAllSectionDescription() const; - static bool classof(const SectionBase *S) { return S->kind() == SectionBase::Output; } diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index a1c534c912c..ade8ebaf3c0 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -1382,11 +1382,6 @@ static void removeUnusedSyntheticSections() { if (auto *ISD = dyn_cast<InputSectionDescription>(B)) llvm::erase_if(ISD->Sections, [=](InputSection *IS) { return IS == SS; }); - - // If there are no other alive sections or commands left in the output - // section description, we remove it from the output. - if (getInputSections(OS).empty() && OS->isAllSectionDescription()) - OS->Live = false; } } |