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