Home | History | Annotate | Download | only in LD
      1 //===- ResolveInfo.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 #ifndef MCLD_LD_RESOLVEINFO_H_
     10 #define MCLD_LD_RESOLVEINFO_H_
     11 
     12 #include <llvm/ADT/StringRef.h>
     13 #include <llvm/Support/DataTypes.h>
     14 
     15 namespace mcld {
     16 
     17 class LDSymbol;
     18 class LinkerConfig;
     19 
     20 /** \class ResolveInfo
     21  *  \brief ResolveInfo records the information about how to resolve a symbol.
     22  *
     23  *  A symbol must have some `attributes':
     24  *  - Desc - Defined, Reference, Common or Indirect
     25  *  - Binding - Global, Local, Weak
     26  *  - IsDyn - appear in dynamic objects or regular objects
     27  *  - Type - what the symbol refers to
     28  *  - Size  - the size of the symbol point to
     29  *  - Value - the pointer to another LDSymbol
     30  *  In order to save the memory and speed up the performance, FragmentLinker
     31  *uses
     32  *  a bit field to store all attributes.
     33  *
     34  *  The maximum string length is (2^16 - 1)
     35  */
     36 class ResolveInfo {
     37   friend class FragmentLinker;
     38   friend class IRBuilder;
     39 
     40  public:
     41   typedef uint64_t SizeType;
     42 
     43   /** \enum Type
     44    *  \brief What the symbol stand for
     45    *
     46    *  It is like ELF32_ST_TYPE
     47    *  MachO does not need this, and can not jump between Thumb and ARM code.
     48    */
     49   enum Type {
     50     NoType = 0,
     51     Object = 1,
     52     Function = 2,
     53     Section = 3,
     54     File = 4,
     55     CommonBlock = 5,
     56     ThreadLocal = 6,
     57     IndirectFunc = 10,
     58     LoProc = 13,
     59     HiProc = 15
     60   };
     61 
     62   /** \enum Desc
     63    *  \brief Description of the symbols.
     64    *
     65    *   Follow the naming in MachO. Like MachO nlist::n_desc
     66    *   In ELF, is a part of st_shndx
     67    */
     68   enum Desc { Undefined = 0, Define = 1, Common = 2, Indirect = 3, NoneDesc };
     69 
     70   enum Binding { Global = 0, Weak = 1, Local = 2, Absolute = 3, NoneBinding };
     71 
     72   enum Visibility { Default = 0, Internal = 1, Hidden = 2, Protected = 3 };
     73 
     74   // -----  For HashTable  ----- //
     75   typedef llvm::StringRef key_type;
     76 
     77  public:
     78   // -----  factory method  ----- //
     79   static ResolveInfo* Create(const key_type& pKey);
     80 
     81   static void Destroy(ResolveInfo*& pInfo);
     82 
     83   static ResolveInfo* Null();
     84 
     85   // -----  modifiers  ----- //
     86   /// setRegular - set the source of the file is a regular object
     87   void setRegular();
     88 
     89   /// setDynamic - set the source of the file is a dynamic object
     90   void setDynamic();
     91 
     92   /// setSource - set the source of the file
     93   /// @param pIsDyn is the source from a dynamic object?
     94   void setSource(bool pIsDyn);
     95 
     96   void setType(uint32_t pType);
     97 
     98   void setDesc(uint32_t pDesc);
     99 
    100   void setBinding(uint32_t pBinding);
    101 
    102   void setOther(uint32_t pOther);
    103 
    104   void setVisibility(Visibility pVisibility);
    105 
    106   void setIsSymbol(bool pIsSymbol);
    107 
    108   void setReserved(uint32_t pReserved);
    109 
    110   void setSize(SizeType pSize) { m_Size = pSize; }
    111 
    112   void override(const ResolveInfo& pForm);
    113 
    114   void overrideAttributes(const ResolveInfo& pFrom);
    115 
    116   void overrideVisibility(const ResolveInfo& pFrom);
    117 
    118   void setSymPtr(const LDSymbol* pSymPtr) {
    119     m_Ptr.sym_ptr = const_cast<LDSymbol*>(pSymPtr);
    120   }
    121 
    122   void setLink(const ResolveInfo* pTarget) {
    123     m_Ptr.info_ptr = const_cast<ResolveInfo*>(pTarget);
    124     m_BitField |= indirect_flag;
    125   }
    126 
    127   /// setInDyn - set if the symbol has been seen in the dynamic objects. Once
    128   /// InDyn set, then it won't be set back to false
    129   void setInDyn();
    130 
    131   // -----  observers  ----- //
    132   bool isNull() const;
    133 
    134   bool isSymbol() const;
    135 
    136   bool isString() const;
    137 
    138   bool isGlobal() const;
    139 
    140   bool isWeak() const;
    141 
    142   bool isLocal() const;
    143 
    144   bool isAbsolute() const;
    145 
    146   bool isDefine() const;
    147 
    148   bool isUndef() const;
    149 
    150   bool isDyn() const;
    151 
    152   bool isCommon() const;
    153 
    154   bool isIndirect() const;
    155 
    156   bool isInDyn() const;
    157 
    158   uint32_t type() const;
    159 
    160   uint32_t desc() const;
    161 
    162   uint32_t binding() const;
    163 
    164   uint32_t reserved() const;
    165 
    166   uint8_t other() const { return (uint8_t)visibility(); }
    167 
    168   Visibility visibility() const;
    169 
    170   LDSymbol* outSymbol() { return m_Ptr.sym_ptr; }
    171 
    172   const LDSymbol* outSymbol() const { return m_Ptr.sym_ptr; }
    173 
    174   ResolveInfo* link() { return m_Ptr.info_ptr; }
    175 
    176   const ResolveInfo* link() const { return m_Ptr.info_ptr; }
    177 
    178   SizeType size() const { return m_Size; }
    179 
    180   const char* name() const { return m_Name; }
    181 
    182   unsigned int nameSize() const { return (m_BitField >> NAME_LENGTH_OFFSET); }
    183 
    184   uint32_t info() const { return (m_BitField & INFO_MASK); }
    185 
    186   uint32_t bitfield() const { return m_BitField; }
    187 
    188   // shouldForceLocal - check if this symbol should be forced to local
    189   bool shouldForceLocal(const LinkerConfig& pConfig);
    190 
    191   // -----  For HashTable  ----- //
    192   bool compare(const key_type& pKey);
    193 
    194  private:
    195   static const uint32_t GLOBAL_OFFSET = 0;
    196   static const uint32_t GLOBAL_MASK = 1;
    197 
    198   static const uint32_t DYN_OFFSET = 1;
    199   static const uint32_t DYN_MASK = 1 << DYN_OFFSET;
    200 
    201   static const uint32_t DESC_OFFSET = 2;
    202   static const uint32_t DESC_MASK = 0x3 << DESC_OFFSET;
    203 
    204   static const uint32_t LOCAL_OFFSET = 4;
    205   static const uint32_t LOCAL_MASK = 1 << LOCAL_OFFSET;
    206 
    207   static const uint32_t BINDING_MASK = GLOBAL_MASK | LOCAL_MASK;
    208 
    209   static const uint32_t VISIBILITY_OFFSET = 5;
    210   static const uint32_t VISIBILITY_MASK = 0x3 << VISIBILITY_OFFSET;
    211 
    212   static const uint32_t TYPE_OFFSET = 7;
    213   static const uint32_t TYPE_MASK = 0xF << TYPE_OFFSET;
    214 
    215   static const uint32_t SYMBOL_OFFSET = 11;
    216   static const uint32_t SYMBOL_MASK = 1 << SYMBOL_OFFSET;
    217 
    218   static const uint32_t RESERVED_OFFSET = 12;
    219   static const uint32_t RESERVED_MASK = 0xF << RESERVED_OFFSET;
    220 
    221   static const uint32_t IN_DYN_OFFSET = 16;
    222   static const uint32_t IN_DYN_MASK = 1 << IN_DYN_OFFSET;
    223 
    224   static const uint32_t NAME_LENGTH_OFFSET = 17;
    225   static const uint32_t INFO_MASK = 0xF;
    226   static const uint32_t RESOLVE_MASK = 0xFFFF;
    227 
    228   union SymOrInfo {
    229     LDSymbol* sym_ptr;
    230     ResolveInfo* info_ptr;
    231   };
    232 
    233  public:
    234   static const uint32_t global_flag = 0 << GLOBAL_OFFSET;
    235   static const uint32_t weak_flag = 1 << GLOBAL_OFFSET;
    236   static const uint32_t regular_flag = 0 << DYN_OFFSET;
    237   static const uint32_t dynamic_flag = 1 << DYN_OFFSET;
    238   static const uint32_t undefine_flag = 0 << DESC_OFFSET;
    239   static const uint32_t define_flag = 1 << DESC_OFFSET;
    240   static const uint32_t common_flag = 2 << DESC_OFFSET;
    241   static const uint32_t indirect_flag = 3 << DESC_OFFSET;
    242   static const uint32_t local_flag = 1 << LOCAL_OFFSET;
    243   static const uint32_t absolute_flag = BINDING_MASK;
    244   static const uint32_t object_flag = Object << TYPE_OFFSET;
    245   static const uint32_t function_flag = Function << TYPE_OFFSET;
    246   static const uint32_t section_flag = Section << TYPE_OFFSET;
    247   static const uint32_t file_flag = File << TYPE_OFFSET;
    248   static const uint32_t string_flag = 0 << SYMBOL_OFFSET;
    249   static const uint32_t symbol_flag = 1 << SYMBOL_OFFSET;
    250   static const uint32_t indyn_flag = 1 << IN_DYN_OFFSET;
    251 
    252  private:
    253   ResolveInfo();
    254   ResolveInfo(const ResolveInfo& pCopy);
    255   ResolveInfo& operator=(const ResolveInfo& pCopy);
    256   ~ResolveInfo();
    257 
    258  private:
    259   SizeType m_Size;
    260   SymOrInfo m_Ptr;
    261 
    262   /** m_BitField
    263    *  31     ...    17 16    15    12 11     10..7 6      ..    5 4     3   2
    264    * 1   0
    265    * |length of m_Name|InDyn|reserved|Symbol|Type |ELF
    266    * visibility|Local|Com|Def|Dyn|Weak|
    267    */
    268   uint32_t m_BitField;
    269   char m_Name[];
    270 };
    271 
    272 }  // namespace mcld
    273 
    274 #endif  // MCLD_LD_RESOLVEINFO_H_
    275