Symbols.cpp revision 314564
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 19using namespace llvm; 20using namespace llvm::object; 21 22// Returns a symbol name for an error message. 23std::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 29namespace lld { 30namespace coff { 31 32StringRef SymbolBody::getName() { 33 // DefinedCOFF 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 D->File->getCOFFObj()->getSymbolName(D->Sym, Name); 43 } 44 return Name; 45} 46 47InputFile *SymbolBody::getFile() { 48 if (auto *Sym = dyn_cast<DefinedCOFF>(this)) 49 return Sym->File; 50 if (auto *Sym = dyn_cast<DefinedBitcode>(this)) 51 return Sym->File; 52 if (auto *Sym = dyn_cast<Lazy>(this)) 53 return Sym->File; 54 return nullptr; 55} 56 57COFFSymbolRef DefinedCOFF::getCOFFSymbol() { 58 size_t SymSize = File->getCOFFObj()->getSymbolTableEntrySize(); 59 if (SymSize == sizeof(coff_symbol16)) 60 return COFFSymbolRef(reinterpret_cast<const coff_symbol16 *>(Sym)); 61 assert(SymSize == sizeof(coff_symbol32)); 62 return COFFSymbolRef(reinterpret_cast<const coff_symbol32 *>(Sym)); 63} 64 65DefinedImportThunk::DefinedImportThunk(StringRef Name, DefinedImportData *S, 66 uint16_t Machine) 67 : Defined(DefinedImportThunkKind, Name) { 68 switch (Machine) { 69 case AMD64: Data = make<ImportThunkChunkX64>(S); return; 70 case I386: Data = make<ImportThunkChunkX86>(S); return; 71 case ARMNT: Data = make<ImportThunkChunkARM>(S); return; 72 default: llvm_unreachable("unknown machine type"); 73 } 74} 75 76Defined *Undefined::getWeakAlias() { 77 // A weak alias may be a weak alias to another symbol, so check recursively. 78 for (SymbolBody *A = WeakAlias; A; A = cast<Undefined>(A)->WeakAlias) 79 if (auto *D = dyn_cast<Defined>(A)) 80 return D; 81 return nullptr; 82} 83} // namespace coff 84} // namespace lld 85