Index: lld/trunk/ELF/OutputSections.cpp =================================================================== --- lld/trunk/ELF/OutputSections.cpp +++ lld/trunk/ELF/OutputSections.cpp @@ -947,7 +947,8 @@ auto RelI = Rels.begin(); auto RelE = Rels.end(); - DenseMap OffsetToIndex; + // Maps offset to Index/Length pair. + DenseMap> OffsetToData; while (!D.empty()) { unsigned Index = S->Offsets.size(); S->Offsets.push_back(std::make_pair(Offset, -1)); @@ -974,21 +975,24 @@ std::pair CieInfo(Entry, Personality); auto P = CieMap.insert(std::make_pair(CieInfo, Cies.size())); - if (P.second) { + if (P.second) Cies.push_back(C); - this->Header.sh_size += RoundUpToAlignment(Length, sizeof(uintX_t)); - } - OffsetToIndex[Offset] = P.first->second; + OffsetToData[Offset] = std::make_pair(P.first->second, Length); } else { if (!HasReloc) error("FDE doesn't reference another section"); InputSectionBase *Target = S->getRelocTarget(*RelI); if (Target != &InputSection::Discarded && Target->isLive()) { uint32_t CieOffset = Offset + 4 - ID; - auto I = OffsetToIndex.find(CieOffset); - if (I == OffsetToIndex.end()) + auto I = OffsetToData.find(CieOffset); + if (I == OffsetToData.end()) error("Invalid CIE reference"); - Cies[I->second].Fdes.push_back(EHRegion(S, Index)); + std::pair &IndLen = I->second; + Cie &Cie = Cies[IndLen.first]; + if (Cie.Fdes.empty()) + this->Header.sh_size += + RoundUpToAlignment(IndLen.second, sizeof(uintX_t)); + Cie.Fdes.push_back(EHRegion(S, Index)); this->Header.sh_size += RoundUpToAlignment(Length, sizeof(uintX_t)); } } Index: lld/trunk/test/ELF/eh-frame-opt.s =================================================================== --- lld/trunk/test/ELF/eh-frame-opt.s +++ lld/trunk/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_X86_64_UNWIND +// 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: