ResolveInfo.h revision 87f34658dec9097d987d254a990ea7f311bfc95f
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#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; 21class LinkerConfig; 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 refers 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, FragmentLinker 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 FragmentLinker; 41friend class IRBuilder; 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 // ----- factory method ----- // 98 static ResolveInfo* Create(const key_type& pKey); 99 100 static void Destroy(ResolveInfo*& pInfo); 101 102 static ResolveInfo* Null(); 103 104 // ----- modifiers ----- // 105 /// setRegular - set the source of the file is a regular object 106 void setRegular(); 107 108 /// setDynamic - set the source of the file is a dynamic object 109 void setDynamic(); 110 111 /// setSource - set the source of the file 112 /// @param pIsDyn is the source from a dynamic object? 113 void setSource(bool pIsDyn); 114 115 void setType(uint32_t pType); 116 117 void setDesc(uint32_t pDesc); 118 119 void setBinding(uint32_t pBinding); 120 121 void setOther(uint32_t pOther); 122 123 void setVisibility(Visibility pVisibility); 124 125 void setIsSymbol(bool pIsSymbol); 126 127 void setReserved(uint32_t pReserved); 128 129 void setSize(SizeType pSize) 130 { m_Size = pSize; } 131 132 void override(const ResolveInfo& pForm); 133 134 void overrideAttributes(const ResolveInfo& pFrom); 135 136 void overrideVisibility(const ResolveInfo& pFrom); 137 138 void setSymPtr(const LDSymbol* pSymPtr) 139 { m_Ptr.sym_ptr = const_cast<LDSymbol*>(pSymPtr); } 140 141 void setLink(const ResolveInfo* pTarget) { 142 m_Ptr.info_ptr = const_cast<ResolveInfo*>(pTarget); 143 m_BitField |= indirect_flag; 144 } 145 146 /// setInDyn - set if the symbol has been seen in the dynamic objects. Once 147 /// InDyn set, then it won't be set back to false 148 void setInDyn(); 149 150 // ----- observers ----- // 151 bool isNull() const; 152 153 bool isSymbol() const; 154 155 bool isString() const; 156 157 bool isGlobal() const; 158 159 bool isWeak() const; 160 161 bool isLocal() const; 162 163 bool isAbsolute() const; 164 165 bool isDefine() const; 166 167 bool isUndef() const; 168 169 bool isDyn() const; 170 171 bool isCommon() const; 172 173 bool isIndirect() const; 174 175 bool isInDyn() const; 176 177 uint32_t type() const; 178 179 uint32_t desc() const; 180 181 uint32_t binding() const; 182 183 uint32_t reserved() const; 184 185 uint8_t other() const 186 { return (uint8_t)visibility(); } 187 188 Visibility visibility() const; 189 190 LDSymbol* outSymbol() 191 { return m_Ptr.sym_ptr; } 192 193 const LDSymbol* outSymbol() const 194 { return m_Ptr.sym_ptr; } 195 196 ResolveInfo* link() 197 { return m_Ptr.info_ptr; } 198 199 const ResolveInfo* link() const 200 { return m_Ptr.info_ptr; } 201 202 SizeType size() const 203 { return m_Size; } 204 205 const char* name() const 206 { return m_Name; } 207 208 unsigned int nameSize() const 209 { return (m_BitField >> NAME_LENGTH_OFFSET); } 210 211 uint32_t info() const 212 { return (m_BitField & INFO_MASK); } 213 214 uint32_t bitfield() const 215 { return m_BitField; } 216 217 // shouldForceLocal - check if this symbol should be forced to local 218 bool shouldForceLocal(const LinkerConfig& pConfig); 219 220 // ----- For HashTable ----- // 221 bool compare(const key_type& pKey); 222 223private: 224 static const uint32_t GLOBAL_OFFSET = 0; 225 static const uint32_t GLOBAL_MASK = 1; 226 227 static const uint32_t DYN_OFFSET = 1; 228 static const uint32_t DYN_MASK = 1 << DYN_OFFSET; 229 230 static const uint32_t DESC_OFFSET = 2; 231 static const uint32_t DESC_MASK = 0x3 << DESC_OFFSET; 232 233 static const uint32_t LOCAL_OFFSET = 4; 234 static const uint32_t LOCAL_MASK = 1 << LOCAL_OFFSET; 235 236 static const uint32_t BINDING_MASK = GLOBAL_MASK | LOCAL_MASK; 237 238 static const uint32_t VISIBILITY_OFFSET = 5; 239 static const uint32_t VISIBILITY_MASK = 0x3 << VISIBILITY_OFFSET; 240 241 static const uint32_t TYPE_OFFSET = 7; 242 static const uint32_t TYPE_MASK = 0xF << TYPE_OFFSET; 243 244 static const uint32_t SYMBOL_OFFSET = 11; 245 static const uint32_t SYMBOL_MASK = 1 << SYMBOL_OFFSET; 246 247 static const uint32_t RESERVED_OFFSET = 12; 248 static const uint32_t RESERVED_MASK = 0xF << RESERVED_OFFSET; 249 250 static const uint32_t IN_DYN_OFFSET = 16; 251 static const uint32_t IN_DYN_MASK = 1 << IN_DYN_OFFSET; 252 253 static const uint32_t NAME_LENGTH_OFFSET = 17; 254 static const uint32_t INFO_MASK = 0xF; 255 static const uint32_t RESOLVE_MASK = 0xFFFF; 256 257 union SymOrInfo { 258 LDSymbol* sym_ptr; 259 ResolveInfo* info_ptr; 260 }; 261 262public: 263 static const uint32_t global_flag = 0 << GLOBAL_OFFSET; 264 static const uint32_t weak_flag = 1 << GLOBAL_OFFSET; 265 static const uint32_t regular_flag = 0 << DYN_OFFSET; 266 static const uint32_t dynamic_flag = 1 << DYN_OFFSET; 267 static const uint32_t undefine_flag = 0 << DESC_OFFSET; 268 static const uint32_t define_flag = 1 << DESC_OFFSET; 269 static const uint32_t common_flag = 2 << DESC_OFFSET; 270 static const uint32_t indirect_flag = 3 << DESC_OFFSET; 271 static const uint32_t local_flag = 1 << LOCAL_OFFSET; 272 static const uint32_t absolute_flag = BINDING_MASK; 273 static const uint32_t object_flag = Object << TYPE_OFFSET; 274 static const uint32_t function_flag = Function << TYPE_OFFSET; 275 static const uint32_t section_flag = Section << TYPE_OFFSET; 276 static const uint32_t file_flag = File << TYPE_OFFSET; 277 static const uint32_t string_flag = 0 << SYMBOL_OFFSET; 278 static const uint32_t symbol_flag = 1 << SYMBOL_OFFSET; 279 static const uint32_t indyn_flag = 1 << IN_DYN_OFFSET; 280 281private: 282 ResolveInfo(); 283 ResolveInfo(const ResolveInfo& pCopy); 284 ResolveInfo& operator=(const ResolveInfo& pCopy); 285 ~ResolveInfo(); 286 287private: 288 SizeType m_Size; 289 SymOrInfo m_Ptr; 290 291 /** m_BitField 292 * 31 ... 17 16 15 12 11 10..7 6 .. 5 4 3 2 1 0 293 * |length of m_Name|InDyn|reserved|Symbol|Type |ELF visibility|Local|Com|Def|Dyn|Weak| 294 */ 295 uint32_t m_BitField; 296 char m_Name[]; 297}; 298 299} // namespace of mcld 300 301#endif 302 303