summaryrefslogtreecommitdiffstats
path: root/lld/lib/ReaderWriter
diff options
context:
space:
mode:
Diffstat (limited to 'lld/lib/ReaderWriter')
-rw-r--r--lld/lib/ReaderWriter/ELF/DefaultLayout.h4
-rw-r--r--lld/lib/ReaderWriter/ELF/OutputELFWriter.h10
-rw-r--r--lld/lib/ReaderWriter/ELF/SectionChunks.h47
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
OpenPOWER on IntegriCloud