1//===- DebugTypes.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 "DebugTypes.h"
10#include "Chunks.h"
11#include "Driver.h"
12#include "InputFiles.h"
13#include "PDB.h"
14#include "TypeMerger.h"
15#include "lld/Common/ErrorHandler.h"
16#include "lld/Common/Memory.h"
17#include "lld/Common/Timer.h"
18#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
19#include "llvm/DebugInfo/CodeView/TypeRecord.h"
20#include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
21#include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"
22#include "llvm/DebugInfo/PDB/GenericError.h"
23#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
24#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
25#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
26#include "llvm/DebugInfo/PDB/Native/TpiHashing.h"
27#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
28#include "llvm/Support/FormatVariadic.h"
29#include "llvm/Support/Parallel.h"
30#include "llvm/Support/Path.h"
31
32using namespace llvm;
33using namespace llvm::codeview;
34using namespace lld;
35using namespace lld::coff;
36
37namespace {
38class TypeServerIpiSource;
39
40// The TypeServerSource class represents a PDB type server, a file referenced by
41// OBJ files compiled with MSVC /Zi. A single PDB can be shared by several OBJ
42// files, therefore there must be only once instance per OBJ lot. The file path
43// is discovered from the dependent OBJ's debug type stream. The
44// TypeServerSource object is then queued and loaded by the COFF Driver. The
45// debug type stream for such PDB files will be merged first in the final PDB,
46// before any dependent OBJ.
47class TypeServerSource : public TpiSource {
48public:
49 explicit TypeServerSource(PDBInputFile *f)
50 : TpiSource(PDB, nullptr), pdbInputFile(f) {
51 if (f->loadErr && *f->loadErr)
52 return;
53 pdb::PDBFile &file = f->session->getPDBFile();
54 auto expectedInfo = file.getPDBInfoStream();
55 if (!expectedInfo)
56 return;
57 auto it = mappings.emplace(expectedInfo->getGuid(), this);
58 assert(it.second);
59 (void)it;
60 }
61
62 Error mergeDebugT(TypeMerger *m) override;
63
64 void loadGHashes() override;
65 void remapTpiWithGHashes(GHashState *g) override;
66
67 bool isDependency() const override { return true; }
68
69 PDBInputFile *pdbInputFile = nullptr;
70
71 // TpiSource for IPI stream.
72 TypeServerIpiSource *ipiSrc = nullptr;
73
74 static std::map<codeview::GUID, TypeServerSource *> mappings;
75};
76
77// Companion to TypeServerSource. Stores the index map for the IPI stream in the
78// PDB. Modeling PDBs with two sources for TPI and IPI helps establish the
79// invariant of one type index space per source.
80class TypeServerIpiSource : public TpiSource {
81public:
82 explicit TypeServerIpiSource() : TpiSource(PDBIpi, nullptr) {}
83
84 friend class TypeServerSource;
85
86 // All of the TpiSource methods are no-ops. The parent TypeServerSource
87 // handles both TPI and IPI.
88 Error mergeDebugT(TypeMerger *m) override { return Error::success(); }
89 void loadGHashes() override {}
90 void remapTpiWithGHashes(GHashState *g) override {}
91 bool isDependency() const override { return true; }
92};
93
94// This class represents the debug type stream of an OBJ file that depends on a
95// PDB type server (see TypeServerSource).
96class UseTypeServerSource : public TpiSource {
97 Expected<TypeServerSource *> getTypeServerSource();
98
99public:
100 UseTypeServerSource(ObjFile *f, TypeServer2Record ts)
101 : TpiSource(UsingPDB, f), typeServerDependency(ts) {}
102
103 Error mergeDebugT(TypeMerger *m) override;
104
105 // No need to load ghashes from /Zi objects.
106 void loadGHashes() override {}
107 void remapTpiWithGHashes(GHashState *g) override;
108
109 // Information about the PDB type server dependency, that needs to be loaded
110 // in before merging this OBJ.
111 TypeServer2Record typeServerDependency;
112};
113
114// This class represents the debug type stream of a Microsoft precompiled
115// headers OBJ (PCH OBJ). This OBJ kind needs to be merged first in the output
116// PDB, before any other OBJs that depend on this. Note that only MSVC generate
117// such files, clang does not.
118class PrecompSource : public TpiSource {
119public:
120 PrecompSource(ObjFile *f) : TpiSource(PCH, f) {
121 if (!f->pchSignature || !*f->pchSignature)
122 fatal(toString(f) +
123 " claims to be a PCH object, but does not have a valid signature");
124 auto it = mappings.emplace(*f->pchSignature, this);
125 if (!it.second)
126 fatal("a PCH object with the same signature has already been provided (" +
127 toString(it.first->second->file) + " and " + toString(file) + ")");
128 }
129
130 void loadGHashes() override;
131
132 bool isDependency() const override { return true; }
133
134 static std::map<uint32_t, PrecompSource *> mappings;
135};
136
137// This class represents the debug type stream of an OBJ file that depends on a
138// Microsoft precompiled headers OBJ (see PrecompSource).
139class UsePrecompSource : public TpiSource {
140public:
141 UsePrecompSource(ObjFile *f, PrecompRecord precomp)
142 : TpiSource(UsingPCH, f), precompDependency(precomp) {}
143
144 Error mergeDebugT(TypeMerger *m) override;
145
146 void loadGHashes() override;
147 void remapTpiWithGHashes(GHashState *g) override;
148
149private:
150 Error mergeInPrecompHeaderObj();
151
152public:
153 // Information about the Precomp OBJ dependency, that needs to be loaded in
154 // before merging this OBJ.
155 PrecompRecord precompDependency;
156};
157} // namespace
158
159std::vector<TpiSource *> TpiSource::instances;
160ArrayRef<TpiSource *> TpiSource::dependencySources;
161ArrayRef<TpiSource *> TpiSource::objectSources;
162
163TpiSource::TpiSource(TpiKind k, ObjFile *f)
164 : kind(k), tpiSrcIdx(instances.size()), file(f) {
165 instances.push_back(this);
166}
167
168// Vtable key method.
169TpiSource::~TpiSource() {
170 // Silence any assertions about unchecked errors.
171 consumeError(std::move(typeMergingError));
172}
173
174void TpiSource::sortDependencies() {
175 // Order dependencies first, but preserve the existing order.
176 std::vector<TpiSource *> deps;
177 std::vector<TpiSource *> objs;
178 for (TpiSource *s : instances)
179 (s->isDependency() ? deps : objs).push_back(s);
180 uint32_t numDeps = deps.size();
181 uint32_t numObjs = objs.size();
182 instances = std::move(deps);
183 instances.insert(instances.end(), objs.begin(), objs.end());
184 for (uint32_t i = 0, e = instances.size(); i < e; ++i)
185 instances[i]->tpiSrcIdx = i;
186 dependencySources = makeArrayRef(instances.data(), numDeps);
187 objectSources = makeArrayRef(instances.data() + numDeps, numObjs);
188}
189
190TpiSource *lld::coff::makeTpiSource(ObjFile *file) {
191 return make<TpiSource>(TpiSource::Regular, file);
192}
193
194TpiSource *lld::coff::makeTypeServerSource(PDBInputFile *pdbInputFile) {
195 // Type server sources come in pairs: the TPI stream, and the IPI stream.
196 auto *tpiSource = make<TypeServerSource>(pdbInputFile);
197 if (pdbInputFile->session->getPDBFile().hasPDBIpiStream())
198 tpiSource->ipiSrc = make<TypeServerIpiSource>();
199 return tpiSource;
200}
201
202TpiSource *lld::coff::makeUseTypeServerSource(ObjFile *file,
203 TypeServer2Record ts) {
204 return make<UseTypeServerSource>(file, ts);
205}
206
207TpiSource *lld::coff::makePrecompSource(ObjFile *file) {
208 return make<PrecompSource>(file);
209}
210
211TpiSource *lld::coff::makeUsePrecompSource(ObjFile *file,
212 PrecompRecord precomp) {
213 return make<UsePrecompSource>(file, precomp);
214}
215
216std::map<codeview::GUID, TypeServerSource *> TypeServerSource::mappings;
217
218std::map<uint32_t, PrecompSource *> PrecompSource::mappings;
219
220bool TpiSource::remapTypeIndex(TypeIndex &ti, TiRefKind refKind) const {
221 if (ti.isSimple())
222 return true;
223
224 // This can be an item index or a type index. Choose the appropriate map.
225 ArrayRef<TypeIndex> tpiOrIpiMap =
226 (refKind == TiRefKind::IndexRef) ? ipiMap : tpiMap;
227 if (ti.toArrayIndex() >= tpiOrIpiMap.size())
228 return false;
229 ti = tpiOrIpiMap[ti.toArrayIndex()];
230 return true;
231}
232
233void TpiSource::remapRecord(MutableArrayRef<uint8_t> rec,
234 ArrayRef<TiReference> typeRefs) {
235 MutableArrayRef<uint8_t> contents = rec.drop_front(sizeof(RecordPrefix));
236 for (const TiReference &ref : typeRefs) {
237 unsigned byteSize = ref.Count * sizeof(TypeIndex);
238 if (contents.size() < ref.Offset + byteSize)
239 fatal("symbol record too short");
240
241 MutableArrayRef<TypeIndex> indices(
242 reinterpret_cast<TypeIndex *>(contents.data() + ref.Offset), ref.Count);
243 for (TypeIndex &ti : indices) {
244 if (!remapTypeIndex(ti, ref.Kind)) {
245 if (config->verbose) {
246 uint16_t kind =
247 reinterpret_cast<const RecordPrefix *>(rec.data())->RecordKind;
248 StringRef fname = file ? file->getName() : "<unknown PDB>";
249 log("failed to remap type index in record of kind 0x" +
250 utohexstr(kind) + " in " + fname + " with bad " +
251 (ref.Kind == TiRefKind::IndexRef ? "item" : "type") +
252 " index 0x" + utohexstr(ti.getIndex()));
253 }
254 ti = TypeIndex(SimpleTypeKind::NotTranslated);
255 continue;
256 }
257 }
258 }
259}
260
261void TpiSource::remapTypesInTypeRecord(MutableArrayRef<uint8_t> rec) {
262 // TODO: Handle errors similar to symbols.
263 SmallVector<TiReference, 32> typeRefs;
264 discoverTypeIndices(CVType(rec), typeRefs);
265 remapRecord(rec, typeRefs);
266}
267
268bool TpiSource::remapTypesInSymbolRecord(MutableArrayRef<uint8_t> rec) {
269 // Discover type index references in the record. Skip it if we don't
270 // know where they are.
271 SmallVector<TiReference, 32> typeRefs;
272 if (!discoverTypeIndicesInSymbol(rec, typeRefs))
273 return false;
274 remapRecord(rec, typeRefs);
275 return true;
276}
277
278// A COFF .debug$H section is currently a clang extension. This function checks
279// if a .debug$H section is in a format that we expect / understand, so that we
280// can ignore any sections which are coincidentally also named .debug$H but do
281// not contain a format we recognize.
282static bool canUseDebugH(ArrayRef<uint8_t> debugH) {
283 if (debugH.size() < sizeof(object::debug_h_header))
284 return false;
285 auto *header =
286 reinterpret_cast<const object::debug_h_header *>(debugH.data());
287 debugH = debugH.drop_front(sizeof(object::debug_h_header));
288 return header->Magic == COFF::DEBUG_HASHES_SECTION_MAGIC &&
289 header->Version == 0 &&
290 header->HashAlgorithm == uint16_t(GlobalTypeHashAlg::SHA1_8) &&
291 (debugH.size() % 8 == 0);
292}
293
294static Optional<ArrayRef<uint8_t>> getDebugH(ObjFile *file) {
295 SectionChunk *sec =
296 SectionChunk::findByName(file->getDebugChunks(), ".debug$H");
297 if (!sec)
298 return llvm::None;
299 ArrayRef<uint8_t> contents = sec->getContents();
300 if (!canUseDebugH(contents))
301 return None;
302 return contents;
303}
304
305static ArrayRef<GloballyHashedType>
306getHashesFromDebugH(ArrayRef<uint8_t> debugH) {
307 assert(canUseDebugH(debugH));
308 debugH = debugH.drop_front(sizeof(object::debug_h_header));
309 uint32_t count = debugH.size() / sizeof(GloballyHashedType);
310 return {reinterpret_cast<const GloballyHashedType *>(debugH.data()), count};
311}
312
313// Merge .debug$T for a generic object file.
314Error TpiSource::mergeDebugT(TypeMerger *m) {
315 assert(!config->debugGHashes &&
316 "use remapTpiWithGHashes when ghash is enabled");
317
318 CVTypeArray types;
319 BinaryStreamReader reader(file->debugTypes, support::little);
320 cantFail(reader.readArray(types, reader.getLength()));
321
322 // When dealing with PCH.OBJ, some indices were already merged.
323 unsigned nbHeadIndices = indexMapStorage.size();
324
325 if (auto err = mergeTypeAndIdRecords(
326 m->idTable, m->typeTable, indexMapStorage, types, file->pchSignature))
327 fatal("codeview::mergeTypeAndIdRecords failed: " +
328 toString(std::move(err)));
329
330 // In an object, there is only one mapping for both types and items.
331 tpiMap = indexMapStorage;
332 ipiMap = indexMapStorage;
333
334 if (config->showSummary) {
335 nbTypeRecords = indexMapStorage.size() - nbHeadIndices;
336 nbTypeRecordsBytes = reader.getLength();
337 // Count how many times we saw each type record in our input. This
338 // calculation requires a second pass over the type records to classify each
339 // record as a type or index. This is slow, but this code executes when
340 // collecting statistics.
341 m->tpiCounts.resize(m->getTypeTable().size());
342 m->ipiCounts.resize(m->getIDTable().size());
343 uint32_t srcIdx = nbHeadIndices;
344 for (CVType &ty : types) {
345 TypeIndex dstIdx = tpiMap[srcIdx++];
346 // Type merging may fail, so a complex source type may become the simple
347 // NotTranslated type, which cannot be used as an array index.
348 if (dstIdx.isSimple())
349 continue;
350 SmallVectorImpl<uint32_t> &counts =
351 isIdRecord(ty.kind()) ? m->ipiCounts : m->tpiCounts;
352 ++counts[dstIdx.toArrayIndex()];
353 }
354 }
355
356 return Error::success();
357}
358
359// Merge types from a type server PDB.
360Error TypeServerSource::mergeDebugT(TypeMerger *m) {
361 assert(!config->debugGHashes &&
362 "use remapTpiWithGHashes when ghash is enabled");
363
364 pdb::PDBFile &pdbFile = pdbInputFile->session->getPDBFile();
365 Expected<pdb::TpiStream &> expectedTpi = pdbFile.getPDBTpiStream();
366 if (auto e = expectedTpi.takeError())
367 fatal("Type server does not have TPI stream: " + toString(std::move(e)));
368 pdb::TpiStream *maybeIpi = nullptr;
369 if (pdbFile.hasPDBIpiStream()) {
370 Expected<pdb::TpiStream &> expectedIpi = pdbFile.getPDBIpiStream();
371 if (auto e = expectedIpi.takeError())
372 fatal("Error getting type server IPI stream: " + toString(std::move(e)));
373 maybeIpi = &*expectedIpi;
374 }
375
376 // Merge TPI first, because the IPI stream will reference type indices.
377 if (auto err = mergeTypeRecords(m->typeTable, indexMapStorage,
378 expectedTpi->typeArray()))
379 fatal("codeview::mergeTypeRecords failed: " + toString(std::move(err)));
380 tpiMap = indexMapStorage;
381
382 // Merge IPI.
383 if (maybeIpi) {
384 if (auto err = mergeIdRecords(m->idTable, tpiMap, ipiSrc->indexMapStorage,
385 maybeIpi->typeArray()))
386 fatal("codeview::mergeIdRecords failed: " + toString(std::move(err)));
387 ipiMap = ipiSrc->indexMapStorage;
388 }
389
390 if (config->showSummary) {
391 nbTypeRecords = tpiMap.size() + ipiMap.size();
392 nbTypeRecordsBytes =
393 expectedTpi->typeArray().getUnderlyingStream().getLength() +
394 (maybeIpi ? maybeIpi->typeArray().getUnderlyingStream().getLength()
395 : 0);
396
397 // Count how many times we saw each type record in our input. If a
398 // destination type index is present in the source to destination type index
399 // map, that means we saw it once in the input. Add it to our histogram.
400 m->tpiCounts.resize(m->getTypeTable().size());
401 m->ipiCounts.resize(m->getIDTable().size());
402 for (TypeIndex ti : tpiMap)
403 if (!ti.isSimple())
404 ++m->tpiCounts[ti.toArrayIndex()];
405 for (TypeIndex ti : ipiMap)
406 if (!ti.isSimple())
407 ++m->ipiCounts[ti.toArrayIndex()];
408 }
409
410 return Error::success();
411}
412
413Expected<TypeServerSource *> UseTypeServerSource::getTypeServerSource() {
414 const codeview::GUID &tsId = typeServerDependency.getGuid();
415 StringRef tsPath = typeServerDependency.getName();
416
417 TypeServerSource *tsSrc;
418 auto it = TypeServerSource::mappings.find(tsId);
419 if (it != TypeServerSource::mappings.end()) {
420 tsSrc = it->second;
421 } else {
422 // The file failed to load, lookup by name
423 PDBInputFile *pdb = PDBInputFile::findFromRecordPath(tsPath, file);
424 if (!pdb)
425 return createFileError(tsPath, errorCodeToError(std::error_code(
426 ENOENT, std::generic_category())));
427 // If an error occurred during loading, throw it now
428 if (pdb->loadErr && *pdb->loadErr)
429 return createFileError(tsPath, std::move(*pdb->loadErr));
430
431 tsSrc = (TypeServerSource *)pdb->debugTypesObj;
432 }
433 return tsSrc;
434}
435
436Error UseTypeServerSource::mergeDebugT(TypeMerger *m) {
437 Expected<TypeServerSource *> tsSrc = getTypeServerSource();
438 if (!tsSrc)
439 return tsSrc.takeError();
440
441 pdb::PDBFile &pdbSession = (*tsSrc)->pdbInputFile->session->getPDBFile();
442 auto expectedInfo = pdbSession.getPDBInfoStream();
443 if (!expectedInfo)
444 return expectedInfo.takeError();
445
446 // Just because a file with a matching name was found and it was an actual
447 // PDB file doesn't mean it matches. For it to match the InfoStream's GUID
448 // must match the GUID specified in the TypeServer2 record.
449 if (expectedInfo->getGuid() != typeServerDependency.getGuid())
450 return createFileError(
451 typeServerDependency.getName(),
452 make_error<pdb::PDBError>(pdb::pdb_error_code::signature_out_of_date));
453
454 // Reuse the type index map of the type server.
455 tpiMap = (*tsSrc)->tpiMap;
456 ipiMap = (*tsSrc)->ipiMap;
457 return Error::success();
458}
459
460static bool equalsPath(StringRef path1, StringRef path2) {
461#if defined(_WIN32)
462 return path1.equals_lower(path2);
463#else
464 return path1.equals(path2);
465#endif
466}
467
468// Find by name an OBJ provided on the command line
469static PrecompSource *findObjByName(StringRef fileNameOnly) {
470 SmallString<128> currentPath;
471 for (auto kv : PrecompSource::mappings) {
472 StringRef currentFileName = sys::path::filename(kv.second->file->getName(),
473 sys::path::Style::windows);
474
475 // Compare based solely on the file name (link.exe behavior)
476 if (equalsPath(currentFileName, fileNameOnly))
477 return kv.second;
478 }
479 return nullptr;
480}
481
482static PrecompSource *findPrecompSource(ObjFile *file, PrecompRecord &pr) {
483 // Cross-compile warning: given that Clang doesn't generate LF_PRECOMP
484 // records, we assume the OBJ comes from a Windows build of cl.exe. Thusly,
485 // the paths embedded in the OBJs are in the Windows format.
486 SmallString<128> prFileName =
487 sys::path::filename(pr.getPrecompFilePath(), sys::path::Style::windows);
488
489 auto it = PrecompSource::mappings.find(pr.getSignature());
490 if (it != PrecompSource::mappings.end()) {
491 return it->second;
492 }
493 // Lookup by name
494 return findObjByName(prFileName);
495}
496
497static Expected<PrecompSource *> findPrecompMap(ObjFile *file,
498 PrecompRecord &pr) {
499 PrecompSource *precomp = findPrecompSource(file, pr);
500
501 if (!precomp)
502 return createFileError(
503 pr.getPrecompFilePath(),
504 make_error<pdb::PDBError>(pdb::pdb_error_code::no_matching_pch));
505
506 if (pr.getSignature() != file->pchSignature)
507 return createFileError(
508 toString(file),
509 make_error<pdb::PDBError>(pdb::pdb_error_code::no_matching_pch));
510
511 if (pr.getSignature() != *precomp->file->pchSignature)
512 return createFileError(
513 toString(precomp->file),
514 make_error<pdb::PDBError>(pdb::pdb_error_code::no_matching_pch));
515
516 return precomp;
517}
518
519/// Merges a precompiled headers TPI map into the current TPI map. The
520/// precompiled headers object will also be loaded and remapped in the
521/// process.
522Error UsePrecompSource::mergeInPrecompHeaderObj() {
523 auto e = findPrecompMap(file, precompDependency);
524 if (!e)
525 return e.takeError();
526
527 PrecompSource *precompSrc = *e;
528 if (precompSrc->tpiMap.empty())
529 return Error::success();
530
531 assert(precompDependency.getStartTypeIndex() ==
532 TypeIndex::FirstNonSimpleIndex);
533 assert(precompDependency.getTypesCount() <= precompSrc->tpiMap.size());
534 // Use the previously remapped index map from the precompiled headers.
535 indexMapStorage.insert(indexMapStorage.begin(), precompSrc->tpiMap.begin(),
536 precompSrc->tpiMap.begin() +
537 precompDependency.getTypesCount());
538
539 return Error::success();
540}
541
542Error UsePrecompSource::mergeDebugT(TypeMerger *m) {
543 // This object was compiled with /Yu, so process the corresponding
544 // precompiled headers object (/Yc) first. Some type indices in the current
545 // object are referencing data in the precompiled headers object, so we need
546 // both to be loaded.
547 if (Error e = mergeInPrecompHeaderObj())
548 return e;
549
550 return TpiSource::mergeDebugT(m);
551}
552
553uint32_t TpiSource::countTypeServerPDBs() {
554 return TypeServerSource::mappings.size();
555}
556
557uint32_t TpiSource::countPrecompObjs() {
558 return PrecompSource::mappings.size();
559}
560
561void TpiSource::clear() {
562 // Clean up any owned ghash allocations.
563 clearGHashes();
564 TpiSource::instances.clear();
565 TypeServerSource::mappings.clear();
566 PrecompSource::mappings.clear();
567}
568
569//===----------------------------------------------------------------------===//
570// Parellel GHash type merging implementation.
571//===----------------------------------------------------------------------===//
572
573void TpiSource::loadGHashes() {
574 if (Optional<ArrayRef<uint8_t>> debugH = getDebugH(file)) {
575 ghashes = getHashesFromDebugH(*debugH);
576 ownedGHashes = false;
577 } else {
578 CVTypeArray types;
579 BinaryStreamReader reader(file->debugTypes, support::little);
580 cantFail(reader.readArray(types, reader.getLength()));
581 assignGHashesFromVector(GloballyHashedType::hashTypes(types));
582 }
583
584 fillIsItemIndexFromDebugT();
585}
586
587// Copies ghashes from a vector into an array. These are long lived, so it's
588// worth the time to copy these into an appropriately sized vector to reduce
589// memory usage.
590void TpiSource::assignGHashesFromVector(
591 std::vector<GloballyHashedType> &&hashVec) {
592 GloballyHashedType *hashes = new GloballyHashedType[hashVec.size()];
593 memcpy(hashes, hashVec.data(), hashVec.size() * sizeof(GloballyHashedType));
594 ghashes = makeArrayRef(hashes, hashVec.size());
595 ownedGHashes = true;
596}
597
598// Faster way to iterate type records. forEachTypeChecked is faster than
599// iterating CVTypeArray. It avoids virtual readBytes calls in inner loops.
600static void forEachTypeChecked(ArrayRef<uint8_t> types,
601 function_ref<void(const CVType &)> fn) {
602 checkError(
603 forEachCodeViewRecord<CVType>(types, [fn](const CVType &ty) -> Error {
604 fn(ty);
605 return Error::success();
606 }));
607}
608
609// Walk over file->debugTypes and fill in the isItemIndex bit vector.
610// TODO: Store this information in .debug$H so that we don't have to recompute
611// it. This is the main bottleneck slowing down parallel ghashing with one
612// thread over single-threaded ghashing.
613void TpiSource::fillIsItemIndexFromDebugT() {
614 uint32_t index = 0;
615 isItemIndex.resize(ghashes.size());
616 forEachTypeChecked(file->debugTypes, [&](const CVType &ty) {
617 if (isIdRecord(ty.kind()))
618 isItemIndex.set(index);
619 ++index;
620 });
621}
622
623void TpiSource::mergeTypeRecord(TypeIndex curIndex, CVType ty) {
624 // Decide if the merged type goes into TPI or IPI.
625 bool isItem = isIdRecord(ty.kind());
626 MergedInfo &merged = isItem ? mergedIpi : mergedTpi;
627
628 // Copy the type into our mutable buffer.
629 assert(ty.length() <= codeview::MaxRecordLength);
630 size_t offset = merged.recs.size();
631 size_t newSize = alignTo(ty.length(), 4);
632 merged.recs.resize(offset + newSize);
633 auto newRec = makeMutableArrayRef(&merged.recs[offset], newSize);
634 memcpy(newRec.data(), ty.data().data(), newSize);
635
636 // Fix up the record prefix and padding bytes if it required resizing.
637 if (newSize != ty.length()) {
638 reinterpret_cast<RecordPrefix *>(newRec.data())->RecordLen = newSize - 2;
639 for (size_t i = ty.length(); i < newSize; ++i)
640 newRec[i] = LF_PAD0 + (newSize - i);
641 }
642
643 // Remap the type indices in the new record.
644 remapTypesInTypeRecord(newRec);
645 uint32_t pdbHash = check(pdb::hashTypeRecord(CVType(newRec)));
646 merged.recSizes.push_back(static_cast<uint16_t>(newSize));
647 merged.recHashes.push_back(pdbHash);
648
649 // Retain a mapping from PDB function id to PDB function type. This mapping is
650 // used during symbol processing to rewrite S_GPROC32_ID symbols to S_GPROC32
651 // symbols.
652 if (ty.kind() == LF_FUNC_ID || ty.kind() == LF_MFUNC_ID) {
653 bool success = ty.length() >= 12;
654 TypeIndex funcId = curIndex;
655 if (success)
656 success &= remapTypeIndex(funcId, TiRefKind::IndexRef);
657 TypeIndex funcType =
658 *reinterpret_cast<const TypeIndex *>(&newRec.data()[8]);
659 if (success) {
660 funcIdToType.push_back({funcId, funcType});
661 } else {
662 StringRef fname = file ? file->getName() : "<unknown PDB>";
663 warn("corrupt LF_[M]FUNC_ID record 0x" + utohexstr(curIndex.getIndex()) +
664 " in " + fname);
665 }
666 }
667}
668
669void TpiSource::mergeUniqueTypeRecords(ArrayRef<uint8_t> typeRecords,
670 TypeIndex beginIndex) {
671 // Re-sort the list of unique types by index.
672 if (kind == PDB)
673 assert(std::is_sorted(uniqueTypes.begin(), uniqueTypes.end()));
674 else
675 llvm::sort(uniqueTypes);
676
677 // Accumulate all the unique types into one buffer in mergedTypes.
678 uint32_t ghashIndex = 0;
679 auto nextUniqueIndex = uniqueTypes.begin();
680 assert(mergedTpi.recs.empty());
681 assert(mergedIpi.recs.empty());
682
683 // Pre-compute the number of elements in advance to avoid std::vector resizes.
684 unsigned nbTpiRecs = 0;
685 unsigned nbIpiRecs = 0;
686 forEachTypeChecked(typeRecords, [&](const CVType &ty) {
687 if (nextUniqueIndex != uniqueTypes.end() &&
688 *nextUniqueIndex == ghashIndex) {
689 assert(ty.length() <= codeview::MaxRecordLength);
690 size_t newSize = alignTo(ty.length(), 4);
691 (isIdRecord(ty.kind()) ? nbIpiRecs : nbTpiRecs) += newSize;
692 ++nextUniqueIndex;
693 }
694 ++ghashIndex;
695 });
696 mergedTpi.recs.reserve(nbTpiRecs);
697 mergedIpi.recs.reserve(nbIpiRecs);
698
699 // Do the actual type merge.
700 ghashIndex = 0;
701 nextUniqueIndex = uniqueTypes.begin();
702 forEachTypeChecked(typeRecords, [&](const CVType &ty) {
703 if (nextUniqueIndex != uniqueTypes.end() &&
704 *nextUniqueIndex == ghashIndex) {
705 mergeTypeRecord(beginIndex + ghashIndex, ty);
706 ++nextUniqueIndex;
707 }
708 ++ghashIndex;
709 });
710 assert(nextUniqueIndex == uniqueTypes.end() &&
711 "failed to merge all desired records");
712 assert(uniqueTypes.size() ==
713 mergedTpi.recSizes.size() + mergedIpi.recSizes.size() &&
714 "missing desired record");
715}
716
717void TpiSource::remapTpiWithGHashes(GHashState *g) {
718 assert(config->debugGHashes && "ghashes must be enabled");
719 fillMapFromGHashes(g);
720 tpiMap = indexMapStorage;
721 ipiMap = indexMapStorage;
722 mergeUniqueTypeRecords(file->debugTypes);
723 // TODO: Free all unneeded ghash resources now that we have a full index map.
724
725 if (config->showSummary) {
726 nbTypeRecords = ghashes.size();
727 nbTypeRecordsBytes = file->debugTypes.size();
728 }
729}
730
731// PDBs do not actually store global hashes, so when merging a type server
732// PDB we have to synthesize global hashes. To do this, we first synthesize
733// global hashes for the TPI stream, since it is independent, then we
734// synthesize hashes for the IPI stream, using the hashes for the TPI stream
735// as inputs.
736void TypeServerSource::loadGHashes() {
737 // Don't hash twice.
738 if (!ghashes.empty())
739 return;
740 pdb::PDBFile &pdbFile = pdbInputFile->session->getPDBFile();
741
742 // Hash TPI stream.
743 Expected<pdb::TpiStream &> expectedTpi = pdbFile.getPDBTpiStream();
744 if (auto e = expectedTpi.takeError())
745 fatal("Type server does not have TPI stream: " + toString(std::move(e)));
746 assignGHashesFromVector(
747 GloballyHashedType::hashTypes(expectedTpi->typeArray()));
748 isItemIndex.resize(ghashes.size());
749
750 // Hash IPI stream, which depends on TPI ghashes.
751 if (!pdbFile.hasPDBIpiStream())
752 return;
753 Expected<pdb::TpiStream &> expectedIpi = pdbFile.getPDBIpiStream();
754 if (auto e = expectedIpi.takeError())
755 fatal("error retrieving IPI stream: " + toString(std::move(e)));
756 ipiSrc->assignGHashesFromVector(
757 GloballyHashedType::hashIds(expectedIpi->typeArray(), ghashes));
758
759 // The IPI stream isItemIndex bitvector should be all ones.
760 ipiSrc->isItemIndex.resize(ipiSrc->ghashes.size());
761 ipiSrc->isItemIndex.set(0, ipiSrc->ghashes.size());
762}
763
764// Flatten discontiguous PDB type arrays to bytes so that we can use
765// forEachTypeChecked instead of CVTypeArray iteration. Copying all types from
766// type servers is faster than iterating all object files compiled with /Z7 with
767// CVTypeArray, which has high overheads due to the virtual interface of
768// BinaryStream::readBytes.
769static ArrayRef<uint8_t> typeArrayToBytes(const CVTypeArray &types) {
770 BinaryStreamRef stream = types.getUnderlyingStream();
771 ArrayRef<uint8_t> debugTypes;
772 checkError(stream.readBytes(0, stream.getLength(), debugTypes));
773 return debugTypes;
774}
775
776// Merge types from a type server PDB.
777void TypeServerSource::remapTpiWithGHashes(GHashState *g) {
778 assert(config->debugGHashes && "ghashes must be enabled");
779
780 // IPI merging depends on TPI, so do TPI first, then do IPI. No need to
781 // propagate errors, those should've been handled during ghash loading.
782 pdb::PDBFile &pdbFile = pdbInputFile->session->getPDBFile();
783 pdb::TpiStream &tpi = check(pdbFile.getPDBTpiStream());
784 fillMapFromGHashes(g);
785 tpiMap = indexMapStorage;
786 mergeUniqueTypeRecords(typeArrayToBytes(tpi.typeArray()));
787 if (pdbFile.hasPDBIpiStream()) {
788 pdb::TpiStream &ipi = check(pdbFile.getPDBIpiStream());
789 ipiSrc->indexMapStorage.resize(ipiSrc->ghashes.size());
790 ipiSrc->fillMapFromGHashes(g);
791 ipiMap = ipiSrc->indexMapStorage;
792 ipiSrc->tpiMap = tpiMap;
793 ipiSrc->ipiMap = ipiMap;
794 ipiSrc->mergeUniqueTypeRecords(typeArrayToBytes(ipi.typeArray()));
795
796 if (config->showSummary) {
797 nbTypeRecords = ipiSrc->ghashes.size();
798 nbTypeRecordsBytes = ipi.typeArray().getUnderlyingStream().getLength();
799 }
800 }
801
802 if (config->showSummary) {
803 nbTypeRecords += ghashes.size();
804 nbTypeRecordsBytes += tpi.typeArray().getUnderlyingStream().getLength();
805 }
806}
807
808void UseTypeServerSource::remapTpiWithGHashes(GHashState *g) {
809 // No remapping to do with /Zi objects. Simply use the index map from the type
810 // server. Errors should have been reported earlier. Symbols from this object
811 // will be ignored.
812 Expected<TypeServerSource *> maybeTsSrc = getTypeServerSource();
813 if (!maybeTsSrc) {
814 typeMergingError =
815 joinErrors(std::move(typeMergingError), maybeTsSrc.takeError());
816 return;
817 }
818 TypeServerSource *tsSrc = *maybeTsSrc;
819 tpiMap = tsSrc->tpiMap;
820 ipiMap = tsSrc->ipiMap;
821}
822
823void PrecompSource::loadGHashes() {
824 if (getDebugH(file)) {
825 warn("ignoring .debug$H section; pch with ghash is not implemented");
826 }
827
828 uint32_t ghashIdx = 0;
829 std::vector<GloballyHashedType> hashVec;
830 forEachTypeChecked(file->debugTypes, [&](const CVType &ty) {
831 // Remember the index of the LF_ENDPRECOMP record so it can be excluded from
832 // the PDB. There must be an entry in the list of ghashes so that the type
833 // indexes of the following records in the /Yc PCH object line up.
834 if (ty.kind() == LF_ENDPRECOMP)
835 endPrecompGHashIdx = ghashIdx;
836
837 hashVec.push_back(GloballyHashedType::hashType(ty, hashVec, hashVec));
838 isItemIndex.push_back(isIdRecord(ty.kind()));
839 ++ghashIdx;
840 });
841 assignGHashesFromVector(std::move(hashVec));
842}
843
844void UsePrecompSource::loadGHashes() {
845 PrecompSource *pchSrc = findPrecompSource(file, precompDependency);
846 if (!pchSrc)
847 return;
848
849 // To compute ghashes of a /Yu object file, we need to build on the the
850 // ghashes of the /Yc PCH object. After we are done hashing, discard the
851 // ghashes from the PCH source so we don't unnecessarily try to deduplicate
852 // them.
853 std::vector<GloballyHashedType> hashVec =
854 pchSrc->ghashes.take_front(precompDependency.getTypesCount());
855 forEachTypeChecked(file->debugTypes, [&](const CVType &ty) {
856 hashVec.push_back(GloballyHashedType::hashType(ty, hashVec, hashVec));
857 isItemIndex.push_back(isIdRecord(ty.kind()));
858 });
859 hashVec.erase(hashVec.begin(),
860 hashVec.begin() + precompDependency.getTypesCount());
861 assignGHashesFromVector(std::move(hashVec));
862}
863
864void UsePrecompSource::remapTpiWithGHashes(GHashState *g) {
865 fillMapFromGHashes(g);
866 // This object was compiled with /Yu, so process the corresponding
867 // precompiled headers object (/Yc) first. Some type indices in the current
868 // object are referencing data in the precompiled headers object, so we need
869 // both to be loaded.
870 if (Error e = mergeInPrecompHeaderObj()) {
871 typeMergingError = joinErrors(std::move(typeMergingError), std::move(e));
872 return;
873 }
874
875 tpiMap = indexMapStorage;
876 ipiMap = indexMapStorage;
877 mergeUniqueTypeRecords(file->debugTypes,
878 TypeIndex(precompDependency.getStartTypeIndex() +
879 precompDependency.getTypesCount()));
880 if (config->showSummary) {
881 nbTypeRecords = ghashes.size();
882 nbTypeRecordsBytes = file->debugTypes.size();
883 }
884}
885
886namespace {
887/// A concurrent hash table for global type hashing. It is based on this paper:
888/// Concurrent Hash Tables: Fast and General(?)!
889/// https://dl.acm.org/doi/10.1145/3309206
890///
891/// This hash table is meant to be used in two phases:
892/// 1. concurrent insertions
893/// 2. concurrent reads
894/// It does not support lookup, deletion, or rehashing. It uses linear probing.
895///
896/// The paper describes storing a key-value pair in two machine words.
897/// Generally, the values stored in this map are type indices, and we can use
898/// those values to recover the ghash key from a side table. This allows us to
899/// shrink the table entries further at the cost of some loads, and sidesteps
900/// the need for a 128 bit atomic compare-and-swap operation.
901///
902/// During insertion, a priority function is used to decide which insertion
903/// should be preferred. This ensures that the output is deterministic. For
904/// ghashing, lower tpiSrcIdx values (earlier inputs) are preferred.
905///
906class GHashCell;
907struct GHashTable {
908 GHashCell *table = nullptr;
909 uint32_t tableSize = 0;
910
911 GHashTable() = default;
912 ~GHashTable();
913
914 /// Initialize the table with the given size. Because the table cannot be
915 /// resized, the initial size of the table must be large enough to contain all
916 /// inputs, or insertion may not be able to find an empty cell.
917 void init(uint32_t newTableSize);
918
919 /// Insert the cell with the given ghash into the table. Return the insertion
920 /// position in the table. It is safe for the caller to store the insertion
921 /// position because the table cannot be resized.
922 uint32_t insert(GloballyHashedType ghash, GHashCell newCell);
923};
924
925/// A ghash table cell for deduplicating types from TpiSources.
926class GHashCell {
927 uint64_t data = 0;
928
929public:
930 GHashCell() = default;
931
932 // Construct data most to least significant so that sorting works well:
933 // - isItem
934 // - tpiSrcIdx
935 // - ghashIdx
936 // Add one to the tpiSrcIdx so that the 0th record from the 0th source has a
937 // non-zero representation.
938 GHashCell(bool isItem, uint32_t tpiSrcIdx, uint32_t ghashIdx)
939 : data((uint64_t(isItem) << 63U) | (uint64_t(tpiSrcIdx + 1) << 32ULL) |
940 ghashIdx) {
941 assert(tpiSrcIdx == getTpiSrcIdx() && "round trip failure");
942 assert(ghashIdx == getGHashIdx() && "round trip failure");
943 }
944
945 explicit GHashCell(uint64_t data) : data(data) {}
946
947 // The empty cell is all zeros.
948 bool isEmpty() const { return data == 0ULL; }
949
950 /// Extract the tpiSrcIdx.
951 uint32_t getTpiSrcIdx() const {
952 return ((uint32_t)(data >> 32U) & 0x7FFFFFFF) - 1;
953 }
954
955 /// Extract the index into the ghash array of the TpiSource.
956 uint32_t getGHashIdx() const { return (uint32_t)data; }
957
958 bool isItem() const { return data & (1ULL << 63U); }
959
960 /// Get the ghash key for this cell.
961 GloballyHashedType getGHash() const {
962 return TpiSource::instances[getTpiSrcIdx()]->ghashes[getGHashIdx()];
963 }
964
965 /// The priority function for the cell. The data is stored such that lower
966 /// tpiSrcIdx and ghashIdx values are preferred, which means that type record
967 /// from earlier sources are more likely to prevail.
968 friend inline bool operator<(const GHashCell &l, const GHashCell &r) {
969 return l.data < r.data;
970 }
971};
972} // namespace
973
974namespace lld {
975namespace coff {
976/// This type is just a wrapper around GHashTable with external linkage so it
977/// can be used from a header.
978struct GHashState {
979 GHashTable table;
980};
981} // namespace coff
982} // namespace lld
983
984GHashTable::~GHashTable() { delete[] table; }
985
986void GHashTable::init(uint32_t newTableSize) {
987 table = new GHashCell[newTableSize];
988 memset(table, 0, newTableSize * sizeof(GHashCell));
989 tableSize = newTableSize;
990}
991
992uint32_t GHashTable::insert(GloballyHashedType ghash, GHashCell newCell) {
993 assert(!newCell.isEmpty() && "cannot insert empty cell value");
994
995 // FIXME: The low bytes of SHA1 have low entropy for short records, which
996 // type records are. Swap the byte order for better entropy. A better ghash
997 // won't need this.
998 uint32_t startIdx =
999 ByteSwap_64(*reinterpret_cast<uint64_t *>(&ghash)) % tableSize;
1000
1001 // Do a linear probe starting at startIdx.
1002 uint32_t idx = startIdx;
1003 while (true) {
1004 // Run a compare and swap loop. There are four cases:
1005 // - cell is empty: CAS into place and return
1006 // - cell has matching key, earlier priority: do nothing, return
1007 // - cell has matching key, later priority: CAS into place and return
1008 // - cell has non-matching key: hash collision, probe next cell
1009 auto *cellPtr = reinterpret_cast<std::atomic<GHashCell> *>(&table[idx]);
1010 GHashCell oldCell(cellPtr->load());
1011 while (oldCell.isEmpty() || oldCell.getGHash() == ghash) {
1012 // Check if there is an existing ghash entry with a higher priority
1013 // (earlier ordering). If so, this is a duplicate, we are done.
1014 if (!oldCell.isEmpty() && oldCell < newCell)
1015 return idx;
1016 // Either the cell is empty, or our value is higher priority. Try to
1017 // compare and swap. If it succeeds, we are done.
1018 if (cellPtr->compare_exchange_weak(oldCell, newCell))
1019 return idx;
1020 // If the CAS failed, check this cell again.
1021 }
1022
1023 // Advance the probe. Wrap around to the beginning if we run off the end.
1024 ++idx;
1025 idx = idx == tableSize ? 0 : idx;
1026 if (idx == startIdx) {
1027 // If this becomes an issue, we could mark failure and rehash from the
1028 // beginning with a bigger table. There is no difference between rehashing
1029 // internally and starting over.
1030 report_fatal_error("ghash table is full");
1031 }
1032 }
1033 llvm_unreachable("left infloop");
1034}
1035
1036TypeMerger::TypeMerger(llvm::BumpPtrAllocator &alloc)
1037 : typeTable(alloc), idTable(alloc) {}
1038
1039TypeMerger::~TypeMerger() = default;
1040
1041void TypeMerger::mergeTypesWithGHash() {
1042 // Load ghashes. Do type servers and PCH objects first.
1043 {
1044 ScopedTimer t1(loadGHashTimer);
1045 parallelForEach(TpiSource::dependencySources,
1046 [&](TpiSource *source) { source->loadGHashes(); });
1047 parallelForEach(TpiSource::objectSources,
1048 [&](TpiSource *source) { source->loadGHashes(); });
1049 }
1050
1051 ScopedTimer t2(mergeGHashTimer);
1052 GHashState ghashState;
1053
1054 // Estimate the size of hash table needed to deduplicate ghashes. This *must*
1055 // be larger than the number of unique types, or hash table insertion may not
1056 // be able to find a vacant slot. Summing the input types guarantees this, but
1057 // it is a gross overestimate. The table size could be reduced to save memory,
1058 // but it would require implementing rehashing, and this table is generally
1059 // small compared to total memory usage, at eight bytes per input type record,
1060 // and most input type records are larger than eight bytes.
1061 size_t tableSize = 0;
1062 for (TpiSource *source : TpiSource::instances)
1063 tableSize += source->ghashes.size();
1064
1065 // Cap the table size so that we can use 32-bit cell indices. Type indices are
1066 // also 32-bit, so this is an inherent PDB file format limit anyway.
1067 tableSize = std::min(size_t(INT32_MAX), tableSize);
1068 ghashState.table.init(static_cast<uint32_t>(tableSize));
1069
1070 // Insert ghashes in parallel. During concurrent insertion, we cannot observe
1071 // the contents of the hash table cell, but we can remember the insertion
1072 // position. Because the table does not rehash, the position will not change
1073 // under insertion. After insertion is done, the value of the cell can be read
1074 // to retrieve the final PDB type index.
1075 parallelForEachN(0, TpiSource::instances.size(), [&](size_t tpiSrcIdx) {
1076 TpiSource *source = TpiSource::instances[tpiSrcIdx];
1077 source->indexMapStorage.resize(source->ghashes.size());
1078 for (uint32_t i = 0, e = source->ghashes.size(); i < e; i++) {
1079 if (source->shouldOmitFromPdb(i)) {
1080 source->indexMapStorage[i] = TypeIndex(SimpleTypeKind::NotTranslated);
1081 continue;
1082 }
1083 GloballyHashedType ghash = source->ghashes[i];
1084 bool isItem = source->isItemIndex.test(i);
1085 uint32_t cellIdx =
1086 ghashState.table.insert(ghash, GHashCell(isItem, tpiSrcIdx, i));
1087
1088 // Store the ghash cell index as a type index in indexMapStorage. Later
1089 // we will replace it with the PDB type index.
1090 source->indexMapStorage[i] = TypeIndex::fromArrayIndex(cellIdx);
1091 }
1092 });
1093
1094 // Collect all non-empty cells and sort them. This will implicitly assign
1095 // destination type indices, and partition the entries into type records and
1096 // item records. It arranges types in this order:
1097 // - type records
1098 // - source 0, type 0...
1099 // - source 1, type 1...
1100 // - item records
1101 // - source 0, type 1...
1102 // - source 1, type 0...
1103 std::vector<GHashCell> entries;
1104 for (const GHashCell &cell :
1105 makeArrayRef(ghashState.table.table, tableSize)) {
1106 if (!cell.isEmpty())
1107 entries.push_back(cell);
1108 }
1109 parallelSort(entries, std::less<GHashCell>());
1110 log(formatv("ghash table load factor: {0:p} (size {1} / capacity {2})\n",
1111 tableSize ? double(entries.size()) / tableSize : 0,
1112 entries.size(), tableSize));
1113
1114 // Find out how many type and item indices there are.
1115 auto mid =
1116 std::lower_bound(entries.begin(), entries.end(), GHashCell(true, 0, 0));
1117 assert((mid == entries.end() || mid->isItem()) &&
1118 (mid == entries.begin() || !std::prev(mid)->isItem()) &&
1119 "midpoint is not midpoint");
1120 uint32_t numTypes = std::distance(entries.begin(), mid);
1121 uint32_t numItems = std::distance(mid, entries.end());
1122 log("Tpi record count: " + Twine(numTypes));
1123 log("Ipi record count: " + Twine(numItems));
1124
1125 // Make a list of the "unique" type records to merge for each tpi source. Type
1126 // merging will skip indices not on this list. Store the destination PDB type
1127 // index for these unique types in the tpiMap for each source. The entries for
1128 // non-unique types will be filled in prior to type merging.
1129 for (uint32_t i = 0, e = entries.size(); i < e; ++i) {
1130 auto &cell = entries[i];
1131 uint32_t tpiSrcIdx = cell.getTpiSrcIdx();
1132 TpiSource *source = TpiSource::instances[tpiSrcIdx];
1133 source->uniqueTypes.push_back(cell.getGHashIdx());
1134
1135 // Update the ghash table to store the destination PDB type index in the
1136 // table.
1137 uint32_t pdbTypeIndex = i < numTypes ? i : i - numTypes;
1138 uint32_t ghashCellIndex =
1139 source->indexMapStorage[cell.getGHashIdx()].toArrayIndex();
1140 ghashState.table.table[ghashCellIndex] =
1141 GHashCell(cell.isItem(), cell.getTpiSrcIdx(), pdbTypeIndex);
1142 }
1143
1144 // In parallel, remap all types.
1145 for_each(TpiSource::dependencySources, [&](TpiSource *source) {
1146 source->remapTpiWithGHashes(&ghashState);
1147 });
1148 parallelForEach(TpiSource::objectSources, [&](TpiSource *source) {
1149 source->remapTpiWithGHashes(&ghashState);
1150 });
1151
1152 // Build a global map of from function ID to function type.
1153 for (TpiSource *source : TpiSource::instances) {
1154 for (auto idToType : source->funcIdToType)
1155 funcIdToType.insert(idToType);
1156 source->funcIdToType.clear();
1157 }
1158
1159 TpiSource::clearGHashes();
1160}
1161
1162/// Given the index into the ghash table for a particular type, return the type
1163/// index for that type in the output PDB.
1164static TypeIndex loadPdbTypeIndexFromCell(GHashState *g,
1165 uint32_t ghashCellIdx) {
1166 GHashCell cell = g->table.table[ghashCellIdx];
1167 return TypeIndex::fromArrayIndex(cell.getGHashIdx());
1168}
1169
1170// Fill in a TPI or IPI index map using ghashes. For each source type, use its
1171// ghash to lookup its final type index in the PDB, and store that in the map.
1172void TpiSource::fillMapFromGHashes(GHashState *g) {
1173 for (size_t i = 0, e = ghashes.size(); i < e; ++i) {
1174 TypeIndex fakeCellIndex = indexMapStorage[i];
1175 if (fakeCellIndex.isSimple())
1176 indexMapStorage[i] = fakeCellIndex;
1177 else
1178 indexMapStorage[i] =
1179 loadPdbTypeIndexFromCell(g, fakeCellIndex.toArrayIndex());
1180 }
1181}
1182
1183void TpiSource::clearGHashes() {
1184 for (TpiSource *src : TpiSource::instances) {
1185 if (src->ownedGHashes)
1186 delete[] src->ghashes.data();
1187 src->ghashes = {};
1188 src->isItemIndex.clear();
1189 src->uniqueTypes.clear();
1190 }
1191}
1192