[PDB] Split TypeServerSource and extend type index map lifetime
[lldb.git] / lld / COFF / DebugTypes.cpp
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 "TypeMerger.h"
14 #include "lld/Common/ErrorHandler.h"
15 #include "lld/Common/Memory.h"
16 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
17 #include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
18 #include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"
19 #include "llvm/DebugInfo/PDB/GenericError.h"
20 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
21 #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
22 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
23 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
24 #include "llvm/Support/Path.h"
25
26 using namespace llvm;
27 using namespace llvm::codeview;
28 using namespace lld;
29 using namespace lld::coff;
30
31 namespace {
32 class TypeServerIpiSource;
33
34 // The TypeServerSource class represents a PDB type server, a file referenced by
35 // OBJ files compiled with MSVC /Zi. A single PDB can be shared by several OBJ
36 // files, therefore there must be only once instance per OBJ lot. The file path
37 // is discovered from the dependent OBJ's debug type stream. The
38 // TypeServerSource object is then queued and loaded by the COFF Driver. The
39 // debug type stream for such PDB files will be merged first in the final PDB,
40 // before any dependent OBJ.
41 class TypeServerSource : public TpiSource {
42 public:
43   explicit TypeServerSource(PDBInputFile *f)
44       : TpiSource(PDB, nullptr), pdbInputFile(f) {
45     if (f->loadErr && *f->loadErr)
46       return;
47     pdb::PDBFile &file = f->session->getPDBFile();
48     auto expectedInfo = file.getPDBInfoStream();
49     if (!expectedInfo)
50       return;
51     auto it = mappings.emplace(expectedInfo->getGuid(), this);
52     assert(it.second);
53     (void)it;
54   }
55
56   Error mergeDebugT(TypeMerger *m) override;
57   bool isDependency() const override { return true; }
58
59   PDBInputFile *pdbInputFile = nullptr;
60
61   // TpiSource for IPI stream.
62   TypeServerIpiSource *ipiSrc = nullptr;
63
64   static std::map<codeview::GUID, TypeServerSource *> mappings;
65 };
66
67 // Companion to TypeServerSource. Stores the index map for the IPI stream in the
68 // PDB. Modeling PDBs with two sources for TPI and IPI helps establish the
69 // invariant of one type index space per source.
70 class TypeServerIpiSource : public TpiSource {
71 public:
72   explicit TypeServerIpiSource() : TpiSource(PDBIpi, nullptr) {}
73
74   friend class TypeServerSource;
75
76   // IPI merging is handled in TypeServerSource::mergeDebugT, since it depends
77   // directly on type merging.
78   Error mergeDebugT(TypeMerger *m) override { return Error::success(); }
79
80   bool isDependency() const override { return true; }
81 };
82
83 // This class represents the debug type stream of an OBJ file that depends on a
84 // PDB type server (see TypeServerSource).
85 class UseTypeServerSource : public TpiSource {
86 public:
87   UseTypeServerSource(ObjFile *f, TypeServer2Record ts)
88       : TpiSource(UsingPDB, f), typeServerDependency(ts) {}
89
90   Error mergeDebugT(TypeMerger *m) override;
91
92   // Information about the PDB type server dependency, that needs to be loaded
93   // in before merging this OBJ.
94   TypeServer2Record typeServerDependency;
95 };
96
97 // This class represents the debug type stream of a Microsoft precompiled
98 // headers OBJ (PCH OBJ). This OBJ kind needs to be merged first in the output
99 // PDB, before any other OBJs that depend on this. Note that only MSVC generate
100 // such files, clang does not.
101 class PrecompSource : public TpiSource {
102 public:
103   PrecompSource(ObjFile *f) : TpiSource(PCH, f) {
104     if (!f->pchSignature || !*f->pchSignature)
105       fatal(toString(f) +
106             " claims to be a PCH object, but does not have a valid signature");
107     auto it = mappings.emplace(*f->pchSignature, this);
108     if (!it.second)
109       fatal("a PCH object with the same signature has already been provided (" +
110             toString(it.first->second->file) + " and " + toString(file) + ")");
111   }
112
113   bool isDependency() const override { return true; }
114
115   static std::map<uint32_t, PrecompSource *> mappings;
116 };
117
118 // This class represents the debug type stream of an OBJ file that depends on a
119 // Microsoft precompiled headers OBJ (see PrecompSource).
120 class UsePrecompSource : public TpiSource {
121 public:
122   UsePrecompSource(ObjFile *f, PrecompRecord precomp)
123       : TpiSource(UsingPCH, f), precompDependency(precomp) {}
124
125   Error mergeDebugT(TypeMerger *m) override;
126
127   // Information about the Precomp OBJ dependency, that needs to be loaded in
128   // before merging this OBJ.
129   PrecompRecord precompDependency;
130 };
131 } // namespace
132
133 static std::vector<TpiSource *> gc;
134
135 TpiSource::TpiSource(TpiKind k, ObjFile *f) : kind(k), file(f) {
136   gc.push_back(this);
137 }
138
139 // Vtable key method.
140 TpiSource::~TpiSource() = default;
141
142 TpiSource *lld::coff::makeTpiSource(ObjFile *file) {
143   return make<TpiSource>(TpiSource::Regular, file);
144 }
145
146 TpiSource *lld::coff::makeTypeServerSource(PDBInputFile *pdbInputFile) {
147   // Type server sources come in pairs: the TPI stream, and the IPI stream.
148   auto *tpiSource = make<TypeServerSource>(pdbInputFile);
149   if (pdbInputFile->session->getPDBFile().hasPDBIpiStream())
150     tpiSource->ipiSrc = make<TypeServerIpiSource>();
151   return tpiSource;
152 }
153
154 TpiSource *lld::coff::makeUseTypeServerSource(ObjFile *file,
155                                               TypeServer2Record ts) {
156   return make<UseTypeServerSource>(file, ts);
157 }
158
159 TpiSource *lld::coff::makePrecompSource(ObjFile *file) {
160   return make<PrecompSource>(file);
161 }
162
163 TpiSource *lld::coff::makeUsePrecompSource(ObjFile *file,
164                                            PrecompRecord precomp) {
165   return make<UsePrecompSource>(file, precomp);
166 }
167
168 void TpiSource::forEachSource(llvm::function_ref<void(TpiSource *)> fn) {
169   for_each(gc, fn);
170 }
171
172 std::map<codeview::GUID, TypeServerSource *> TypeServerSource::mappings;
173
174 std::map<uint32_t, PrecompSource *> PrecompSource::mappings;
175
176 // A COFF .debug$H section is currently a clang extension.  This function checks
177 // if a .debug$H section is in a format that we expect / understand, so that we
178 // can ignore any sections which are coincidentally also named .debug$H but do
179 // not contain a format we recognize.
180 static bool canUseDebugH(ArrayRef<uint8_t> debugH) {
181   if (debugH.size() < sizeof(object::debug_h_header))
182     return false;
183   auto *header =
184       reinterpret_cast<const object::debug_h_header *>(debugH.data());
185   debugH = debugH.drop_front(sizeof(object::debug_h_header));
186   return header->Magic == COFF::DEBUG_HASHES_SECTION_MAGIC &&
187          header->Version == 0 &&
188          header->HashAlgorithm == uint16_t(GlobalTypeHashAlg::SHA1_8) &&
189          (debugH.size() % 8 == 0);
190 }
191
192 static Optional<ArrayRef<uint8_t>> getDebugH(ObjFile *file) {
193   SectionChunk *sec =
194       SectionChunk::findByName(file->getDebugChunks(), ".debug$H");
195   if (!sec)
196     return llvm::None;
197   ArrayRef<uint8_t> contents = sec->getContents();
198   if (!canUseDebugH(contents))
199     return None;
200   return contents;
201 }
202
203 static ArrayRef<GloballyHashedType>
204 getHashesFromDebugH(ArrayRef<uint8_t> debugH) {
205   assert(canUseDebugH(debugH));
206
207   debugH = debugH.drop_front(sizeof(object::debug_h_header));
208   uint32_t count = debugH.size() / sizeof(GloballyHashedType);
209   return {reinterpret_cast<const GloballyHashedType *>(debugH.data()), count};
210 }
211
212 // Merge .debug$T for a generic object file.
213 Error TpiSource::mergeDebugT(TypeMerger *m) {
214   CVTypeArray types;
215   BinaryStreamReader reader(file->debugTypes, support::little);
216   cantFail(reader.readArray(types, reader.getLength()));
217
218   if (config->debugGHashes) {
219     ArrayRef<GloballyHashedType> hashes;
220     std::vector<GloballyHashedType> ownedHashes;
221     if (Optional<ArrayRef<uint8_t>> debugH = getDebugH(file))
222       hashes = getHashesFromDebugH(*debugH);
223     else {
224       ownedHashes = GloballyHashedType::hashTypes(types);
225       hashes = ownedHashes;
226     }
227
228     if (auto err = mergeTypeAndIdRecords(m->globalIDTable, m->globalTypeTable,
229                                          indexMapStorage, types, hashes,
230                                          file->pchSignature))
231       fatal("codeview::mergeTypeAndIdRecords failed: " +
232             toString(std::move(err)));
233   } else {
234     if (auto err =
235             mergeTypeAndIdRecords(m->idTable, m->typeTable, indexMapStorage,
236                                   types, file->pchSignature))
237       fatal("codeview::mergeTypeAndIdRecords failed: " +
238             toString(std::move(err)));
239   }
240
241   // In an object, there is only one mapping for both types and items.
242   tpiMap = indexMapStorage;
243   ipiMap = indexMapStorage;
244
245   if (config->showSummary) {
246     // Count how many times we saw each type record in our input. This
247     // calculation requires a second pass over the type records to classify each
248     // record as a type or index. This is slow, but this code executes when
249     // collecting statistics.
250     m->tpiCounts.resize(m->getTypeTable().size());
251     m->ipiCounts.resize(m->getIDTable().size());
252     uint32_t srcIdx = 0;
253     for (CVType &ty : types) {
254       TypeIndex dstIdx = tpiMap[srcIdx++];
255       // Type merging may fail, so a complex source type may become the simple
256       // NotTranslated type, which cannot be used as an array index.
257       if (dstIdx.isSimple())
258         continue;
259       SmallVectorImpl<uint32_t> &counts =
260           isIdRecord(ty.kind()) ? m->ipiCounts : m->tpiCounts;
261       ++counts[dstIdx.toArrayIndex()];
262     }
263   }
264
265   return Error::success();
266 }
267
268 // Merge types from a type server PDB.
269 Error TypeServerSource::mergeDebugT(TypeMerger *m) {
270   pdb::PDBFile &pdbFile = pdbInputFile->session->getPDBFile();
271   Expected<pdb::TpiStream &> expectedTpi = pdbFile.getPDBTpiStream();
272   if (auto e = expectedTpi.takeError())
273     fatal("Type server does not have TPI stream: " + toString(std::move(e)));
274   pdb::TpiStream *maybeIpi = nullptr;
275   if (pdbFile.hasPDBIpiStream()) {
276     Expected<pdb::TpiStream &> expectedIpi = pdbFile.getPDBIpiStream();
277     if (auto e = expectedIpi.takeError())
278       fatal("Error getting type server IPI stream: " + toString(std::move(e)));
279     maybeIpi = &*expectedIpi;
280   }
281
282   if (config->debugGHashes) {
283     // PDBs do not actually store global hashes, so when merging a type server
284     // PDB we have to synthesize global hashes.  To do this, we first synthesize
285     // global hashes for the TPI stream, since it is independent, then we
286     // synthesize hashes for the IPI stream, using the hashes for the TPI stream
287     // as inputs.
288     auto tpiHashes = GloballyHashedType::hashTypes(expectedTpi->typeArray());
289     Optional<uint32_t> endPrecomp;
290     // Merge TPI first, because the IPI stream will reference type indices.
291     if (auto err =
292             mergeTypeRecords(m->globalTypeTable, indexMapStorage,
293                              expectedTpi->typeArray(), tpiHashes, endPrecomp))
294       fatal("codeview::mergeTypeRecords failed: " + toString(std::move(err)));
295     tpiMap = indexMapStorage;
296
297     // Merge IPI.
298     if (maybeIpi) {
299       auto ipiHashes =
300           GloballyHashedType::hashIds(maybeIpi->typeArray(), tpiHashes);
301       if (auto err =
302               mergeIdRecords(m->globalIDTable, tpiMap, ipiSrc->indexMapStorage,
303                              maybeIpi->typeArray(), ipiHashes))
304         fatal("codeview::mergeIdRecords failed: " + toString(std::move(err)));
305       ipiMap = ipiSrc->indexMapStorage;
306     }
307   } else {
308     // Merge TPI first, because the IPI stream will reference type indices.
309     if (auto err = mergeTypeRecords(m->typeTable, indexMapStorage,
310                                     expectedTpi->typeArray()))
311       fatal("codeview::mergeTypeRecords failed: " + toString(std::move(err)));
312     tpiMap = indexMapStorage;
313
314     // Merge IPI.
315     if (maybeIpi) {
316       if (auto err = mergeIdRecords(m->idTable, tpiMap, ipiSrc->indexMapStorage,
317                                     maybeIpi->typeArray()))
318         fatal("codeview::mergeIdRecords failed: " + toString(std::move(err)));
319       ipiMap = ipiSrc->indexMapStorage;
320     }
321   }
322
323   if (config->showSummary) {
324     // Count how many times we saw each type record in our input. If a
325     // destination type index is present in the source to destination type index
326     // map, that means we saw it once in the input. Add it to our histogram.
327     m->tpiCounts.resize(m->getTypeTable().size());
328     m->ipiCounts.resize(m->getIDTable().size());
329     for (TypeIndex ti : tpiMap)
330       if (!ti.isSimple())
331         ++m->tpiCounts[ti.toArrayIndex()];
332     for (TypeIndex ti : ipiMap)
333       if (!ti.isSimple())
334         ++m->ipiCounts[ti.toArrayIndex()];
335   }
336
337   return Error::success();
338 }
339
340 Error UseTypeServerSource::mergeDebugT(TypeMerger *m) {
341   const codeview::GUID &tsId = typeServerDependency.getGuid();
342   StringRef tsPath = typeServerDependency.getName();
343
344   TypeServerSource *tsSrc;
345   auto it = TypeServerSource::mappings.find(tsId);
346   if (it != TypeServerSource::mappings.end()) {
347     tsSrc = it->second;
348   } else {
349     // The file failed to load, lookup by name
350     PDBInputFile *pdb = PDBInputFile::findFromRecordPath(tsPath, file);
351     if (!pdb)
352       return createFileError(tsPath, errorCodeToError(std::error_code(
353                                          ENOENT, std::generic_category())));
354     // If an error occurred during loading, throw it now
355     if (pdb->loadErr && *pdb->loadErr)
356       return createFileError(tsPath, std::move(*pdb->loadErr));
357
358     tsSrc = (TypeServerSource *)pdb->debugTypesObj;
359   }
360
361   pdb::PDBFile &pdbSession = tsSrc->pdbInputFile->session->getPDBFile();
362   auto expectedInfo = pdbSession.getPDBInfoStream();
363   if (!expectedInfo)
364     return expectedInfo.takeError();
365
366   // Just because a file with a matching name was found and it was an actual
367   // PDB file doesn't mean it matches.  For it to match the InfoStream's GUID
368   // must match the GUID specified in the TypeServer2 record.
369   if (expectedInfo->getGuid() != typeServerDependency.getGuid())
370     return createFileError(
371         tsPath,
372         make_error<pdb::PDBError>(pdb::pdb_error_code::signature_out_of_date));
373
374   // Reuse the type index map of the type server.
375   tpiMap = tsSrc->tpiMap;
376   ipiMap = tsSrc->ipiMap;
377   return Error::success();
378 }
379
380 static bool equalsPath(StringRef path1, StringRef path2) {
381 #if defined(_WIN32)
382   return path1.equals_lower(path2);
383 #else
384   return path1.equals(path2);
385 #endif
386 }
387
388 // Find by name an OBJ provided on the command line
389 static PrecompSource *findObjByName(StringRef fileNameOnly) {
390   SmallString<128> currentPath;
391   for (auto kv : PrecompSource::mappings) {
392     StringRef currentFileName = sys::path::filename(kv.second->file->getName(),
393                                                     sys::path::Style::windows);
394
395     // Compare based solely on the file name (link.exe behavior)
396     if (equalsPath(currentFileName, fileNameOnly))
397       return kv.second;
398   }
399   return nullptr;
400 }
401
402 static Expected<PrecompSource *> findPrecompMap(ObjFile *file,
403                                                 PrecompRecord &pr) {
404   // Cross-compile warning: given that Clang doesn't generate LF_PRECOMP
405   // records, we assume the OBJ comes from a Windows build of cl.exe. Thusly,
406   // the paths embedded in the OBJs are in the Windows format.
407   SmallString<128> prFileName =
408       sys::path::filename(pr.getPrecompFilePath(), sys::path::Style::windows);
409
410   PrecompSource *precomp;
411   auto it = PrecompSource::mappings.find(pr.getSignature());
412   if (it != PrecompSource::mappings.end()) {
413     precomp = it->second;
414   } else {
415     // Lookup by name
416     precomp = findObjByName(prFileName);
417   }
418
419   if (!precomp)
420     return createFileError(
421         prFileName,
422         make_error<pdb::PDBError>(pdb::pdb_error_code::no_matching_pch));
423
424   if (pr.getSignature() != file->pchSignature)
425     return createFileError(
426         toString(file),
427         make_error<pdb::PDBError>(pdb::pdb_error_code::no_matching_pch));
428
429   if (pr.getSignature() != *precomp->file->pchSignature)
430     return createFileError(
431         toString(precomp->file),
432         make_error<pdb::PDBError>(pdb::pdb_error_code::no_matching_pch));
433
434   return precomp;
435 }
436
437 /// Merges a precompiled headers TPI map into the current TPI map. The
438 /// precompiled headers object will also be loaded and remapped in the
439 /// process.
440 static Error
441 mergeInPrecompHeaderObj(ObjFile *file,
442                         SmallVectorImpl<TypeIndex> &indexMapStorage,
443                         PrecompRecord &precomp) {
444   auto e = findPrecompMap(file, precomp);
445   if (!e)
446     return e.takeError();
447
448   PrecompSource *precompSrc = *e;
449   if (precompSrc->tpiMap.empty())
450     return Error::success();
451
452   assert(precomp.getStartTypeIndex() == TypeIndex::FirstNonSimpleIndex);
453   assert(precomp.getTypesCount() <= precompSrc->tpiMap.size());
454   // Use the previously remapped index map from the precompiled headers.
455   indexMapStorage.append(precompSrc->tpiMap.begin(),
456                          precompSrc->tpiMap.begin() + precomp.getTypesCount());
457   return Error::success();
458 }
459
460 Error UsePrecompSource::mergeDebugT(TypeMerger *m) {
461   // This object was compiled with /Yu, so process the corresponding
462   // precompiled headers object (/Yc) first. Some type indices in the current
463   // object are referencing data in the precompiled headers object, so we need
464   // both to be loaded.
465   if (Error e =
466           mergeInPrecompHeaderObj(file, indexMapStorage, precompDependency))
467     return e;
468
469   return TpiSource::mergeDebugT(m);
470 }
471
472 uint32_t TpiSource::countTypeServerPDBs() {
473   return TypeServerSource::mappings.size();
474 }
475
476 uint32_t TpiSource::countPrecompObjs() {
477   return PrecompSource::mappings.size();
478 }
479
480 void TpiSource::clear() {
481   gc.clear();
482   TypeServerSource::mappings.clear();
483   PrecompSource::mappings.clear();
484 }