1 //===- Stub.h -------------------------------------------------------------===// 2 // 3 // The MCLinker Project 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef MCLD_FRAGMENT_STUB_H_ 11 #define MCLD_FRAGMENT_STUB_H_ 12 13 #include "mcld/Fragment/Fragment.h" 14 #include "mcld/Fragment/Relocation.h" 15 16 #include <llvm/Support/DataTypes.h> 17 18 #include <string> 19 #include <vector> 20 21 namespace mcld { 22 23 class BranchIsland; 24 class IRBuilder; 25 class Relocation; 26 class ResolveInfo; 27 28 class Stub : public Fragment { 29 public: 30 typedef Relocation::DWord DWord; 31 typedef Relocation::SWord SWord; 32 typedef Relocation::Type Type; 33 34 class Fixup { 35 public: Fixup(DWord pOffset,SWord pAddend,Type pType)36 Fixup(DWord pOffset, SWord pAddend, Type pType) 37 : m_Offset(pOffset), m_Addend(pAddend), m_Type(pType) {} 38 ~Fixup()39 ~Fixup() {} 40 offset()41 DWord offset() const { return m_Offset; } 42 addend()43 SWord addend() const { return m_Addend; } 44 type()45 Type type() const { return m_Type; } 46 47 private: 48 DWord m_Offset; 49 SWord m_Addend; 50 Type m_Type; 51 }; 52 53 public: 54 typedef std::vector<Fixup*> FixupListType; 55 typedef FixupListType::iterator fixup_iterator; 56 typedef FixupListType::const_iterator const_fixup_iterator; 57 58 public: 59 Stub(); 60 61 virtual ~Stub(); 62 63 /// clone - clone function for stub factory to create the corresponding stub clone()64 Stub* clone() { return doClone(); } 65 66 /// isMyDuty - return true when the pReloc is problematic and the stub is able 67 /// to fix it! isMyDuty(const Relocation & pReloc,uint64_t pSource,uint64_t pTargetSymValue)68 virtual bool isMyDuty(const Relocation& pReloc, 69 uint64_t pSource, 70 uint64_t pTargetSymValue) const { 71 return false; 72 } 73 isMyDuty(const FragmentRef & pFragRef)74 virtual bool isMyDuty(const FragmentRef& pFragRef) const { 75 return false; 76 } 77 78 /// name - name of this stub 79 virtual const std::string& name() const = 0; 80 81 /// getContent - content of the stub 82 virtual const uint8_t* getContent() const = 0; 83 84 /// size - size of the stub 85 virtual size_t size() const = 0; 86 87 /// alignment - alignment of the stub 88 virtual size_t alignment() const = 0; 89 90 /// symInfo - ResolveInfo of this Stub symInfo()91 ResolveInfo* symInfo() { return m_pSymInfo; } 92 symInfo()93 const ResolveInfo* symInfo() const { return m_pSymInfo; } 94 95 /// symValue - initial value for stub's symbol initSymValue()96 virtual uint64_t initSymValue() const { return 0x0; } 97 98 /// ----- Fixup ----- /// fixup_begin()99 fixup_iterator fixup_begin() { return m_FixupList.begin(); } 100 fixup_begin()101 const_fixup_iterator fixup_begin() const { return m_FixupList.begin(); } 102 fixup_end()103 fixup_iterator fixup_end() { return m_FixupList.end(); } 104 fixup_end()105 const_fixup_iterator fixup_end() const { return m_FixupList.end(); } 106 fixup_size()107 size_t fixup_size() const { return m_FixupList.size(); } 108 109 virtual void applyFixup(Relocation& pSrcReloc, 110 IRBuilder& pBuilder, 111 BranchIsland& pIsland); 112 113 virtual void applyFixup(FragmentRef& pSrcFragRef, 114 IRBuilder& pBuilder, 115 BranchIsland& pIsland); 116 117 /// ----- modifiers ----- /// 118 void setSymInfo(ResolveInfo* pSymInfo); 119 120 // Stub is a kind of Fragment with type of Stub classof(const Fragment * F)121 static bool classof(const Fragment* F) { 122 return F->getKind() == Fragment::Stub; 123 } 124 classof(const Stub *)125 static bool classof(const Stub*) { return true; } 126 127 protected: 128 /// addFixup - add a fixup for this stub to build a relocation 129 void addFixup(DWord pOffset, SWord pAddend, Type pType); 130 131 /// addFixup - add a fixup from a existing fixup of the prototype 132 void addFixup(const Fixup& pFixup); 133 getFixupList()134 const FixupListType& getFixupList() const { return m_FixupList; } getFixupList()135 FixupListType& getFixupList() { return m_FixupList; } 136 137 private: 138 /// doClone - when adding a backend stub, we should implement this function 139 virtual Stub* doClone() = 0; 140 141 private: 142 ResolveInfo* m_pSymInfo; 143 FixupListType m_FixupList; 144 }; 145 146 } // namespace mcld 147 148 #endif // MCLD_FRAGMENT_STUB_H_ 149