| //===- HexagonRelocator.h ------------------------------------------------===// |
| // |
| // The MCLinker Project |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| #ifndef HEXAGON_RELOCATION_FACTORY_H |
| #define HEXAGON_RELOCATION_FACTORY_H |
| #ifdef ENABLE_UNITTEST |
| #include <gtest.h> |
| #endif |
| |
| #include <mcld/LD/Relocator.h> |
| #include <mcld/Target/GOT.h> |
| #include <mcld/Target/PLT.h> |
| #include <mcld/Target/SymbolEntryMap.h> |
| #include "HexagonLDBackend.h" |
| |
| namespace mcld { |
| |
| class ResolveInfo; |
| class LinkerConfig; |
| |
| /** \class HexagonRelocator |
| * \brief HexagonRelocator creates and destroys the Hexagon relocations. |
| * |
| */ |
| class HexagonRelocator : public Relocator |
| { |
| public: |
| typedef SymbolEntryMap<PLTEntryBase> SymPLTMap; |
| typedef SymbolEntryMap<HexagonGOTEntry> SymGOTMap; |
| typedef SymbolEntryMap<HexagonGOTEntry> SymGOTPLTMap; |
| |
| |
| public: |
| /** \enum ReservedEntryType |
| * \brief The reserved entry type of reserved space in ResolveInfo. |
| * |
| * This is used for sacnRelocation to record what kinds of entries are |
| * reserved for this resolved symbol |
| * |
| * In Hexagon, there are three kinds of entries, GOT, PLT, and dynamic |
| * relocation. |
| * |
| * GOT may needs a corresponding relocation to relocate itself, so we |
| * separate GOT to two situations: GOT and GOTRel. Besides, for the same |
| * symbol, there might be two kinds of entries reserved for different location. |
| * For example, reference to the same symbol, one may use GOT and the other may |
| * use dynamic relocation. |
| * |
| * bit: 3 2 1 0 |
| * | PLT | GOTRel | GOT | Rel | |
| * |
| * value Name - Description |
| * |
| * 0000 None - no reserved entry |
| * 0001 ReserveRel - reserve an dynamic relocation entry |
| * 0010 ReserveGOT - reserve an GOT entry |
| * 0011 GOTandRel - For different relocation, we've reserved GOT and |
| * Rel for different location. |
| * 0100 GOTRel - reserve an GOT entry and the corresponding Dyncamic |
| * relocation entry which relocate this GOT entry |
| * 0101 GOTRelandRel - For different relocation, we've reserved GOTRel |
| * and relocation entry for different location. |
| * 1000 ReservePLT - reserve an PLT entry and the corresponding GOT, |
| * Dynamic relocation entries |
| * 1001 PLTandRel - For different relocation, we've reserved PLT and |
| * Rel for different location. |
| */ |
| enum ReservedEntryType { |
| None = 0, |
| ReserveRel = 1, |
| ReserveGOT = 2, |
| GOTandRel = 3, |
| GOTRel = 4, |
| GOTRelandRel = 5, |
| ReservePLT = 8, |
| PLTandRel = 9 |
| }; |
| |
| HexagonRelocator(HexagonLDBackend& pParent, const LinkerConfig& pConfig); |
| ~HexagonRelocator(); |
| |
| Result applyRelocation(Relocation& pRelocation); |
| |
| /// scanRelocation - determine the empty entries are needed or not and create |
| /// the empty entries if needed. |
| /// For Hexagon, following entries are check to create: |
| /// - GOT entry (for .got and .got.plt sections) |
| /// - PLT entry (for .plt section) |
| /// - dynamin relocation entries (for .rel.plt and .rel.dyn sections) |
| void scanRelocation(Relocation& pReloc, |
| IRBuilder& pBuilder, |
| Module& pModule, |
| LDSection& pSection); |
| |
| // Handle partial linking |
| void partialScanRelocation(Relocation& pReloc, |
| Module& pModule, |
| const LDSection& pSection); |
| |
| HexagonLDBackend& getTarget() |
| { return m_Target; } |
| |
| const HexagonLDBackend& getTarget() const |
| { return m_Target; } |
| |
| const char* getName(Relocation::Type pType) const; |
| |
| Size getSize(Relocation::Type pType) const; |
| |
| const SymPLTMap& getSymPLTMap() const { return m_SymPLTMap; } |
| SymPLTMap& getSymPLTMap() { return m_SymPLTMap; } |
| |
| const SymGOTMap& getSymGOTMap() const { return m_SymGOTMap; } |
| SymGOTMap& getSymGOTMap() { return m_SymGOTMap; } |
| |
| const SymGOTPLTMap& getSymGOTPLTMap() const { return m_SymGOTPLTMap; } |
| SymGOTPLTMap& getSymGOTPLTMap() { return m_SymGOTPLTMap; } |
| |
| protected: |
| /// addCopyReloc - add a copy relocation into .rela.dyn for pSym |
| /// @param pSym - A resolved copy symbol that defined in BSS section |
| void addCopyReloc(ResolveInfo& pSym, HexagonLDBackend& pTarget); |
| |
| /// defineSymbolforCopyReloc - allocate a space in BSS section and |
| /// and force define the copy of pSym to BSS section |
| /// @return the output LDSymbol of the copy symbol |
| LDSymbol& defineSymbolforCopyReloc(IRBuilder& pLinker, |
| const ResolveInfo& pSym, |
| HexagonLDBackend& pTarget); |
| |
| private: |
| virtual void scanLocalReloc(Relocation& pReloc, |
| IRBuilder& pBuilder, |
| Module& pModule, |
| LDSection& pSection); |
| |
| virtual void scanGlobalReloc(Relocation& pReloc, |
| IRBuilder& pBuilder, |
| Module& pModule, |
| LDSection& pSection); |
| |
| HexagonLDBackend& m_Target; |
| SymPLTMap m_SymPLTMap; |
| SymGOTMap m_SymGOTMap; |
| SymGOTPLTMap m_SymGOTPLTMap; |
| }; |
| |
| } // namespace of mcld |
| |
| #endif |
| |