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 16using namespace mcld; 17 18/// g_NullResolveInfo - a pointer to Null ResolveInfo. 19static ResolveInfo* g_NullResolveInfo = NULL; 20 21//===----------------------------------------------------------------------===// 22// ResolveInfo 23//===----------------------------------------------------------------------===// 24ResolveInfo::ResolveInfo() 25 : m_Size(0), m_BitField(0) { 26 m_Ptr.sym_ptr = 0; 27} 28 29ResolveInfo::~ResolveInfo() 30{ 31} 32 33void ResolveInfo::override(const ResolveInfo& pFrom) 34{ 35 m_Size = pFrom.m_Size; 36 overrideAttributes(pFrom); 37 overrideVisibility(pFrom); 38} 39 40void 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 48void 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 75void ResolveInfo::setRegular() 76{ 77 m_BitField &= (~dynamic_flag); 78} 79 80void ResolveInfo::setDynamic() 81{ 82 m_BitField |= dynamic_flag; 83} 84 85void ResolveInfo::setSource(bool pIsDyn) 86{ 87 if (pIsDyn) 88 m_BitField |= dynamic_flag; 89 else 90 m_BitField &= (~dynamic_flag); 91} 92 93void ResolveInfo::setType(uint32_t pType) 94{ 95 m_BitField &= ~TYPE_MASK; 96 m_BitField |= ((pType << TYPE_OFFSET) & TYPE_MASK); 97} 98 99void ResolveInfo::setDesc(uint32_t pDesc) 100{ 101 m_BitField &= ~DESC_MASK; 102 m_BitField |= ((pDesc << DESC_OFFSET) & DESC_MASK); 103} 104 105void 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 114void ResolveInfo::setReserved(uint32_t pReserved) 115{ 116 m_BitField &= ~RESERVED_MASK; 117 m_BitField |= ((pReserved << RESERVED_OFFSET) & RESERVED_MASK); 118} 119 120void ResolveInfo::setOther(uint32_t pOther) 121{ 122 setVisibility(static_cast<ResolveInfo::Visibility>(pOther & 0x3)); 123} 124 125void ResolveInfo::setVisibility(ResolveInfo::Visibility pVisibility) 126{ 127 m_BitField &= ~VISIBILITY_MASK; 128 m_BitField |= pVisibility << VISIBILITY_OFFSET; 129} 130 131void ResolveInfo::setIsSymbol(bool pIsSymbol) 132{ 133 if (pIsSymbol) 134 m_BitField |= symbol_flag; 135 else 136 m_BitField &= ~symbol_flag; 137} 138 139bool ResolveInfo::isNull() const 140{ 141 return (this == Null()); 142} 143 144bool ResolveInfo::isDyn() const 145{ 146 return (dynamic_flag == (m_BitField & DYN_MASK)); 147} 148 149bool ResolveInfo::isUndef() const 150{ 151 return (undefine_flag == (m_BitField & DESC_MASK)); 152} 153 154bool ResolveInfo::isDefine() const 155{ 156 return (define_flag == (m_BitField & DESC_MASK)); 157} 158 159bool ResolveInfo::isCommon() const 160{ 161 return (common_flag == (m_BitField & DESC_MASK)); 162} 163 164bool ResolveInfo::isIndirect() const 165{ 166 return (indirect_flag == (m_BitField & DESC_MASK)); 167} 168 169// isGlobal - [L,W] == [0, 0] 170bool ResolveInfo::isGlobal() const 171{ 172 return (global_flag == (m_BitField & BINDING_MASK)); 173} 174 175// isWeak - [L,W] == [0, 1] 176bool ResolveInfo::isWeak() const 177{ 178 return (weak_flag == (m_BitField & BINDING_MASK)); 179} 180 181// isLocal - [L,W] == [1, 0] 182bool ResolveInfo::isLocal() const 183{ 184 return (local_flag == (m_BitField & BINDING_MASK)); 185} 186 187// isAbsolute - [L,W] == [1, 1] 188bool ResolveInfo::isAbsolute() const 189{ 190 return (absolute_flag == (m_BitField & BINDING_MASK)); 191} 192 193bool ResolveInfo::isSymbol() const 194{ 195 return (symbol_flag == (m_BitField & SYMBOL_MASK)); 196} 197 198bool ResolveInfo::isString() const 199{ 200 return (string_flag == (m_BitField & SYMBOL_MASK)); 201} 202 203uint32_t ResolveInfo::type() const 204{ 205 return (m_BitField & TYPE_MASK) >> TYPE_OFFSET; 206} 207 208uint32_t ResolveInfo::desc() const 209{ 210 return (m_BitField & DESC_MASK) >> DESC_OFFSET; 211} 212 213uint32_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 224uint32_t ResolveInfo::reserved() const 225{ 226 return (m_BitField & RESERVED_MASK) >> RESERVED_OFFSET; 227} 228 229ResolveInfo::Visibility ResolveInfo::visibility() const 230{ 231 return static_cast<ResolveInfo::Visibility>((m_BitField & VISIBILITY_MASK) >> VISIBILITY_OFFSET); 232} 233 234bool 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//===----------------------------------------------------------------------===// 245ResolveInfo* 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 260void 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 273ResolveInfo* 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