Symbols.cpp revision 344779
1219820Sjeff//===- Symbols.cpp --------------------------------------------------------===// 2219820Sjeff// 3219820Sjeff// The LLVM Linker 4219820Sjeff// 5271127Shselasky// This file is distributed under the University of Illinois Open Source 6219820Sjeff// License. See LICENSE.TXT for details. 7219820Sjeff// 8219820Sjeff//===----------------------------------------------------------------------===// 9219820Sjeff 10219820Sjeff#include "Symbols.h" 11219820Sjeff#include "InputFiles.h" 12219820Sjeff#include "lld/Common/ErrorHandler.h" 13219820Sjeff#include "lld/Common/Memory.h" 14219820Sjeff#include "lld/Common/Strings.h" 15219820Sjeff#include "llvm/ADT/STLExtras.h" 16219820Sjeff#include "llvm/Support/Debug.h" 17219820Sjeff#include "llvm/Support/raw_ostream.h" 18219820Sjeff 19219820Sjeffusing namespace llvm; 20219820Sjeffusing namespace llvm::object; 21219820Sjeff 22219820Sjeff// Returns a symbol name for an error message. 23219820Sjeffstd::string lld::toString(coff::Symbol &B) { 24219820Sjeff if (Optional<std::string> S = lld::demangleMSVC(B.getName())) 25219820Sjeff return ("\"" + *S + "\" (" + B.getName() + ")").str(); 26219820Sjeff return B.getName(); 27219820Sjeff} 28219820Sjeff 29219820Sjeffnamespace lld { 30219820Sjeffnamespace coff { 31219820Sjeff 32219820SjeffStringRef Symbol::getName() { 33219820Sjeff // COFF symbol names are read lazily for a performance reason. 34219820Sjeff // Non-external symbol names are never used by the linker except for logging 35219820Sjeff // or debugging. Their internal references are resolved not by name but by 36219820Sjeff // symbol index. And because they are not external, no one can refer them by 37219820Sjeff // name. Object files contain lots of non-external symbols, and creating 38219820Sjeff // StringRefs for them (which involves lots of strlen() on the string table) 39219820Sjeff // is a waste of time. 40219820Sjeff if (Name.empty()) { 41219820Sjeff auto *D = cast<DefinedCOFF>(this); 42219820Sjeff cast<ObjFile>(D->File)->getCOFFObj()->getSymbolName(D->Sym, Name); 43219820Sjeff } 44219820Sjeff return Name; 45219820Sjeff} 46219820Sjeff 47219820SjeffInputFile *Symbol::getFile() { 48219820Sjeff if (auto *Sym = dyn_cast<DefinedCOFF>(this)) 49219820Sjeff return Sym->File; 50219820Sjeff if (auto *Sym = dyn_cast<Lazy>(this)) 51219820Sjeff return Sym->File; 52219820Sjeff return nullptr; 53219820Sjeff} 54219820Sjeff 55219820Sjeffbool Symbol::isLive() const { 56219820Sjeff if (auto *R = dyn_cast<DefinedRegular>(this)) 57219820Sjeff return R->getChunk()->Live; 58219820Sjeff if (auto *Imp = dyn_cast<DefinedImportData>(this)) 59219820Sjeff return Imp->File->Live; 60219820Sjeff if (auto *Imp = dyn_cast<DefinedImportThunk>(this)) 61219820Sjeff return Imp->WrappedSym->File->ThunkLive; 62219820Sjeff // Assume any other kind of symbol is live. 63 return true; 64} 65 66// MinGW specific. 67void Symbol::replaceKeepingName(Symbol *Other, size_t Size) { 68 StringRef OrigName = Name; 69 memcpy(this, Other, Size); 70 Name = OrigName; 71} 72 73COFFSymbolRef 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 81uint16_t DefinedAbsolute::NumOutputSections; 82 83static 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 94DefinedImportThunk::DefinedImportThunk(StringRef Name, DefinedImportData *S, 95 uint16_t Machine) 96 : Defined(DefinedImportThunkKind, Name), WrappedSym(S), 97 Data(makeImportThunk(S, Machine)) {} 98 99Defined *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