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
15namespace mcld {
16
17class LDSymbol;
18class 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 */
35class ResolveInfo
36{
37friend class FragmentLinker;
38friend class IRBuilder;
39public:
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
93public:
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
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
135  void setSymPtr(const LDSymbol* pSymPtr)
136  { m_Ptr.sym_ptr = const_cast<LDSymbol*>(pSymPtr); }
137
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
182  uint8_t other() const
183  { return (uint8_t)visibility(); }
184
185  Visibility visibility() const;
186
187  LDSymbol* outSymbol()
188  { return m_Ptr.sym_ptr; }
189
190  const LDSymbol* outSymbol() const
191  { return m_Ptr.sym_ptr; }
192
193  ResolveInfo* link()
194  { return m_Ptr.info_ptr; }
195
196  const ResolveInfo* link() const
197  { return m_Ptr.info_ptr; }
198
199  SizeType size() const
200  { return m_Size; }
201
202  const char* name() const
203  { return m_Name; }
204
205  unsigned int nameSize() const
206  { return (m_BitField >> NAME_LENGTH_OFFSET); }
207
208  uint32_t info() const
209  { return (m_BitField & INFO_MASK); }
210
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
220private:
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
259public:
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
278private:
279  ResolveInfo();
280  ResolveInfo(const ResolveInfo& pCopy);
281  ResolveInfo& operator=(const ResolveInfo& pCopy);
282  ~ResolveInfo();
283
284private:
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