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