ResolveInfo.h revision 22add6ff3426df1a85089fe6a6e1597ee3b6f300
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 points 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; 40public: 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 { 69 Undefined = 0, 70 Define = 1, 71 Common = 2, 72 Indirect = 3, 73 NoneDesc 74 }; 75 76 enum Binding { 77 Global = 0, 78 Weak = 1, 79 Local = 2, 80 Absolute = 3, 81 NoneBinding 82 }; 83 84 enum Visibility { 85 Default = 0, 86 Internal = 1, 87 Hidden = 2, 88 Protected = 3 89 }; 90 91 // ----- For HashTable ----- // 92 typedef llvm::StringRef key_type; 93 94public: 95 // ----- factory method ----- // 96 static ResolveInfo* Create(const key_type& pKey); 97 98 static void Destroy(ResolveInfo*& pInfo); 99 100 static ResolveInfo* Null(); 101 102 // ----- modifiers ----- // 103 /// setRegular - set the source of the file is a regular object 104 void setRegular(); 105 106 /// setDynamic - set the source of the file is a dynamic object 107 void setDynamic(); 108 109 /// setSource - set the source of the file 110 /// @param pIsDyn is the source from a dynamic object? 111 void setSource(bool pIsDyn); 112 113 void setType(uint32_t pType); 114 115 void setDesc(uint32_t pDesc); 116 117 void setBinding(uint32_t pBinding); 118 119 void setOther(uint32_t pOther); 120 121 void setVisibility(Visibility pVisibility); 122 123 void setIsSymbol(bool pIsSymbol); 124 125 void setReserved(uint32_t pReserved); 126 127 void setSize(SizeType pSize) 128 { m_Size = pSize; } 129 130 void override(const ResolveInfo& pForm); 131 132 void overrideAttributes(const ResolveInfo& pFrom); 133 134 void overrideVisibility(const ResolveInfo& pFrom); 135 136 void setSymPtr(const LDSymbol* pSymPtr) 137 { m_Ptr.sym_ptr = const_cast<LDSymbol*>(pSymPtr); } 138 139 void setLink(const ResolveInfo* pTarget) { 140 m_Ptr.info_ptr = const_cast<ResolveInfo*>(pTarget); 141 m_BitField |= indirect_flag; 142 } 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