aboutsummaryrefslogtreecommitdiff
path: root/lib/ReaderWriter/ELF/SegmentChunks.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ReaderWriter/ELF/SegmentChunks.h')
-rw-r--r--lib/ReaderWriter/ELF/SegmentChunks.h246
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