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