Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -416,6 +416,7 @@ // Any input section assigned to it is discarded. if (Sec->Name == "/DISCARD/") { discard(V); + Sec->SectionCommands.clear(); continue; } @@ -771,6 +772,25 @@ } } +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; + + // 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 (Cmd.AddrExpr || Cmd.AlignExpr || Cmd.LMAExpr) + return false; + + for (BaseCommand *Base : Cmd.SectionCommands) + if (!isa(*Base)) + return false; + return true; +} + 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 @@ auto *Sec = dyn_cast(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 (getInputSections(Sec).empty() && isAllSectionDescription(*Sec)) { + Sec->Live = false; Cmd = nullptr; + } } // It is common practice to use very generic linker scripts. So for any Index: ELF/OutputSections.h =================================================================== --- ELF/OutputSections.h +++ ELF/OutputSections.h @@ -42,8 +42,6 @@ public: OutputSection(StringRef Name, uint32_t Type, uint64_t Flags); - bool isAllSectionDescription() const; - static bool classof(const SectionBase *S) { return S->kind() == SectionBase::Output; } Index: ELF/OutputSections.cpp =================================================================== --- ELF/OutputSections.cpp +++ ELF/OutputSections.cpp @@ -78,25 +78,6 @@ 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(*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 Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -1382,11 +1382,6 @@ if (auto *ISD = dyn_cast(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; } }