Symbols.cpp revision 309124
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 "Target.h" 16 17#include "llvm/ADT/STLExtras.h" 18 19using namespace llvm; 20using namespace llvm::object; 21using namespace llvm::ELF; 22 23using namespace lld; 24using namespace lld::elf; 25 26template <class ELFT> 27static typename ELFT::uint getSymVA(const SymbolBody &Body, 28 typename ELFT::uint &Addend) { 29 typedef typename ELFT::uint uintX_t; 30 31 switch (Body.kind()) { 32 case SymbolBody::DefinedSyntheticKind: { 33 auto &D = cast<DefinedSynthetic<ELFT>>(Body); 34 const OutputSectionBase<ELFT> *Sec = D.Section; 35 if (!Sec) 36 return D.Value; 37 if (D.Value == DefinedSynthetic<ELFT>::SectionEnd) 38 return Sec->getVA() + Sec->getSize(); 39 return Sec->getVA() + D.Value; 40 } 41 case SymbolBody::DefinedRegularKind: { 42 auto &D = cast<DefinedRegular<ELFT>>(Body); 43 InputSectionBase<ELFT> *SC = D.Section; 44 45 // According to the ELF spec reference to a local symbol from outside 46 // the group are not allowed. Unfortunately .eh_frame breaks that rule 47 // and must be treated specially. For now we just replace the symbol with 48 // 0. 49 if (SC == &InputSection<ELFT>::Discarded) 50 return 0; 51 52 // This is an absolute symbol. 53 if (!SC) 54 return D.Value; 55 56 uintX_t Offset = D.Value; 57 if (D.isSection()) { 58 Offset += Addend; 59 Addend = 0; 60 } 61 uintX_t VA = SC->OutSec->getVA() + SC->getOffset(Offset); 62 if (D.isTls()) 63 return VA - Out<ELFT>::TlsPhdr->p_vaddr; 64 return VA; 65 } 66 case SymbolBody::DefinedCommonKind: 67 return Out<ELFT>::Bss->getVA() + cast<DefinedCommon>(Body).OffsetInBss; 68 case SymbolBody::SharedKind: { 69 auto &SS = cast<SharedSymbol<ELFT>>(Body); 70 if (!SS.NeedsCopyOrPltAddr) 71 return 0; 72 if (SS.isFunc()) 73 return Body.getPltVA<ELFT>(); 74 return Out<ELFT>::Bss->getVA() + SS.OffsetInBss; 75 } 76 case SymbolBody::UndefinedKind: 77 return 0; 78 case SymbolBody::LazyArchiveKind: 79 case SymbolBody::LazyObjectKind: 80 assert(Body.symbol()->IsUsedInRegularObj && "lazy symbol reached writer"); 81 return 0; 82 case SymbolBody::DefinedBitcodeKind: 83 llvm_unreachable("should have been replaced"); 84 } 85 llvm_unreachable("invalid symbol kind"); 86} 87 88SymbolBody::SymbolBody(Kind K, uint32_t NameOffset, uint8_t StOther, 89 uint8_t Type) 90 : SymbolKind(K), NeedsCopyOrPltAddr(false), IsLocal(true), 91 IsInGlobalMipsGot(false), Type(Type), StOther(StOther), 92 NameOffset(NameOffset) {} 93 94SymbolBody::SymbolBody(Kind K, StringRef Name, uint8_t StOther, uint8_t Type) 95 : SymbolKind(K), NeedsCopyOrPltAddr(false), IsLocal(false), 96 IsInGlobalMipsGot(false), Type(Type), StOther(StOther), 97 Name({Name.data(), Name.size()}) {} 98 99StringRef SymbolBody::getName() const { 100 assert(!isLocal()); 101 return StringRef(Name.S, Name.Len); 102} 103 104void SymbolBody::setName(StringRef S) { 105 Name.S = S.data(); 106 Name.Len = S.size(); 107} 108 109// Returns true if a symbol can be replaced at load-time by a symbol 110// with the same name defined in other ELF executable or DSO. 111bool SymbolBody::isPreemptible() const { 112 if (isLocal()) 113 return false; 114 115 // Shared symbols resolve to the definition in the DSO. The exceptions are 116 // symbols with copy relocations (which resolve to .bss) or preempt plt 117 // entries (which resolve to that plt entry). 118 if (isShared()) 119 return !NeedsCopyOrPltAddr; 120 121 // That's all that can be preempted in a non-DSO. 122 if (!Config->Shared) 123 return false; 124 125 // Only symbols that appear in dynsym can be preempted. 126 if (!symbol()->includeInDynsym()) 127 return false; 128 129 // Only default visibility symbols can be preempted. 130 if (symbol()->Visibility != STV_DEFAULT) 131 return false; 132 133 // -Bsymbolic means that definitions are not preempted. 134 if (Config->Bsymbolic || (Config->BsymbolicFunctions && isFunc())) 135 return !isDefined(); 136 return true; 137} 138 139template <class ELFT> bool SymbolBody::hasThunk() const { 140 if (auto *DR = dyn_cast<DefinedRegular<ELFT>>(this)) 141 return DR->ThunkData != nullptr; 142 if (auto *S = dyn_cast<SharedSymbol<ELFT>>(this)) 143 return S->ThunkData != nullptr; 144 return false; 145} 146 147template <class ELFT> 148typename ELFT::uint SymbolBody::getVA(typename ELFT::uint Addend) const { 149 typename ELFT::uint OutVA = getSymVA<ELFT>(*this, Addend); 150 return OutVA + Addend; 151} 152 153template <class ELFT> typename ELFT::uint SymbolBody::getGotVA() const { 154 return Out<ELFT>::Got->getVA() + getGotOffset<ELFT>(); 155} 156 157template <class ELFT> typename ELFT::uint SymbolBody::getGotOffset() const { 158 return GotIndex * Target->GotEntrySize; 159} 160 161template <class ELFT> typename ELFT::uint SymbolBody::getGotPltVA() const { 162 return Out<ELFT>::GotPlt->getVA() + getGotPltOffset<ELFT>(); 163} 164 165template <class ELFT> typename ELFT::uint SymbolBody::getGotPltOffset() const { 166 return GotPltIndex * Target->GotPltEntrySize; 167} 168 169template <class ELFT> typename ELFT::uint SymbolBody::getPltVA() const { 170 return Out<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 fatal("getThunkVA() not supported for Symbol class\n"); 180} 181 182template <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 192Defined::Defined(Kind K, StringRef Name, uint8_t StOther, uint8_t Type) 193 : SymbolBody(K, Name, StOther, Type) {} 194 195Defined::Defined(Kind K, uint32_t NameOffset, uint8_t StOther, uint8_t Type) 196 : SymbolBody(K, NameOffset, StOther, Type) {} 197 198DefinedBitcode::DefinedBitcode(StringRef Name, uint8_t StOther, uint8_t Type, 199 BitcodeFile *F) 200 : Defined(DefinedBitcodeKind, Name, StOther, Type) { 201 this->File = F; 202} 203 204bool DefinedBitcode::classof(const SymbolBody *S) { 205 return S->kind() == DefinedBitcodeKind; 206} 207 208Undefined::Undefined(StringRef Name, uint8_t StOther, uint8_t Type, 209 InputFile *File) 210 : SymbolBody(SymbolBody::UndefinedKind, Name, StOther, Type) { 211 this->File = File; 212} 213 214Undefined::Undefined(uint32_t NameOffset, uint8_t StOther, uint8_t Type, 215 InputFile *File) 216 : SymbolBody(SymbolBody::UndefinedKind, NameOffset, StOther, Type) { 217 this->File = File; 218} 219 220template <typename ELFT> 221DefinedSynthetic<ELFT>::DefinedSynthetic(StringRef N, uintX_t Value, 222 OutputSectionBase<ELFT> *Section) 223 : Defined(SymbolBody::DefinedSyntheticKind, N, STV_HIDDEN, 0 /* Type */), 224 Value(Value), Section(Section) {} 225 226DefinedCommon::DefinedCommon(StringRef N, uint64_t Size, uint64_t Alignment, 227 uint8_t StOther, uint8_t Type, InputFile *File) 228 : Defined(SymbolBody::DefinedCommonKind, N, StOther, Type), 229 Alignment(Alignment), Size(Size) { 230 this->File = File; 231} 232 233std::unique_ptr<InputFile> Lazy::fetch() { 234 if (auto *S = dyn_cast<LazyArchive>(this)) 235 return S->fetch(); 236 return cast<LazyObject>(this)->fetch(); 237} 238 239LazyArchive::LazyArchive(ArchiveFile &File, 240 const llvm::object::Archive::Symbol S, uint8_t Type) 241 : Lazy(LazyArchiveKind, S.getName(), Type), Sym(S) { 242 this->File = &File; 243} 244 245LazyObject::LazyObject(StringRef Name, LazyObjectFile &File, uint8_t Type) 246 : Lazy(LazyObjectKind, Name, Type) { 247 this->File = &File; 248} 249 250std::unique_ptr<InputFile> LazyArchive::fetch() { 251 MemoryBufferRef MBRef = file()->getMember(&Sym); 252 253 // getMember returns an empty buffer if the member was already 254 // read from the library. 255 if (MBRef.getBuffer().empty()) 256 return std::unique_ptr<InputFile>(nullptr); 257 return createObjectFile(MBRef, file()->getName()); 258} 259 260std::unique_ptr<InputFile> LazyObject::fetch() { 261 MemoryBufferRef MBRef = file()->getBuffer(); 262 if (MBRef.getBuffer().empty()) 263 return std::unique_ptr<InputFile>(nullptr); 264 return createObjectFile(MBRef); 265} 266 267bool Symbol::includeInDynsym() const { 268 if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED) 269 return false; 270 return (ExportDynamic && VersionId != VER_NDX_LOCAL) || body()->isShared() || 271 (body()->isUndefined() && Config->Shared); 272} 273 274// Print out a log message for --trace-symbol. 275void elf::printTraceSymbol(Symbol *Sym) { 276 SymbolBody *B = Sym->body(); 277 outs() << getFilename(B->File); 278 279 if (B->isUndefined()) 280 outs() << ": reference to "; 281 else if (B->isCommon()) 282 outs() << ": common definition of "; 283 else 284 outs() << ": definition of "; 285 outs() << B->getName() << "\n"; 286} 287 288template bool SymbolBody::hasThunk<ELF32LE>() const; 289template bool SymbolBody::hasThunk<ELF32BE>() const; 290template bool SymbolBody::hasThunk<ELF64LE>() const; 291template bool SymbolBody::hasThunk<ELF64BE>() const; 292 293template uint32_t SymbolBody::template getVA<ELF32LE>(uint32_t) const; 294template uint32_t SymbolBody::template getVA<ELF32BE>(uint32_t) const; 295template uint64_t SymbolBody::template getVA<ELF64LE>(uint64_t) const; 296template uint64_t SymbolBody::template getVA<ELF64BE>(uint64_t) const; 297 298template uint32_t SymbolBody::template getGotVA<ELF32LE>() const; 299template uint32_t SymbolBody::template getGotVA<ELF32BE>() const; 300template uint64_t SymbolBody::template getGotVA<ELF64LE>() const; 301template uint64_t SymbolBody::template getGotVA<ELF64BE>() const; 302 303template uint32_t SymbolBody::template getGotOffset<ELF32LE>() const; 304template uint32_t SymbolBody::template getGotOffset<ELF32BE>() const; 305template uint64_t SymbolBody::template getGotOffset<ELF64LE>() const; 306template uint64_t SymbolBody::template getGotOffset<ELF64BE>() const; 307 308template uint32_t SymbolBody::template getGotPltVA<ELF32LE>() const; 309template uint32_t SymbolBody::template getGotPltVA<ELF32BE>() const; 310template uint64_t SymbolBody::template getGotPltVA<ELF64LE>() const; 311template uint64_t SymbolBody::template getGotPltVA<ELF64BE>() const; 312 313template uint32_t SymbolBody::template getThunkVA<ELF32LE>() const; 314template uint32_t SymbolBody::template getThunkVA<ELF32BE>() const; 315template uint64_t SymbolBody::template getThunkVA<ELF64LE>() const; 316template uint64_t SymbolBody::template getThunkVA<ELF64BE>() const; 317 318template uint32_t SymbolBody::template getGotPltOffset<ELF32LE>() const; 319template uint32_t SymbolBody::template getGotPltOffset<ELF32BE>() const; 320template uint64_t SymbolBody::template getGotPltOffset<ELF64LE>() const; 321template uint64_t SymbolBody::template getGotPltOffset<ELF64BE>() const; 322 323template uint32_t SymbolBody::template getPltVA<ELF32LE>() const; 324template uint32_t SymbolBody::template getPltVA<ELF32BE>() const; 325template uint64_t SymbolBody::template getPltVA<ELF64LE>() const; 326template uint64_t SymbolBody::template getPltVA<ELF64BE>() const; 327 328template uint32_t SymbolBody::template getSize<ELF32LE>() const; 329template uint32_t SymbolBody::template getSize<ELF32BE>() const; 330template uint64_t SymbolBody::template getSize<ELF64LE>() const; 331template uint64_t SymbolBody::template getSize<ELF64BE>() const; 332 333template class elf::DefinedSynthetic<ELF32LE>; 334template class elf::DefinedSynthetic<ELF32BE>; 335template class elf::DefinedSynthetic<ELF64LE>; 336template class elf::DefinedSynthetic<ELF64BE>; 337