Index: ELF/OutputSections.cpp =================================================================== --- ELF/OutputSections.cpp +++ ELF/OutputSections.cpp @@ -360,12 +360,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: ELF/SyntheticSections.h =================================================================== --- ELF/SyntheticSections.h +++ ELF/SyntheticSections.h @@ -79,6 +79,8 @@ size_t NumFdes = 0; + std::vector *> Sections; + private: uint64_t Size = 0; template @@ -92,7 +94,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: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -504,6 +504,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: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ 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(); @@ -912,6 +932,11 @@ if (isa(IS) || isa>(IS)) Fn(*IS); } + + if (!Config->Relocatable) { + for (EhInputSection *ES : In::EhFrame->Sections) + Fn(*ES); + } } template void Writer::createSections() { Index: test/ELF/linkerscript/eh-frame.s =================================================================== --- /dev/null +++ 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