Coverage Report

Created: 2018-08-19 21:11

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