blob 9b590790 (3020B) - Raw
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 "Error.h" 12 #include "InputFiles.h" 13 #include "Memory.h" 14 #include "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::SymbolBody &B) { 24 if (Optional<std::string> S = coff::demangle(B.getName())) 25 return ("\"" + *S + "\" (" + B.getName() + ")").str(); 26 return B.getName(); 27 } 28 29 namespace lld { 30 namespace coff { 31 32 StringRef SymbolBody::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<ObjectFile>(D->File)->getCOFFObj()->getSymbolName(D->Sym, Name); 43 } 44 return Name; 45 } 46 47 InputFile *SymbolBody::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 COFFSymbolRef DefinedCOFF::getCOFFSymbol() { 56 size_t SymSize = 57 cast<ObjectFile>(File)->getCOFFObj()->getSymbolTableEntrySize(); 58 if (SymSize == sizeof(coff_symbol16)) 59 return COFFSymbolRef(reinterpret_cast<const coff_symbol16 *>(Sym)); 60 assert(SymSize == sizeof(coff_symbol32)); 61 return COFFSymbolRef(reinterpret_cast<const coff_symbol32 *>(Sym)); 62 } 63 64 uint16_t DefinedAbsolute::OutputSectionIndex = 0; 65 66 static Chunk *makeImportThunk(DefinedImportData *S, uint16_t Machine) { 67 if (Machine == AMD64) 68 return make<ImportThunkChunkX64>(S); 69 if (Machine == I386) 70 return make<ImportThunkChunkX86>(S); 71 if (Machine == ARM64) 72 return make<ImportThunkChunkARM64>(S); 73 assert(Machine == ARMNT); 74 return make<ImportThunkChunkARM>(S); 75 } 76 77 DefinedImportThunk::DefinedImportThunk(StringRef Name, DefinedImportData *S, 78 uint16_t Machine) 79 : Defined(DefinedImportThunkKind, Name), WrappedSym(S), 80 Data(makeImportThunk(S, Machine)) {} 81 82 Defined *Undefined::getWeakAlias() { 83 // A weak alias may be a weak alias to another symbol, so check recursively. 84 for (SymbolBody *A = WeakAlias; A; A = cast<Undefined>(A)->WeakAlias) 85 if (auto *D = dyn_cast<Defined>(A)) 86 return D; 87 return nullptr; 88 } 89 } // namespace coff 90 } // namespace lld