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