[lld] r288012 - Always create a PT_ARM_EXIDX if needed.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Sun Nov 27 16:40:21 PST 2016


Author: rafael
Date: Sun Nov 27 18:40:21 2016
New Revision: 288012

URL: http://llvm.org/viewvc/llvm-project?rev=288012&view=rev
Log:
Always create a PT_ARM_EXIDX if needed.

Unfortunatelly PT_ARM_EXIDX is special. There is no way to create it
from linker scripts, so we have to create it even if PHDRS is used.

This matches bfd and is required for the lld output to survive bfd's strip.

Added:
    lld/trunk/test/ELF/linkerscript/arm-exidx-phdrs.s
Modified:
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=288012&r1=288011&r2=288012&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Sun Nov 27 18:40:21 2016
@@ -60,6 +60,7 @@ private:
   void addPredefinedSections();
 
   std::vector<Phdr> createPhdrs();
+  void addPtArmExid(std::vector<Phdr> &Phdrs);
   void assignAddresses();
   void assignFileOffsets();
   void assignFileOffsetsBinary();
@@ -181,6 +182,7 @@ template <class ELFT> void Writer<ELFT>:
   } else {
     Phdrs = Script<ELFT>::X->hasPhdrsCommands() ? Script<ELFT>::X->createPhdrs()
                                                 : createPhdrs();
+    addPtArmExid(Phdrs);
     fixHeaders();
     if (ScriptConfig->HasSections) {
       Script<ELFT>::X->assignAddresses(Phdrs);
@@ -1129,7 +1131,6 @@ template <class ELFT> std::vector<PhdrEn
   Phdr TlsHdr(PT_TLS, PF_R);
   Phdr RelRo(PT_GNU_RELRO, PF_R);
   Phdr Note(PT_NOTE, PF_R);
-  Phdr ARMExidx(PT_ARM_EXIDX, PF_R);
   for (OutputSectionBase *Sec : OutputSections) {
     if (!(Sec->Flags & SHF_ALLOC))
       break;
@@ -1160,8 +1161,6 @@ template <class ELFT> std::vector<PhdrEn
       RelRo.add(Sec);
     if (Sec->Type == SHT_NOTE)
       Note.add(Sec);
-    if (Config->EMachine == EM_ARM && Sec->Type == SHT_ARM_EXIDX)
-      ARMExidx.add(Sec);
   }
 
   // Add the TLS segment unless it's empty.
@@ -1194,10 +1193,6 @@ template <class ELFT> std::vector<PhdrEn
     Hdr.add(Sec);
   }
 
-  // PT_ARM_EXIDX is the ARM EHABI equivalent of PT_GNU_EH_FRAME
-  if (ARMExidx.First)
-    Ret.push_back(std::move(ARMExidx));
-
   // PT_GNU_STACK is a special section to tell the loader to make the
   // pages for the stack non-executable.
   if (!Config->ZExecstack) {
@@ -1218,6 +1213,22 @@ template <class ELFT> std::vector<PhdrEn
   return Ret;
 }
 
+template <class ELFT>
+void Writer<ELFT>::addPtArmExid(std::vector<PhdrEntry<ELFT>> &Phdrs) {
+  if (Config->EMachine != EM_ARM)
+    return;
+  auto I = std::find_if(
+      OutputSections.begin(), OutputSections.end(),
+      [](OutputSectionBase *Sec) { return Sec->Type == SHT_ARM_EXIDX; });
+  if (I == OutputSections.end())
+    return;
+
+  // PT_ARM_EXIDX is the ARM EHABI equivalent of PT_GNU_EH_FRAME
+  Phdr ARMExidx(PT_ARM_EXIDX, PF_R);
+  ARMExidx.add(*I);
+  Phdrs.push_back(ARMExidx);
+}
+
 // The first section of each PT_LOAD and the first section after PT_GNU_RELRO
 // have to be page aligned so that the dynamic linker can set the permissions.
 template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {

Added: lld/trunk/test/ELF/linkerscript/arm-exidx-phdrs.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/arm-exidx-phdrs.s?rev=288012&view=auto
==============================================================================
--- lld/trunk/test/ELF/linkerscript/arm-exidx-phdrs.s (added)
+++ lld/trunk/test/ELF/linkerscript/arm-exidx-phdrs.s Sun Nov 27 18:40:21 2016
@@ -0,0 +1,16 @@
+// REQUIRES: arm
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
+// RUN: echo "PHDRS { ph_text PT_LOAD; } \
+// RUN:       SECTIONS { \
+// RUN:         . = SIZEOF_HEADERS; \
+// RUN:         .text : { *(.text) } : ph_text \
+// RUN:       }" > %t.script
+// RUN: ld.lld -T %t.script %t.o -shared -o %t.so
+// RUN: llvm-readobj --program-headers %t.so | FileCheck %s
+
+// CHECK: Type: PT_ARM_EXIDX
+
+.fnstart
+bx      lr
+.cantunwind
+.fnend




More information about the llvm-commits mailing list