Index: COFF/PDB.cpp =================================================================== --- COFF/PDB.cpp +++ COFF/PDB.cpp @@ -115,11 +115,11 @@ /// If the object does not use a type server PDB (compiled with /Z7), we merge /// all the type and item records from the .debug$S stream and fill in the /// caller-provided ObjectIndexMap. - Expected mergeDebugT(ObjFile *File, - CVIndexMap &ObjectIndexMap); + Expected mergeDebugT(ObjFile *File, + CVIndexMap &ObjectIndexMap); - Expected maybeMergeTypeServerPDB(ObjFile *File, - TypeServer2Record &TS); + Expected maybeMergeTypeServerPDB(ObjFile *File, + TypeServer2Record &TS); /// Add the section map and section contributions to the PDB. void addSections(ArrayRef OutputSections, @@ -256,8 +256,8 @@ return std::move(TS); } -Expected PDBLinker::mergeDebugT(ObjFile *File, - CVIndexMap &ObjectIndexMap) { +Expected +PDBLinker::mergeDebugT(ObjFile *File, CVIndexMap &ObjectIndexMap) { ScopedTimer T(TypeMergingTimer); ArrayRef Data = getDebugSection(File, ".debug$T"); @@ -332,15 +332,15 @@ return std::move(NS); } -Expected PDBLinker::maybeMergeTypeServerPDB(ObjFile *File, - TypeServer2Record &TS) { - const GUID& TSId = TS.getGuid(); +Expected +PDBLinker::maybeMergeTypeServerPDB(ObjFile *File, TypeServer2Record &TS) { + const GUID &TSId = TS.getGuid(); StringRef TSPath = TS.getName(); // First, check if the PDB has previously failed to load. if (MissingTypeServerPDBs.count(TSId)) return make_error( - pdb::generic_error_code::type_server_not_found, TSPath); + pdb::generic_error_code::type_server_not_found, TSPath); // Second, check if we already loaded a PDB with this GUID. Return the type // index mapping if we have it. @@ -361,8 +361,8 @@ StringRef LocalPath = !File->ParentName.empty() ? File->ParentName : File->getName(); SmallString<128> Path = sys::path::parent_path(LocalPath); - sys::path::append( - Path, sys::path::filename(TSPath, sys::path::Style::windows)); + sys::path::append(Path, + sys::path::filename(TSPath, sys::path::Style::windows)); ExpectedSession = tryToLoadPDB(TSId, Path); } if (auto E = ExpectedSession.takeError()) { @@ -1085,6 +1085,21 @@ EBS, Allocator, CodeViewContainer::Pdb)); } +static void addLinkerModuleCoffGroup(const Chunk *firstChunk, + const Chunk *lastChunk, + pdb::DbiModuleDescriptorBuilder &Mod, + OutputSection &OS, + BumpPtrAllocator &Allocator) { + CoffGroupSym CGS(SymbolRecordKind::CoffGroupSym); + CGS.Name = firstChunk->getSectionName(); + CGS.Segment = OS.SectionIndex; + CGS.Offset = firstChunk->getRVA() - OS.getRVA(); + CGS.Size = lastChunk->getRVA() + lastChunk->getSize() - firstChunk->getRVA(); + CGS.Characteristics = firstChunk->getOutputCharacteristics(); + Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol( + CGS, Allocator, CodeViewContainer::Pdb)); +} + static void addLinkerModuleSectionSymbol(pdb::DbiModuleDescriptorBuilder &Mod, OutputSection &OS, BumpPtrAllocator &Allocator) { @@ -1097,6 +1112,39 @@ Sym.SectionNumber = OS.SectionIndex; Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol( Sym, Allocator, CodeViewContainer::Pdb)); + + // Output COFF groups for individual chunks of this section. + // There may be several chunks with the same name (e.g. .text$di), but we only + // want to output each unique chunk once. + Chunk *firstChunkInSubSection = nullptr; + Chunk *lastChunkInSubSection = nullptr; + + for (Chunk *C : OS.getChunks()) { + auto *SecChunk = dyn_cast(C); + + // If this chunk doesn't represent an unmerged input file chunk, or it + // didn't contribute to the final output file, skip it. + if (!SecChunk || !SecChunk->isLive()) + continue; + + if (!firstChunkInSubSection) { + firstChunkInSubSection = C; + } + + if (C->getSectionName() != firstChunkInSubSection->getSectionName()) { + addLinkerModuleCoffGroup(firstChunkInSubSection, lastChunkInSubSection, + Mod, OS, Allocator); + + firstChunkInSubSection = C; + } + + lastChunkInSubSection = C; + } + + if (firstChunkInSubSection && lastChunkInSubSection) { + addLinkerModuleCoffGroup(firstChunkInSubSection, lastChunkInSubSection, Mod, + OS, Allocator); + } } // Creates a PDB file.