diff options
Diffstat (limited to 'lib/ReaderWriter/ELF/TargetLayout.h')
-rw-r--r-- | lib/ReaderWriter/ELF/TargetLayout.h | 327 |
1 files changed, 0 insertions, 327 deletions
diff --git a/lib/ReaderWriter/ELF/TargetLayout.h b/lib/ReaderWriter/ELF/TargetLayout.h deleted file mode 100644 index 52512f8e279e..000000000000 --- a/lib/ReaderWriter/ELF/TargetLayout.h +++ /dev/null @@ -1,327 +0,0 @@ -//===- lib/ReaderWriter/ELF/TargetLayout.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_DEFAULT_LAYOUT_H -#define LLD_READER_WRITER_ELF_DEFAULT_LAYOUT_H - -#include "Atoms.h" -#include "HeaderChunks.h" -#include "SectionChunks.h" -#include "SegmentChunks.h" -#include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringRef.h" -#include <unordered_map> - -namespace lld { -namespace elf { - -/// \brief The TargetLayout class is used by the Writer to arrange -/// sections and segments in the order determined by the target ELF -/// format. The writer creates a single instance of the TargetLayout -/// class -template <class ELFT> class TargetLayout { -public: - typedef uint32_t SectionOrder; - typedef uint32_t SegmentType; - - // The order in which the sections appear in the output file - // If its determined, that the layout needs to change - // just changing the order of enumerations would essentially - // change the layout in the output file - // Change the enumerations so that Target can override and stick - // a section anywhere it wants to - enum DefaultSectionOrder { - ORDER_NOT_DEFINED = 0, - ORDER_INTERP = 10, - ORDER_RO_NOTE = 15, - ORDER_HASH = 30, - ORDER_DYNAMIC_SYMBOLS = 40, - ORDER_DYNAMIC_STRINGS = 50, - ORDER_DYNAMIC_RELOCS = 52, - ORDER_DYNAMIC_PLT_RELOCS = 54, - ORDER_INIT = 60, - ORDER_PLT = 70, - ORDER_TEXT = 80, - ORDER_FINI = 90, - ORDER_REL = 95, - ORDER_RODATA = 100, - ORDER_EH_FRAME = 110, - ORDER_EH_FRAMEHDR = 120, - ORDER_TDATA = 124, - ORDER_TBSS = 128, - ORDER_CTORS = 130, - ORDER_DTORS = 140, - ORDER_INIT_ARRAY = 150, - ORDER_FINI_ARRAY = 160, - ORDER_DYNAMIC = 170, - ORDER_GOT = 180, - ORDER_GOT_PLT = 190, - ORDER_DATA = 200, - ORDER_RW_NOTE = 205, - ORDER_BSS = 210, - ORDER_NOALLOC = 215, - ORDER_OTHER = 220, - ORDER_SECTION_STRINGS = 230, - ORDER_SYMBOL_TABLE = 240, - ORDER_STRING_TABLE = 250, - ORDER_SECTION_HEADERS = 260 - }; - -public: - - // The Key used for creating Sections - // The sections are created using - // SectionName, contentPermissions - struct SectionKey { - SectionKey(StringRef name, DefinedAtom::ContentPermissions perm, - StringRef path) - : _name(name), _perm(perm), _path(path) {} - - // Data members - StringRef _name; - DefinedAtom::ContentPermissions _perm; - StringRef _path; - }; - - struct SectionKeyHash { - int64_t operator()(const SectionKey &k) const { - return llvm::hash_combine(k._name, k._perm, k._path); - } - }; - - struct SectionKeyEq { - bool operator()(const SectionKey &lhs, const SectionKey &rhs) const { - return ((lhs._name == rhs._name) && (lhs._perm == rhs._perm) && - (lhs._path == rhs._path)); - } - }; - - typedef typename std::vector<Chunk<ELFT> *>::iterator ChunkIter; - typedef typename std::vector<Segment<ELFT> *>::iterator SegmentIter; - - // Properties used during segment creation - struct SegmentKey { - SegmentKey(StringRef name, int64_t type, uint64_t flags, bool segFlags) - : _name(name), _type(type), _flags(flags), - _segmentFlags(segFlags && flags != 0) {} - StringRef _name = ""; - int64_t _type = 0; - uint64_t _flags = 0; - bool _segmentFlags = false; - }; - - struct SegmentKeyHash { - int64_t operator()(const SegmentKey &k) const { - return llvm::hash_combine(k._name, k._type, k._flags); - } - }; - - struct SegmentKeyEq { - bool operator()(const SegmentKey &lhs, const SegmentKey &rhs) const { - return ((lhs._name == rhs._name) && (lhs._type == rhs._type) && - (lhs._flags == rhs._flags)); - } - }; - - // Output Sections contain the map of Section names to a vector of sections, - // that have been merged to form a single section - typedef llvm::StringMap<OutputSection<ELFT> *> OutputSectionMapT; - typedef - typename std::vector<OutputSection<ELFT> *>::iterator OutputSectionIter; - - typedef std::unordered_map<SectionKey, AtomSection<ELFT> *, SectionKeyHash, - SectionKeyEq> SectionMapT; - typedef std::unordered_map<SegmentKey, Segment<ELFT> *, SegmentKeyHash, - SegmentKeyEq> SegmentMapT; - - typedef typename std::vector<AtomLayout *>::iterator AbsoluteAtomIterT; - - typedef llvm::DenseSet<const Atom *> AtomSetT; - - TargetLayout(ELFLinkingContext &ctx) - : _ctx(ctx), _linkerScriptSema(ctx.linkerScriptSema()) {} - - virtual ~TargetLayout() = default; - - /// \brief Return the section order for a input section - virtual SectionOrder getSectionOrder(StringRef name, int32_t contentType, - int32_t contentPermissions); - - /// \brief Return the name of the input section by decoding the input - /// sectionChoice. - virtual StringRef getInputSectionName(const DefinedAtom *da) const; - - /// \brief Return the name of the output section from the input section. - virtual StringRef getOutputSectionName(StringRef archivePath, - StringRef memberPath, - StringRef inputSectionName) const; - - /// \brief Gets or creates a section. - AtomSection<ELFT> * - getSection(StringRef name, int32_t contentType, - DefinedAtom::ContentPermissions contentPermissions, - const DefinedAtom *da); - - /// \brief Gets the segment for a output section - virtual SegmentType getSegmentType(const Section<ELFT> *section) const; - - /// \brief Returns true/false depending on whether the section has a Output - // segment or not - static bool hasOutputSegment(Section<ELFT> *section); - - /// \brief Append the Atom to the layout and create appropriate sections. - /// \returns A reference to the atom layout or an error. The atom layout will - /// be updated as linking progresses. - virtual ErrorOr<const AtomLayout *> addAtom(const Atom *atom); - - /// \brief Find an output Section given a section name. - OutputSection<ELFT> *findOutputSection(StringRef name) { - auto iter = _outputSectionMap.find(name); - if (iter == _outputSectionMap.end()) - return nullptr; - return iter->second; - } - - /// \brief find a absolute atom given a name - AtomLayout *findAbsoluteAtom(StringRef name) { - auto iter = std::find_if( - _absoluteAtoms.begin(), _absoluteAtoms.end(), - [=](const AtomLayout *a) { return a->_atom->name() == name; }); - if (iter == _absoluteAtoms.end()) - return nullptr; - return *iter; - } - - // Output sections with the same name into a OutputSection - void createOutputSections(); - - // Query for segments based on output and input sections - std::vector<SegmentKey> getSegmentsForSection(const OutputSection<ELFT> *os, - const Section<ELFT> *sec) const; - - /// \brief Sort the sections by their order as defined by the layout, - /// preparing all sections to be assigned to a segment. - virtual void sortInputSections(); - - /// \brief Add extra chunks to a segment just before including the input - /// section given by <archivePath, memberPath, sectionName>. This - /// is used to add linker script expressions before each section. - virtual void addExtraChunksToSegment(Segment<ELFT> *segment, - StringRef archivePath, - StringRef memberPath, - StringRef sectionName); - - /// \brief associates a section to a segment - virtual void assignSectionsToSegments(); - - /// \brief associates a virtual address to the segment, section, and the atom - virtual void assignVirtualAddress(); - - void assignFileOffsetsForMiscSections(); - - range<AbsoluteAtomIterT> absoluteAtoms() { return _absoluteAtoms; } - - void addSection(Chunk<ELFT> *c) { _sections.push_back(c); } - - void finalize() { - ScopedTask task(getDefaultDomain(), "Finalize layout"); - for (auto &si : _sections) - si->finalize(); - } - - void doPreFlight() { - for (auto &si : _sections) - si->doPreFlight(); - } - - /// \brief find the Atom in the current layout - virtual const AtomLayout *findAtomLayoutByName(StringRef name) const; - - void setHeader(ELFHeader<ELFT> *elfHeader) { _elfHeader = elfHeader; } - - void setProgramHeader(ProgramHeader<ELFT> *p) { - _programHeader = p; - } - - range<OutputSectionIter> outputSections() { return _outputSections; } - - range<ChunkIter> sections() { return _sections; } - - range<SegmentIter> segments() { return _segments; } - - ELFHeader<ELFT> *getHeader() { return _elfHeader; } - - bool hasDynamicRelocationTable() const { return !!_dynamicRelocationTable; } - - bool hasPLTRelocationTable() const { return !!_pltRelocationTable; } - - /// \brief Get or create the dynamic relocation table. All relocations in this - /// table are processed at startup. - RelocationTable<ELFT> *getDynamicRelocationTable(); - - /// \brief Get or create the PLT relocation table. Referenced by DT_JMPREL. - RelocationTable<ELFT> *getPLTRelocationTable(); - - uint64_t getTLSSize() const; - - bool isReferencedByDefinedAtom(const Atom *a) const { - return _referencedDynAtoms.count(a); - } - - bool isCopied(const SharedLibraryAtom *sla) const { - return _copiedDynSymNames.count(sla->name()); - } - -protected: - /// \brief TargetLayouts may use these functions to reorder the input sections - /// in a order defined by their ABI. - virtual void finalizeOutputSectionLayout() {} - - /// \brief Allocate a new section. - virtual AtomSection<ELFT> *createSection( - StringRef name, int32_t contentType, - DefinedAtom::ContentPermissions contentPermissions, - SectionOrder sectionOrder); - - /// \brief Create a new relocation table. - virtual unique_bump_ptr<RelocationTable<ELFT>> - createRelocationTable(StringRef name, int32_t order) { - return unique_bump_ptr<RelocationTable<ELFT>>( - new (_allocator) RelocationTable<ELFT>(_ctx, name, order)); - } - - virtual uint64_t getLookupSectionFlags(const OutputSection<ELFT> *os) const; - - /// \brief Sort segements stored in the _segments - virtual void sortSegments(); - -protected: - llvm::BumpPtrAllocator _allocator; - SectionMapT _sectionMap; - OutputSectionMapT _outputSectionMap; - SegmentMapT _segmentMap; - std::vector<Chunk<ELFT> *> _sections; - std::vector<Segment<ELFT> *> _segments; - std::vector<OutputSection<ELFT> *> _outputSections; - ELFHeader<ELFT> *_elfHeader; - ProgramHeader<ELFT> *_programHeader; - unique_bump_ptr<RelocationTable<ELFT>> _dynamicRelocationTable; - unique_bump_ptr<RelocationTable<ELFT>> _pltRelocationTable; - std::vector<AtomLayout *> _absoluteAtoms; - AtomSetT _referencedDynAtoms; - llvm::StringSet<> _copiedDynSymNames; - ELFLinkingContext &_ctx; - script::Sema &_linkerScriptSema; -}; - -} // end namespace elf -} // end namespace lld - -#endif |