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