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