diff options
| author | Eugene Leviant <evgeny.leviant@gmail.com> | 2016-08-16 06:40:58 +0000 |
|---|---|---|
| committer | Eugene Leviant <evgeny.leviant@gmail.com> | 2016-08-16 06:40:58 +0000 |
| commit | f9bc3bd2cf6651c1cdaf2d5915c280a313a9043e (patch) | |
| tree | e0c549464cbab989dfd94995a579ce05cd895552 | |
| parent | bc84fc9f1dc427083792de338039f20f3f95099e (diff) | |
| download | bcm5719-llvm-f9bc3bd2cf6651c1cdaf2d5915c280a313a9043e.tar.gz bcm5719-llvm-f9bc3bd2cf6651c1cdaf2d5915c280a313a9043e.zip | |
[ELF] Ignore .interp section in case linker script specifies PHDRS without PT_INTERP
llvm-svn: 278781
| -rw-r--r-- | lld/ELF/LinkerScript.cpp | 9 | ||||
| -rw-r--r-- | lld/ELF/LinkerScript.h | 1 | ||||
| -rw-r--r-- | lld/ELF/Writer.cpp | 3 | ||||
| -rw-r--r-- | lld/test/ELF/linkerscript/linkerscript-discard-interp.s | 12 |
4 files changed, 24 insertions, 1 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index dd9ef6a7f9a..7195d8f6c41 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -486,6 +486,15 @@ std::vector<PhdrEntry<ELFT>> LinkerScript<ELFT>::createPhdrs() { return Ret; } +template <class ELFT> bool LinkerScript<ELFT>::ignoreInterpSection() { + // Ignore .interp section in case we have PHDRS specification + // and PT_INTERP isn't listed. + return !Opt.PhdrsCommands.empty() && + llvm::find_if(Opt.PhdrsCommands, [](const PhdrsCommand &Cmd) { + return Cmd.Type == PT_INTERP; + }) == Opt.PhdrsCommands.end(); +} + template <class ELFT> ArrayRef<uint8_t> LinkerScript<ELFT>::getFiller(StringRef Name) { for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h index 53a6db5632a..d33c12e41ee 100644 --- a/lld/ELF/LinkerScript.h +++ b/lld/ELF/LinkerScript.h @@ -144,6 +144,7 @@ public: void createSections(OutputSectionFactory<ELFT> &Factory); std::vector<PhdrEntry<ELFT>> createPhdrs(); + bool ignoreInterpSection(); ArrayRef<uint8_t> getFiller(StringRef Name); bool shouldKeep(InputSectionBase<ELFT> *S); diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 108ca54afea..5a395599ed0 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -105,7 +105,8 @@ template <class ELFT> void elf::reportDiscarded(InputSectionBase<ELFT> *IS) { template <class ELFT> static bool needsInterpSection() { return !Symtab<ELFT>::X->getSharedFiles().empty() && - !Config->DynamicLinker.empty(); + !Config->DynamicLinker.empty() && + !Script<ELFT>::X->ignoreInterpSection(); } template <class ELFT> void elf::writeResult() { diff --git a/lld/test/ELF/linkerscript/linkerscript-discard-interp.s b/lld/test/ELF/linkerscript/linkerscript-discard-interp.s new file mode 100644 index 00000000000..5f2d82ea4ab --- /dev/null +++ b/lld/test/ELF/linkerscript/linkerscript-discard-interp.s @@ -0,0 +1,12 @@ +// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/../Inputs/shared.s -o %t2.o +// RUN: ld.lld -shared %t2.o -o %t2.so +// RUN: echo "PHDRS { text PT_LOAD FILEHDR PHDRS; } \ +// RUN: SECTIONS { .text : { *(.text) } : text }" >> %t.script +// RUN: ld.lld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -rpath foo -rpath bar --script %t.script --export-dynamic %t.o %t2.so -o %t +// RUN: llvm-readobj -s %t | FileCheck %s + +// CHECK-NOT: Name: .interp + +.global _start +_start: |

