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 <llvm/Support/DataTypes.h>
14 #include <mcld/Fragment/Fragment.h>
15 #include <mcld/Fragment/Relocation.h>
16 #include <vector>
17 #include <string>
18 
19 namespace mcld
20 {
21 
22 class Relocation;
23 class ResolveInfo;
24 
25 class Stub: public Fragment
26 {
27 public:
28   typedef Relocation::DWord DWord;
29   typedef Relocation::SWord SWord;
30   typedef Relocation::Type  Type;
31 
32   class Fixup
33   {
34   public:
Fixup(DWord pOffset,SWord pAddend,Type pType)35     Fixup(DWord pOffset, SWord pAddend, Type pType)
36      : m_Offset(pOffset), m_Addend(pAddend), m_Type(pType)
37     { }
38 
~Fixup()39     ~Fixup()
40     { }
41 
offset()42     DWord offset() const { return m_Offset; }
43 
addend()44     SWord addend() const { return m_Addend; }
45 
type()46     Type  type() const   { return m_Type; }
47 
48   private:
49     DWord m_Offset;
50     SWord m_Addend;
51     Type  m_Type;
52   };
53 
54 public:
55   typedef std::vector<Fixup*> FixupListType;
56   typedef FixupListType::iterator fixup_iterator;
57   typedef FixupListType::const_iterator const_fixup_iterator;
58 
59 public:
60   Stub();
61 
62   virtual ~Stub();
63 
64   /// clone - clone function for stub factory to create the corresponding stub
clone()65   Stub* clone() { return doClone(); }
66 
67   /// isMyDuty - return true when the pReloc is problematic and the stub is able
68   /// to fix it!
69   virtual bool isMyDuty(const class Relocation& pReloc,
70                         uint64_t pSource,
71                         uint64_t pTargetSymValue) const = 0;
72 
73   /// name - name of this stub
74   virtual const std::string& name() const = 0;
75 
76   /// getContent - content of the stub
77   virtual const uint8_t* getContent() const = 0;
78 
79   /// size - size of the stub
80   virtual size_t size() const = 0;
81 
82   /// alignment - alignment of the stub
83   virtual size_t alignment() const = 0;
84 
85   /// symInfo - ResolveInfo of this Stub
symInfo()86   ResolveInfo* symInfo()             { return m_pSymInfo; }
87 
symInfo()88   const ResolveInfo* symInfo() const { return m_pSymInfo; }
89 
90   /// symValue - initial value for stub's symbol
initSymValue()91   virtual uint64_t initSymValue() const  { return 0x0; }
92 
93   ///  -----  Fixup  -----  ///
fixup_begin()94   fixup_iterator       fixup_begin()       { return m_FixupList.begin(); }
95 
fixup_begin()96   const_fixup_iterator fixup_begin() const { return m_FixupList.begin(); }
97 
fixup_end()98   fixup_iterator       fixup_end()         { return m_FixupList.end();   }
99 
fixup_end()100   const_fixup_iterator fixup_end()   const { return m_FixupList.end();   }
101 
102   /// ----- modifiers ----- ///
103   void setSymInfo(ResolveInfo* pSymInfo);
104 
105   // Stub is a kind of Fragment with type of Stub
classof(const Fragment * F)106   static bool classof(const Fragment *F)
107   { return F->getKind() == Fragment::Stub; }
108 
classof(const Stub *)109   static bool classof(const Stub *)
110   { return true; }
111 
112 protected:
113   /// addFixup - add a fixup for this stub to build a relocation
114   void addFixup(DWord pOffset, SWord pAddend, Type pType);
115 
116   /// addFixup - add a fixup from a existing fixup of the prototype
117   void addFixup(const Fixup& pFixup);
118 
119 private:
120   /// doClone - when adding a backend stub, we should implement this function
121   virtual Stub* doClone() = 0;
122 
123 private:
124   ResolveInfo* m_pSymInfo;
125   FixupListType m_FixupList;
126 };
127 
128 } // namespace of mcld
129 
130 #endif
131 
132