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