//===- lib/ReaderWriter/ELF/Hexagon/HexagonTargetHandler.h ----------------===// // // The LLVM Linker // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #ifndef HEXAGON_TARGET_HANDLER_H #define HEXAGON_TARGET_HANDLER_H #include "DefaultTargetHandler.h" #include "HexagonELFReader.h" #include "HexagonExecutableAtoms.h" #include "HexagonRelocationHandler.h" #include "HexagonSectionChunks.h" #include "TargetLayout.h" namespace lld { namespace elf { class HexagonLinkingContext; /// \brief TargetLayout for Hexagon template class HexagonTargetLayout final : public TargetLayout { public: enum HexagonSectionOrder { ORDER_SDATA = 205 }; HexagonTargetLayout(HexagonLinkingContext &hti) : TargetLayout(hti), _sdataSection(nullptr), _gotSymAtom(nullptr), _cachedGotSymAtom(false) { _sdataSection = new (_alloc) SDataSection(hti); } /// \brief Return the section order for a input section virtual Layout::SectionOrder getSectionOrder( StringRef name, int32_t contentType, int32_t contentPermissions) { if ((contentType == DefinedAtom::typeDataFast) || (contentType == DefinedAtom::typeZeroFillFast)) return ORDER_SDATA; return DefaultLayout::getSectionOrder(name, contentType, contentPermissions); } /// \brief Return the appropriate input section name. virtual StringRef getInputSectionName(const DefinedAtom *da) const { switch (da->contentType()) { case DefinedAtom::typeDataFast: case DefinedAtom::typeZeroFillFast: return ".sdata"; default: break; } return DefaultLayout::getInputSectionName(da); } /// \brief Gets or creates a section. virtual AtomSection * createSection(StringRef name, int32_t contentType, DefinedAtom::ContentPermissions contentPermissions, Layout::SectionOrder sectionOrder) { if ((contentType == DefinedAtom::typeDataFast) || (contentType == DefinedAtom::typeZeroFillFast)) return _sdataSection; return DefaultLayout::createSection( name, contentType, contentPermissions, sectionOrder); } /// \brief get the segment type for the section thats defined by the target virtual Layout::SegmentType getSegmentType(Section *section) const { if (section->order() == ORDER_SDATA) return PT_LOAD; return DefaultLayout::getSegmentType(section); } Section *getSDataSection() const { return _sdataSection; } uint64_t getGOTSymAddr() { if (!_cachedGotSymAtom) { auto gotAtomIter = this->findAbsoluteAtom("_GLOBAL_OFFSET_TABLE_"); _gotSymAtom = (*gotAtomIter); _cachedGotSymAtom = true; } if (_gotSymAtom) return _gotSymAtom->_virtualAddr; return 0; } private: llvm::BumpPtrAllocator _alloc; SDataSection *_sdataSection; AtomLayout *_gotSymAtom; bool _cachedGotSymAtom; }; /// \brief TargetHandler for Hexagon class HexagonTargetHandler final : public DefaultTargetHandler { public: HexagonTargetHandler(HexagonLinkingContext &targetInfo); void registerRelocationNames(Registry ®istry) override; const HexagonTargetRelocationHandler &getRelocationHandler() const override { return *(_hexagonRelocationHandler.get()); } HexagonTargetLayout &getTargetLayout() override { return *(_hexagonTargetLayout.get()); } std::unique_ptr getObjReader() override { return std::unique_ptr( new HexagonELFObjectReader(_hexagonLinkingContext)); } std::unique_ptr getDSOReader() override { return std::unique_ptr( new HexagonELFDSOReader(_hexagonLinkingContext)); } std::unique_ptr getWriter() override; private: llvm::BumpPtrAllocator _alloc; static const Registry::KindStrings kindStrings[]; HexagonLinkingContext &_hexagonLinkingContext; std::unique_ptr > _hexagonRuntimeFile; std::unique_ptr> _hexagonTargetLayout; std::unique_ptr _hexagonRelocationHandler; }; } // end namespace elf } // end namespace lld #endif