15ffd83dbSDimitry Andric //===- Symbols.cpp --------------------------------------------------------===// 25ffd83dbSDimitry Andric // 35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65ffd83dbSDimitry Andric // 75ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 85ffd83dbSDimitry Andric 95ffd83dbSDimitry Andric #include "Symbols.h" 105ffd83dbSDimitry Andric #include "InputFiles.h" 11e8d8bef9SDimitry Andric #include "SyntheticSections.h" 125ffd83dbSDimitry Andric 135ffd83dbSDimitry Andric using namespace llvm; 145ffd83dbSDimitry Andric using namespace lld; 155ffd83dbSDimitry Andric using namespace lld::macho; 165ffd83dbSDimitry Andric 17e8d8bef9SDimitry Andric // Returns a symbol for an error message. 18e8d8bef9SDimitry Andric static std::string demangle(StringRef symName) { 19e8d8bef9SDimitry Andric if (config->demangle) 20e8d8bef9SDimitry Andric return demangleItanium(symName); 21e8d8bef9SDimitry Andric return std::string(symName); 22e8d8bef9SDimitry Andric } 23e8d8bef9SDimitry Andric 24*fe6060f1SDimitry Andric std::string lld::toString(const Symbol &sym) { return demangle(sym.getName()); } 25e8d8bef9SDimitry Andric 26e8d8bef9SDimitry Andric std::string lld::toMachOString(const object::Archive::Symbol &b) { 27e8d8bef9SDimitry Andric return demangle(b.getName()); 28e8d8bef9SDimitry Andric } 29e8d8bef9SDimitry Andric 30*fe6060f1SDimitry Andric uint64_t Symbol::getStubVA() const { return in.stubs->getVA(stubsIndex); } 31*fe6060f1SDimitry Andric uint64_t Symbol::getGotVA() const { return in.got->getVA(gotIndex); } 32*fe6060f1SDimitry Andric uint64_t Symbol::getTlvVA() const { return in.tlvPointers->getVA(gotIndex); } 33*fe6060f1SDimitry Andric 34*fe6060f1SDimitry Andric bool Symbol::isLive() const { 35*fe6060f1SDimitry Andric if (isa<DylibSymbol>(this) || isa<Undefined>(this)) 36*fe6060f1SDimitry Andric return used; 37*fe6060f1SDimitry Andric 38*fe6060f1SDimitry Andric if (auto *d = dyn_cast<Defined>(this)) { 39*fe6060f1SDimitry Andric // Non-absolute symbols might be alive because their section is 40*fe6060f1SDimitry Andric // no_dead_strip or live_support. In that case, the section will know 41*fe6060f1SDimitry Andric // that it's live but `used` might be false. Non-absolute symbols always 42*fe6060f1SDimitry Andric // have to use the section's `live` bit as source of truth. 43*fe6060f1SDimitry Andric if (d->isAbsolute()) 44*fe6060f1SDimitry Andric return used; 45*fe6060f1SDimitry Andric return d->isec->canonical()->isLive(d->value); 46*fe6060f1SDimitry Andric } 47*fe6060f1SDimitry Andric 48*fe6060f1SDimitry Andric assert(!isa<CommonSymbol>(this) && 49*fe6060f1SDimitry Andric "replaceCommonSymbols() runs before dead code stripping, and isLive() " 50*fe6060f1SDimitry Andric "should only be called after dead code stripping"); 51*fe6060f1SDimitry Andric 52*fe6060f1SDimitry Andric // Assume any other kind of symbol is live. 53*fe6060f1SDimitry Andric return true; 54*fe6060f1SDimitry Andric } 55*fe6060f1SDimitry Andric 56e8d8bef9SDimitry Andric uint64_t Defined::getVA() const { 57*fe6060f1SDimitry Andric assert(isLive() && "this should only be called for live symbols"); 58*fe6060f1SDimitry Andric 59e8d8bef9SDimitry Andric if (isAbsolute()) 60e8d8bef9SDimitry Andric return value; 61*fe6060f1SDimitry Andric 62*fe6060f1SDimitry Andric if (!isec->canonical()->isFinal) { 63*fe6060f1SDimitry Andric // A target arch that does not use thunks ought never ask for 64*fe6060f1SDimitry Andric // the address of a function that has not yet been finalized. 65*fe6060f1SDimitry Andric assert(target->usesThunks()); 66*fe6060f1SDimitry Andric 67*fe6060f1SDimitry Andric // ConcatOutputSection::finalize() can seek the address of a 68*fe6060f1SDimitry Andric // function before its address is assigned. The thunking algorithm 69*fe6060f1SDimitry Andric // knows that unfinalized functions will be out of range, so it is 70*fe6060f1SDimitry Andric // expedient to return a contrived out-of-range address. 71*fe6060f1SDimitry Andric return TargetInfo::outOfRangeVA; 72*fe6060f1SDimitry Andric } 73*fe6060f1SDimitry Andric return isec->canonical()->getVA(value); 74e8d8bef9SDimitry Andric } 75e8d8bef9SDimitry Andric 76*fe6060f1SDimitry Andric uint64_t DylibSymbol::getVA() const { 77*fe6060f1SDimitry Andric return isInStubs() ? getStubVA() : Symbol::getVA(); 78e8d8bef9SDimitry Andric } 79e8d8bef9SDimitry Andric 80*fe6060f1SDimitry Andric void LazySymbol::fetchArchiveMember() { getFile()->fetch(sym); } 81