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 "lld/Common/ErrorHandler.h" 13 #include "lld/Common/Memory.h" 14 #include "lld/Common/Strings.h" 15 #include "llvm/ADT/STLExtras.h" 16 #include "llvm/Support/Debug.h" 17 #include "llvm/Support/raw_ostream.h" 18 19 using namespace llvm; 20 using namespace llvm::object; 21 22 // Returns a symbol name for an error message. 23 std::string lld::toString(coff::Symbol &B) { 24 if (Optional<std::string> S = lld::demangleMSVC(B.getName())) 25 return ("\"" + *S + "\" (" + B.getName() + ")").str(); 26 return B.getName(); 27 } 28 29 namespace lld { 30 namespace coff { 31 32 StringRef 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 47 InputFile *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 55 bool Symbol::isLive() const { 56 if (auto *R = dyn_cast<DefinedRegular>(this)) 57 return R->getChunk()->Live; 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->ThunkLive; 62 // Assume any other kind of symbol is live. 63 return true; 64 } 65 66 // MinGW specific. 67 void Symbol::replaceKeepingName(Symbol *Other, size_t Size) { 68 StringRef OrigName = Name; 69 memcpy(this, Other, Size); 70 Name = OrigName; 71 } 72 73 COFFSymbolRef DefinedCOFF::getCOFFSymbol() { 74 size_t SymSize = cast<ObjFile>(File)->getCOFFObj()->getSymbolTableEntrySize(); 75 if (SymSize == sizeof(coff_symbol16)) 76 return COFFSymbolRef(reinterpret_cast<const coff_symbol16 *>(Sym)); 77 assert(SymSize == sizeof(coff_symbol32)); 78 return COFFSymbolRef(reinterpret_cast<const coff_symbol32 *>(Sym)); 79 } 80 81 uint16_t DefinedAbsolute::NumOutputSections; 82 83 static Chunk *makeImportThunk(DefinedImportData *S, uint16_t Machine) { 84 if (Machine == AMD64) 85 return make<ImportThunkChunkX64>(S); 86 if (Machine == I386) 87 return make<ImportThunkChunkX86>(S); 88 if (Machine == ARM64) 89 return make<ImportThunkChunkARM64>(S); 90 assert(Machine == ARMNT); 91 return make<ImportThunkChunkARM>(S); 92 } 93 94 DefinedImportThunk::DefinedImportThunk(StringRef Name, DefinedImportData *S, 95 uint16_t Machine) 96 : Defined(DefinedImportThunkKind, Name), WrappedSym(S), 97 Data(makeImportThunk(S, Machine)) {} 98 99 Defined *Undefined::getWeakAlias() { 100 // A weak alias may be a weak alias to another symbol, so check recursively. 101 for (Symbol *A = WeakAlias; A; A = cast<Undefined>(A)->WeakAlias) 102 if (auto *D = dyn_cast<Defined>(A)) 103 return D; 104 return nullptr; 105 } 106 } // namespace coff 107 } // namespace lld 108