]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lld/COFF/Symbols.cpp
Update lldb to trunk r290819 and resolve conflicts.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lld / COFF / Symbols.cpp
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 namespace lld {
23 namespace coff {
24
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.
33   if (Name.empty()) {
34     auto *D = cast<DefinedCOFF>(this);
35     D->File->getCOFFObj()->getSymbolName(D->Sym, Name);
36   }
37   return Name;
38 }
39
40 InputFile *SymbolBody::getFile() {
41   if (auto *Sym = dyn_cast<DefinedCOFF>(this))
42     return Sym->File;
43   if (auto *Sym = dyn_cast<DefinedBitcode>(this))
44     return Sym->File;
45   if (auto *Sym = dyn_cast<Lazy>(this))
46     return Sym->File;
47   return nullptr;
48 }
49
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));
56 }
57
58 DefinedImportThunk::DefinedImportThunk(StringRef Name, DefinedImportData *S,
59                                        uint16_t Machine)
60     : Defined(DefinedImportThunkKind, Name) {
61   switch (Machine) {
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");
66   }
67 }
68
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))
73       return D;
74   return nullptr;
75 }
76
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();
81   return B.getName();
82 }
83
84 } // namespace coff
85 } // namespace lld