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