diff options
| author | Michael J. Spencer <bigcheesegs@gmail.com> | 2013-02-20 20:13:47 +0000 |
|---|---|---|
| committer | Michael J. Spencer <bigcheesegs@gmail.com> | 2013-02-20 20:13:47 +0000 |
| commit | e4c0e3712ffd21c792a83d3a5f148d2146b188c7 (patch) | |
| tree | 6058f6f774b4470b5bec64825c60986869492a19 | |
| parent | fce7f1f4348d7a84b77de3efc8169aa72279a52e (diff) | |
| download | bcm5719-llvm-e4c0e3712ffd21c792a83d3a5f148d2146b188c7.tar.gz bcm5719-llvm-e4c0e3712ffd21c792a83d3a5f148d2146b188c7.zip | |
[ELF][Writer] Add .interp section.
llvm-svn: 175657
| -rw-r--r-- | lld/include/lld/ReaderWriter/ELFTargetInfo.h | 4 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/HeaderChunks.h | 3 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/SectionChunks.h | 25 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/ELF/Writer.cpp | 5 | ||||
| -rw-r--r-- | lld/test/elf/dynamic-interp.test | 8 |
5 files changed, 44 insertions, 1 deletions
diff --git a/lld/include/lld/ReaderWriter/ELFTargetInfo.h b/lld/include/lld/ReaderWriter/ELFTargetInfo.h index b1753b2ccb8..9362aac71e3 100644 --- a/lld/include/lld/ReaderWriter/ELFTargetInfo.h +++ b/lld/include/lld/ReaderWriter/ELFTargetInfo.h @@ -49,6 +49,10 @@ public: return false; } + virtual StringRef getInterpreter() const { + return "/lib64/ld-linux-x86-64.so.2"; + } + /// \brief Does the output have dynamic sections. bool isDynamic() const { return _options._outputKind == OutputKind::DynamicExecutable || diff --git a/lld/lib/ReaderWriter/ELF/HeaderChunks.h b/lld/lib/ReaderWriter/ELF/HeaderChunks.h index cda2c6532d5..84bcde9f631 100644 --- a/lld/lib/ReaderWriter/ELF/HeaderChunks.h +++ b/lld/lib/ReaderWriter/ELF/HeaderChunks.h @@ -183,7 +183,8 @@ bool ProgramHeader<ELFT>::addSegment(Segment<ELFT> *segment) { for (auto slice : segment->slices()) { // If we have a TLS segment, emit a LOAD first. if (segment->segmentType() == llvm::ELF::PT_TLS || - segment->segmentType() == llvm::ELF::PT_DYNAMIC) { + segment->segmentType() == llvm::ELF::PT_DYNAMIC || + segment->segmentType() == llvm::ELF::PT_INTERP) { auto phdr = allocateProgramHeader(); if (phdr.second) allocatedNew = true; diff --git a/lld/lib/ReaderWriter/ELF/SectionChunks.h b/lld/lib/ReaderWriter/ELF/SectionChunks.h index f67e5350a43..c5b80475891 100644 --- a/lld/lib/ReaderWriter/ELF/SectionChunks.h +++ b/lld/lib/ReaderWriter/ELF/SectionChunks.h @@ -758,6 +758,31 @@ public: private: EntriesT _entries; }; + +template <class ELFT> class InterpSection : public Section<ELFT> { +public: + InterpSection(const ELFTargetInfo &ti, StringRef str, int32_t order, + StringRef interp) + : Section<ELFT>(ti, str), + _interp(interp){ + this->setOrder(order); + this->_align2 = 1; + // + 1 for null term. + this->_fsize = interp.size() + 1; + this->_msize = this->_fsize; + this->_type = SHT_PROGBITS; + this->_flags = SHF_ALLOC; + } + + void write(ELFWriter *writer, llvm::FileOutputBuffer &buffer) { + uint8_t *chunkBuffer = buffer.getBufferStart(); + uint8_t *dest = chunkBuffer + this->fileOffset(); + std::memcpy(dest, _interp.data(), _interp.size()); + } + +private: + StringRef _interp; +}; } // end namespace elf } // end namespace lld diff --git a/lld/lib/ReaderWriter/ELF/Writer.cpp b/lld/lib/ReaderWriter/ELF/Writer.cpp index 411fee31f75..49a876b013d 100644 --- a/lld/lib/ReaderWriter/ELF/Writer.cpp +++ b/lld/lib/ReaderWriter/ELF/Writer.cpp @@ -69,6 +69,7 @@ private: /// \name Dynamic sections. /// @{ LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>) _dynamicTable; + LLD_UNIQUE_BUMP_PTR(InterpSection<ELFT>) _interpSection; /// @} CRuntimeFile<ELFT> _runtimeFile; }; @@ -337,7 +338,11 @@ void ExecutableWriter<ELFT>::createDefaultSections() { if (_targetInfo.isDynamic()) { _dynamicTable.reset(new (_alloc) DynamicTable<ELFT>( _targetInfo, ".dynamic", DefaultLayout<ELFT>::ORDER_DYNAMIC)); + _interpSection.reset(new (_alloc) InterpSection<ELFT>( + _targetInfo, ".interp", DefaultLayout<ELFT>::ORDER_INTERP, + _targetInfo.getInterpreter())); _layout->addSection(_dynamicTable.get()); + _layout->addSection(_interpSection.get()); } // give a chance for the target to add sections diff --git a/lld/test/elf/dynamic-interp.test b/lld/test/elf/dynamic-interp.test new file mode 100644 index 00000000000..d7b631c0f35 --- /dev/null +++ b/lld/test/elf/dynamic-interp.test @@ -0,0 +1,8 @@ +RUN: lld -core -target x86_64-linux %p/Inputs/use-shared.x86-64 \ +RUN: %p/Inputs/shared.so-x86-64 -output=%t -entry=main \ +RUN: -output-type=dynamic +RUN: llvm-objdump -p %t | FileCheck %s + +CHECK: INTERP +CHECK: flags r-- +CHECK: off |

