122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===- Stub.h -------------------------------------------------------------===//
222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//
322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//                     The MCLinker Project
422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//
522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// This file is distributed under the University of Illinois Open Source
622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao// License. See LICENSE.TXT for details.
722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//
822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao//===----------------------------------------------------------------------===//
922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#ifndef MCLD_FRAGMENT_STUB_H_
1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#define MCLD_FRAGMENT_STUB_H_
1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines
1337b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/Fragment.h"
1437b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Fragment/Relocation.h"
1522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
1622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <llvm/Support/DataTypes.h>
1737b74a387bb3993387029859c2d9d051c41c724eStephen Hines
1822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao#include <string>
1937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <vector>
2022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace mcld {
2222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
23b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesclass BranchIsland;
24b0d0eb206527b43c771933602e147bbd7b471082Stephen Hinesclass IRBuilder;
2522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass Relocation;
2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liaoclass ResolveInfo;
2722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
2837b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass Stub : public Fragment {
2937b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
3022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  typedef Relocation::DWord DWord;
3122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  typedef Relocation::SWord SWord;
3237b74a387bb3993387029859c2d9d051c41c724eStephen Hines  typedef Relocation::Type Type;
3322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3437b74a387bb3993387029859c2d9d051c41c724eStephen Hines  class Fixup {
3537b74a387bb3993387029859c2d9d051c41c724eStephen Hines   public:
3622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    Fixup(DWord pOffset, SWord pAddend, Type pType)
3737b74a387bb3993387029859c2d9d051c41c724eStephen Hines        : m_Offset(pOffset), m_Addend(pAddend), m_Type(pType) {}
3822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
3937b74a387bb3993387029859c2d9d051c41c724eStephen Hines    ~Fixup() {}
4022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    DWord offset() const { return m_Offset; }
4222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    SWord addend() const { return m_Addend; }
4422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4537b74a387bb3993387029859c2d9d051c41c724eStephen Hines    Type type() const { return m_Type; }
4622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
4737b74a387bb3993387029859c2d9d051c41c724eStephen Hines   private:
4822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    DWord m_Offset;
4922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao    SWord m_Addend;
5037b74a387bb3993387029859c2d9d051c41c724eStephen Hines    Type m_Type;
5122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  };
5222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
5337b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
5422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  typedef std::vector<Fixup*> FixupListType;
5522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  typedef FixupListType::iterator fixup_iterator;
5622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  typedef FixupListType::const_iterator const_fixup_iterator;
5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
5837b74a387bb3993387029859c2d9d051c41c724eStephen Hines public:
5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Stub();
6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual ~Stub();
6222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
6322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// clone - clone function for stub factory to create the corresponding stub
6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  Stub* clone() { return doClone(); }
6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
6622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// isMyDuty - return true when the pReloc is problematic and the stub is able
6722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// to fix it!
68b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  virtual bool isMyDuty(const Relocation& pReloc,
6922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao                        uint64_t pSource,
70b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines                        uint64_t pTargetSymValue) const {
71b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines    return false;
72b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  }
73b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines
74b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  virtual bool isMyDuty(const FragmentRef& pFragRef) const {
75b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines    return false;
76b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  }
7722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
7822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// name - name of this stub
7922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual const std::string& name() const = 0;
8022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
8122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// getContent - content of the stub
8222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual const uint8_t* getContent() const = 0;
8322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
8422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// size - size of the stub
8522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual size_t size() const = 0;
8622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
8722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// alignment - alignment of the stub
8822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual size_t alignment() const = 0;
8922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
9022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// symInfo - ResolveInfo of this Stub
9137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  ResolveInfo* symInfo() { return m_pSymInfo; }
9222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
9322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const ResolveInfo* symInfo() const { return m_pSymInfo; }
9422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
9522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// symValue - initial value for stub's symbol
9637b74a387bb3993387029859c2d9d051c41c724eStephen Hines  virtual uint64_t initSymValue() const { return 0x0; }
9722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
9822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ///  -----  Fixup  -----  ///
9937b74a387bb3993387029859c2d9d051c41c724eStephen Hines  fixup_iterator fixup_begin() { return m_FixupList.begin(); }
10022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  const_fixup_iterator fixup_begin() const { return m_FixupList.begin(); }
10222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  fixup_iterator fixup_end() { return m_FixupList.end(); }
10422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
10537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  const_fixup_iterator fixup_end() const { return m_FixupList.end(); }
10622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
107b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  size_t fixup_size() const { return m_FixupList.size(); }
108b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines
109b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  virtual void applyFixup(Relocation& pSrcReloc,
110b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines                          IRBuilder& pBuilder,
111b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines                          BranchIsland& pIsland);
112b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines
113b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  virtual void applyFixup(FragmentRef& pSrcFragRef,
114b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines                          IRBuilder& pBuilder,
115b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines                          BranchIsland& pIsland);
116b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines
11722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// ----- modifiers ----- ///
11822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  void setSymInfo(ResolveInfo* pSymInfo);
11922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
12022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  // Stub is a kind of Fragment with type of Stub
12137b74a387bb3993387029859c2d9d051c41c724eStephen Hines  static bool classof(const Fragment* F) {
12237b74a387bb3993387029859c2d9d051c41c724eStephen Hines    return F->getKind() == Fragment::Stub;
12337b74a387bb3993387029859c2d9d051c41c724eStephen Hines  }
12422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
12537b74a387bb3993387029859c2d9d051c41c724eStephen Hines  static bool classof(const Stub*) { return true; }
12622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
12737b74a387bb3993387029859c2d9d051c41c724eStephen Hines protected:
12822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// addFixup - add a fixup for this stub to build a relocation
12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  void addFixup(DWord pOffset, SWord pAddend, Type pType);
13022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
13122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// addFixup - add a fixup from a existing fixup of the prototype
13222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  void addFixup(const Fixup& pFixup);
13322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
134b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  const FixupListType& getFixupList() const { return m_FixupList; }
135b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines  FixupListType&       getFixupList()       { return m_FixupList; }
136b0d0eb206527b43c771933602e147bbd7b471082Stephen Hines
13737b74a387bb3993387029859c2d9d051c41c724eStephen Hines private:
13822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  /// doClone - when adding a backend stub, we should implement this function
13922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  virtual Stub* doClone() = 0;
14022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
14137b74a387bb3993387029859c2d9d051c41c724eStephen Hines private:
14222add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  ResolveInfo* m_pSymInfo;
14322add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao  FixupListType m_FixupList;
14422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao};
14522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
14637b74a387bb3993387029859c2d9d051c41c724eStephen Hines}  // namespace mcld
14722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao
14837b74a387bb3993387029859c2d9d051c41c724eStephen Hines#endif  // MCLD_FRAGMENT_STUB_H_
149