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