Index: lld/trunk/ELF/LinkerScript.cpp =================================================================== --- lld/trunk/ELF/LinkerScript.cpp +++ lld/trunk/ELF/LinkerScript.cpp @@ -889,10 +889,9 @@ Sec->Alignment = std::max(Sec->Alignment, Sec->AlignExpr().getValue()); - // A live output section means that some input section was added to it. It - // might have been removed (if it was empty synthetic section), but we at - // least know the flags. - if (Sec->isLive()) + // The input section might have been removed (if it was an empty synthetic + // section), but we at least know the flags. + if (Sec->HasInputSections) Flags = Sec->Flags; // We do not want to keep any special flags for output section Index: lld/trunk/ELF/OutputSections.h =================================================================== --- lld/trunk/ELF/OutputSections.h +++ lld/trunk/ELF/OutputSections.h @@ -93,6 +93,11 @@ bool UsedInExpression = false; bool InOverlay = false; + // Tracks whether the section has ever had an input section added to it, even + // if the section was later removed (e.g. because it is a synthetic section + // that wasn't needed). This is needed for orphan placement. + bool HasInputSections = false; + void finalize(); template void writeTo(uint8_t *Buf); template void maybeCompress(); Index: lld/trunk/ELF/OutputSections.cpp =================================================================== --- lld/trunk/ELF/OutputSections.cpp +++ lld/trunk/ELF/OutputSections.cpp @@ -84,9 +84,10 @@ } void OutputSection::addSection(InputSection *IS) { - if (!isLive()) { + if (!HasInputSections) { // If IS is the first section to be added to this section, // initialize Partition, Type, Entsize and flags from IS. + HasInputSections = true; Partition = IS->Partition; Type = IS->Type; Entsize = IS->Entsize; Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -1052,7 +1052,7 @@ static int getRankProximity(OutputSection *A, BaseCommand *B) { auto *Sec = dyn_cast(B); - return (Sec && Sec->isLive()) ? getRankProximityAux(A, Sec) : -1; + return (Sec && Sec->HasInputSections) ? getRankProximityAux(A, Sec) : -1; } // When placing orphan sections, we want to place them after symbol assignments @@ -1094,19 +1094,20 @@ int Proximity = getRankProximity(Sec, *I); for (; I != E; ++I) { auto *CurSec = dyn_cast(*I); - if (!CurSec || !CurSec->isLive()) + if (!CurSec || !CurSec->HasInputSections) continue; if (getRankProximity(Sec, CurSec) != Proximity || Sec->SortRank < CurSec->SortRank) break; } - auto IsLiveOutputSec = [](BaseCommand *Cmd) { + auto IsOutputSecWithInputSections = [](BaseCommand *Cmd) { auto *OS = dyn_cast(Cmd); - return OS && OS->isLive(); + return OS && OS->HasInputSections; }; auto J = std::find_if(llvm::make_reverse_iterator(I), - llvm::make_reverse_iterator(B), IsLiveOutputSec); + llvm::make_reverse_iterator(B), + IsOutputSecWithInputSections); I = J.base(); // As a special case, if the orphan section is the last section, put @@ -1114,7 +1115,7 @@ // 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, IsLiveOutputSec); + auto NextSec = std::find_if(I, E, IsOutputSecWithInputSections); if (NextSec == E) return E;