Symbols.cpp revision 305067
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 "Error.h"
11#include "InputFiles.h"
12#include "Symbols.h"
13#include "llvm/ADT/STLExtras.h"
14#include "llvm/Support/Debug.h"
15#include "llvm/Support/raw_ostream.h"
16
17using namespace llvm::object;
18using llvm::sys::fs::identify_magic;
19using llvm::sys::fs::file_magic;
20
21namespace lld {
22namespace coff {
23
24StringRef SymbolBody::getName() {
25  // DefinedCOFF names are read lazily for a performance reason.
26  // Non-external symbol names are never used by the linker except for logging
27  // or debugging. Their internal references are resolved not by name but by
28  // symbol index. And because they are not external, no one can refer them by
29  // name. Object files contain lots of non-external symbols, and creating
30  // StringRefs for them (which involves lots of strlen() on the string table)
31  // is a waste of time.
32  if (Name.empty()) {
33    auto *D = cast<DefinedCOFF>(this);
34    D->File->getCOFFObj()->getSymbolName(D->Sym, Name);
35  }
36  return Name;
37}
38
39// Returns 1, 0 or -1 if this symbol should take precedence
40// over the Other, tie or lose, respectively.
41int SymbolBody::compare(SymbolBody *Other) {
42  Kind LK = kind(), RK = Other->kind();
43
44  // Normalize so that the smaller kind is on the left.
45  if (LK > RK)
46    return -Other->compare(this);
47
48  // First handle comparisons between two different kinds.
49  if (LK != RK) {
50    if (RK > LastDefinedKind) {
51      if (LK == LazyKind && cast<Undefined>(Other)->WeakAlias)
52        return -1;
53
54      // The LHS is either defined or lazy and so it wins.
55      assert((LK <= LastDefinedKind || LK == LazyKind) && "Bad kind!");
56      return 1;
57    }
58
59    // Bitcode has special complexities.
60    if (RK == DefinedBitcodeKind) {
61      auto *RHS = cast<DefinedBitcode>(Other);
62
63      switch (LK) {
64      case DefinedCommonKind:
65        return 1;
66
67      case DefinedRegularKind:
68        // As an approximation, regular symbols win over bitcode symbols,
69        // but we definitely have a conflict if the regular symbol is not
70        // replaceable and neither is the bitcode symbol. We do not
71        // replicate the rest of the symbol resolution logic here; symbol
72        // resolution will be done accurately after lowering bitcode symbols
73        // to regular symbols in addCombinedLTOObject().
74        if (cast<DefinedRegular>(this)->isCOMDAT() || RHS->IsReplaceable)
75          return 1;
76
77        // Fallthrough to the default of a tie otherwise.
78      default:
79        return 0;
80      }
81    }
82
83    // Either of the object file kind will trump a higher kind.
84    if (LK <= LastDefinedCOFFKind)
85      return 1;
86
87    // The remaining kind pairs are ties amongst defined symbols.
88    return 0;
89  }
90
91  // Now handle the case where the kinds are the same.
92  switch (LK) {
93  case DefinedRegularKind: {
94    auto *LHS = cast<DefinedRegular>(this);
95    auto *RHS = cast<DefinedRegular>(Other);
96    if (LHS->isCOMDAT() && RHS->isCOMDAT())
97      return LHS->getFileIndex() < RHS->getFileIndex() ? 1 : -1;
98    return 0;
99  }
100
101  case DefinedCommonKind: {
102    auto *LHS = cast<DefinedCommon>(this);
103    auto *RHS = cast<DefinedCommon>(Other);
104    if (LHS->getSize() == RHS->getSize())
105      return LHS->getFileIndex() < RHS->getFileIndex() ? 1 : -1;
106    return LHS->getSize() > RHS->getSize() ? 1 : -1;
107  }
108
109  case DefinedBitcodeKind: {
110    auto *LHS = cast<DefinedBitcode>(this);
111    auto *RHS = cast<DefinedBitcode>(Other);
112    // If both are non-replaceable, we have a tie.
113    if (!LHS->IsReplaceable && !RHS->IsReplaceable)
114      return 0;
115
116    // Non-replaceable symbols win, but even two replaceable symboles don't
117    // tie. If both symbols are replaceable, choice is arbitrary.
118    if (RHS->IsReplaceable && LHS->IsReplaceable)
119      return uintptr_t(LHS) < uintptr_t(RHS) ? 1 : -1;
120    return LHS->IsReplaceable ? -1 : 1;
121  }
122
123  case LazyKind: {
124    // Don't tie, pick the earliest.
125    auto *LHS = cast<Lazy>(this);
126    auto *RHS = cast<Lazy>(Other);
127    return LHS->getFileIndex() < RHS->getFileIndex() ? 1 : -1;
128  }
129
130  case UndefinedKind: {
131    auto *LHS = cast<Undefined>(this);
132    auto *RHS = cast<Undefined>(Other);
133    // Tie if both undefined symbols have different weak aliases.
134    if (LHS->WeakAlias && RHS->WeakAlias) {
135      if (LHS->WeakAlias->getName() != RHS->WeakAlias->getName())
136        return 0;
137      return uintptr_t(LHS) < uintptr_t(RHS) ? 1 : -1;
138    }
139    return LHS->WeakAlias ? 1 : -1;
140  }
141
142  case DefinedLocalImportKind:
143  case DefinedImportThunkKind:
144  case DefinedImportDataKind:
145  case DefinedAbsoluteKind:
146  case DefinedRelativeKind:
147    // These all simply tie.
148    return 0;
149  }
150  llvm_unreachable("unknown symbol kind");
151}
152
153std::string SymbolBody::getDebugName() {
154  std::string N = getName().str();
155  if (auto *D = dyn_cast<DefinedCOFF>(this)) {
156    N += " ";
157    N += D->File->getShortName();
158  } else if (auto *D = dyn_cast<DefinedBitcode>(this)) {
159    N += " ";
160    N += D->File->getShortName();
161  }
162  return N;
163}
164
165COFFSymbolRef DefinedCOFF::getCOFFSymbol() {
166  size_t SymSize = File->getCOFFObj()->getSymbolTableEntrySize();
167  if (SymSize == sizeof(coff_symbol16))
168    return COFFSymbolRef(reinterpret_cast<const coff_symbol16 *>(Sym));
169  assert(SymSize == sizeof(coff_symbol32));
170  return COFFSymbolRef(reinterpret_cast<const coff_symbol32 *>(Sym));
171}
172
173DefinedImportThunk::DefinedImportThunk(StringRef Name, DefinedImportData *S,
174                                       uint16_t Machine)
175    : Defined(DefinedImportThunkKind, Name) {
176  switch (Machine) {
177  case AMD64: Data.reset(new ImportThunkChunkX64(S)); return;
178  case I386:  Data.reset(new ImportThunkChunkX86(S)); return;
179  case ARMNT: Data.reset(new ImportThunkChunkARM(S)); return;
180  default:    llvm_unreachable("unknown machine type");
181  }
182}
183
184std::unique_ptr<InputFile> Lazy::getMember() {
185  MemoryBufferRef MBRef = File->getMember(&Sym);
186
187  // getMember returns an empty buffer if the member was already
188  // read from the library.
189  if (MBRef.getBuffer().empty())
190    return std::unique_ptr<InputFile>(nullptr);
191
192  file_magic Magic = identify_magic(MBRef.getBuffer());
193  if (Magic == file_magic::coff_import_library)
194    return std::unique_ptr<InputFile>(new ImportFile(MBRef));
195
196  std::unique_ptr<InputFile> Obj;
197  if (Magic == file_magic::coff_object)
198    Obj.reset(new ObjectFile(MBRef));
199  else if (Magic == file_magic::bitcode)
200    Obj.reset(new BitcodeFile(MBRef));
201  else
202    fatal("unknown file type: " + File->getName());
203
204  Obj->setParentName(File->getName());
205  return Obj;
206}
207
208Defined *Undefined::getWeakAlias() {
209  // A weak alias may be a weak alias to another symbol, so check recursively.
210  for (SymbolBody *A = WeakAlias; A; A = cast<Undefined>(A)->WeakAlias)
211    if (auto *D = dyn_cast<Defined>(A->repl()))
212      return D;
213  return nullptr;
214}
215
216} // namespace coff
217} // namespace lld
218