Index: ELF/InputSection.h =================================================================== --- ELF/InputSection.h +++ ELF/InputSection.h @@ -174,9 +174,10 @@ void splitIntoPieces(); // Mark the piece at a given offset live. Used by GC. + // We always keep whole non-alloc sections (usually debug ones). void markLiveAt(uintX_t Offset) { - assert(this->Flags & llvm::ELF::SHF_ALLOC); - LiveOffsets.insert(Offset); + if (this->Flags & SHF_ALLOC) + LiveOffsets.insert(Offset); } // Translate an offset in the input section to an offset Index: ELF/InputSection.cpp =================================================================== --- ELF/InputSection.cpp +++ ELF/InputSection.cpp @@ -57,6 +57,8 @@ uint32_t Info, uintX_t Addralign, ArrayRef Data, StringRef Name, Kind SectionKind) + // We do not GC non-allocatable sections which typically contain debugging + // information, so set Live flag for them. : InputSectionData(SectionKind, Name, Data, !Config->GcSections || !(Flags & SHF_ALLOC)), File(File), Flags(Flags), Entsize(Entsize), Type(Type), Link(Link), Index: ELF/MarkLive.cpp =================================================================== --- ELF/MarkLive.cpp +++ ELF/MarkLive.cpp @@ -156,9 +156,8 @@ scanEhFrameSection(EH, EH.rels(), Enqueue); } -// We do not garbage-collect two types of sections: -// 1) Sections used by the loader (.init, .fini, .ctors, .dtors or .jcr) -// 2) Non-allocatable sections which typically contain debugging information +// We do not garbage-collect sections used by the loader (.init, .fini, .ctors, +// .dtors or .jcr) template static bool isReserved(InputSectionBase *Sec) { switch (Sec->Type) { case SHT_FINI_ARRAY: @@ -167,9 +166,6 @@ case SHT_PREINIT_ARRAY: return true; default: - if (!(Sec->Flags & SHF_ALLOC)) - return true; - // We do not want to reclaim sections if they can be referred // by __start_* and __stop_* symbols. StringRef S = Sec->Name; @@ -196,10 +192,6 @@ if (!R.Sec || R.Sec == &InputSection::Discarded) return; - // We don't gc non alloc sections. - if (!(R.Sec->Flags & SHF_ALLOC)) - return; - // Usually, a whole section is marked as live or dead, but in mergeable // (splittable) sections, each piece of data has independent liveness bit. // So we explicitly tell it which offset is in use. @@ -240,7 +232,7 @@ // referred by .eh_frame here. if (auto *EH = dyn_cast_or_null>(Sec)) scanEhFrameSection(*EH, Enqueue); - if (isReserved(Sec) || Script::X->shouldKeep(Sec)) + if (Sec->Live || isReserved(Sec) || Script::X->shouldKeep(Sec)) Enqueue({Sec, 0}); }