summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/Writer.cpp25
-rw-r--r--lld/test/ELF/linkerscript/arm-exidx-phdrs.s16
2 files changed, 34 insertions, 7 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 51bbcd49f30..6bc31fcff7a 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -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>::run() {
} 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<PhdrEntry<ELFT>> Writer<ELFT>::createPhdrs() {
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<PhdrEntry<ELFT>> Writer<ELFT>::createPhdrs() {
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<PhdrEntry<ELFT>> Writer<ELFT>::createPhdrs() {
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<PhdrEntry<ELFT>> Writer<ELFT>::createPhdrs() {
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() {
diff --git a/lld/test/ELF/linkerscript/arm-exidx-phdrs.s b/lld/test/ELF/linkerscript/arm-exidx-phdrs.s
new file mode 100644
index 00000000000..971702f55d7
--- /dev/null
+++ b/lld/test/ELF/linkerscript/arm-exidx-phdrs.s
@@ -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
OpenPOWER on IntegriCloud