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