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