Index: ELF/OutputSections.cpp =================================================================== --- ELF/OutputSections.cpp +++ ELF/OutputSections.cpp @@ -1112,6 +1112,8 @@ size_t Off = 0; for (CieRecord *Cie : Cies) { + if (Cie->FdePieces.empty()) + continue; Cie->Piece->OutputOff = Off; Off += alignTo(Cie->Piece->size(), sizeof(uintX_t)); @@ -1159,6 +1161,8 @@ template void EhOutputSection::writeTo(uint8_t *Buf) { const endianness E = ELFT::TargetEndianness; for (CieRecord *Cie : Cies) { + if (Cie->FdePieces.empty()) + continue; size_t CieOffset = Cie->Piece->OutputOff; writeCieFde(Buf + CieOffset, Cie->Piece->data()); Index: test/ELF/eh-frame-opt.s =================================================================== --- test/ELF/eh-frame-opt.s +++ test/ELF/eh-frame-opt.s @@ -0,0 +1,39 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld --gc-sections %t.o -o %t +# RUN: llvm-readobj -s -section-data %t | FileCheck %s + +# Here we check that if all FDEs referencing a CIE +# were removed, CIE is also removed. +# CHECK: Section { +# CHECK: Index: +# CHECK: Name: .eh_frame +# CHECK-NEXT: Type: SHT_PROGBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x10120 +# CHECK-NEXT: Offset: 0x120 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 8 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: SectionData ( +# CHECK-NEXT: ) +# CHECK-NEXT: } + +.section .foo,"ax",@progbits +.cfi_startproc + nop +.cfi_endproc + +.section .bar,"ax",@progbits +.cfi_startproc + nop + nop +.cfi_endproc + +.text +.globl _start; +_start: