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 "Strings.h" 15 #include "SyntheticSections.h" 16 #include "Target.h" 17 #include "Writer.h" 18 19 #include "lld/Common/ErrorHandler.h" 20 #include "llvm/ADT/STLExtras.h" 21 #include "llvm/Support/Path.h" 22 #include <cstring> 23 24 using namespace llvm; 25 using namespace llvm::object; 26 using namespace llvm::ELF; 27 28 using namespace lld; 29 using namespace lld::elf; 30 31 Defined *ElfSym::Bss; 32 Defined *ElfSym::Etext1; 33 Defined *ElfSym::Etext2; 34 Defined *ElfSym::Edata1; 35 Defined *ElfSym::Edata2; 36 Defined *ElfSym::End1; 37 Defined *ElfSym::End2; 38 Defined *ElfSym::GlobalOffsetTable; 39 Defined *ElfSym::MipsGp; 40 Defined *ElfSym::MipsGpDisp; 41 Defined *ElfSym::MipsLocalGp; 42 43 static 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 if (auto *ISB = dyn_cast_or_null<InputSectionBase>(IS)) 49 IS = ISB->Repl; 50 51 // According to the ELF spec reference to a local symbol from outside 52 // the group are not allowed. Unfortunately .eh_frame breaks that rule 53 // and must be treated specially. For now we just replace the symbol with 54 // 0. 55 if (IS == &InputSection::Discarded) 56 return 0; 57 58 // This is an absolute symbol. 59 if (!IS) 60 return D.Value; 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 const OutputSection *OutSec = IS->getOutputSection(); 81 82 // In the typical case, this is actually very simple and boils 83 // down to adding together 3 numbers: 84 // 1. The address of the output section. 85 // 2. The offset of the input section within the output section. 86 // 3. The offset within the input section (this addition happens 87 // inside InputSection::getOffset). 88 // 89 // If you understand the data structures involved with this next 90 // line (and how they get built), then you have a pretty good 91 // understanding of the linker. 92 uint64_t VA = (OutSec ? OutSec->Addr : 0) + IS->getOffset(Offset); 93 94 if (D.isTls() && !Config->Relocatable) { 95 if (!Out::TlsPhdr) 96 fatal(toString(D.getFile()) + 97 " has an STT_TLS symbol but doesn't have an SHF_TLS section"); 98 return VA - Out::TlsPhdr->p_vaddr; 99 } 100 return VA; 101 } 102 case Symbol::SharedKind: { 103 auto &SS = cast<SharedSymbol>(Sym); 104 if (SS.CopyRelSec) 105 return SS.CopyRelSec->getParent()->Addr + SS.CopyRelSec->OutSecOff; 106 if (SS.NeedsPltAddr) 107 return Sym.getPltVA(); 108 return 0; 109 } 110 case Symbol::UndefinedKind: 111 return 0; 112 case Symbol::LazyArchiveKind: 113 case Symbol::LazyObjectKind: 114 assert(Sym.IsUsedInRegularObj && "lazy symbol reached writer"); 115 return 0; 116 } 117 llvm_unreachable("invalid symbol kind"); 118 } 119 120 // Returns true if this is a weak undefined symbol. 121 bool Symbol::isUndefWeak() const { 122 // See comment on Lazy in Symbols.h for the details. 123 return !isLocal() && isWeak() && (isUndefined() || isLazy()); 124 } 125 126 InputFile *Symbol::getFile() const { 127 if (isLocal()) { 128 const SectionBase *Sec = cast<Defined>(this)->Section; 129 // Local absolute symbols actually have a file, but that is not currently 130 // used. We could support that by having a mostly redundant InputFile in 131 // Symbol, or having a special absolute section if needed. 132 return Sec ? cast<InputSectionBase>(Sec)->File : nullptr; 133 } 134 return File; 135 } 136 137 // Overwrites all attributes with Other's so that this symbol becomes 138 // an alias to Other. This is useful for handling some options such as 139 // --wrap. 140 void Symbol::copyFrom(Symbol *Other) { 141 Symbol Sym = *this; 142 memcpy(this, Other, sizeof(SymbolUnion)); 143 144 Binding = Sym.Binding; 145 VersionId = Sym.VersionId; 146 Visibility = Sym.Visibility; 147 IsUsedInRegularObj = Sym.IsUsedInRegularObj; 148 ExportDynamic = Sym.ExportDynamic; 149 CanInline = Sym.CanInline; 150 Traced = Sym.Traced; 151 InVersionScript = Sym.InVersionScript; 152 } 153 154 uint64_t Symbol::getVA(int64_t Addend) const { 155 uint64_t OutVA = getSymVA(*this, Addend); 156 return OutVA + Addend; 157 } 158 159 uint64_t Symbol::getGotVA() const { return InX::Got->getVA() + getGotOffset(); } 160 161 uint64_t Symbol::getGotOffset() const { 162 return GotIndex * Target->GotEntrySize; 163 } 164 165 uint64_t Symbol::getGotPltVA() const { 166 if (this->IsInIgot) 167 return InX::IgotPlt->getVA() + getGotPltOffset(); 168 return InX::GotPlt->getVA() + getGotPltOffset(); 169 } 170 171 uint64_t Symbol::getGotPltOffset() const { 172 return GotPltIndex * Target->GotPltEntrySize; 173 } 174 175 uint64_t Symbol::getPltVA() const { 176 if (this->IsInIplt) 177 return InX::Iplt->getVA() + PltIndex * Target->PltEntrySize; 178 return InX::Plt->getVA() + Target->PltHeaderSize + 179 PltIndex * Target->PltEntrySize; 180 } 181 182 uint64_t Symbol::getSize() const { 183 if (const auto *DR = dyn_cast<Defined>(this)) 184 return DR->Size; 185 if (const auto *S = dyn_cast<SharedSymbol>(this)) 186 return S->Size; 187 return 0; 188 } 189 190 OutputSection *Symbol::getOutputSection() const { 191 if (auto *S = dyn_cast<Defined>(this)) { 192 if (S->Section) 193 return S->Section->getOutputSection(); 194 return nullptr; 195 } 196 197 if (auto *S = dyn_cast<SharedSymbol>(this)) { 198 if (S->CopyRelSec) 199 return S->CopyRelSec->getParent(); 200 return nullptr; 201 } 202 203 return nullptr; 204 } 205 206 // If a symbol name contains '@', the characters after that is 207 // a symbol version name. This function parses that. 208 void Symbol::parseSymbolVersion() { 209 StringRef S = getName(); 210 size_t Pos = S.find('@'); 211 if (Pos == 0 || Pos == StringRef::npos) 212 return; 213 StringRef Verstr = S.substr(Pos + 1); 214 if (Verstr.empty()) 215 return; 216 217 // Truncate the symbol name so that it doesn't include the version string. 218 Name = {S.data(), Pos}; 219 220 // If this is not in this DSO, it is not a definition. 221 if (!isDefined()) 222 return; 223 224 // '@@' in a symbol name means the default version. 225 // It is usually the most recent one. 226 bool IsDefault = (Verstr[0] == '@'); 227 if (IsDefault) 228 Verstr = Verstr.substr(1); 229 230 for (VersionDefinition &Ver : Config->VersionDefinitions) { 231 if (Ver.Name != Verstr) 232 continue; 233 234 if (IsDefault) 235 VersionId = Ver.Id; 236 else 237 VersionId = Ver.Id | VERSYM_HIDDEN; 238 return; 239 } 240 241 // It is an error if the specified version is not defined. 242 // Usually version script is not provided when linking executable, 243 // but we may still want to override a versioned symbol from DSO, 244 // so we do not report error in this case. 245 if (Config->Shared) 246 error(toString(getFile()) + ": symbol " + S + " has undefined version " + 247 Verstr); 248 } 249 250 InputFile *Lazy::fetch() { 251 if (auto *S = dyn_cast<LazyArchive>(this)) 252 return S->fetch(); 253 return cast<LazyObject>(this)->fetch(); 254 } 255 256 ArchiveFile *LazyArchive::getFile() { 257 return cast<ArchiveFile>(Symbol::getFile()); 258 } 259 260 InputFile *LazyArchive::fetch() { 261 std::pair<MemoryBufferRef, uint64_t> MBInfo = getFile()->getMember(&Sym); 262 263 // getMember returns an empty buffer if the member was already 264 // read from the library. 265 if (MBInfo.first.getBuffer().empty()) 266 return nullptr; 267 return createObjectFile(MBInfo.first, getFile()->getName(), MBInfo.second); 268 } 269 270 LazyObjFile *LazyObject::getFile() { 271 return cast<LazyObjFile>(Symbol::getFile()); 272 } 273 274 InputFile *LazyObject::fetch() { return getFile()->fetch(); } 275 276 uint8_t Symbol::computeBinding() const { 277 if (Config->Relocatable) 278 return Binding; 279 if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED) 280 return STB_LOCAL; 281 if (VersionId == VER_NDX_LOCAL && isDefined()) 282 return STB_LOCAL; 283 if (Config->NoGnuUnique && Binding == STB_GNU_UNIQUE) 284 return STB_GLOBAL; 285 return Binding; 286 } 287 288 bool Symbol::includeInDynsym() const { 289 if (!Config->HasDynSymTab) 290 return false; 291 if (computeBinding() == STB_LOCAL) 292 return false; 293 if (!isDefined()) 294 return true; 295 return ExportDynamic; 296 } 297 298 // Print out a log message for --trace-symbol. 299 void elf::printTraceSymbol(Symbol *Sym) { 300 std::string S; 301 if (Sym->isUndefined()) 302 S = ": reference to "; 303 else if (Sym->isLazy()) 304 S = ": lazy definition of "; 305 else if (Sym->isShared()) 306 S = ": shared definition of "; 307 else if (dyn_cast_or_null<BssSection>(cast<Defined>(Sym)->Section)) 308 S = ": common definition of "; 309 else 310 S = ": definition of "; 311 312 message(toString(Sym->File) + S + Sym->getName()); 313 } 314 315 // Returns a symbol for an error message. 316 std::string lld::toString(const Symbol &B) { 317 if (Config->Demangle) 318 if (Optional<std::string> S = demangle(B.getName())) 319 return *S; 320 return B.getName(); 321 } 322