Coverage Report

Created: 2018-06-25 02:00

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/COFF/SymbolTable.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- SymbolTable.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 "SymbolTable.h"
11
#include "Config.h"
12
#include "Driver.h"
13
#include "LTO.h"
14
#include "PDB.h"
15
#include "Symbols.h"
16
#include "lld/Common/ErrorHandler.h"
17
#include "lld/Common/Memory.h"
18
#include "lld/Common/Timer.h"
19
#include "llvm/IR/LLVMContext.h"
20
#include "llvm/Support/Debug.h"
21
#include "llvm/Support/raw_ostream.h"
22
#include <utility>
23
24
using namespace llvm;
25
26
namespace lld {
27
namespace coff {
28
29
static Timer LTOTimer("LTO", Timer::root());
30
31
SymbolTable *Symtab;
32
33
633
void SymbolTable::addFile(InputFile *File) {
34
633
  log("Reading " + toString(File));
35
633
  File->parse();
36
633
37
633
  MachineTypes MT = File->getMachineType();
38
633
  if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) {
39
397
    Config->Machine = MT;
40
397
  } else 
if (236
MT != IMAGE_FILE_MACHINE_UNKNOWN236
&&
Config->Machine != MT98
) {
41
2
    error(toString(File) + ": machine type " + machineToStr(MT) +
42
2
          " conflicts with " + machineToStr(Config->Machine));
43
2
    return;
44
2
  }
45
631
46
631
  if (auto *F = dyn_cast<ObjFile>(File)) {
47
437
    ObjFile::Instances.push_back(F);
48
437
  } else 
if (auto *194
F194
= dyn_cast<BitcodeFile>(File)) {
49
52
    BitcodeFile::Instances.push_back(F);
50
142
  } else if (auto *F = dyn_cast<ImportFile>(File)) {
51
78
    ImportFile::Instances.push_back(F);
52
78
  }
53
631
54
631
  StringRef S = File->getDirectives();
55
631
  if (S.empty())
56
492
    return;
57
139
58
139
  log("Directives: " + toString(File) + ": " + S);
59
139
  Driver->parseDirectives(S);
60
139
}
61
62
26
static void errorOrWarn(const Twine &S) {
63
26
  if (Config->Force)
64
1
    warn(S);
65
25
  else
66
25
    error(S);
67
26
}
68
69
// Returns the name of the symbol in SC whose value is <= Addr that is closest
70
// to Addr. This is generally the name of the global variable or function whose
71
// definition contains Addr.
72
18
static StringRef getSymbolName(SectionChunk *SC, uint32_t Addr) {
73
18
  DefinedRegular *Candidate = nullptr;
74
18
75
290
  for (Symbol *S : SC->File->getSymbols()) {
76
290
    auto *D = dyn_cast_or_null<DefinedRegular>(S);
77
290
    if (!D || 
D->getChunk() != SC139
||
D->getValue() > Addr44
||
78
290
        
(38
Candidate38
&&
D->getValue() < Candidate->getValue()20
))
79
252
      continue;
80
38
81
38
    Candidate = D;
82
38
  }
83
18
84
18
  if (!Candidate)
85
0
    return "";
86
18
  return Candidate->getName();
87
18
}
88
89
16
static std::string getSymbolLocations(ObjFile *File, uint32_t SymIndex) {
90
16
  struct Location {
91
16
    StringRef SymName;
92
16
    std::pair<StringRef, uint32_t> FileLine;
93
16
  };
94
16
  std::vector<Location> Locations;
95
16
96
50
  for (Chunk *C : File->getChunks()) {
97
50
    auto *SC = dyn_cast<SectionChunk>(C);
98
50
    if (!SC)
99
0
      continue;
100
62
    
for (const coff_relocation &R : SC->Relocs)50
{
101
62
      if (R.SymbolTableIndex != SymIndex)
102
44
        continue;
103
18
      std::pair<StringRef, uint32_t> FileLine =
104
18
          getFileLine(SC, R.VirtualAddress);
105
18
      StringRef SymName = getSymbolName(SC, R.VirtualAddress);
106
18
      if (!FileLine.first.empty() || 
!SymName.empty()13
)
107
18
        Locations.push_back({SymName, FileLine});
108
18
    }
109
50
  }
110
16
111
16
  if (Locations.empty())
112
2
    return "\n>>> referenced by " + toString(File) + "\n";
113
14
114
14
  std::string Out;
115
14
  llvm::raw_string_ostream OS(Out);
116
18
  for (Location Loc : Locations) {
117
18
    OS << "\n>>> referenced by ";
118
18
    if (!Loc.FileLine.first.empty())
119
5
      OS << Loc.FileLine.first << ":" << Loc.FileLine.second
120
5
         << "\n>>>               ";
121
18
    OS << toString(File);
122
18
    if (!Loc.SymName.empty())
123
18
      OS << ":(" << Loc.SymName << ')';
124
18
  }
125
14
  OS << '\n';
126
14
  return OS.str();
127
14
}
128
129
400
void SymbolTable::reportRemainingUndefines() {
130
400
  SmallPtrSet<Symbol *, 8> Undefs;
131
400
  DenseMap<Symbol *, Symbol *> LocalImports;
132
400
133
5.07k
  for (auto &I : SymMap) {
134
5.07k
    Symbol *Sym = I.second;
135
5.07k
    auto *Undef = dyn_cast<Undefined>(Sym);
136
5.07k
    if (!Undef)
137
4.98k
      continue;
138
81
    if (!Sym->IsUsedInRegularObj)
139
21
      continue;
140
60
141
60
    StringRef Name = Undef->getName();
142
60
143
60
    // A weak alias may have been resolved, so check for that.
144
60
    if (Defined *D = Undef->getWeakAlias()) {
145
28
      // We want to replace Sym with D. However, we can't just blindly
146
28
      // copy sizeof(SymbolUnion) bytes from D to Sym because D may be an
147
28
      // internal symbol, and internal symbols are stored as "unparented"
148
28
      // Symbols. For that reason we need to check which type of symbol we
149
28
      // are dealing with and copy the correct number of bytes.
150
28
      if (isa<DefinedRegular>(D))
151
26
        memcpy(Sym, D, sizeof(DefinedRegular));
152
2
      else if (isa<DefinedAbsolute>(D))
153
0
        memcpy(Sym, D, sizeof(DefinedAbsolute));
154
2
      else
155
2
        memcpy(Sym, D, sizeof(SymbolUnion));
156
28
      continue;
157
28
    }
158
32
159
32
    // If we can resolve a symbol by removing __imp_ prefix, do that.
160
32
    // This odd rule is for compatibility with MSVC linker.
161
32
    if (Name.startswith("__imp_")) {
162
6
      Symbol *Imp = find(Name.substr(strlen("__imp_")));
163
6
      if (Imp && isa<Defined>(Imp)) {
164
6
        auto *D = cast<Defined>(Imp);
165
6
        replaceSymbol<DefinedLocalImport>(Sym, Name, D);
166
6
        LocalImportChunks.push_back(cast<DefinedLocalImport>(Sym)->getChunk());
167
6
        LocalImports[Sym] = D;
168
6
        continue;
169
6
      }
170
26
    }
171
26
172
26
    // Remaining undefined symbols are not fatal if /force is specified.
173
26
    // They are replaced with dummy defined symbols.
174
26
    if (Config->Force)
175
1
      replaceSymbol<DefinedAbsolute>(Sym, Name, 0);
176
26
    Undefs.insert(Sym);
177
26
  }
178
400
179
400
  if (Undefs.empty() && 
LocalImports.empty()385
)
180
379
    return;
181
21
182
22
  
for (Symbol *B : Config->GCRoot)21
{
183
22
    if (Undefs.count(B))
184
10
      errorOrWarn("<root>: undefined symbol: " + B->getName());
185
22
    if (Config->WarnLocallyDefinedImported)
186
21
      if (Symbol *Imp = LocalImports.lookup(B))
187
0
        warn("<root>: locally defined symbol imported: " + Imp->getName() +
188
0
             " (defined in " + toString(Imp->getFile()) + ") [LNK4217]");
189
22
  }
190
21
191
24
  for (ObjFile *File : ObjFile::Instances) {
192
24
    size_t SymIndex = -1ull;
193
167
    for (Symbol *Sym : File->getSymbols()) {
194
167
      ++SymIndex;
195
167
      if (!Sym)
196
58
        continue;
197
109
      if (Undefs.count(Sym))
198
16
        errorOrWarn("undefined symbol: " + Sym->getName() +
199
16
                    getSymbolLocations(File, SymIndex));
200
109
      if (Config->WarnLocallyDefinedImported)
201
104
        if (Symbol *Imp = LocalImports.lookup(Sym))
202
6
          warn(toString(File) + ": locally defined symbol imported: " +
203
6
               Imp->getName() + " (defined in " + toString(Imp->getFile()) +
204
6
               ") [LNK4217]");
205
109
    }
206
24
  }
207
21
}
208
209
6.25k
std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) {
210
6.25k
  Symbol *&Sym = SymMap[CachedHashStringRef(Name)];
211
6.25k
  if (Sym)
212
1.07k
    return {Sym, false};
213
5.18k
  Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
214
5.18k
  Sym->IsUsedInRegularObj = false;
215
5.18k
  Sym->PendingArchiveLoad = false;
216
5.18k
  return {Sym, true};
217
5.18k
}
218
219
Symbol *SymbolTable::addUndefined(StringRef Name, InputFile *F,
220
873
                                  bool IsWeakAlias) {
221
873
  Symbol *S;
222
873
  bool WasInserted;
223
873
  std::tie(S, WasInserted) = insert(Name);
224
873
  if (!F || 
!isa<BitcodeFile>(F)235
)
225
849
    S->IsUsedInRegularObj = true;
226
873
  if (WasInserted || 
(602
isa<Lazy>(S)602
&&
IsWeakAlias17
)) {
227
271
    replaceSymbol<Undefined>(S, Name);
228
271
    return S;
229
271
  }
230
602
  if (auto *L = dyn_cast<Lazy>(S)) {
231
17
    if (!S->PendingArchiveLoad) {
232
17
      S->PendingArchiveLoad = true;
233
17
      L->File->addMember(&L->Sym);
234
17
    }
235
17
  }
236
602
  return S;
237
602
}
238
239
342
void SymbolTable::addLazy(ArchiveFile *F, const Archive::Symbol Sym) {
240
342
  StringRef Name = Sym.getName();
241
342
  Symbol *S;
242
342
  bool WasInserted;
243
342
  std::tie(S, WasInserted) = insert(Name);
244
342
  if (WasInserted) {
245
247
    replaceSymbol<Lazy>(S, F, Sym);
246
247
    return;
247
247
  }
248
95
  auto *U = dyn_cast<Undefined>(S);
249
95
  if (!U || 
U->WeakAlias84
||
S->PendingArchiveLoad84
)
250
11
    return;
251
84
  S->PendingArchiveLoad = true;
252
84
  F->addMember(&Sym);
253
84
}
254
255
2
void SymbolTable::reportDuplicate(Symbol *Existing, InputFile *NewFile) {
256
2
  error("duplicate symbol: " + toString(*Existing) + " in " +
257
2
        toString(Existing->getFile()) + " and in " + toString(NewFile));
258
2
}
259
260
6
Symbol *SymbolTable::addAbsolute(StringRef N, COFFSymbolRef Sym) {
261
6
  Symbol *S;
262
6
  bool WasInserted;
263
6
  std::tie(S, WasInserted) = insert(N);
264
6
  S->IsUsedInRegularObj = true;
265
6
  if (WasInserted || 
isa<Undefined>(S)0
||
isa<Lazy>(S)0
)
266
6
    replaceSymbol<DefinedAbsolute>(S, N, Sym);
267
0
  else if (!isa<DefinedCOFF>(S))
268
0
    reportDuplicate(S, nullptr);
269
6
  return S;
270
6
}
271
272
3.40k
Symbol *SymbolTable::addAbsolute(StringRef N, uint64_t VA) {
273
3.40k
  Symbol *S;
274
3.40k
  bool WasInserted;
275
3.40k
  std::tie(S, WasInserted) = insert(N);
276
3.40k
  S->IsUsedInRegularObj = true;
277
3.40k
  if (WasInserted || 
isa<Undefined>(S)46
||
isa<Lazy>(S)0
)
278
3.40k
    replaceSymbol<DefinedAbsolute>(S, N, VA);
279
0
  else if (!isa<DefinedCOFF>(S))
280
0
    reportDuplicate(S, nullptr);
281
3.40k
  return S;
282
3.40k
}
283
284
409
Symbol *SymbolTable::addSynthetic(StringRef N, Chunk *C) {
285
409
  Symbol *S;
286
409
  bool WasInserted;
287
409
  std::tie(S, WasInserted) = insert(N);
288
409
  S->IsUsedInRegularObj = true;
289
409
  if (WasInserted || 
isa<Undefined>(S)17
||
isa<Lazy>(S)0
)
290
409
    replaceSymbol<DefinedSynthetic>(S, N, C);
291
0
  else if (!isa<DefinedCOFF>(S))
292
0
    reportDuplicate(S, nullptr);
293
409
  return S;
294
409
}
295
296
Symbol *SymbolTable::addRegular(InputFile *F, StringRef N,
297
                                const coff_symbol_generic *Sym,
298
779
                                SectionChunk *C) {
299
779
  Symbol *S;
300
779
  bool WasInserted;
301
779
  std::tie(S, WasInserted) = insert(N);
302
779
  if (!isa<BitcodeFile>(F))
303
718
    S->IsUsedInRegularObj = true;
304
779
  if (WasInserted || 
!isa<DefinedRegular>(S)58
)
305
779
    replaceSymbol<DefinedRegular>(S, F, N, /*IsCOMDAT*/ false,
306
779
                                  /*IsExternal*/ true, Sym, C);
307
0
  else
308
0
    reportDuplicate(S, F);
309
779
  return S;
310
779
}
311
312
std::pair<Symbol *, bool>
313
SymbolTable::addComdat(InputFile *F, StringRef N,
314
273
                       const coff_symbol_generic *Sym) {
315
273
  Symbol *S;
316
273
  bool WasInserted;
317
273
  std::tie(S, WasInserted) = insert(N);
318
273
  if (!isa<BitcodeFile>(F))
319
250
    S->IsUsedInRegularObj = true;
320
273
  if (WasInserted || 
!isa<DefinedRegular>(S)97
) {
321
254
    replaceSymbol<DefinedRegular>(S, F, N, /*IsCOMDAT*/ true,
322
254
                                  /*IsExternal*/ true, Sym, nullptr);
323
254
    return {S, true};
324
254
  }
325
19
  if (!cast<DefinedRegular>(S)->isCOMDAT())
326
0
    reportDuplicate(S, F);
327
19
  return {S, false};
328
19
}
329
330
Symbol *SymbolTable::addCommon(InputFile *F, StringRef N, uint64_t Size,
331
11
                               const coff_symbol_generic *Sym, CommonChunk *C) {
332
11
  Symbol *S;
333
11
  bool WasInserted;
334
11
  std::tie(S, WasInserted) = insert(N);
335
11
  if (!isa<BitcodeFile>(F))
336
11
    S->IsUsedInRegularObj = true;
337
11
  if (WasInserted || 
!isa<DefinedCOFF>(S)0
)
338
11
    replaceSymbol<DefinedCommon>(S, F, N, Size, Sym, C);
339
0
  else if (auto *DC = dyn_cast<DefinedCommon>(S))
340
0
    if (Size > DC->getSize())
341
0
      replaceSymbol<DefinedCommon>(S, F, N, Size, Sym, C);
342
11
  return S;
343
11
}
344
345
79
DefinedImportData *SymbolTable::addImportData(StringRef N, ImportFile *F) {
346
79
  Symbol *S;
347
79
  bool WasInserted;
348
79
  std::tie(S, WasInserted) = insert(N);
349
79
  S->IsUsedInRegularObj = true;
350
79
  if (WasInserted || isa<Undefined>(S) || 
isa<Lazy>(S)72
) {
351
78
    replaceSymbol<DefinedImportData>(S, N, F);
352
78
    return cast<DefinedImportData>(S);
353
78
  }
354
1
355
1
  reportDuplicate(S, F);
356
1
  return nullptr;
357
1
}
358
359
DefinedImportThunk *SymbolTable::addImportThunk(StringRef Name,
360
                                               DefinedImportData *ID,
361
76
                                               uint16_t Machine) {
362
76
  Symbol *S;
363
76
  bool WasInserted;
364
76
  std::tie(S, WasInserted) = insert(Name);
365
76
  S->IsUsedInRegularObj = true;
366
76
  if (WasInserted || isa<Undefined>(S) || 
isa<Lazy>(S)14
) {
367
75
    replaceSymbol<DefinedImportThunk>(S, Name, ID, Machine);
368
75
    return cast<DefinedImportThunk>(S);
369
75
  }
370
1
371
1
  reportDuplicate(S, ID->File);
372
1
  return nullptr;
373
1
}
374
375
986
std::vector<Chunk *> SymbolTable::getChunks() {
376
986
  std::vector<Chunk *> Res;
377
1.18k
  for (ObjFile *File : ObjFile::Instances) {
378
1.18k
    ArrayRef<Chunk *> V = File->getChunks();
379
1.18k
    Res.insert(Res.end(), V.begin(), V.end());
380
1.18k
  }
381
986
  return Res;
382
986
}
383
384
1.49k
Symbol *SymbolTable::find(StringRef Name) {
385
1.49k
  return SymMap.lookup(CachedHashStringRef(Name));
386
1.49k
}
387
388
1.38k
Symbol *SymbolTable::findUnderscore(StringRef Name) {
389
1.38k
  if (Config->Machine == I386)
390
221
    return find(("_" + Name).str());
391
1.16k
  return find(Name);
392
1.16k
}
393
394
72
StringRef SymbolTable::findByPrefix(StringRef Prefix) {
395
637
  for (auto Pair : SymMap) {
396
637
    StringRef Name = Pair.first.val();
397
637
    if (Name.startswith(Prefix))
398
18
      return Name;
399
637
  }
400
72
  
return ""54
;
401
72
}
402
403
63
StringRef SymbolTable::findMangle(StringRef Name) {
404
63
  if (Symbol *Sym = find(Name))
405
46
    if (!isa<Undefined>(Sym))
406
12
      return Name;
407
51
  if (Config->Machine != I386)
408
33
    return findByPrefix(("?" + Name + "@@Y").str());
409
18
  if (!Name.startswith("_"))
410
0
    return "";
411
18
  // Search for x86 stdcall function.
412
18
  StringRef S = findByPrefix((Name + "@").str());
413
18
  if (!S.empty())
414
10
    return S;
415
8
  // Search for x86 fastcall function.
416
8
  S = findByPrefix(("@" + Name.substr(1) + "@").str());
417
8
  if (!S.empty())
418
1
    return S;
419
7
  // Search for x86 vectorcall function.
420
7
  S = findByPrefix((Name.substr(1) + "@@").str());
421
7
  if (!S.empty())
422
1
    return S;
423
6
  // Search for x86 C++ non-member function.
424
6
  return findByPrefix(("?" + Name.substr(1) + "@@Y").str());
425
6
}
426
427
475
void SymbolTable::mangleMaybe(Symbol *B) {
428
475
  auto *U = dyn_cast<Undefined>(B);
429
475
  if (!U || 
U->WeakAlias39
)
430
441
    return;
431
34
  StringRef Alias = findMangle(U->getName());
432
34
  if (!Alias.empty()) {
433
17
    log(U->getName() + " aliased to " + Alias);
434
17
    U->WeakAlias = addUndefined(Alias);
435
17
  }
436
34
}
437
438
638
Symbol *SymbolTable::addUndefined(StringRef Name) {
439
638
  return addUndefined(Name, nullptr, false);
440
638
}
441
442
39
std::vector<StringRef> SymbolTable::compileBitcodeFiles() {
443
39
  LTO.reset(new BitcodeCompiler);
444
39
  for (BitcodeFile *F : BitcodeFile::Instances)
445
52
    LTO->add(*F);
446
39
  return LTO->compile();
447
39
}
448
449
400
void SymbolTable::addCombinedLTOObjects() {
450
400
  if (BitcodeFile::Instances.empty())
451
361
    return;
452
39
453
39
  ScopedTimer T(LTOTimer);
454
49
  for (StringRef Object : compileBitcodeFiles()) {
455
49
    auto *Obj = make<ObjFile>(MemoryBufferRef(Object, "lto.tmp"));
456
49
    Obj->parse();
457
49
    ObjFile::Instances.push_back(Obj);
458
49
  }
459
39
}
460
461
} // namespace coff
462
} // namespace lld