Symbols.cpp revision 344779
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 "InputFiles.h" 12#include "InputSection.h" 13#include "OutputSections.h" 14#include "SyntheticSections.h" 15#include "Target.h" 16#include "Writer.h" 17#include "lld/Common/ErrorHandler.h" 18#include "lld/Common/Strings.h" 19#include "llvm/ADT/STLExtras.h" 20#include "llvm/Support/Path.h" 21#include <cstring> 22 23using namespace llvm; 24using namespace llvm::object; 25using namespace llvm::ELF; 26 27using namespace lld; 28using namespace lld::elf; 29 30Defined *ElfSym::Bss; 31Defined *ElfSym::Etext1; 32Defined *ElfSym::Etext2; 33Defined *ElfSym::Edata1; 34Defined *ElfSym::Edata2; 35Defined *ElfSym::End1; 36Defined *ElfSym::End2; 37Defined *ElfSym::GlobalOffsetTable; 38Defined *ElfSym::MipsGp; 39Defined *ElfSym::MipsGpDisp; 40Defined *ElfSym::MipsLocalGp; 41Defined *ElfSym::RelaIpltStart; 42Defined *ElfSym::RelaIpltEnd; 43 44static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) { 45 switch (Sym.kind()) { 46 case Symbol::DefinedKind: { 47 auto &D = cast<Defined>(Sym); 48 SectionBase *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::Discarded) 55 return 0; 56 57 // This is an absolute symbol. 58 if (!IS) 59 return D.Value; 60 61 IS = IS->Repl; 62 63 uint64_t Offset = D.Value; 64 65 // An object in an SHF_MERGE section might be referenced via a 66 // section symbol (as a hack for reducing the number of local 67 // symbols). 68 // Depending on the addend, the reference via a section symbol 69 // refers to a different object in the merge section. 70 // Since the objects in the merge section are not necessarily 71 // contiguous in the output, the addend can thus affect the final 72 // VA in a non-linear way. 73 // To make this work, we incorporate the addend into the section 74 // offset (and zero out the addend for later processing) so that 75 // we find the right object in the section. 76 if (D.isSection()) { 77 Offset += Addend; 78 Addend = 0; 79 } 80 81 // In the typical case, this is actually very simple and boils 82 // down to adding together 3 numbers: 83 // 1. The address of the output section. 84 // 2. The offset of the input section within the output section. 85 // 3. The offset within the input section (this addition happens 86 // inside InputSection::getOffset). 87 // 88 // If you understand the data structures involved with this next 89 // line (and how they get built), then you have a pretty good 90 // understanding of the linker. 91 uint64_t VA = IS->getVA(Offset); 92 93 if (D.isTls() && !Config->Relocatable) { 94 // Use the address of the TLS segment's first section rather than the 95 // segment's address, because segment addresses aren't initialized until 96 // after sections are finalized. (e.g. Measuring the size of .rela.dyn 97 // for Android relocation packing requires knowing TLS symbol addresses 98 // during section finalization.) 99 if (!Out::TlsPhdr || !Out::TlsPhdr->FirstSec) 100 fatal(toString(D.File) + 101 " has an STT_TLS symbol but doesn't have an SHF_TLS section"); 102 return VA - Out::TlsPhdr->FirstSec->Addr; 103 } 104 return VA; 105 } 106 case Symbol::SharedKind: 107 case Symbol::UndefinedKind: 108 return 0; 109 case Symbol::LazyArchiveKind: 110 case Symbol::LazyObjectKind: 111 assert(Sym.IsUsedInRegularObj && "lazy symbol reached writer"); 112 return 0; 113 case Symbol::PlaceholderKind: 114 llvm_unreachable("placeholder symbol reached writer"); 115 } 116 llvm_unreachable("invalid symbol kind"); 117} 118 119uint64_t Symbol::getVA(int64_t Addend) const { 120 uint64_t OutVA = getSymVA(*this, Addend); 121 return OutVA + Addend; 122} 123 124uint64_t Symbol::getGotVA() const { return In.Got->getVA() + getGotOffset(); } 125 126uint64_t Symbol::getGotOffset() const { 127 return GotIndex * Target->GotEntrySize; 128} 129 130uint64_t Symbol::getGotPltVA() const { 131 if (this->IsInIgot) 132 return In.IgotPlt->getVA() + getGotPltOffset(); 133 return In.GotPlt->getVA() + getGotPltOffset(); 134} 135 136uint64_t Symbol::getGotPltOffset() const { 137 if (IsInIgot) 138 return PltIndex * Target->GotPltEntrySize; 139 return (PltIndex + Target->GotPltHeaderEntriesNum) * Target->GotPltEntrySize; 140} 141 142uint64_t Symbol::getPPC64LongBranchOffset() const { 143 assert(PPC64BranchltIndex != 0xffff); 144 return PPC64BranchltIndex * Target->GotPltEntrySize; 145} 146 147uint64_t Symbol::getPltVA() const { 148 PltSection *Plt = IsInIplt ? In.Iplt : In.Plt; 149 return Plt->getVA() + Plt->HeaderSize + PltIndex * Target->PltEntrySize; 150} 151 152uint64_t Symbol::getPPC64LongBranchTableVA() const { 153 assert(PPC64BranchltIndex != 0xffff); 154 return In.PPC64LongBranchTarget->getVA() + 155 PPC64BranchltIndex * Target->GotPltEntrySize; 156} 157 158uint64_t Symbol::getSize() const { 159 if (const auto *DR = dyn_cast<Defined>(this)) 160 return DR->Size; 161 return cast<SharedSymbol>(this)->Size; 162} 163 164OutputSection *Symbol::getOutputSection() const { 165 if (auto *S = dyn_cast<Defined>(this)) { 166 if (auto *Sec = S->Section) 167 return Sec->Repl->getOutputSection(); 168 return nullptr; 169 } 170 return nullptr; 171} 172 173// If a symbol name contains '@', the characters after that is 174// a symbol version name. This function parses that. 175void Symbol::parseSymbolVersion() { 176 StringRef S = getName(); 177 size_t Pos = S.find('@'); 178 if (Pos == 0 || Pos == StringRef::npos) 179 return; 180 StringRef Verstr = S.substr(Pos + 1); 181 if (Verstr.empty()) 182 return; 183 184 // Truncate the symbol name so that it doesn't include the version string. 185 NameSize = Pos; 186 187 // If this is not in this DSO, it is not a definition. 188 if (!isDefined()) 189 return; 190 191 // '@@' in a symbol name means the default version. 192 // It is usually the most recent one. 193 bool IsDefault = (Verstr[0] == '@'); 194 if (IsDefault) 195 Verstr = Verstr.substr(1); 196 197 for (VersionDefinition &Ver : Config->VersionDefinitions) { 198 if (Ver.Name != Verstr) 199 continue; 200 201 if (IsDefault) 202 VersionId = Ver.Id; 203 else 204 VersionId = Ver.Id | VERSYM_HIDDEN; 205 return; 206 } 207 208 // It is an error if the specified version is not defined. 209 // Usually version script is not provided when linking executable, 210 // but we may still want to override a versioned symbol from DSO, 211 // so we do not report error in this case. We also do not error 212 // if the symbol has a local version as it won't be in the dynamic 213 // symbol table. 214 if (Config->Shared && VersionId != VER_NDX_LOCAL) 215 error(toString(File) + ": symbol " + S + " has undefined version " + 216 Verstr); 217} 218 219InputFile *LazyArchive::fetch() { return cast<ArchiveFile>(File)->fetch(Sym); } 220 221MemoryBufferRef LazyArchive::getMemberBuffer() { 222 Archive::Child C = CHECK( 223 Sym.getMember(), "could not get the member for symbol " + Sym.getName()); 224 225 return CHECK(C.getMemoryBufferRef(), 226 "could not get the buffer for the member defining symbol " + 227 Sym.getName()); 228} 229 230uint8_t Symbol::computeBinding() const { 231 if (Config->Relocatable) 232 return Binding; 233 if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED) 234 return STB_LOCAL; 235 if (VersionId == VER_NDX_LOCAL && isDefined() && !IsPreemptible) 236 return STB_LOCAL; 237 if (!Config->GnuUnique && Binding == STB_GNU_UNIQUE) 238 return STB_GLOBAL; 239 return Binding; 240} 241 242bool Symbol::includeInDynsym() const { 243 if (!Config->HasDynSymTab) 244 return false; 245 if (computeBinding() == STB_LOCAL) 246 return false; 247 if (!isDefined()) 248 return true; 249 return ExportDynamic; 250} 251 252// Print out a log message for --trace-symbol. 253void elf::printTraceSymbol(Symbol *Sym) { 254 std::string S; 255 if (Sym->isUndefined()) 256 S = ": reference to "; 257 else if (Sym->isLazy()) 258 S = ": lazy definition of "; 259 else if (Sym->isShared()) 260 S = ": shared definition of "; 261 else if (dyn_cast_or_null<BssSection>(cast<Defined>(Sym)->Section)) 262 S = ": common definition of "; 263 else 264 S = ": definition of "; 265 266 message(toString(Sym->File) + S + Sym->getName()); 267} 268 269void elf::maybeWarnUnorderableSymbol(const Symbol *Sym) { 270 if (!Config->WarnSymbolOrdering) 271 return; 272 273 // If UnresolvedPolicy::Ignore is used, no "undefined symbol" error/warning 274 // is emitted. It makes sense to not warn on undefined symbols. 275 // 276 // Note, ld.bfd --symbol-ordering-file= does not warn on undefined symbols, 277 // but we don't have to be compatible here. 278 if (Sym->isUndefined() && 279 Config->UnresolvedSymbols == UnresolvedPolicy::Ignore) 280 return; 281 282 const InputFile *File = Sym->File; 283 auto *D = dyn_cast<Defined>(Sym); 284 285 auto Warn = [&](StringRef S) { warn(toString(File) + S + Sym->getName()); }; 286 287 if (Sym->isUndefined()) 288 Warn(": unable to order undefined symbol: "); 289 else if (Sym->isShared()) 290 Warn(": unable to order shared symbol: "); 291 else if (D && !D->Section) 292 Warn(": unable to order absolute symbol: "); 293 else if (D && isa<OutputSection>(D->Section)) 294 Warn(": unable to order synthetic symbol: "); 295 else if (D && !D->Section->Repl->Live) 296 Warn(": unable to order discarded symbol: "); 297} 298 299// Returns a symbol for an error message. 300std::string lld::toString(const Symbol &B) { 301 if (Config->Demangle) 302 if (Optional<std::string> S = demangleItanium(B.getName())) 303 return *S; 304 return B.getName(); 305} 306