1 //===- Symbols.cpp --------------------------------------------------------===// 2 // 3 // The LLVM Linker 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "Symbols.h" 11 #include "Error.h" 12 #include "InputFiles.h" 13 #include "InputSection.h" 14 #include "OutputSections.h" 15 #include "Strings.h" 16 #include "SyntheticSections.h" 17 #include "Target.h" 18 #include "Writer.h" 19 20 #include "llvm/ADT/STLExtras.h" 21 #include "llvm/Support/Path.h" 22 #include <cstring> 23 24 using namespace llvm; 25 using namespace llvm::object; 26 using namespace llvm::ELF; 27 28 using namespace lld; 29 using namespace lld::elf; 30 31 template <class ELFT> 32 static typename ELFT::uint getSymVA(const SymbolBody &Body, 33 typename ELFT::uint &Addend) { 34 typedef typename ELFT::uint uintX_t; 35 36 switch (Body.kind()) { 37 case SymbolBody::DefinedSyntheticKind: { 38 auto &D = cast<DefinedSynthetic>(Body); 39 const OutputSectionBase *Sec = D.Section; 40 if (!Sec) 41 return D.Value; 42 if (D.Value == uintX_t(-1)) 43 return Sec->Addr + Sec->Size; 44 return Sec->Addr + D.Value; 45 } 46 case SymbolBody::DefinedRegularKind: { 47 auto &D = cast<DefinedRegular<ELFT>>(Body); 48 InputSectionBase<ELFT> *IS = D.Section; 49 50 // According to the ELF spec reference to a local symbol from outside 51 // the group are not allowed. Unfortunately .eh_frame breaks that rule 52 // and must be treated specially. For now we just replace the symbol with 53 // 0. 54 if (IS == &InputSection<ELFT>::Discarded) 55 return 0; 56 57 // This is an absolute symbol. 58 if (!IS) 59 return D.Value; 60 61 uintX_t Offset = D.Value; 62 if (D.isSection()) { 63 Offset += Addend; 64 Addend = 0; 65 } 66 uintX_t VA = (IS->OutSec ? IS->OutSec->Addr : 0) + IS->getOffset(Offset); 67 if (D.isTls() && !Config->Relocatable) { 68 if (!Out<ELFT>::TlsPhdr) 69 fatal(toString(D.File) + 70 " has a STT_TLS symbol but doesn't have a PT_TLS section"); 71 return VA - Out<ELFT>::TlsPhdr->p_vaddr; 72 } 73 return VA; 74 } 75 case SymbolBody::DefinedCommonKind: 76 return In<ELFT>::Common->OutSec->Addr + In<ELFT>::Common->OutSecOff + 77 cast<DefinedCommon>(Body).Offset; 78 case SymbolBody::SharedKind: { 79 auto &SS = cast<SharedSymbol<ELFT>>(Body); 80 if (!SS.NeedsCopyOrPltAddr) 81 return 0; 82 if (SS.isFunc()) 83 return Body.getPltVA<ELFT>(); 84 return SS.getBssSectionForCopy()->Addr + SS.CopyOffset; 85 } 86 case SymbolBody::UndefinedKind: 87 return 0; 88 case SymbolBody::LazyArchiveKind: 89 case SymbolBody::LazyObjectKind: 90 assert(Body.symbol()->IsUsedInRegularObj && "lazy symbol reached writer"); 91 return 0; 92 } 93 llvm_unreachable("invalid symbol kind"); 94 } 95 96 SymbolBody::SymbolBody(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther, 97 uint8_t Type) 98 : SymbolKind(K), NeedsCopyOrPltAddr(false), IsLocal(IsLocal), 99 IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false), 100 IsInIgot(false), CopyIsInBssRelRo(false), Type(Type), StOther(StOther), 101 Name(Name) {} 102 103 // Returns true if a symbol can be replaced at load-time by a symbol 104 // with the same name defined in other ELF executable or DSO. 105 bool SymbolBody::isPreemptible() const { 106 if (isLocal()) 107 return false; 108 109 // Shared symbols resolve to the definition in the DSO. The exceptions are 110 // symbols with copy relocations (which resolve to .bss) or preempt plt 111 // entries (which resolve to that plt entry). 112 if (isShared()) 113 return !NeedsCopyOrPltAddr; 114 115 // That's all that can be preempted in a non-DSO. 116 if (!Config->Shared) 117 return false; 118 119 // Only symbols that appear in dynsym can be preempted. 120 if (!symbol()->includeInDynsym()) 121 return false; 122 123 // Only default visibility symbols can be preempted. 124 if (symbol()->Visibility != STV_DEFAULT) 125 return false; 126 127 // -Bsymbolic means that definitions are not preempted. 128 if (Config->Bsymbolic || (Config->BsymbolicFunctions && isFunc())) 129 return !isDefined(); 130 return true; 131 } 132 133 template <class ELFT> bool SymbolBody::hasThunk() const { 134 if (auto *DR = dyn_cast<DefinedRegular<ELFT>>(this)) 135 return DR->ThunkData != nullptr; 136 if (auto *S = dyn_cast<SharedSymbol<ELFT>>(this)) 137 return S->ThunkData != nullptr; 138 return false; 139 } 140 141 template <class ELFT> 142 typename ELFT::uint SymbolBody::getVA(typename ELFT::uint Addend) const { 143 typename ELFT::uint OutVA = getSymVA<ELFT>(*this, Addend); 144 return OutVA + Addend; 145 } 146 147 template <class ELFT> typename ELFT::uint SymbolBody::getGotVA() const { 148 return In<ELFT>::Got->getVA() + getGotOffset<ELFT>(); 149 } 150 151 template <class ELFT> typename ELFT::uint SymbolBody::getGotOffset() const { 152 return GotIndex * Target->GotEntrySize; 153 } 154 155 template <class ELFT> typename ELFT::uint SymbolBody::getGotPltVA() const { 156 if (this->IsInIgot) 157 return In<ELFT>::IgotPlt->getVA() + getGotPltOffset<ELFT>(); 158 return In<ELFT>::GotPlt->getVA() + getGotPltOffset<ELFT>(); 159 } 160 161 template <class ELFT> typename ELFT::uint SymbolBody::getGotPltOffset() const { 162 return GotPltIndex * Target->GotPltEntrySize; 163 } 164 165 template <class ELFT> typename ELFT::uint SymbolBody::getPltVA() const { 166 if (this->IsInIplt) 167 return In<ELFT>::Iplt->getVA() + PltIndex * Target->PltEntrySize; 168 return In<ELFT>::Plt->getVA() + Target->PltHeaderSize + 169 PltIndex * Target->PltEntrySize; 170 } 171 172 template <class ELFT> typename ELFT::uint SymbolBody::getThunkVA() const { 173 if (const auto *DR = dyn_cast<DefinedRegular<ELFT>>(this)) 174 return DR->ThunkData->getVA(); 175 if (const auto *S = dyn_cast<SharedSymbol<ELFT>>(this)) 176 return S->ThunkData->getVA(); 177 if (const auto *S = dyn_cast<Undefined<ELFT>>(this)) 178 return S->ThunkData->getVA(); 179 fatal("getThunkVA() not supported for Symbol class\n"); 180 } 181 182 template <class ELFT> typename ELFT::uint SymbolBody::getSize() const { 183 if (const auto *C = dyn_cast<DefinedCommon>(this)) 184 return C->Size; 185 if (const auto *DR = dyn_cast<DefinedRegular<ELFT>>(this)) 186 return DR->Size; 187 if (const auto *S = dyn_cast<SharedSymbol<ELFT>>(this)) 188 return S->Sym.st_size; 189 return 0; 190 } 191 192 // If a symbol name contains '@', the characters after that is 193 // a symbol version name. This function parses that. 194 void SymbolBody::parseSymbolVersion() { 195 StringRef S = getName(); 196 size_t Pos = S.find('@'); 197 if (Pos == 0 || Pos == StringRef::npos) 198 return; 199 StringRef Verstr = S.substr(Pos + 1); 200 if (Verstr.empty()) 201 return; 202 203 // Truncate the symbol name so that it doesn't include the version string. 204 Name = {S.data(), Pos}; 205 206 // If this is an undefined or shared symbol it is not a definition. 207 if (isUndefined() || isShared()) 208 return; 209 210 // '@@' in a symbol name means the default version. 211 // It is usually the most recent one. 212 bool IsDefault = (Verstr[0] == '@'); 213 if (IsDefault) 214 Verstr = Verstr.substr(1); 215 216 for (VersionDefinition &Ver : Config->VersionDefinitions) { 217 if (Ver.Name != Verstr) 218 continue; 219 220 if (IsDefault) 221 symbol()->VersionId = Ver.Id; 222 else 223 symbol()->VersionId = Ver.Id | VERSYM_HIDDEN; 224 return; 225 } 226 227 // It is an error if the specified version is not defined. 228 error(toString(File) + ": symbol " + S + " has undefined version " + Verstr); 229 } 230 231 Defined::Defined(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther, 232 uint8_t Type) 233 : SymbolBody(K, Name, IsLocal, StOther, Type) {} 234 235 template <class ELFT> bool DefinedRegular<ELFT>::isMipsPIC() const { 236 if (!Section || !isFunc()) 237 return false; 238 return (this->StOther & STO_MIPS_MIPS16) == STO_MIPS_PIC || 239 (Section->getFile()->getObj().getHeader()->e_flags & EF_MIPS_PIC); 240 } 241 242 template <typename ELFT> 243 Undefined<ELFT>::Undefined(StringRefZ Name, bool IsLocal, uint8_t StOther, 244 uint8_t Type, InputFile *File) 245 : SymbolBody(SymbolBody::UndefinedKind, Name, IsLocal, StOther, Type) { 246 this->File = File; 247 } 248 249 template <typename ELFT> 250 OutputSection<ELFT> *SharedSymbol<ELFT>::getBssSectionForCopy() const { 251 assert(needsCopy()); 252 return CopyIsInBssRelRo ? Out<ELFT>::BssRelRo : Out<ELFT>::Bss; 253 } 254 255 DefinedCommon::DefinedCommon(StringRef Name, uint64_t Size, uint64_t Alignment, 256 uint8_t StOther, uint8_t Type, InputFile *File) 257 : Defined(SymbolBody::DefinedCommonKind, Name, /*IsLocal=*/false, StOther, 258 Type), 259 Alignment(Alignment), Size(Size) { 260 this->File = File; 261 } 262 263 InputFile *Lazy::fetch() { 264 if (auto *S = dyn_cast<LazyArchive>(this)) 265 return S->fetch(); 266 return cast<LazyObject>(this)->fetch(); 267 } 268 269 LazyArchive::LazyArchive(ArchiveFile &File, 270 const llvm::object::Archive::Symbol S, uint8_t Type) 271 : Lazy(LazyArchiveKind, S.getName(), Type), Sym(S) { 272 this->File = &File; 273 } 274 275 LazyObject::LazyObject(StringRef Name, LazyObjectFile &File, uint8_t Type) 276 : Lazy(LazyObjectKind, Name, Type) { 277 this->File = &File; 278 } 279 280 InputFile *LazyArchive::fetch() { 281 std::pair<MemoryBufferRef, uint64_t> MBInfo = file()->getMember(&Sym); 282 283 // getMember returns an empty buffer if the member was already 284 // read from the library. 285 if (MBInfo.first.getBuffer().empty()) 286 return nullptr; 287 return createObjectFile(MBInfo.first, file()->getName(), MBInfo.second); 288 } 289 290 InputFile *LazyObject::fetch() { 291 MemoryBufferRef MBRef = file()->getBuffer(); 292 if (MBRef.getBuffer().empty()) 293 return nullptr; 294 return createObjectFile(MBRef); 295 } 296 297 uint8_t Symbol::computeBinding() const { 298 if (Config->Relocatable) 299 return Binding; 300 if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED) 301 return STB_LOCAL; 302 if (VersionId == VER_NDX_LOCAL && !body()->isUndefined()) 303 return STB_LOCAL; 304 if (Config->NoGnuUnique && Binding == STB_GNU_UNIQUE) 305 return STB_GLOBAL; 306 return Binding; 307 } 308 309 bool Symbol::includeInDynsym() const { 310 if (computeBinding() == STB_LOCAL) 311 return false; 312 return ExportDynamic || body()->isShared() || 313 (body()->isUndefined() && Config->Shared); 314 } 315 316 // Print out a log message for --trace-symbol. 317 void elf::printTraceSymbol(Symbol *Sym) { 318 SymbolBody *B = Sym->body(); 319 outs() << toString(B->File); 320 321 if (B->isUndefined()) 322 outs() << ": reference to "; 323 else if (B->isCommon()) 324 outs() << ": common definition of "; 325 else 326 outs() << ": definition of "; 327 outs() << B->getName() << "\n"; 328 } 329 330 // Returns a symbol for an error message. 331 std::string lld::toString(const SymbolBody &B) { 332 if (Config->Demangle) 333 if (Optional<std::string> S = demangle(B.getName())) 334 return *S; 335 return B.getName(); 336 } 337 338 template bool SymbolBody::hasThunk<ELF32LE>() const; 339 template bool SymbolBody::hasThunk<ELF32BE>() const; 340 template bool SymbolBody::hasThunk<ELF64LE>() const; 341 template bool SymbolBody::hasThunk<ELF64BE>() const; 342 343 template uint32_t SymbolBody::template getVA<ELF32LE>(uint32_t) const; 344 template uint32_t SymbolBody::template getVA<ELF32BE>(uint32_t) const; 345 template uint64_t SymbolBody::template getVA<ELF64LE>(uint64_t) const; 346 template uint64_t SymbolBody::template getVA<ELF64BE>(uint64_t) const; 347 348 template uint32_t SymbolBody::template getGotVA<ELF32LE>() const; 349 template uint32_t SymbolBody::template getGotVA<ELF32BE>() const; 350 template uint64_t SymbolBody::template getGotVA<ELF64LE>() const; 351 template uint64_t SymbolBody::template getGotVA<ELF64BE>() const; 352 353 template uint32_t SymbolBody::template getGotOffset<ELF32LE>() const; 354 template uint32_t SymbolBody::template getGotOffset<ELF32BE>() const; 355 template uint64_t SymbolBody::template getGotOffset<ELF64LE>() const; 356 template uint64_t SymbolBody::template getGotOffset<ELF64BE>() const; 357 358 template uint32_t SymbolBody::template getGotPltVA<ELF32LE>() const; 359 template uint32_t SymbolBody::template getGotPltVA<ELF32BE>() const; 360 template uint64_t SymbolBody::template getGotPltVA<ELF64LE>() const; 361 template uint64_t SymbolBody::template getGotPltVA<ELF64BE>() const; 362 363 template uint32_t SymbolBody::template getThunkVA<ELF32LE>() const; 364 template uint32_t SymbolBody::template getThunkVA<ELF32BE>() const; 365 template uint64_t SymbolBody::template getThunkVA<ELF64LE>() const; 366 template uint64_t SymbolBody::template getThunkVA<ELF64BE>() const; 367 368 template uint32_t SymbolBody::template getGotPltOffset<ELF32LE>() const; 369 template uint32_t SymbolBody::template getGotPltOffset<ELF32BE>() const; 370 template uint64_t SymbolBody::template getGotPltOffset<ELF64LE>() const; 371 template uint64_t SymbolBody::template getGotPltOffset<ELF64BE>() const; 372 373 template uint32_t SymbolBody::template getPltVA<ELF32LE>() const; 374 template uint32_t SymbolBody::template getPltVA<ELF32BE>() const; 375 template uint64_t SymbolBody::template getPltVA<ELF64LE>() const; 376 template uint64_t SymbolBody::template getPltVA<ELF64BE>() const; 377 378 template uint32_t SymbolBody::template getSize<ELF32LE>() const; 379 template uint32_t SymbolBody::template getSize<ELF32BE>() const; 380 template uint64_t SymbolBody::template getSize<ELF64LE>() const; 381 template uint64_t SymbolBody::template getSize<ELF64BE>() const; 382 383 template class elf::Undefined<ELF32LE>; 384 template class elf::Undefined<ELF32BE>; 385 template class elf::Undefined<ELF64LE>; 386 template class elf::Undefined<ELF64BE>; 387 388 template class elf::SharedSymbol<ELF32LE>; 389 template class elf::SharedSymbol<ELF32BE>; 390 template class elf::SharedSymbol<ELF64LE>; 391 template class elf::SharedSymbol<ELF64BE>; 392 393 template class elf::DefinedRegular<ELF32LE>; 394 template class elf::DefinedRegular<ELF32BE>; 395 template class elf::DefinedRegular<ELF64LE>; 396 template class elf::DefinedRegular<ELF64BE>; 397