diff options
Diffstat (limited to 'lib/ReaderWriter/ELF/SegmentChunks.h')
-rw-r--r-- | lib/ReaderWriter/ELF/SegmentChunks.h | 246 |
1 files changed, 0 insertions, 246 deletions
diff --git a/lib/ReaderWriter/ELF/SegmentChunks.h b/lib/ReaderWriter/ELF/SegmentChunks.h deleted file mode 100644 index b444f44c04eb..000000000000 --- a/lib/ReaderWriter/ELF/SegmentChunks.h +++ /dev/null @@ -1,246 +0,0 @@ -//===- lib/ReaderWriter/ELF/SegmentChunks.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_SEGMENT_CHUNKS_H -#define LLD_READER_WRITER_ELF_SEGMENT_CHUNKS_H - -#include "Chunk.h" -#include "SectionChunks.h" -#include "Writer.h" -#include "lld/Core/range.h" -#include "lld/Core/Writer.h" -#include "llvm/ADT/StringRef.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" -#include <memory> - -namespace lld { -namespace elf { - -template <typename ELFT> class TargetLayout; - -/// \brief A segment can be divided into segment slices -/// depending on how the segments can be split -template<class ELFT> -class SegmentSlice { -public: - typedef typename std::vector<Chunk<ELFT> *>::iterator SectionIter; - - /// Set the start of the slice. - void setStart(int32_t s) { _startSection = s; } - - // Set the segment slice start and end iterators. This is used to walk through - // the sections that are part of the Segment slice - void setSections(range<SectionIter> sections) { _sections = sections; } - - // Return the fileOffset of the slice - uint64_t fileOffset() const { return _offset; } - void setFileOffset(uint64_t offset) { _offset = offset; } - - // Return the size of the slice - uint64_t fileSize() const { return _fsize; } - void setFileSize(uint64_t filesz) { _fsize = filesz; } - - // Return the start of the slice - int32_t startSection() const { return _startSection; } - - // Return the start address of the slice - uint64_t virtualAddr() const { return _addr; } - - // Return the memory size of the slice - uint64_t memSize() const { return _memSize; } - - // Return the alignment of the slice - uint64_t alignment() const { return _alignment; } - - void setMemSize(uint64_t memsz) { _memSize = memsz; } - - void setVirtualAddr(uint64_t addr) { _addr = addr; } - - void setAlign(uint64_t align) { _alignment = align; } - - static bool compare_slices(SegmentSlice<ELFT> *a, SegmentSlice<ELFT> *b); - - range<SectionIter> sections() { return _sections; } - -private: - range<SectionIter> _sections; - int32_t _startSection; - uint64_t _addr; - uint64_t _offset; - uint64_t _alignment; - uint64_t _fsize; - uint64_t _memSize; -}; - -/// \brief A segment contains a set of sections, that have similar properties -// the sections are already separated based on different flags and properties -// the segment is just a way to concatenate sections to segments -template<class ELFT> -class Segment : public Chunk<ELFT> { -public: - typedef typename std::vector<SegmentSlice<ELFT> *>::iterator SliceIter; - typedef typename std::vector<Chunk<ELFT> *>::iterator SectionIter; - - Segment(const ELFLinkingContext &ctx, StringRef name, - const typename TargetLayout<ELFT>::SegmentType type); - - /// \brief the Order of segments that appear in the output file - enum SegmentOrder { - permUnknown, - permRWX, - permRX, - permR, - permRWL, - permRW, - permNonAccess - }; - - /// append a section to a segment - virtual void append(Chunk<ELFT> *chunk); - - /// Sort segments depending on the property - /// If we have a Program Header segment, it should appear first - /// If we have a INTERP segment, that should appear after the Program Header - /// All Loadable segments appear next in this order - /// All Read Write Execute segments follow - /// All Read Execute segments appear next - /// All Read only segments appear first - /// All Write execute segments follow - static bool compareSegments(Segment<ELFT> *sega, Segment<ELFT> *segb); - - /// \brief Start assigning file offset to the segment chunks The fileoffset - /// needs to be page at the start of the segment and in addition the - /// fileoffset needs to be aligned to the max section alignment within the - /// segment. This is required so that the ELF property p_poffset % p_align = - /// p_vaddr mod p_align holds true. - /// The algorithm starts off by assigning the startOffset thats passed in as - /// parameter to the first section in the segment, if the difference between - /// the newly computed offset is greater than a page, then we create a segment - /// slice, as it would be a waste of virtual memory just to be filled with - /// zeroes - void assignFileOffsets(uint64_t startOffset); - - /// \brief Assign virtual addresses to the slices - void assignVirtualAddress(uint64_t addr); - - // Write the Segment - void write(ELFWriter *writer, TargetLayout<ELFT> &layout, - llvm::FileOutputBuffer &buffer) override; - - int64_t flags() const; - - // Set segment flags directly. - void setSegmentFlags(uint64_t flags); - - /// Prepend a generic chunk to the segment. - void prepend(Chunk<ELFT> *c) { - _sections.insert(_sections.begin(), c); - } - - /// Finalize the segment, before we want to write the segment header - /// information - void finalize() override; - - // For LLVM RTTI - static bool classof(const Chunk<ELFT> *c) { - return c->kind() == Chunk<ELFT>::Kind::ELFSegment; - } - - // Getters - int32_t sectionCount() const { return _sections.size(); } - - /// \brief, this function returns the type of segment (PT_*) - typename TargetLayout<ELFT>::SegmentType segmentType() const { - return _segmentType; - } - - /// \brief return the segment type depending on the content, - /// If the content corresponds to Code, this will return Segment::Code - /// If the content corresponds to Data, this will return Segment::Data - /// If the content corresponds to TLS, this will return Segment::TLS - int getContentType() const override; - - int pageSize() const { return this->_ctx.getPageSize(); } - int rawflags() const { return _atomflags; } - int64_t atomflags() const; - int64_t numSlices() const { return _segmentSlices.size(); } - range<SliceIter> slices() { return _segmentSlices; } - Chunk<ELFT> *firstSection() { return _sections[0]; } - -private: - /// \brief Check if the chunk needs to be aligned - bool needAlign(Chunk<ELFT> *chunk) const; - - // Cached value of outputMagic - ELFLinkingContext::OutputMagic _outputMagic; - -protected: - /// \brief Section or some other chunk type. - std::vector<Chunk<ELFT> *> _sections; - std::vector<SegmentSlice<ELFT> *> _segmentSlices; - typename TargetLayout<ELFT>::SegmentType _segmentType; - uint64_t _flags; - int64_t _atomflags; - bool _segmentFlags; - llvm::BumpPtrAllocator _segmentAllocate; -}; - -/// This chunk represents a linker script expression that needs to be calculated -/// at the time the virtual addresses for the parent segment are being assigned. -template <class ELFT> class ExpressionChunk : public Chunk<ELFT> { -public: - ExpressionChunk(ELFLinkingContext &ctx, const script::SymbolAssignment *expr) - : Chunk<ELFT>(StringRef(), Chunk<ELFT>::Kind::Expression, ctx), - _expr(expr), _linkerScriptSema(ctx.linkerScriptSema()) { - this->_alignment = 1; - } - - static bool classof(const Chunk<ELFT> *c) { - return c->kind() == Chunk<ELFT>::Kind::Expression; - } - - int getContentType() const override { - return Chunk<ELFT>::ContentType::Unknown; - } - - void write(ELFWriter *, TargetLayout<ELFT> &, - llvm::FileOutputBuffer &) override {} - - std::error_code evalExpr(uint64_t &curPos) { - return _linkerScriptSema.evalExpr(_expr, curPos); - } - -private: - const script::SymbolAssignment *_expr; - script::Sema &_linkerScriptSema; -}; - -/// \brief A Program Header segment contains a set of chunks instead of sections -/// The segment doesn't contain any slice -template <class ELFT> class ProgramHeaderSegment : public Segment<ELFT> { -public: - ProgramHeaderSegment(const ELFLinkingContext &ctx) - : Segment<ELFT>(ctx, "PHDR", llvm::ELF::PT_PHDR) { - this->_alignment = 8; - this->_flags = (llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR); - } - - /// Finalize the segment, before we want to write the segment header - /// information - void finalize() override; -}; - -} // end namespace elf -} // end namespace lld - -#endif // LLD_READER_WRITER_ELF_SEGMENT_CHUNKS_H |