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