• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
setSize(SizeType pSize)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 
setSymPtr(const LDSymbol * pSymPtr)131   void setSymPtr(const LDSymbol* pSymPtr)
132   { m_Ptr.sym_ptr = const_cast<LDSymbol*>(pSymPtr); }
133 
setLink(const ResolveInfo * pTarget)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 
other()171   uint8_t other() const
172   { return (uint8_t)visibility(); }
173 
174   Visibility visibility() const;
175 
outSymbol()176   LDSymbol* outSymbol()
177   { return m_Ptr.sym_ptr; }
178 
outSymbol()179   const LDSymbol* outSymbol() const
180   { return m_Ptr.sym_ptr; }
181 
link()182   ResolveInfo* link()
183   { return m_Ptr.info_ptr; }
184 
link()185   const ResolveInfo* link() const
186   { return m_Ptr.info_ptr; }
187 
size()188   SizeType size() const
189   { return m_Size; }
190 
name()191   const char* name() const
192   { return m_Name; }
193 
nameSize()194   unsigned int nameSize() const
195   { return (m_BitField >> NAME_LENGTH_OFFSET); }
196 
info()197   uint32_t info() const
198   { return (m_BitField & INFO_MASK); }
199 
bitfield()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