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.
toString(coff::Symbol & B)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
getName()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
getFile()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
isLive() const55 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.
replaceKeepingName(Symbol * Other,size_t Size)67 void Symbol::replaceKeepingName(Symbol *Other, size_t Size) {
68 StringRef OrigName = Name;
69 memcpy(this, Other, Size);
70 Name = OrigName;
71 }
72
getCOFFSymbol()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
makeImportThunk(DefinedImportData * S,uint16_t Machine)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
DefinedImportThunk(StringRef Name,DefinedImportData * S,uint16_t Machine)94 DefinedImportThunk::DefinedImportThunk(StringRef Name, DefinedImportData *S,
95 uint16_t Machine)
96 : Defined(DefinedImportThunkKind, Name), WrappedSym(S),
97 Data(makeImportThunk(S, Machine)) {}
98
getWeakAlias()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