• 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_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 
setSize(SizeType pSize)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 
setSymPtr(const LDSymbol * pSymPtr)135   void setSymPtr(const LDSymbol* pSymPtr)
136   { m_Ptr.sym_ptr = const_cast<LDSymbol*>(pSymPtr); }
137 
setLink(const ResolveInfo * pTarget)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 
other()182   uint8_t other() const
183   { return (uint8_t)visibility(); }
184 
185   Visibility visibility() const;
186 
outSymbol()187   LDSymbol* outSymbol()
188   { return m_Ptr.sym_ptr; }
189 
outSymbol()190   const LDSymbol* outSymbol() const
191   { return m_Ptr.sym_ptr; }
192 
link()193   ResolveInfo* link()
194   { return m_Ptr.info_ptr; }
195 
link()196   const ResolveInfo* link() const
197   { return m_Ptr.info_ptr; }
198 
size()199   SizeType size() const
200   { return m_Size; }
201 
name()202   const char* name() const
203   { return m_Name; }
204 
nameSize()205   unsigned int nameSize() const
206   { return (m_BitField >> NAME_LENGTH_OFFSET); }
207 
info()208   uint32_t info() const
209   { return (m_BitField & INFO_MASK); }
210 
bitfield()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