1 //===- Symbols.cpp --------------------------------------------------------===//
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
12 #include "InputFiles.h"
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/Support/Debug.h"
17 #include "llvm/Support/raw_ostream.h"
20 using namespace llvm::object;
25 StringRef SymbolBody::getName() {
26 // DefinedCOFF names are read lazily for a performance reason.
27 // Non-external symbol names are never used by the linker except for logging
28 // or debugging. Their internal references are resolved not by name but by
29 // symbol index. And because they are not external, no one can refer them by
30 // name. Object files contain lots of non-external symbols, and creating
31 // StringRefs for them (which involves lots of strlen() on the string table)
32 // is a waste of time.
34 auto *D = cast<DefinedCOFF>(this);
35 D->File->getCOFFObj()->getSymbolName(D->Sym, Name);
40 InputFile *SymbolBody::getFile() {
41 if (auto *Sym = dyn_cast<DefinedCOFF>(this))
43 if (auto *Sym = dyn_cast<DefinedBitcode>(this))
45 if (auto *Sym = dyn_cast<Lazy>(this))
50 COFFSymbolRef DefinedCOFF::getCOFFSymbol() {
51 size_t SymSize = File->getCOFFObj()->getSymbolTableEntrySize();
52 if (SymSize == sizeof(coff_symbol16))
53 return COFFSymbolRef(reinterpret_cast<const coff_symbol16 *>(Sym));
54 assert(SymSize == sizeof(coff_symbol32));
55 return COFFSymbolRef(reinterpret_cast<const coff_symbol32 *>(Sym));
58 DefinedImportThunk::DefinedImportThunk(StringRef Name, DefinedImportData *S,
60 : Defined(DefinedImportThunkKind, Name) {
62 case AMD64: Data = make<ImportThunkChunkX64>(S); return;
63 case I386: Data = make<ImportThunkChunkX86>(S); return;
64 case ARMNT: Data = make<ImportThunkChunkARM>(S); return;
65 default: llvm_unreachable("unknown machine type");
69 Defined *Undefined::getWeakAlias() {
70 // A weak alias may be a weak alias to another symbol, so check recursively.
71 for (SymbolBody *A = WeakAlias; A; A = cast<Undefined>(A)->WeakAlias)
72 if (auto *D = dyn_cast<Defined>(A))
77 // Returns a symbol name for an error message.
78 std::string toString(SymbolBody &B) {
79 if (Optional<std::string> S = demangle(B.getName()))
80 return ("\"" + *S + "\" (" + B.getName() + ")").str();