ResolveInfo.h revision f7ac0f19a1c8d0ad14bcf6456ce368b830fea886
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
18namespace mcld {
19
20class 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 */
37class ResolveInfo
38{
39friend class FragmentLinker;
40friend class IRBuilder;
41public:
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
95public:
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
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
137  void setSymPtr(const LDSymbol* pSymPtr)
138  { m_Ptr.sym_ptr = const_cast<LDSymbol*>(pSymPtr); }
139
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
178  uint8_t other() const
179  { return (uint8_t)visibility(); }
180
181  Visibility visibility() const;
182
183  LDSymbol* outSymbol()
184  { return m_Ptr.sym_ptr; }
185
186  const LDSymbol* outSymbol() const
187  { return m_Ptr.sym_ptr; }
188
189  ResolveInfo* link()
190  { return m_Ptr.info_ptr; }
191
192  const ResolveInfo* link() const
193  { return m_Ptr.info_ptr; }
194
195  SizeType size() const
196  { return m_Size; }
197
198  const char* name() const
199  { return m_Name; }
200
201  unsigned int nameSize() const
202  { return (m_BitField >> NAME_LENGTH_OFFSET); }
203
204  uint32_t info() const
205  { return (m_BitField & INFO_MASK); }
206
207  uint32_t bitfield() const
208  { return m_BitField; }
209
210  // -----  For HashTable  ----- //
211  bool compare(const key_type& pKey);
212
213private:
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
248public:
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
266private:
267  ResolveInfo();
268  ResolveInfo(const ResolveInfo& pCopy);
269  ResolveInfo& operator=(const ResolveInfo& pCopy);
270  ~ResolveInfo();
271
272private:
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