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 18 namespace mcld { 19 20 class 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 */ 37 class ResolveInfo 38 { 39 friend class FragmentLinker; 40 friend class IRBuilder; 41 public: 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 95 public: 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 setSize(SizeType pSize)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 setSymPtr(const LDSymbol * pSymPtr)137 void setSymPtr(const LDSymbol* pSymPtr) 138 { m_Ptr.sym_ptr = const_cast<LDSymbol*>(pSymPtr); } 139 setLink(const ResolveInfo * pTarget)140 void setLink(const ResolveInfo* pTarget) { 141 m_Ptr.info_ptr = const_cast<ResolveInfo*>(pTarget); 142 m_BitField |= indirect_flag; 143 } 144 145 146 // ----- observers ----- // 147 bool isNull() const; 148 149 bool isSymbol() const; 150 151 bool isString() const; 152 153 bool isGlobal() const; 154 155 bool isWeak() const; 156 157 bool isLocal() const; 158 159 bool isAbsolute() const; 160 161 bool isDefine() const; 162 163 bool isUndef() const; 164 165 bool isDyn() const; 166 167 bool isCommon() const; 168 169 bool isIndirect() const; 170 171 uint32_t type() const; 172 173 uint32_t desc() const; 174 175 uint32_t binding() const; 176 177 uint32_t reserved() const; 178 other()179 uint8_t other() const 180 { return (uint8_t)visibility(); } 181 182 Visibility visibility() const; 183 outSymbol()184 LDSymbol* outSymbol() 185 { return m_Ptr.sym_ptr; } 186 outSymbol()187 const LDSymbol* outSymbol() const 188 { return m_Ptr.sym_ptr; } 189 link()190 ResolveInfo* link() 191 { return m_Ptr.info_ptr; } 192 link()193 const ResolveInfo* link() const 194 { return m_Ptr.info_ptr; } 195 size()196 SizeType size() const 197 { return m_Size; } 198 name()199 const char* name() const 200 { return m_Name; } 201 nameSize()202 unsigned int nameSize() const 203 { return (m_BitField >> NAME_LENGTH_OFFSET); } 204 info()205 uint32_t info() const 206 { return (m_BitField & INFO_MASK); } 207 bitfield()208 uint32_t bitfield() const 209 { return m_BitField; } 210 211 // ----- For HashTable ----- // 212 bool compare(const key_type& pKey); 213 214 private: 215 static const uint32_t GLOBAL_OFFSET = 0; 216 static const uint32_t GLOBAL_MASK = 1; 217 218 static const uint32_t DYN_OFFSET = 1; 219 static const uint32_t DYN_MASK = 1 << DYN_OFFSET; 220 221 static const uint32_t DESC_OFFSET = 2; 222 static const uint32_t DESC_MASK = 0x3 << DESC_OFFSET; 223 224 static const uint32_t LOCAL_OFFSET = 4; 225 static const uint32_t LOCAL_MASK = 1 << LOCAL_OFFSET; 226 227 static const uint32_t BINDING_MASK = GLOBAL_MASK | LOCAL_MASK; 228 229 static const uint32_t VISIBILITY_OFFSET = 5; 230 static const uint32_t VISIBILITY_MASK = 0x3 << VISIBILITY_OFFSET; 231 232 static const uint32_t TYPE_OFFSET = 7; 233 static const uint32_t TYPE_MASK = 0xF << TYPE_OFFSET; 234 235 static const uint32_t SYMBOL_OFFSET = 11; 236 static const uint32_t SYMBOL_MASK = 1 << SYMBOL_OFFSET; 237 238 static const uint32_t RESERVED_OFFSET = 12; 239 static const uint32_t RESERVED_MASK = 0xF << RESERVED_OFFSET; 240 static const uint32_t NAME_LENGTH_OFFSET = 16; 241 static const uint32_t INFO_MASK = 0xF; 242 static const uint32_t RESOLVE_MASK = 0xFFFF; 243 244 union SymOrInfo { 245 LDSymbol* sym_ptr; 246 ResolveInfo* info_ptr; 247 }; 248 249 public: 250 static const uint32_t global_flag = 0 << GLOBAL_OFFSET; 251 static const uint32_t weak_flag = 1 << GLOBAL_OFFSET; 252 static const uint32_t regular_flag = 0 << DYN_OFFSET; 253 static const uint32_t dynamic_flag = 1 << DYN_OFFSET; 254 static const uint32_t undefine_flag = 0 << DESC_OFFSET; 255 static const uint32_t define_flag = 1 << DESC_OFFSET; 256 static const uint32_t common_flag = 2 << DESC_OFFSET; 257 static const uint32_t indirect_flag = 3 << DESC_OFFSET; 258 static const uint32_t local_flag = 1 << LOCAL_OFFSET; 259 static const uint32_t absolute_flag = BINDING_MASK; 260 static const uint32_t object_flag = Object << TYPE_OFFSET; 261 static const uint32_t function_flag = Function << TYPE_OFFSET; 262 static const uint32_t section_flag = Section << TYPE_OFFSET; 263 static const uint32_t file_flag = File << TYPE_OFFSET; 264 static const uint32_t string_flag = 0 << SYMBOL_OFFSET; 265 static const uint32_t symbol_flag = 1 << SYMBOL_OFFSET; 266 267 private: 268 ResolveInfo(); 269 ResolveInfo(const ResolveInfo& pCopy); 270 ResolveInfo& operator=(const ResolveInfo& pCopy); 271 ~ResolveInfo(); 272 273 private: 274 SizeType m_Size; 275 SymOrInfo m_Ptr; 276 277 /** m_BitField 278 * 31 ... 16 15 12 11 10..7 6 .. 5 4 3 2 1 0 279 * |length of m_Name|reserved|Symbol|Type |ELF visibility|Local|Com|Def|Dyn|Weak| 280 */ 281 uint32_t m_BitField; 282 char m_Name[]; 283 }; 284 285 } // namespace of mcld 286 287 #endif 288 289