//===- 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 "ELFReader.h" #include "HexagonELFFile.h" #include "HexagonRelocationHandler.h" #include "TargetLayout.h" namespace lld { namespace elf { class HexagonLinkingContext; /// \brief Handle Hexagon SData section class SDataSection : public AtomSection { public: SDataSection(const HexagonLinkingContext &ctx); /// \brief Finalize the section contents before writing void doPreFlight() override; /// \brief Does this section have an output segment. bool hasOutputSegment() const override { return true; } const AtomLayout *appendAtom(const Atom *atom) override; }; /// \brief TargetLayout for Hexagon class HexagonTargetLayout final : public TargetLayout { public: enum HexagonSectionOrder { ORDER_SDATA = 205 }; HexagonTargetLayout(HexagonLinkingContext &ctx) : TargetLayout(ctx), _sdataSection(ctx) {} /// \brief Return the section order for a input section TargetLayout::SectionOrder getSectionOrder(StringRef name, int32_t contentType, int32_t contentPermissions) override { if (contentType == DefinedAtom::typeDataFast || contentType == DefinedAtom::typeZeroFillFast) return ORDER_SDATA; return TargetLayout::getSectionOrder(name, contentType, contentPermissions); } /// \brief Return the appropriate input section name. StringRef getInputSectionName(const DefinedAtom *da) const override { switch (da->contentType()) { case DefinedAtom::typeDataFast: case DefinedAtom::typeZeroFillFast: return ".sdata"; default: break; } return TargetLayout::getInputSectionName(da); } /// \brief Gets or creates a section. AtomSection * createSection(StringRef name, int32_t contentType, DefinedAtom::ContentPermissions contentPermissions, TargetLayout::SectionOrder sectionOrder) override { if (contentType == DefinedAtom::typeDataFast || contentType == DefinedAtom::typeZeroFillFast) return &_sdataSection; return TargetLayout::createSection(name, contentType, contentPermissions, sectionOrder); } /// \brief get the segment type for the section thats defined by the target TargetLayout::SegmentType getSegmentType(const Section *section) const override { if (section->order() == ORDER_SDATA) return PT_LOAD; return TargetLayout::getSegmentType(section); } Section *getSDataSection() { return &_sdataSection; } uint64_t getGOTSymAddr() { std::call_once(_gotOnce, [this]() { if (AtomLayout *got = findAbsoluteAtom("_GLOBAL_OFFSET_TABLE_")) _gotAddr = got->_virtualAddr; }); return _gotAddr; } private: SDataSection _sdataSection; uint64_t _gotAddr = 0; std::once_flag _gotOnce; }; /// \brief TargetHandler for Hexagon class HexagonTargetHandler final : public TargetHandler { public: HexagonTargetHandler(HexagonLinkingContext &targetInfo); const TargetRelocationHandler &getRelocationHandler() const override { return *_relocationHandler; } std::unique_ptr getObjReader() override { return llvm::make_unique>(_ctx); } std::unique_ptr getDSOReader() override { return llvm::make_unique>>(_ctx); } std::unique_ptr getWriter() override; private: HexagonLinkingContext &_ctx; std::unique_ptr _targetLayout; std::unique_ptr _relocationHandler; }; void finalizeHexagonRuntimeAtomValues(HexagonTargetLayout &layout); } // end namespace elf } // end namespace lld #endif