Coverage Report

Created: 2019-05-19 14:56

/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
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "SymbolTable.h"
10
#include "Config.h"
11
#include "Driver.h"
12
#include "LTO.h"
13
#include "PDB.h"
14
#include "Symbols.h"
15
#include "lld/Common/ErrorHandler.h"
16
#include "lld/Common/Memory.h"
17
#include "lld/Common/Timer.h"
18
#include "llvm/IR/LLVMContext.h"
19
#include "llvm/Support/Debug.h"
20
#include "llvm/Support/raw_ostream.h"
21
#include <utility>
22
23
using namespace llvm;
24
25
namespace lld {
26
namespace coff {
27
28
static Timer LTOTimer("LTO", Timer::root());
29
30
SymbolTable *Symtab;
31
32
983
void SymbolTable::addFile(InputFile *File) {
33
983
  log("Reading " + toString(File));
34
983
  File->parse();
35
983
36
983
  MachineTypes MT = File->getMachineType();
37
983
  if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) {
38
587
    Config->Machine = MT;
39
587
  } else 
if (396
MT != IMAGE_FILE_MACHINE_UNKNOWN396
&&
Config->Machine != MT201
) {
40
2
    error(toString(File) + ": machine type " + machineToStr(MT) +
41
2
          " conflicts with " + machineToStr(Config->Machine));
42
2
    return;
43
2
  }
44
981
45
981
  if (auto *F = dyn_cast<ObjFile>(File)) {
46
720
    ObjFile::Instances.push_back(F);
47
720
  } else 
if (auto *261
F261
= dyn_cast<BitcodeFile>(File)) {
48
60
    BitcodeFile::Instances.push_back(F);
49
201
  } else if (auto *F = dyn_cast<ImportFile>(File)) {
50
109
    ImportFile::Instances.push_back(F);
51
109
  }
52
981
53
981
  Driver->parseDirectives(File);
54
981
}
55
56
66
static void errorOrWarn(const Twine &S) {
57
66
  if (Config->ForceUnresolved)
58
20
    warn(S);
59
46
  else
60
46
    error(S);
61
66
}
62
63
// Returns the symbol in SC whose value is <= Addr that is closest to Addr.
64
// This is generally the global variable or function whose definition contains
65
// Addr.
66
42
static Symbol *getSymbol(SectionChunk *SC, uint32_t Addr) {
67
42
  DefinedRegular *Candidate = nullptr;
68
42
69
667
  for (Symbol *S : SC->File->getSymbols()) {
70
667
    auto *D = dyn_cast_or_null<DefinedRegular>(S);
71
667
    if (!D || 
D->getChunk() != SC313
||
D->getValue() > Addr104
||
72
667
        
(92
Candidate92
&&
D->getValue() < Candidate->getValue()50
))
73
575
      continue;
74
92
75
92
    Candidate = D;
76
92
  }
77
42
78
42
  return Candidate;
79
42
}
80
81
35
std::string getSymbolLocations(ObjFile *File, uint32_t SymIndex) {
82
35
  struct Location {
83
35
    Symbol *Sym;
84
35
    std::pair<StringRef, uint32_t> FileLine;
85
35
  };
86
35
  std::vector<Location> Locations;
87
35
88
115
  for (Chunk *C : File->getChunks()) {
89
115
    auto *SC = dyn_cast<SectionChunk>(C);
90
115
    if (!SC)
91
0
      continue;
92
133
    
for (const coff_relocation &R : SC->getRelocs())115
{
93
133
      if (R.SymbolTableIndex != SymIndex)
94
91
        continue;
95
42
      std::pair<StringRef, uint32_t> FileLine =
96
42
          getFileLine(SC, R.VirtualAddress);
97
42
      Symbol *Sym = getSymbol(SC, R.VirtualAddress);
98
42
      if (!FileLine.first.empty() || 
Sym31
)
99
42
        Locations.push_back({Sym, FileLine});
100
42
    }
101
115
  }
102
35
103
35
  if (Locations.empty())
104
2
    return "\n>>> referenced by " + toString(File);
105
33
106
33
  std::string Out;
107
33
  llvm::raw_string_ostream OS(Out);
108
42
  for (Location Loc : Locations) {
109
42
    OS << "\n>>> referenced by ";
110
42
    if (!Loc.FileLine.first.empty())
111
11
      OS << Loc.FileLine.first << ":" << Loc.FileLine.second
112
11
         << "\n>>>               ";
113
42
    OS << toString(File);
114
42
    if (Loc.Sym)
115
42
      OS << ":(" << toString(*Loc.Sym) << ')';
116
42
  }
117
33
  return OS.str();
118
33
}
119
120
43
void SymbolTable::loadMinGWAutomaticImports() {
121
769
  for (auto &I : SymMap) {
122
769
    Symbol *Sym = I.second;
123
769
    auto *Undef = dyn_cast<Undefined>(Sym);
124
769
    if (!Undef)
125
759
      continue;
126
10
    if (!Sym->IsUsedInRegularObj)
127
0
      continue;
128
10
129
10
    StringRef Name = Undef->getName();
130
10
131
10
    if (Name.startswith("__imp_"))
132
0
      continue;
133
10
    // If we have an undefined symbol, but we have a Lazy representing a
134
10
    // symbol we could load from file, make sure to load that.
135
10
    Lazy *L = dyn_cast_or_null<Lazy>(find(("__imp_" + Name).str()));
136
10
    if (!L || 
L->PendingArchiveLoad7
)
137
3
      continue;
138
7
139
7
    log("Loading lazy " + L->getName() + " from " + L->File->getName() +
140
7
        " for automatic import");
141
7
    L->PendingArchiveLoad = true;
142
7
    L->File->addMember(&L->Sym);
143
7
  }
144
43
}
145
146
8
bool SymbolTable::handleMinGWAutomaticImport(Symbol *Sym, StringRef Name) {
147
8
  if (Name.startswith("__imp_"))
148
0
    return false;
149
8
  Defined *Imp = dyn_cast_or_null<Defined>(find(("__imp_" + Name).str()));
150
8
  if (!Imp)
151
1
    return false;
152
7
153
7
  // Replace the reference directly to a variable with a reference
154
7
  // to the import address table instead. This obviously isn't right,
155
7
  // but we mark the symbol as IsRuntimePseudoReloc, and a later pass
156
7
  // will add runtime pseudo relocations for every relocation against
157
7
  // this Symbol. The runtime pseudo relocation framework expects the
158
7
  // reference itself to point at the IAT entry.
159
7
  size_t ImpSize = 0;
160
7
  if (isa<DefinedImportData>(Imp)) {
161
6
    log("Automatically importing " + Name + " from " +
162
6
        cast<DefinedImportData>(Imp)->getDLLName());
163
6
    ImpSize = sizeof(DefinedImportData);
164
6
  } else 
if (1
isa<DefinedRegular>(Imp)1
) {
165
1
    log("Automatically importing " + Name + " from " +
166
1
        toString(cast<DefinedRegular>(Imp)->File));
167
1
    ImpSize = sizeof(DefinedRegular);
168
1
  } else {
169
0
    warn("unable to automatically import " + Name + " from " + Imp->getName() +
170
0
         " from " + toString(cast<DefinedRegular>(Imp)->File) +
171
0
         "; unexpected symbol type");
172
0
    return false;
173
0
  }
174
7
  Sym->replaceKeepingName(Imp, ImpSize);
175
7
  Sym->IsRuntimePseudoReloc = true;
176
7
177
7
  // There may exist symbols named .refptr.<name> which only consist
178
7
  // of a single pointer to <name>. If it turns out <name> is
179
7
  // automatically imported, we don't need to keep the .refptr.<name>
180
7
  // pointer at all, but redirect all accesses to it to the IAT entry
181
7
  // for __imp_<name> instead, and drop the whole .refptr.<name> chunk.
182
7
  DefinedRegular *Refptr =
183
7
      dyn_cast_or_null<DefinedRegular>(find((".refptr." + Name).str()));
184
7
  if (Refptr && 
Refptr->getChunk()->getSize() == Config->Wordsize1
) {
185
1
    SectionChunk *SC = dyn_cast_or_null<SectionChunk>(Refptr->getChunk());
186
1
    if (SC && SC->getRelocs().size() == 1 && *SC->symbols().begin() == Sym) {
187
1
      log("Replacing .refptr." + Name + " with " + Imp->getName());
188
1
      Refptr->getChunk()->Live = false;
189
1
      Refptr->replaceKeepingName(Imp, ImpSize);
190
1
    }
191
1
  }
192
7
  return true;
193
7
}
194
195
573
void SymbolTable::reportRemainingUndefines() {
196
573
  SmallPtrSet<Symbol *, 8> Undefs;
197
573
  DenseMap<Symbol *, Symbol *> LocalImports;
198
573
199
7.40k
  for (auto &I : SymMap) {
200
7.40k
    Symbol *Sym = I.second;
201
7.40k
    auto *Undef = dyn_cast<Undefined>(Sym);
202
7.40k
    if (!Undef)
203
7.26k
      continue;
204
141
    if (!Sym->IsUsedInRegularObj)
205
21
      continue;
206
120
207
120
    StringRef Name = Undef->getName();
208
120
209
120
    // A weak alias may have been resolved, so check for that.
210
120
    if (Defined *D = Undef->getWeakAlias()) {
211
33
      // We want to replace Sym with D. However, we can't just blindly
212
33
      // copy sizeof(SymbolUnion) bytes from D to Sym because D may be an
213
33
      // internal symbol, and internal symbols are stored as "unparented"
214
33
      // Symbols. For that reason we need to check which type of symbol we
215
33
      // are dealing with and copy the correct number of bytes.
216
33
      if (isa<DefinedRegular>(D))
217
31
        memcpy(Sym, D, sizeof(DefinedRegular));
218
2
      else if (isa<DefinedAbsolute>(D))
219
0
        memcpy(Sym, D, sizeof(DefinedAbsolute));
220
2
      else
221
2
        memcpy(Sym, D, sizeof(SymbolUnion));
222
33
      continue;
223
33
    }
224
87
225
87
    // If we can resolve a symbol by removing __imp_ prefix, do that.
226
87
    // This odd rule is for compatibility with MSVC linker.
227
87
    if (Name.startswith("__imp_")) {
228
12
      Symbol *Imp = find(Name.substr(strlen("__imp_")));
229
12
      if (Imp && 
isa<Defined>(Imp)9
) {
230
9
        auto *D = cast<Defined>(Imp);
231
9
        replaceSymbol<DefinedLocalImport>(Sym, Name, D);
232
9
        LocalImportChunks.push_back(cast<DefinedLocalImport>(Sym)->getChunk());
233
9
        LocalImports[Sym] = D;
234
9
        continue;
235
9
      }
236
78
    }
237
78
238
78
    // We don't want to report missing Microsoft precompiled headers symbols.
239
78
    // A proper message will be emitted instead in PDBLinker::aquirePrecompObj
240
78
    if (Name.contains("_PchSym_"))
241
5
      continue;
242
73
243
73
    if (Config->MinGW && 
handleMinGWAutomaticImport(Sym, Name)8
)
244
7
      continue;
245
66
246
66
    // Remaining undefined symbols are not fatal if /force is specified.
247
66
    // They are replaced with dummy defined symbols.
248
66
    if (Config->ForceUnresolved)
249
20
      replaceSymbol<DefinedAbsolute>(Sym, Name, 0);
250
66
    Undefs.insert(Sym);
251
66
  }
252
573
253
573
  if (Undefs.empty() && 
LocalImports.empty()533
)
254
524
    return;
255
49
256
58
  
for (Symbol *B : Config->GCRoot)49
{
257
58
    if (Undefs.count(B))
258
34
      errorOrWarn("<root>: undefined symbol: " + toString(*B));
259
58
    if (Config->WarnLocallyDefinedImported)
260
56
      if (Symbol *Imp = LocalImports.lookup(B))
261
0
        warn("<root>: locally defined symbol imported: " + toString(*Imp) +
262
0
             " (defined in " + toString(Imp->getFile()) + ") [LNK4217]");
263
58
  }
264
49
265
60
  for (ObjFile *File : ObjFile::Instances) {
266
60
    size_t SymIndex = (size_t)-1;
267
582
    for (Symbol *Sym : File->getSymbols()) {
268
582
      ++SymIndex;
269
582
      if (!Sym)
270
264
        continue;
271
318
      if (Undefs.count(Sym))
272
32
        errorOrWarn("undefined symbol: " + toString(*Sym) +
273
32
                    getSymbolLocations(File, SymIndex));
274
318
      if (Config->WarnLocallyDefinedImported)
275
307
        if (Symbol *Imp = LocalImports.lookup(Sym))
276
8
          warn(toString(File) +
277
8
               ": locally defined symbol imported: " + toString(*Imp) +
278
8
               " (defined in " + toString(Imp->getFile()) + ") [LNK4217]");
279
318
    }
280
60
  }
281
49
}
282
283
8.96k
std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) {
284
8.96k
  bool Inserted = false;
285
8.96k
  Symbol *&Sym = SymMap[CachedHashStringRef(Name)];
286
8.96k
  if (!Sym) {
287
7.49k
    Sym = reinterpret_cast<Symbol *>(make<SymbolUnion>());
288
7.49k
    Sym->IsUsedInRegularObj = false;
289
7.49k
    Sym->PendingArchiveLoad = false;
290
7.49k
    Inserted = true;
291
7.49k
  }
292
8.96k
  return {Sym, Inserted};
293
8.96k
}
294
295
8.46k
std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, InputFile *File) {
296
8.46k
  std::pair<Symbol *, bool> Result = insert(Name);
297
8.46k
  if (!File || 
!isa<BitcodeFile>(File)1.84k
)
298
8.34k
    Result.first->IsUsedInRegularObj = true;
299
8.46k
  return Result;
300
8.46k
}
301
302
Symbol *SymbolTable::addUndefined(StringRef Name, InputFile *F,
303
1.20k
                                  bool IsWeakAlias) {
304
1.20k
  Symbol *S;
305
1.20k
  bool WasInserted;
306
1.20k
  std::tie(S, WasInserted) = insert(Name, F);
307
1.20k
  if (WasInserted || 
(768
isa<Lazy>(S)768
&&
IsWeakAlias29
)) {
308
435
    replaceSymbol<Undefined>(S, Name);
309
435
    return S;
310
435
  }
311
768
  if (auto *L = dyn_cast<Lazy>(S)) {
312
29
    if (!S->PendingArchiveLoad) {
313
29
      S->PendingArchiveLoad = true;
314
29
      L->File->addMember(&L->Sym);
315
29
    }
316
29
  }
317
768
  return S;
318
768
}
319
320
503
void SymbolTable::addLazy(ArchiveFile *F, const Archive::Symbol Sym) {
321
503
  StringRef Name = Sym.getName();
322
503
  Symbol *S;
323
503
  bool WasInserted;
324
503
  std::tie(S, WasInserted) = insert(Name);
325
503
  if (WasInserted) {
326
371
    replaceSymbol<Lazy>(S, F, Sym);
327
371
    return;
328
371
  }
329
132
  auto *U = dyn_cast<Undefined>(S);
330
132
  if (!U || 
U->WeakAlias116
||
S->PendingArchiveLoad116
)
331
16
    return;
332
116
  S->PendingArchiveLoad = true;
333
116
  F->addMember(&Sym);
334
116
}
335
336
20
void SymbolTable::reportDuplicate(Symbol *Existing, InputFile *NewFile) {
337
20
  std::string Msg = "duplicate symbol: " + toString(*Existing) + " in " +
338
20
                    toString(Existing->getFile()) + " and in " +
339
20
                    toString(NewFile);
340
20
341
20
  if (Config->ForceMultiple)
342
3
    warn(Msg);
343
17
  else
344
17
    error(Msg);
345
20
}
346
347
8
Symbol *SymbolTable::addAbsolute(StringRef N, COFFSymbolRef Sym) {
348
8
  Symbol *S;
349
8
  bool WasInserted;
350
8
  std::tie(S, WasInserted) = insert(N, nullptr);
351
8
  S->IsUsedInRegularObj = true;
352
8
  if (WasInserted || 
isa<Undefined>(S)0
||
isa<Lazy>(S)0
)
353
8
    replaceSymbol<DefinedAbsolute>(S, N, Sym);
354
0
  else if (!isa<DefinedCOFF>(S))
355
0
    reportDuplicate(S, nullptr);
356
8
  return S;
357
8
}
358
359
4.97k
Symbol *SymbolTable::addAbsolute(StringRef N, uint64_t VA) {
360
4.97k
  Symbol *S;
361
4.97k
  bool WasInserted;
362
4.97k
  std::tie(S, WasInserted) = insert(N, nullptr);
363
4.97k
  S->IsUsedInRegularObj = true;
364
4.97k
  if (WasInserted || 
isa<Undefined>(S)77
||
isa<Lazy>(S)0
)
365
4.97k
    replaceSymbol<DefinedAbsolute>(S, N, VA);
366
0
  else if (!isa<DefinedCOFF>(S))
367
0
    reportDuplicate(S, nullptr);
368
4.97k
  return S;
369
4.97k
}
370
371
577
Symbol *SymbolTable::addSynthetic(StringRef N, Chunk *C) {
372
577
  Symbol *S;
373
577
  bool WasInserted;
374
577
  std::tie(S, WasInserted) = insert(N, nullptr);
375
577
  S->IsUsedInRegularObj = true;
376
577
  if (WasInserted || 
isa<Undefined>(S)26
||
isa<Lazy>(S)0
)
377
577
    replaceSymbol<DefinedSynthetic>(S, N, C);
378
0
  else if (!isa<DefinedCOFF>(S))
379
0
    reportDuplicate(S, nullptr);
380
577
  return S;
381
577
}
382
383
Symbol *SymbolTable::addRegular(InputFile *F, StringRef N,
384
                                const coff_symbol_generic *Sym,
385
1.10k
                                SectionChunk *C) {
386
1.10k
  Symbol *S;
387
1.10k
  bool WasInserted;
388
1.10k
  std::tie(S, WasInserted) = insert(N, F);
389
1.10k
  if (WasInserted || 
!isa<DefinedRegular>(S)112
)
390
1.09k
    replaceSymbol<DefinedRegular>(S, F, N, /*IsCOMDAT*/ false,
391
1.09k
                                  /*IsExternal*/ true, Sym, C);
392
8
  else
393
8
    reportDuplicate(S, F);
394
1.10k
  return S;
395
1.10k
}
396
397
std::pair<DefinedRegular *, bool>
398
SymbolTable::addComdat(InputFile *F, StringRef N,
399
378
                       const coff_symbol_generic *Sym) {
400
378
  Symbol *S;
401
378
  bool WasInserted;
402
378
  std::tie(S, WasInserted) = insert(N, F);
403
378
  if (WasInserted || 
!isa<DefinedRegular>(S)148
) {
404
329
    replaceSymbol<DefinedRegular>(S, F, N, /*IsCOMDAT*/ true,
405
329
                                  /*IsExternal*/ true, Sym, nullptr);
406
329
    return {cast<DefinedRegular>(S), true};
407
329
  }
408
49
  auto *ExistingSymbol = cast<DefinedRegular>(S);
409
49
  if (!ExistingSymbol->isCOMDAT())
410
0
    reportDuplicate(S, F);
411
49
  return {ExistingSymbol, false};
412
49
}
413
414
Symbol *SymbolTable::addCommon(InputFile *F, StringRef N, uint64_t Size,
415
12
                               const coff_symbol_generic *Sym, CommonChunk *C) {
416
12
  Symbol *S;
417
12
  bool WasInserted;
418
12
  std::tie(S, WasInserted) = insert(N, F);
419
12
  if (WasInserted || 
!isa<DefinedCOFF>(S)0
)
420
12
    replaceSymbol<DefinedCommon>(S, F, N, Size, Sym, C);
421
0
  else if (auto *DC = dyn_cast<DefinedCommon>(S))
422
0
    if (Size > DC->getSize())
423
0
      replaceSymbol<DefinedCommon>(S, F, N, Size, Sym, C);
424
12
  return S;
425
12
}
426
427
110
Symbol *SymbolTable::addImportData(StringRef N, ImportFile *F) {
428
110
  Symbol *S;
429
110
  bool WasInserted;
430
110
  std::tie(S, WasInserted) = insert(N, nullptr);
431
110
  S->IsUsedInRegularObj = true;
432
110
  if (WasInserted || isa<Undefined>(S) || 
isa<Lazy>(S)99
) {
433
108
    replaceSymbol<DefinedImportData>(S, N, F);
434
108
    return S;
435
108
  }
436
2
437
2
  reportDuplicate(S, F);
438
2
  return nullptr;
439
2
}
440
441
Symbol *SymbolTable::addImportThunk(StringRef Name, DefinedImportData *ID,
442
99
                                    uint16_t Machine) {
443
99
  Symbol *S;
444
99
  bool WasInserted;
445
99
  std::tie(S, WasInserted) = insert(Name, nullptr);
446
99
  S->IsUsedInRegularObj = true;
447
99
  if (WasInserted || isa<Undefined>(S) || 
isa<Lazy>(S)20
) {
448
98
    replaceSymbol<DefinedImportThunk>(S, Name, ID, Machine);
449
98
    return S;
450
98
  }
451
1
452
1
  reportDuplicate(S, ID->File);
453
1
  return nullptr;
454
1
}
455
456
1.42k
std::vector<Chunk *> SymbolTable::getChunks() {
457
1.42k
  std::vector<Chunk *> Res;
458
1.85k
  for (ObjFile *File : ObjFile::Instances) {
459
1.85k
    ArrayRef<Chunk *> V = File->getChunks();
460
1.85k
    Res.insert(Res.end(), V.begin(), V.end());
461
1.85k
  }
462
1.42k
  return Res;
463
1.42k
}
464
465
3.33k
Symbol *SymbolTable::find(StringRef Name) {
466
3.33k
  return SymMap.lookup(CachedHashStringRef(Name));
467
3.33k
}
468
469
1.89k
Symbol *SymbolTable::findUnderscore(StringRef Name) {
470
1.89k
  if (Config->Machine == I386)
471
325
    return find(("_" + Name).str());
472
1.57k
  return find(Name);
473
1.57k
}
474
475
1.24k
StringRef SymbolTable::findByPrefix(StringRef Prefix) {
476
4.38k
  for (auto Pair : SymMap) {
477
4.38k
    StringRef Name = Pair.first.val();
478
4.38k
    if (Name.startswith(Prefix))
479
26
      return Name;
480
4.38k
  }
481
1.24k
  
return ""1.22k
;
482
1.24k
}
483
484
1.09k
StringRef SymbolTable::findMangle(StringRef Name) {
485
1.09k
  if (Symbol *Sym = find(Name))
486
311
    if (!isa<Undefined>(Sym))
487
254
      return Name;
488
838
  if (Config->Machine != I386)
489
687
    return findByPrefix(("?" + Name + "@@Y").str());
490
151
  if (!Name.startswith("_"))
491
0
    return "";
492
151
  // Search for x86 stdcall function.
493
151
  StringRef S = findByPrefix((Name + "@").str());
494
151
  if (!S.empty())
495
14
    return S;
496
137
  // Search for x86 fastcall function.
497
137
  S = findByPrefix(("@" + Name.substr(1) + "@").str());
498
137
  if (!S.empty())
499
1
    return S;
500
136
  // Search for x86 vectorcall function.
501
136
  S = findByPrefix((Name.substr(1) + "@@").str());
502
136
  if (!S.empty())
503
1
    return S;
504
135
  // Search for x86 C++ non-member function.
505
135
  return findByPrefix(("?" + Name.substr(1) + "@@Y").str());
506
135
}
507
508
626
void SymbolTable::mangleMaybe(Symbol *B) {
509
626
  auto *U = dyn_cast<Undefined>(B);
510
626
  if (!U || 
U->WeakAlias62
)
511
569
    return;
512
57
  StringRef Alias = findMangle(U->getName());
513
57
  if (!Alias.empty()) {
514
19
    log(U->getName() + " aliased to " + Alias);
515
19
    U->WeakAlias = addUndefined(Alias);
516
19
  }
517
57
}
518
519
846
Symbol *SymbolTable::addUndefined(StringRef Name) {
520
846
  return addUndefined(Name, nullptr, false);
521
846
}
522
523
43
std::vector<StringRef> SymbolTable::compileBitcodeFiles() {
524
43
  LTO.reset(new BitcodeCompiler);
525
43
  for (BitcodeFile *F : BitcodeFile::Instances)
526
58
    LTO->add(*F);
527
43
  return LTO->compile();
528
43
}
529
530
573
void SymbolTable::addCombinedLTOObjects() {
531
573
  if (BitcodeFile::Instances.empty())
532
530
    return;
533
43
534
43
  ScopedTimer T(LTOTimer);
535
56
  for (StringRef Object : compileBitcodeFiles()) {
536
56
    auto *Obj = make<ObjFile>(MemoryBufferRef(Object, "lto.tmp"));
537
56
    Obj->parse();
538
56
    ObjFile::Instances.push_back(Obj);
539
56
  }
540
43
}
541
542
} // namespace coff
543
} // namespace lld