Home | History | Annotate | Download | only in Fragment
      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:
     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