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