From 8e67000f1a0a9a03b6f8a002a01d7c3fd7b945b6 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 28 Nov 2016 00:40:21 +0000 Subject: [PATCH] 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. llvm-svn: 288012 --- lld/ELF/Writer.cpp | 25 +++++++++++++++------ lld/test/ELF/linkerscript/arm-exidx-phdrs.s | 16 +++++++++++++ 2 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 lld/test/ELF/linkerscript/arm-exidx-phdrs.s diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 51bbcd49f304..6bc31fcff7aa 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -60,6 +60,7 @@ private: void addPredefinedSections(); std::vector createPhdrs(); + void addPtArmExid(std::vector &Phdrs); void assignAddresses(); void assignFileOffsets(); void assignFileOffsetsBinary(); @@ -181,6 +182,7 @@ template void Writer::run() { } else { Phdrs = Script::X->hasPhdrsCommands() ? Script::X->createPhdrs() : createPhdrs(); + addPtArmExid(Phdrs); fixHeaders(); if (ScriptConfig->HasSections) { Script::X->assignAddresses(Phdrs); @@ -1129,7 +1131,6 @@ template std::vector> Writer::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 std::vector> Writer::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 std::vector> Writer::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 std::vector> Writer::createPhdrs() { return Ret; } +template +void Writer::addPtArmExid(std::vector> &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 void Writer::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 000000000000..971702f55d7b --- /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 -- GitLab