//===- lib/ReaderWriter/ELF/HeaderChunks.h --------------------------------===// // // The LLVM Linker // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef LLD_READER_WRITER_ELF_HEADER_CHUNKS_H #define LLD_READER_WRITER_ELF_HEADER_CHUNKS_H #include "SegmentChunks.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Object/ELF.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/ELF.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileOutputBuffer.h" /// \brief An Header represents the Elf[32/64]_Ehdr structure at the /// start of an ELF executable file. namespace lld { namespace elf { template class ELFHeader : public Chunk { public: typedef llvm::object::Elf_Ehdr_Impl Elf_Ehdr; ELFHeader(const ELFLinkingContext &); void e_ident(int I, unsigned char C) { _eh.e_ident[I] = C; } void e_type(uint16_t type) { _eh.e_type = type; } void e_machine(uint16_t machine) { _eh.e_machine = machine; } void e_version(uint32_t version) { _eh.e_version = version; } void e_entry(int64_t entry) { _eh.e_entry = entry; } void e_phoff(int64_t phoff) { _eh.e_phoff = phoff; } void e_shoff(int64_t shoff) { _eh.e_shoff = shoff; } void e_flags(uint32_t flags) { _eh.e_flags = flags; } void e_ehsize(uint16_t ehsize) { _eh.e_ehsize = ehsize; } void e_phentsize(uint16_t phentsize) { _eh.e_phentsize = phentsize; } void e_phnum(uint16_t phnum) { _eh.e_phnum = phnum; } void e_shentsize(uint16_t shentsize) { _eh.e_shentsize = shentsize; } void e_shnum(uint16_t shnum) { _eh.e_shnum = shnum; } void e_shstrndx(uint16_t shstrndx) { _eh.e_shstrndx = shstrndx; } uint64_t fileSize() const override { return sizeof(Elf_Ehdr); } static bool classof(const Chunk *c) { return c->kind() == Chunk::Kind::ELFHeader; } int getContentType() const override { return Chunk::ContentType::Header; } void write(ELFWriter *writer, TargetLayout &layout, llvm::FileOutputBuffer &buffer) override; void finalize() override; private: Elf_Ehdr _eh; }; /// \brief An ProgramHeader represents the Elf[32/64]_Phdr structure at the /// start of an ELF executable file. template class ProgramHeader : public Chunk { public: typedef llvm::object::Elf_Phdr_Impl Elf_Phdr; typedef typename std::vector::iterator PhIterT; typedef typename std::reverse_iterator ReversePhIterT; ProgramHeader(const ELFLinkingContext &ctx) : Chunk("elfphdr", Chunk::Kind::ProgramHeader, ctx) { this->_alignment = ELFT::Is64Bits ? 8 : 4; resetProgramHeaders(); } bool addSegment(Segment *segment); void resetProgramHeaders() { _phi = _ph.begin(); } uint64_t fileSize() const override { return sizeof(Elf_Phdr) * _ph.size(); } static bool classof(const Chunk *c) { return c->kind() == Chunk::Kind::ProgramHeader; } void write(ELFWriter *writer, TargetLayout &layout, llvm::FileOutputBuffer &buffer) override; PhIterT begin() { return _ph.begin(); } PhIterT end() { return _ph.end(); } ReversePhIterT rbegin() { return _ph.rbegin(); } ReversePhIterT rend() { return _ph.rend(); } int64_t entsize() { return sizeof(Elf_Phdr); } int64_t numHeaders() { return _ph.size(); } int getContentType() const override { return Chunk::ContentType::Header; } private: Elf_Phdr *allocateProgramHeader(bool &allocatedNew); std::vector _ph; PhIterT _phi; llvm::BumpPtrAllocator _allocator; }; /// \brief An SectionHeader represents the Elf[32/64]_Shdr structure /// at the end of the file template class SectionHeader : public Chunk { public: typedef llvm::object::Elf_Shdr_Impl Elf_Shdr; SectionHeader(const ELFLinkingContext &, int32_t order); void appendSection(OutputSection *section); void updateSection(Section *section); static bool classof(const Chunk *c) { return c->kind() == Chunk::Kind::SectionHeader; } void setStringSection(StringTable *s) { _stringSection = s; } void write(ELFWriter *writer, TargetLayout &layout, llvm::FileOutputBuffer &buffer) override; uint64_t fileSize() const override { return sizeof(Elf_Shdr) * _sectionInfo.size(); } uint64_t entsize() { return sizeof(Elf_Shdr); } int getContentType() const override { return Chunk::ContentType::Header; } uint64_t numHeaders() { return _sectionInfo.size(); } private: StringTable *_stringSection; std::vector _sectionInfo; llvm::BumpPtrAllocator _sectionAllocate; }; } // end namespace elf } // end namespace lld #endif