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 11 #include "mcld/LinkerConfig.h" 12 #include "mcld/LD/LDSection.h" 13 #include "mcld/Support/GCFactory.h" 14 15 #include <llvm/Support/ManagedStatic.h> 16 17 #include <cstdlib> 18 #include <cstring> 19 20 namespace mcld { 21 22 /// g_NullResolveInfo - a pointer to Null ResolveInfo. 23 static ResolveInfo* g_NullResolveInfo = NULL; 24 25 //===----------------------------------------------------------------------===// 26 // ResolveInfo 27 //===----------------------------------------------------------------------===// 28 ResolveInfo::ResolveInfo() : m_Size(0), m_BitField(0) { 29 m_Ptr.sym_ptr = 0; 30 } 31 32 ResolveInfo::~ResolveInfo() { 33 } 34 35 void ResolveInfo::override(const ResolveInfo& pFrom) { 36 m_Size = pFrom.m_Size; 37 overrideAttributes(pFrom); 38 overrideVisibility(pFrom); 39 } 40 41 void ResolveInfo::overrideAttributes(const ResolveInfo& pFrom) { 42 m_BitField &= ~RESOLVE_MASK | VISIBILITY_MASK; 43 m_BitField |= (pFrom.m_BitField & (RESOLVE_MASK & ~VISIBILITY_MASK)); 44 } 45 46 /// overrideVisibility - override the visibility 47 /// always use the most strict visibility 48 void ResolveInfo::overrideVisibility(const ResolveInfo& pFrom) { 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 (from_vis != 0) { 65 if (cur_vis == 0) 66 setVisibility(from_vis); 67 else if (cur_vis > from_vis) 68 setVisibility(from_vis); 69 } 70 } 71 72 void ResolveInfo::setRegular() { 73 m_BitField &= (~dynamic_flag); 74 } 75 76 void ResolveInfo::setDynamic() { 77 m_BitField |= dynamic_flag; 78 } 79 80 void ResolveInfo::setSource(bool pIsDyn) { 81 if (pIsDyn) 82 m_BitField |= dynamic_flag; 83 else 84 m_BitField &= (~dynamic_flag); 85 } 86 87 void ResolveInfo::setInDyn() { 88 m_BitField |= indyn_flag; 89 } 90 91 void ResolveInfo::setType(uint32_t pType) { 92 m_BitField &= ~TYPE_MASK; 93 m_BitField |= ((pType << TYPE_OFFSET) & TYPE_MASK); 94 } 95 96 void ResolveInfo::setDesc(uint32_t pDesc) { 97 m_BitField &= ~DESC_MASK; 98 m_BitField |= ((pDesc << DESC_OFFSET) & DESC_MASK); 99 } 100 101 void ResolveInfo::setBinding(uint32_t pBinding) { 102 m_BitField &= ~BINDING_MASK; 103 if (pBinding == Local || pBinding == Absolute) 104 m_BitField |= local_flag; 105 if (pBinding == Weak || pBinding == Absolute) 106 m_BitField |= weak_flag; 107 } 108 109 void ResolveInfo::setReserved(uint32_t pReserved) { 110 m_BitField &= ~RESERVED_MASK; 111 m_BitField |= ((pReserved << RESERVED_OFFSET) & RESERVED_MASK); 112 } 113 114 void ResolveInfo::setOther(uint32_t pOther) { 115 setVisibility(static_cast<ResolveInfo::Visibility>(pOther & 0x3)); 116 } 117 118 void ResolveInfo::setVisibility(ResolveInfo::Visibility pVisibility) { 119 m_BitField &= ~VISIBILITY_MASK; 120 m_BitField |= pVisibility << VISIBILITY_OFFSET; 121 } 122 123 void ResolveInfo::setIsSymbol(bool pIsSymbol) { 124 if (pIsSymbol) 125 m_BitField |= symbol_flag; 126 else 127 m_BitField &= ~symbol_flag; 128 } 129 130 bool ResolveInfo::isNull() const { 131 return (this == Null()); 132 } 133 134 bool ResolveInfo::isDyn() const { 135 return (dynamic_flag == (m_BitField & DYN_MASK)); 136 } 137 138 bool ResolveInfo::isUndef() const { 139 return (undefine_flag == (m_BitField & DESC_MASK)); 140 } 141 142 bool ResolveInfo::isDefine() const { 143 return (define_flag == (m_BitField & DESC_MASK)); 144 } 145 146 bool ResolveInfo::isCommon() const { 147 return (common_flag == (m_BitField & DESC_MASK)); 148 } 149 150 bool ResolveInfo::isIndirect() const { 151 return (indirect_flag == (m_BitField & DESC_MASK)); 152 } 153 154 // isGlobal - [L,W] == [0, 0] 155 bool ResolveInfo::isGlobal() const { 156 return (global_flag == (m_BitField & BINDING_MASK)); 157 } 158 159 // isWeak - [L,W] == [0, 1] 160 bool ResolveInfo::isWeak() const { 161 return (weak_flag == (m_BitField & BINDING_MASK)); 162 } 163 164 // isLocal - [L,W] == [1, 0] 165 bool ResolveInfo::isLocal() const { 166 return (local_flag == (m_BitField & BINDING_MASK)); 167 } 168 169 // isAbsolute - [L,W] == [1, 1] 170 bool ResolveInfo::isAbsolute() const { 171 return (absolute_flag == (m_BitField & BINDING_MASK)); 172 } 173 174 bool ResolveInfo::isSymbol() const { 175 return (symbol_flag == (m_BitField & SYMBOL_MASK)); 176 } 177 178 bool ResolveInfo::isString() const { 179 return (string_flag == (m_BitField & SYMBOL_MASK)); 180 } 181 182 bool ResolveInfo::isInDyn() const { 183 return (indyn_flag == (m_BitField & IN_DYN_MASK)); 184 } 185 186 uint32_t ResolveInfo::type() const { 187 return (m_BitField & TYPE_MASK) >> TYPE_OFFSET; 188 } 189 190 uint32_t ResolveInfo::desc() const { 191 return (m_BitField & DESC_MASK) >> DESC_OFFSET; 192 } 193 194 uint32_t ResolveInfo::binding() const { 195 if (m_BitField & LOCAL_MASK) { 196 if (m_BitField & GLOBAL_MASK) { 197 return ResolveInfo::Absolute; 198 } 199 return ResolveInfo::Local; 200 } 201 return m_BitField & GLOBAL_MASK; 202 } 203 204 uint32_t ResolveInfo::reserved() const { 205 return (m_BitField & RESERVED_MASK) >> RESERVED_OFFSET; 206 } 207 208 ResolveInfo::Visibility ResolveInfo::visibility() const { 209 return static_cast<ResolveInfo::Visibility>((m_BitField & VISIBILITY_MASK) >> 210 VISIBILITY_OFFSET); 211 } 212 213 bool ResolveInfo::compare(const ResolveInfo::key_type& pKey) { 214 size_t length = nameSize(); 215 if (length != pKey.size()) 216 return false; 217 return (std::memcmp(m_Name, pKey.data(), length) == 0); 218 } 219 220 bool ResolveInfo::shouldForceLocal(const LinkerConfig& pConfig) { 221 // forced local symbol matches all rules: 222 // 1. We are not doing incremental linking. 223 // 2. The symbol is with Hidden or Internal visibility. 224 // 3. The symbol should be global or weak. Otherwise, local symbol is local. 225 // 4. The symbol is defined or common 226 if (LinkerConfig::Object != pConfig.codeGenType() && 227 (visibility() == ResolveInfo::Hidden || 228 visibility() == ResolveInfo::Internal) && 229 (isGlobal() || isWeak()) && (isDefine() || isCommon())) 230 return true; 231 return false; 232 } 233 //===----------------------------------------------------------------------===// 234 // ResolveInfo Factory Methods 235 //===----------------------------------------------------------------------===// 236 ResolveInfo* ResolveInfo::Create(const ResolveInfo::key_type& pKey) { 237 ResolveInfo* info = 238 static_cast<ResolveInfo*>(malloc(sizeof(ResolveInfo) + pKey.size() + 1)); 239 if (info == NULL) 240 return NULL; 241 242 new (info) ResolveInfo(); // call constructor at the `result` address. 243 std::memcpy(info->m_Name, pKey.data(), pKey.size()); 244 info->m_Name[pKey.size()] = '\0'; 245 info->m_BitField &= ~ResolveInfo::RESOLVE_MASK; 246 info->m_BitField |= (pKey.size() << ResolveInfo::NAME_LENGTH_OFFSET); 247 return info; 248 } 249 250 void ResolveInfo::Destroy(ResolveInfo*& pInfo) { 251 if (pInfo->isNull()) 252 return; 253 254 if (pInfo != NULL) { 255 pInfo->~ResolveInfo(); 256 free(pInfo); 257 } 258 259 pInfo = NULL; 260 } 261 262 ResolveInfo* ResolveInfo::Null() { 263 if (g_NullResolveInfo == NULL) { 264 g_NullResolveInfo = 265 static_cast<ResolveInfo*>(malloc(sizeof(ResolveInfo) + 1)); 266 new (g_NullResolveInfo) ResolveInfo(); 267 g_NullResolveInfo->m_Name[0] = '\0'; 268 g_NullResolveInfo->m_BitField = 0x0; 269 g_NullResolveInfo->setBinding(Local); 270 } 271 return g_NullResolveInfo; 272 } 273 274 } // namespace mcld 275