[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