diff options
Diffstat (limited to 'lld/lib/ReaderWriter')
-rw-r--r-- | lld/lib/ReaderWriter/ELF/DefaultLayout.h | 4 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/OutputELFWriter.h | 10 | ||||
-rw-r--r-- | lld/lib/ReaderWriter/ELF/SectionChunks.h | 47 |
3 files changed, 60 insertions, 1 deletions
diff --git a/lld/lib/ReaderWriter/ELF/DefaultLayout.h b/lld/lib/ReaderWriter/ELF/DefaultLayout.h index 85420c4bf23..c980c533aca 100644 --- a/lld/lib/ReaderWriter/ELF/DefaultLayout.h +++ b/lld/lib/ReaderWriter/ELF/DefaultLayout.h @@ -439,7 +439,6 @@ Layout::SegmentType DefaultLayout<ELFT>::getSegmentType( case ORDER_FINI: case ORDER_RODATA: case ORDER_EH_FRAME: - case ORDER_EH_FRAMEHDR: return llvm::ELF::PT_LOAD; case ORDER_RO_NOTE: @@ -453,6 +452,9 @@ Layout::SegmentType DefaultLayout<ELFT>::getSegmentType( case ORDER_DTORS: return llvm::ELF::PT_GNU_RELRO; + case ORDER_EH_FRAMEHDR: + return llvm::ELF::PT_GNU_EH_FRAME; + case ORDER_GOT: case ORDER_GOT_PLT: case ORDER_DATA: diff --git a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h index cc044002c4f..d8319da09df 100644 --- a/lld/lib/ReaderWriter/ELF/OutputELFWriter.h +++ b/lld/lib/ReaderWriter/ELF/OutputELFWriter.h @@ -105,6 +105,7 @@ protected: LLD_UNIQUE_BUMP_PTR(StringTable<ELFT>) _strtab; LLD_UNIQUE_BUMP_PTR(StringTable<ELFT>) _shstrtab; LLD_UNIQUE_BUMP_PTR(SectionHeader<ELFT>) _shdrtab; + LLD_UNIQUE_BUMP_PTR(EHFrameHeader<ELFT>) _ehFrameHeader; /// \name Dynamic sections. /// @{ LLD_UNIQUE_BUMP_PTR(DynamicTable<ELFT>) _dynamicTable; @@ -267,6 +268,15 @@ template <class ELFT> void OutputELFWriter<ELFT>::createDefaultSections() { _symtab->setStringSection(_strtab.get()); _layout->addSection(_shdrtab.get()); + for (auto sec : _layout->sections()) { + if (sec->name() != ".eh_frame") + continue; + _ehFrameHeader.reset(new (_alloc) EHFrameHeader<ELFT>( + _context, ".eh_frame_hdr", DefaultLayout<ELFT>::ORDER_EH_FRAMEHDR)); + _layout->addSection(_ehFrameHeader.get()); + break; + } + if (_context.isDynamic()) { _dynamicTable.reset(new (_alloc) DynamicTable<ELFT>( _context, ".dynamic", DefaultLayout<ELFT>::ORDER_DYNAMIC)); diff --git a/lld/lib/ReaderWriter/ELF/SectionChunks.h b/lld/lib/ReaderWriter/ELF/SectionChunks.h index 2e61ad33b1b..a6bc9478b87 100644 --- a/lld/lib/ReaderWriter/ELF/SectionChunks.h +++ b/lld/lib/ReaderWriter/ELF/SectionChunks.h @@ -26,6 +26,7 @@ #include "llvm/Object/ELF.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/Dwarf.h" #include "llvm/Support/ELF.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileOutputBuffer.h" @@ -1284,6 +1285,52 @@ private: std::vector<uint32_t> _chains; const DynamicSymbolTable<ELFT> *_symbolTable; }; + +template <class ELFT> class EHFrameHeader : public Section<ELFT> { +public: + EHFrameHeader(const ELFLinkingContext &context, StringRef name, int32_t order) + : Section<ELFT>(context, name) { + this->setOrder(order); + this->_entSize = 0; + this->_type = SHT_PROGBITS; + this->_flags = SHF_ALLOC; + // Set the alignment properly depending on the target architecture + if (context.is64Bits()) + this->_align2 = 8; + else + this->_align2 = 4; + // Minimum size for empty .eh_frame_hdr. + this->_fsize = 1 + 1 + 1 + 1 + 4; + this->_msize = this->_fsize; + } + + virtual void doPreFlight() LLVM_OVERRIDE { + // TODO: Generate a proper binary search table. + } + + virtual void finalize() LLVM_OVERRIDE { + MergedSections<ELFT> *s = this->_context.template getTargetHandler<ELFT>() + .targetLayout() + .findOutputSection(".eh_frame"); + _ehFrameAddr = s ? s->virtualAddr() : 0; + } + + virtual void write(ELFWriter *writer, + llvm::FileOutputBuffer &buffer) LLVM_OVERRIDE { + uint8_t *chunkBuffer = buffer.getBufferStart(); + uint8_t *dest = chunkBuffer + this->fileOffset(); + int pos = 0; + dest[pos++] = 1; // version + dest[pos++] = llvm::dwarf::DW_EH_PE_udata4; // eh_frame_ptr_enc + dest[pos++] = llvm::dwarf::DW_EH_PE_omit; // fde_count_enc + dest[pos++] = llvm::dwarf::DW_EH_PE_omit; // table_enc + *reinterpret_cast<typename llvm::object::ELFFile<ELFT>::Elf_Word *>( + dest + pos) = (uint32_t)_ehFrameAddr; + } + +private: + uint64_t _ehFrameAddr; +}; } // end namespace elf } // end namespace lld |