1 //===- ResolveInfo.cpp ----------------------------------------------------===// 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 #include <mcld/LD/ResolveInfo.h> 10 #include <mcld/LD/LDSection.h> 11 #include <mcld/Support/GCFactory.h> 12 #include <llvm/Support/ManagedStatic.h> 13 #include <cstdlib> 14 #include <cstring> 15 16 using namespace mcld; 17 18 /// g_NullResolveInfo - a pointer to Null ResolveInfo. 19 static ResolveInfo* g_NullResolveInfo = NULL; 20 21 //===----------------------------------------------------------------------===// 22 // ResolveInfo 23 //===----------------------------------------------------------------------===// 24 ResolveInfo::ResolveInfo() 25 : m_Size(0), m_BitField(0) { 26 m_Ptr.sym_ptr = 0; 27 } 28 29 ResolveInfo::~ResolveInfo() 30 { 31 } 32 33 void ResolveInfo::override(const ResolveInfo& pFrom) 34 { 35 m_Size = pFrom.m_Size; 36 overrideAttributes(pFrom); 37 overrideVisibility(pFrom); 38 } 39 40 void ResolveInfo::overrideAttributes(const ResolveInfo& pFrom) 41 { 42 m_BitField &= ~RESOLVE_MASK; 43 m_BitField |= (pFrom.m_BitField & RESOLVE_MASK); 44 } 45 46 /// overrideVisibility - override the visibility 47 /// always use the most strict visibility 48 void ResolveInfo::overrideVisibility(const ResolveInfo& pFrom) 49 { 50 // Reference: Google gold linker: resolve.cc 51 // 52 // The rule for combining visibility is that we always choose the 53 // most constrained visibility. In order of increasing constraint, 54 // visibility goes PROTECTED, HIDDEN, INTERNAL. This is the reverse 55 // of the numeric values, so the effect is that we always want the 56 // smallest non-zero value. 57 // 58 // enum { 59 // STV_DEFAULT = 0, 60 // STV_INTERNAL = 1, 61 // STV_HIDDEN = 2, 62 // STV_PROTECTED = 3 63 // }; 64 65 Visibility from_vis = pFrom.visibility(); 66 Visibility cur_vis = visibility(); 67 if (0 != from_vis ) { 68 if (0 == cur_vis) 69 setVisibility(from_vis); 70 else if (cur_vis > from_vis) 71 setVisibility(from_vis); 72 } 73 } 74 75 void ResolveInfo::setRegular() 76 { 77 m_BitField &= (~dynamic_flag); 78 } 79 80 void ResolveInfo::setDynamic() 81 { 82 m_BitField |= dynamic_flag; 83 } 84 85 void ResolveInfo::setSource(bool pIsDyn) 86 { 87 if (pIsDyn) 88 m_BitField |= dynamic_flag; 89 else 90 m_BitField &= (~dynamic_flag); 91 } 92 93 void ResolveInfo::setType(uint32_t pType) 94 { 95 m_BitField &= ~TYPE_MASK; 96 m_BitField |= ((pType << TYPE_OFFSET) & TYPE_MASK); 97 } 98 99 void ResolveInfo::setDesc(uint32_t pDesc) 100 { 101 m_BitField &= ~DESC_MASK; 102 m_BitField |= ((pDesc << DESC_OFFSET) & DESC_MASK); 103 } 104 105 void ResolveInfo::setBinding(uint32_t pBinding) 106 { 107 m_BitField &= ~BINDING_MASK; 108 if (pBinding == Local || pBinding == Absolute) 109 m_BitField |= local_flag; 110 if (pBinding == Weak || pBinding == Absolute) 111 m_BitField |= weak_flag; 112 } 113 114 void ResolveInfo::setReserved(uint32_t pReserved) 115 { 116 m_BitField &= ~RESERVED_MASK; 117 m_BitField |= ((pReserved << RESERVED_OFFSET) & RESERVED_MASK); 118 } 119 120 void ResolveInfo::setOther(uint32_t pOther) 121 { 122 setVisibility(static_cast<ResolveInfo::Visibility>(pOther & 0x3)); 123 } 124 125 void ResolveInfo::setVisibility(ResolveInfo::Visibility pVisibility) 126 { 127 m_BitField &= ~VISIBILITY_MASK; 128 m_BitField |= pVisibility << VISIBILITY_OFFSET; 129 } 130 131 void ResolveInfo::setIsSymbol(bool pIsSymbol) 132 { 133 if (pIsSymbol) 134 m_BitField |= symbol_flag; 135 else 136 m_BitField &= ~symbol_flag; 137 } 138 139 bool ResolveInfo::isNull() const 140 { 141 return (this == Null()); 142 } 143 144 bool ResolveInfo::isDyn() const 145 { 146 return (dynamic_flag == (m_BitField & DYN_MASK)); 147 } 148 149 bool ResolveInfo::isUndef() const 150 { 151 return (undefine_flag == (m_BitField & DESC_MASK)); 152 } 153 154 bool ResolveInfo::isDefine() const 155 { 156 return (define_flag == (m_BitField & DESC_MASK)); 157 } 158 159 bool ResolveInfo::isCommon() const 160 { 161 return (common_flag == (m_BitField & DESC_MASK)); 162 } 163 164 bool ResolveInfo::isIndirect() const 165 { 166 return (indirect_flag == (m_BitField & DESC_MASK)); 167 } 168 169 // isGlobal - [L,W] == [0, 0] 170 bool ResolveInfo::isGlobal() const 171 { 172 return (global_flag == (m_BitField & BINDING_MASK)); 173 } 174 175 // isWeak - [L,W] == [0, 1] 176 bool ResolveInfo::isWeak() const 177 { 178 return (weak_flag == (m_BitField & BINDING_MASK)); 179 } 180 181 // isLocal - [L,W] == [1, 0] 182 bool ResolveInfo::isLocal() const 183 { 184 return (local_flag == (m_BitField & BINDING_MASK)); 185 } 186 187 // isAbsolute - [L,W] == [1, 1] 188 bool ResolveInfo::isAbsolute() const 189 { 190 return (absolute_flag == (m_BitField & BINDING_MASK)); 191 } 192 193 bool ResolveInfo::isSymbol() const 194 { 195 return (symbol_flag == (m_BitField & SYMBOL_MASK)); 196 } 197 198 bool ResolveInfo::isString() const 199 { 200 return (string_flag == (m_BitField & SYMBOL_MASK)); 201 } 202 203 uint32_t ResolveInfo::type() const 204 { 205 return (m_BitField & TYPE_MASK) >> TYPE_OFFSET; 206 } 207 208 uint32_t ResolveInfo::desc() const 209 { 210 return (m_BitField & DESC_MASK) >> DESC_OFFSET; 211 } 212 213 uint32_t ResolveInfo::binding() const 214 { 215 if (m_BitField & LOCAL_MASK) { 216 if (m_BitField & GLOBAL_MASK) { 217 return ResolveInfo::Absolute; 218 } 219 return ResolveInfo::Local; 220 } 221 return m_BitField & GLOBAL_MASK; 222 } 223 224 uint32_t ResolveInfo::reserved() const 225 { 226 return (m_BitField & RESERVED_MASK) >> RESERVED_OFFSET; 227 } 228 229 ResolveInfo::Visibility ResolveInfo::visibility() const 230 { 231 return static_cast<ResolveInfo::Visibility>((m_BitField & VISIBILITY_MASK) >> VISIBILITY_OFFSET); 232 } 233 234 bool ResolveInfo::compare(const ResolveInfo::key_type& pKey) 235 { 236 size_t length = nameSize(); 237 if (length != pKey.size()) 238 return false; 239 return (0 == std::memcmp(m_Name, pKey.data(), length)); 240 } 241 242 //===----------------------------------------------------------------------===// 243 // ResolveInfo Factory Methods 244 //===----------------------------------------------------------------------===// 245 ResolveInfo* ResolveInfo::Create(const ResolveInfo::key_type& pKey) 246 { 247 ResolveInfo* result = static_cast<ResolveInfo*>( 248 malloc(sizeof(ResolveInfo)+pKey.size()+1)); 249 if (NULL == result) 250 return NULL; 251 252 new (result) ResolveInfo(); 253 std::memcpy(result->m_Name, pKey.data(), pKey.size()); 254 result->m_Name[pKey.size()] = '\0'; 255 result->m_BitField &= ~ResolveInfo::RESOLVE_MASK; 256 result->m_BitField |= (pKey.size() << ResolveInfo::NAME_LENGTH_OFFSET); 257 return result; 258 } 259 260 void ResolveInfo::Destroy(ResolveInfo*& pInfo) 261 { 262 if (pInfo->isNull()) 263 return; 264 265 if (NULL != pInfo) { 266 pInfo->~ResolveInfo(); 267 free(pInfo); 268 } 269 270 pInfo = NULL; 271 } 272 273 ResolveInfo* ResolveInfo::Null() 274 { 275 if (NULL == g_NullResolveInfo) { 276 g_NullResolveInfo = static_cast<ResolveInfo*>( 277 malloc(sizeof(ResolveInfo) + 1)); 278 new (g_NullResolveInfo) ResolveInfo(); 279 g_NullResolveInfo->m_Name[0] = '\0'; 280 g_NullResolveInfo->m_BitField = 0x0; 281 g_NullResolveInfo->setBinding(Local); 282 } 283 return g_NullResolveInfo; 284 } 285 286 287