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