// Add all object files to the PDB. Merge .debug$T sections into IpiData and // TpiData. static void addObjectsToPDB(BumpPtrAllocator &Alloc, SymbolTable *Symtab, pdb::PDBFileBuilder &Builder, TypeTableBuilder &TypeTable, TypeTableBuilder &IDTable) { // Follow type servers. If the same type server is encountered more than // once for this instance of `PDBTypeServerHandler` (for example if many // object files reference the same TypeServer), the types from the // TypeServer will only be visited once. pdb::PDBTypeServerHandler Handler; // PDBs use a single global string table for filenames in the file checksum // table. auto PDBStrTab = std::make_shared<DebugStringTableSubsection>(); // Visit all .debug$T sections to add them to Builder. for (ObjectFile *File : Symtab->ObjectFiles) { // Add a module descriptor for every object file. We need to put an absolute // path to the object into the PDB. If this is a plain object, we make its // path absolute. If it's an object in an archive, we make the archive path // absolute. bool InArchive = !File->ParentName.empty(); SmallString<128> Path = InArchive ? File->ParentName : File->getName(); sys::fs::make_absolute(Path); StringRef Name = InArchive ? File->getName() : StringRef(Path); File->ModuleDBI = &ExitOnErr(Builder.getDbiBuilder().addModuleInfo(Name)); File->ModuleDBI->setObjFileName(Path); // Before we can process symbol substreams from .debug$S, we need to process // type information, file checksums, and the string table. Add type info to // the PDB first, so that we can get the map from object file type and item // indices to PDB type and item indices. SmallVector<TypeIndex, 128> TypeIndexMap; mergeDebugT(File, IDTable, TypeTable, TypeIndexMap, Handler); // Now do all line info. for (SectionChunk *DebugChunk : File->getDebugChunks()) { if (!DebugChunk->isLive() || DebugChunk->getSectionName() != ".debug$S") continue; ArrayRef<uint8_t> RelocatedDebugContents = relocateDebugChunk(Alloc, DebugChunk); if (RelocatedDebugContents.empty()) continue; DebugSubsectionArray Subsections; BinaryStreamReader Reader(RelocatedDebugContents, support::little); ExitOnErr(Reader.readArray(Subsections, RelocatedDebugContents.size())); DebugStringTableSubsectionRef CVStrTab; DebugChecksumsSubsectionRef Checksums; for (const DebugSubsectionRecord &SS : Subsections) { switch (SS.kind()) { case DebugSubsectionKind::StringTable: ExitOnErr(CVStrTab.initialize(SS.getRecordData())); break; case DebugSubsectionKind::FileChecksums: ExitOnErr(Checksums.initialize(SS.getRecordData())); break; case DebugSubsectionKind::Lines: // We can add the relocated line table directly to the PDB without // modification because the file checksum offsets will stay the same. File->ModuleDBI->addDebugSubsection(SS); break; case DebugSubsectionKind::Symbols: mergeSymbolRecords(Alloc, File, TypeIndexMap, SS.getRecordData()); break; default: // FIXME: Process the rest of the subsections. break; } } if (Checksums.valid()) { // Make a new file checksum table that refers to offsets in the PDB-wide // string table. Generally the string table subsection appears after the // checksum table, so we have to do this after looping over all the // subsections. if (!CVStrTab.valid()) fatal(".debug$S sections must have both a string table subsection " "and a checksum subsection table or neither"); auto NewChecksums = make_unique<DebugChecksumsSubsection>(*PDBStrTab); for (FileChecksumEntry &FC : Checksums) { StringRef FileName = ExitOnErr(CVStrTab.getString(FC.FileNameOffset)); ExitOnErr(Builder.getDbiBuilder().addModuleSourceFile( *File->ModuleDBI, FileName)); NewChecksums->addChecksum(FileName, FC.Kind, FC.Checksum); } File->ModuleDBI->addDebugSubsection(std::move(NewChecksums)); } } } Builder.getStringTableBuilder().setStrings(*PDBStrTab); // Construct TPI stream contents. addTypeInfo(Builder.getTpiBuilder(), TypeTable); // Construct IPI stream contents. addTypeInfo(Builder.getIpiBuilder(), IDTable); }