Symbols.cpp revision 341825
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::RelaIpltEnd; 42 43static uint64_t getSymVA(const Symbol &Sym, int64_t &Addend) { 44 switch (Sym.kind()) { 45 case Symbol::DefinedKind: { 46 auto &D = cast<Defined>(Sym); 47 SectionBase *IS = 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 (IS == &InputSection::Discarded) 54 return 0; 55 56 // This is an absolute symbol. 57 if (!IS) 58 return D.Value; 59 60 IS = IS->Repl; 61 62 uint64_t Offset = D.Value; 63 64 // An object in an SHF_MERGE section might be referenced via a 65 // section symbol (as a hack for reducing the number of local 66 // symbols). 67 // Depending on the addend, the reference via a section symbol 68 // refers to a different object in the merge section. 69 // Since the objects in the merge section are not necessarily 70 // contiguous in the output, the addend can thus affect the final 71 // VA in a non-linear way. 72 // To make this work, we incorporate the addend into the section 73 // offset (and zero out the addend for later processing) so that 74 // we find the right object in the section. 75 if (D.isSection()) { 76 Offset += Addend; 77 Addend = 0; 78 } 79 80 // In the typical case, this is actually very simple and boils 81 // down to adding together 3 numbers: 82 // 1. The address of the output section. 83 // 2. The offset of the input section within the output section. 84 // 3. The offset within the input section (this addition happens 85 // inside InputSection::getOffset). 86 // 87 // If you understand the data structures involved with this next 88 // line (and how they get built), then you have a pretty good 89 // understanding of the linker. 90 uint64_t VA = IS->getVA(Offset); 91 92 if (D.isTls() && !Config->Relocatable) { 93 if (!Out::TlsPhdr) 94 fatal(toString(D.File) + 95 " has an STT_TLS symbol but doesn't have an SHF_TLS section"); 96 return VA - Out::TlsPhdr->p_vaddr; 97 } 98 return VA; 99 } 100 case Symbol::SharedKind: 101 case Symbol::UndefinedKind: 102 return 0; 103 case Symbol::LazyArchiveKind: 104 case Symbol::LazyObjectKind: 105 llvm_unreachable("lazy symbol reached writer"); 106 } 107 llvm_unreachable("invalid symbol kind"); 108} 109 110uint64_t Symbol::getVA(int64_t Addend) const { 111 uint64_t OutVA = getSymVA(*this, Addend); 112 return OutVA + Addend; 113} 114 115uint64_t Symbol::getGotVA() const { return InX::Got->getVA() + getGotOffset(); } 116 117uint64_t Symbol::getGotOffset() const { 118 return GotIndex * Target->GotEntrySize; 119} 120 121uint64_t Symbol::getGotPltVA() const { 122 if (this->IsInIgot) 123 return InX::IgotPlt->getVA() + getGotPltOffset(); 124 return InX::GotPlt->getVA() + getGotPltOffset(); 125} 126 127uint64_t Symbol::getGotPltOffset() const { 128 if (IsInIgot) 129 return PltIndex * Target->GotPltEntrySize; 130 return (PltIndex + Target->GotPltHeaderEntriesNum) * Target->GotPltEntrySize; 131} 132 133uint64_t Symbol::getPltVA() const { 134 if (this->IsInIplt) 135 return InX::Iplt->getVA() + PltIndex * Target->PltEntrySize; 136 return InX::Plt->getVA() + Target->getPltEntryOffset(PltIndex); 137} 138 139uint64_t Symbol::getPltOffset() const { 140 assert(!this->IsInIplt); 141 return Target->getPltEntryOffset(PltIndex); 142} 143 144uint64_t Symbol::getSize() const { 145 if (const auto *DR = dyn_cast<Defined>(this)) 146 return DR->Size; 147 return cast<SharedSymbol>(this)->Size; 148} 149 150OutputSection *Symbol::getOutputSection() const { 151 if (auto *S = dyn_cast<Defined>(this)) { 152 if (auto *Sec = S->Section) 153 return Sec->Repl->getOutputSection(); 154 return nullptr; 155 } 156 return nullptr; 157} 158 159// If a symbol name contains '@', the characters after that is 160// a symbol version name. This function parses that. 161void Symbol::parseSymbolVersion() { 162 StringRef S = getName(); 163 size_t Pos = S.find('@'); 164 if (Pos == 0 || Pos == StringRef::npos) 165 return; 166 StringRef Verstr = S.substr(Pos + 1); 167 if (Verstr.empty()) 168 return; 169 170 // Truncate the symbol name so that it doesn't include the version string. 171 NameSize = Pos; 172 173 // If this is not in this DSO, it is not a definition. 174 if (!isDefined()) 175 return; 176 177 // '@@' in a symbol name means the default version. 178 // It is usually the most recent one. 179 bool IsDefault = (Verstr[0] == '@'); 180 if (IsDefault) 181 Verstr = Verstr.substr(1); 182 183 for (VersionDefinition &Ver : Config->VersionDefinitions) { 184 if (Ver.Name != Verstr) 185 continue; 186 187 if (IsDefault) 188 VersionId = Ver.Id; 189 else 190 VersionId = Ver.Id | VERSYM_HIDDEN; 191 return; 192 } 193 194 // It is an error if the specified version is not defined. 195 // Usually version script is not provided when linking executable, 196 // but we may still want to override a versioned symbol from DSO, 197 // so we do not report error in this case. We also do not error 198 // if the symbol has a local version as it won't be in the dynamic 199 // symbol table. 200 if (Config->Shared && VersionId != VER_NDX_LOCAL) 201 error(toString(File) + ": symbol " + S + " has undefined version " + 202 Verstr); 203} 204 205InputFile *LazyArchive::fetch() { return cast<ArchiveFile>(File)->fetch(Sym); } 206 207uint8_t Symbol::computeBinding() const { 208 if (Config->Relocatable) 209 return Binding; 210 if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED) 211 return STB_LOCAL; 212 if (VersionId == VER_NDX_LOCAL && isDefined() && !IsPreemptible) 213 return STB_LOCAL; 214 if (!Config->GnuUnique && Binding == STB_GNU_UNIQUE) 215 return STB_GLOBAL; 216 return Binding; 217} 218 219bool Symbol::includeInDynsym() const { 220 if (!Config->HasDynSymTab) 221 return false; 222 if (computeBinding() == STB_LOCAL) 223 return false; 224 if (!isDefined()) 225 return true; 226 return ExportDynamic; 227} 228 229// Print out a log message for --trace-symbol. 230void elf::printTraceSymbol(Symbol *Sym) { 231 std::string S; 232 if (Sym->isUndefined()) 233 S = ": reference to "; 234 else if (Sym->isLazy()) 235 S = ": lazy definition of "; 236 else if (Sym->isShared()) 237 S = ": shared definition of "; 238 else if (dyn_cast_or_null<BssSection>(cast<Defined>(Sym)->Section)) 239 S = ": common definition of "; 240 else 241 S = ": definition of "; 242 243 message(toString(Sym->File) + S + Sym->getName()); 244} 245 246void elf::warnUnorderableSymbol(const Symbol *Sym) { 247 if (!Config->WarnSymbolOrdering) 248 return; 249 250 const InputFile *File = Sym->File; 251 auto *D = dyn_cast<Defined>(Sym); 252 253 auto Warn = [&](StringRef S) { warn(toString(File) + S + Sym->getName()); }; 254 255 if (Sym->isUndefined()) 256 Warn(": unable to order undefined symbol: "); 257 else if (Sym->isShared()) 258 Warn(": unable to order shared symbol: "); 259 else if (D && !D->Section) 260 Warn(": unable to order absolute symbol: "); 261 else if (D && isa<OutputSection>(D->Section)) 262 Warn(": unable to order synthetic symbol: "); 263 else if (D && !D->Section->Repl->Live) 264 Warn(": unable to order discarded symbol: "); 265} 266 267// Returns a symbol for an error message. 268std::string lld::toString(const Symbol &B) { 269 if (Config->Demangle) 270 if (Optional<std::string> S = demangleItanium(B.getName())) 271 return *S; 272 return B.getName(); 273} 274