[lld] r297501 - [ELF] Propely handle .eh_frame in linker scripts
Petr Hosek via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 10 12:00:42 PST 2017
Author: phosek
Date: Fri Mar 10 14:00:42 2017
New Revision: 297501
URL: http://llvm.org/viewvc/llvm-project?rev=297501&view=rev
Log:
[ELF] Propely handle .eh_frame in linker scripts
Using .eh_frame input section pattern in linker script currently
causes a crash; this is because .eh_frame input sections require
special handling since they're all combined into a synthetic
section rather than regular output section.
Differential Revision: https://reviews.llvm.org/D30627
Added:
lld/trunk/test/ELF/linkerscript/eh-frame.s
Modified:
lld/trunk/ELF/OutputSections.cpp
lld/trunk/ELF/SyntheticSections.cpp
lld/trunk/ELF/SyntheticSections.h
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=297501&r1=297500&r2=297501&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Fri Mar 10 14:00:42 2017
@@ -362,12 +362,7 @@ void OutputSectionFactory::addInputSec(I
}
Sec->Flags |= Flags;
} else {
- uint32_t Type = IS->Type;
- if (IS->kind() == InputSectionBase::EHFrame) {
- In<ELFT>::EhFrame->addSection(IS);
- return;
- }
- Sec = make<OutputSection>(Key.Name, Type, Flags);
+ Sec = make<OutputSection>(Key.Name, IS->Type, Flags);
OutputSections.push_back(Sec);
}
Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=297501&r1=297500&r2=297501&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Fri Mar 10 14:00:42 2017
@@ -506,6 +506,8 @@ void EhFrameSection<ELFT>::addSection(In
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
Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=297501&r1=297500&r2=297501&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Fri Mar 10 14:00:42 2017
@@ -84,6 +84,8 @@ public:
size_t NumFdes = 0;
+ std::vector<EhInputSection *> Sections;
+
private:
uint64_t Size = 0;
template <class RelTy>
@@ -97,7 +99,6 @@ private:
uintX_t getFdePc(uint8_t *Buf, size_t Off, uint8_t Enc);
- std::vector<EhInputSection *> Sections;
std::vector<CieRecord *> Cies;
// CIE records are uniquified by their contents and personality functions.
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=297501&r1=297500&r2=297501&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Mar 10 14:00:42 2017
@@ -199,6 +199,23 @@ template <class ELFT> static void combin
V.erase(std::remove(V.begin(), V.end(), nullptr), V.end());
}
+template <class ELFT> static void combineEhFrameSections() {
+ for (InputSectionBase *&S : InputSections) {
+ EhInputSection *ES = dyn_cast<EhInputSection>(S);
+ if (!ES)
+ continue;
+
+ if (!ES->Live)
+ continue;
+
+ In<ELFT>::EhFrame->addSection(ES);
+ S = nullptr;
+ }
+
+ std::vector<InputSectionBase *> &V = InputSections;
+ V.erase(std::remove(V.begin(), V.end(), nullptr), V.end());
+}
+
// The main function of the writer.
template <class ELFT> void Writer<ELFT>::run() {
// Create linker-synthesized sections such as .got or .plt.
@@ -206,6 +223,9 @@ template <class ELFT> void Writer<ELFT>:
createSyntheticSections();
combineMergableSections<ELFT>();
+ if (!Config->Relocatable)
+ combineEhFrameSections<ELFT>();
+
// We need to create some reserved symbols such as _end. Create them.
if (!Config->Relocatable)
addReservedSymbols();
@@ -907,6 +927,11 @@ void Writer<ELFT>::forEachRelSec(std::fu
if (isa<InputSection>(IS) || isa<EhInputSection>(IS))
Fn(*IS);
}
+
+ if (!Config->Relocatable) {
+ for (EhInputSection *ES : In<ELFT>::EhFrame->Sections)
+ Fn(*ES);
+ }
}
template <class ELFT> void Writer<ELFT>::createSections() {
Added: lld/trunk/test/ELF/linkerscript/eh-frame.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/eh-frame.s?rev=297501&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/eh-frame.s (added)
+++ lld/trunk/test/ELF/linkerscript/eh-frame.s Fri Mar 10 14:00:42 2017
@@ -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", at progbits
+.cfi_startproc
+ nop
+.cfi_endproc
More information about the llvm-commits
mailing list