Index: lld/trunk/ELF/OutputSections.cpp =================================================================== --- lld/trunk/ELF/OutputSections.cpp +++ lld/trunk/ELF/OutputSections.cpp @@ -362,12 +362,7 @@ } Sec->Flags |= Flags; } else { - uint32_t Type = IS->Type; - if (IS->kind() == InputSectionBase::EHFrame) { - In::EhFrame->addSection(IS); - return; - } - Sec = make(Key.Name, Type, Flags); + Sec = make(Key.Name, IS->Type, Flags); OutputSections.push_back(Sec); } Index: lld/trunk/ELF/SyntheticSections.h =================================================================== --- lld/trunk/ELF/SyntheticSections.h +++ lld/trunk/ELF/SyntheticSections.h @@ -84,6 +84,8 @@ size_t NumFdes = 0; + std::vector Sections; + private: uint64_t Size = 0; template @@ -97,7 +99,6 @@ uintX_t getFdePc(uint8_t *Buf, size_t Off, uint8_t Enc); - std::vector Sections; std::vector Cies; // CIE records are uniquified by their contents and personality functions. Index: lld/trunk/ELF/SyntheticSections.cpp =================================================================== --- lld/trunk/ELF/SyntheticSections.cpp +++ lld/trunk/ELF/SyntheticSections.cpp @@ -506,6 +506,8 @@ Sec->EHSec = this; updateAlignment(Sec->Alignment); Sections.push_back(Sec); + for (auto *DS : Sec->DependentSections) + DependentSections.push_back(DS); // .eh_frame is a sequence of CIE or FDE records. This function // splits it into pieces so that we can call Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -199,6 +199,23 @@ V.erase(std::remove(V.begin(), V.end(), nullptr), V.end()); } +template static void combineEhFrameSections() { + for (InputSectionBase *&S : InputSections) { + EhInputSection *ES = dyn_cast(S); + if (!ES) + continue; + + if (!ES->Live) + continue; + + In::EhFrame->addSection(ES); + S = nullptr; + } + + std::vector &V = InputSections; + V.erase(std::remove(V.begin(), V.end(), nullptr), V.end()); +} + // The main function of the writer. template void Writer::run() { // Create linker-synthesized sections such as .got or .plt. @@ -206,6 +223,9 @@ createSyntheticSections(); combineMergableSections(); + if (!Config->Relocatable) + combineEhFrameSections(); + // We need to create some reserved symbols such as _end. Create them. if (!Config->Relocatable) addReservedSymbols(); @@ -907,6 +927,11 @@ if (isa(IS) || isa(IS)) Fn(*IS); } + + if (!Config->Relocatable) { + for (EhInputSection *ES : In::EhFrame->Sections) + Fn(*ES); + } } template void Writer::createSections() { Index: lld/trunk/test/ELF/linkerscript/eh-frame.s =================================================================== --- lld/trunk/test/ELF/linkerscript/eh-frame.s +++ lld/trunk/test/ELF/linkerscript/eh-frame.s @@ -0,0 +1,19 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: echo "SECTIONS { \ +# RUN: .eh_frame : { *(.eh_frame) } \ +# RUN: }" > %t.script +# RUN: ld.lld -o %t1 --script %t.script %t +# RUN: llvm-objdump -s -section=".eh_frame" %t1 | FileCheck %s + +# CHECK: 0000 14000000 00000000 017a5200 01781001 +# CHECK-NEXT: 0010 1b0c0708 90010000 + +.global _start +_start: + nop + +.section .dah,"ax",@progbits +.cfi_startproc + nop +.cfi_endproc