Stub.h revision cfcb22478ca64c308df58f9abe6fa2dedb213c16
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
21namespace mcld {
22
23class BranchIsland;
24class IRBuilder;
25class Relocation;
26class ResolveInfo;
27
28class 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:
36    Fixup(DWord pOffset, SWord pAddend, Type pType)
37        : m_Offset(pOffset), m_Addend(pAddend), m_Type(pType) {}
38
39    ~Fixup() {}
40
41    DWord offset() const { return m_Offset; }
42
43    SWord addend() const { return m_Addend; }
44
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
64  Stub* clone() { return doClone(); }
65
66  /// isMyDuty - return true when the pReloc is problematic and the stub is able
67  /// to fix it!
68  virtual bool isMyDuty(const Relocation& pReloc,
69                        uint64_t pSource,
70                        uint64_t pTargetSymValue) const {
71    return false;
72  }
73
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
91  ResolveInfo* symInfo() { return m_pSymInfo; }
92
93  const ResolveInfo* symInfo() const { return m_pSymInfo; }
94
95  /// symValue - initial value for stub's symbol
96  virtual uint64_t initSymValue() const { return 0x0; }
97
98  ///  -----  Fixup  -----  ///
99  fixup_iterator fixup_begin() { return m_FixupList.begin(); }
100
101  const_fixup_iterator fixup_begin() const { return m_FixupList.begin(); }
102
103  fixup_iterator fixup_end() { return m_FixupList.end(); }
104
105  const_fixup_iterator fixup_end() const { return m_FixupList.end(); }
106
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
121  static bool classof(const Fragment* F) {
122    return F->getKind() == Fragment::Stub;
123  }
124
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
134  const FixupListType& getFixupList() const { return m_FixupList; }
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