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