Symbols.cpp revision 327952
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 "Strings.h" 13#include "lld/Common/ErrorHandler.h" 14#include "lld/Common/Memory.h" 15#include "llvm/ADT/STLExtras.h" 16#include "llvm/Support/Debug.h" 17#include "llvm/Support/raw_ostream.h" 18 19using namespace llvm; 20using namespace llvm::object; 21 22// Returns a symbol name for an error message. 23std::string lld::toString(coff::Symbol &B) { 24 if (Optional<std::string> S = coff::demangleMSVC(B.getName())) 25 return ("\"" + *S + "\" (" + B.getName() + ")").str(); 26 return B.getName(); 27} 28 29namespace lld { 30namespace coff { 31 32StringRef Symbol::getName() { 33 // COFF symbol names are read lazily for a performance reason. 34 // Non-external symbol names are never used by the linker except for logging 35 // or debugging. Their internal references are resolved not by name but by 36 // symbol index. And because they are not external, no one can refer them by 37 // name. Object files contain lots of non-external symbols, and creating 38 // StringRefs for them (which involves lots of strlen() on the string table) 39 // is a waste of time. 40 if (Name.empty()) { 41 auto *D = cast<DefinedCOFF>(this); 42 cast<ObjFile>(D->File)->getCOFFObj()->getSymbolName(D->Sym, Name); 43 } 44 return Name; 45} 46 47InputFile *Symbol::getFile() { 48 if (auto *Sym = dyn_cast<DefinedCOFF>(this)) 49 return Sym->File; 50 if (auto *Sym = dyn_cast<Lazy>(this)) 51 return Sym->File; 52 return nullptr; 53} 54 55bool Symbol::isLive() const { 56 if (auto *R = dyn_cast<DefinedRegular>(this)) 57 return R->getChunk()->isLive(); 58 if (auto *Imp = dyn_cast<DefinedImportData>(this)) 59 return Imp->File->Live; 60 if (auto *Imp = dyn_cast<DefinedImportThunk>(this)) 61 return Imp->WrappedSym->File->Live; 62 // Assume any other kind of symbol is live. 63 return true; 64} 65 66COFFSymbolRef DefinedCOFF::getCOFFSymbol() { 67 size_t SymSize = cast<ObjFile>(File)->getCOFFObj()->getSymbolTableEntrySize(); 68 if (SymSize == sizeof(coff_symbol16)) 69 return COFFSymbolRef(reinterpret_cast<const coff_symbol16 *>(Sym)); 70 assert(SymSize == sizeof(coff_symbol32)); 71 return COFFSymbolRef(reinterpret_cast<const coff_symbol32 *>(Sym)); 72} 73 74uint16_t DefinedAbsolute::OutputSectionIndex = 0; 75 76static Chunk *makeImportThunk(DefinedImportData *S, uint16_t Machine) { 77 if (Machine == AMD64) 78 return make<ImportThunkChunkX64>(S); 79 if (Machine == I386) 80 return make<ImportThunkChunkX86>(S); 81 if (Machine == ARM64) 82 return make<ImportThunkChunkARM64>(S); 83 assert(Machine == ARMNT); 84 return make<ImportThunkChunkARM>(S); 85} 86 87DefinedImportThunk::DefinedImportThunk(StringRef Name, DefinedImportData *S, 88 uint16_t Machine) 89 : Defined(DefinedImportThunkKind, Name), WrappedSym(S), 90 Data(makeImportThunk(S, Machine)) {} 91 92Defined *Undefined::getWeakAlias() { 93 // A weak alias may be a weak alias to another symbol, so check recursively. 94 for (Symbol *A = WeakAlias; A; A = cast<Undefined>(A)->WeakAlias) 95 if (auto *D = dyn_cast<Defined>(A)) 96 return D; 97 return nullptr; 98} 99} // namespace coff 100} // namespace lld 101