Index: COFF/InputFiles.h =================================================================== --- COFF/InputFiles.h +++ COFF/InputFiles.h @@ -128,9 +128,6 @@ // Returns the underlying COFF file. COFFObjectFile *getCOFFObj() { return COFFObj.get(); } - // Whether the object was already merged into the final PDB or not - bool wasProcessedForPDB() const { return !!ModuleDBI; } - static std::vector Instances; // Flags in the absolute @feat.00 symbol if it is present. These usually @@ -161,6 +158,9 @@ // Tells whether this file was compiled with /hotpatch bool HotPatchable = false; + // Whether the object was already merged into the final PDB or not + bool Merged = false; + private: const coff_section* getSection(uint32_t I); const coff_section *getSection(COFFSymbolRef Sym) { Index: COFF/PDB.cpp =================================================================== --- COFF/PDB.cpp +++ COFF/PDB.cpp @@ -1212,32 +1212,56 @@ File.ModuleDBI->addDebugSubsection(std::move(NewChecksums)); } -void PDBLinker::addObjFile(ObjFile *File, CVIndexMap *ExternIndexMap) { - if (File->wasProcessedForPDB()) - return; - // 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. +static StringRef getModObjName(InputFile *File, SmallVectorImpl &ObjName) { bool InArchive = !File->ParentName.empty(); - SmallString<128> Path = InArchive ? File->ParentName : File->getName(); - pdbMakeAbsolute(Path); - StringRef Name = InArchive ? File->getName() : StringRef(Path); + StringRef Name = InArchive ? File->ParentName : File->getName(); + ObjName.assign(Name.begin(), Name.end()); + pdbMakeAbsolute(ObjName); + StringRef ModName = + InArchive ? File->getName() : StringRef(ObjName.data(), ObjName.size()); + return ModName; +} +// 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. +static void createModuleDBI(pdb::PDBFileBuilder &Builder) { pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder(); - File->ModuleDBI = &ExitOnErr(DbiBuilder.addModuleInfo(Name)); - File->ModuleDBI->setObjFileName(Path); + SmallString<128> ObjName; + for (ObjFile *File : ObjFile::Instances) { + StringRef ModName = getModObjName(File, ObjName); + File->ModuleDBI = &ExitOnErr(DbiBuilder.addModuleInfo(ModName)); + File->ModuleDBI->setObjFileName(ObjName); + ArrayRef Chunks = File->getChunks(); + uint32_t Modi = File->ModuleDBI->getModuleIndex(); + for (Chunk *C : Chunks) { + auto *SecChunk = dyn_cast(C); + if (!SecChunk || !SecChunk->Live) + continue; + pdb::SectionContrib SC = createSectionContrib(SecChunk, Modi); + File->ModuleDBI->setFirstSectionContrib(SC); + break; + } + } +} - auto Chunks = File->getChunks(); - uint32_t Modi = File->ModuleDBI->getModuleIndex(); - for (Chunk *C : Chunks) { - auto *SecChunk = dyn_cast(C); - if (!SecChunk || !SecChunk->Live) - continue; - pdb::SectionContrib SC = createSectionContrib(SecChunk, Modi); - File->ModuleDBI->setFirstSectionContrib(SC); - break; +static void warnUnusable(InputFile *F, Error E) { + if (!Config->WarnDebugInfoUnusable) { + consumeError(std::move(E)); + return; } + auto Msg = "Cannot use debug info for '" + toString(F) + "' [LNK4099]"; + if (E) + warn(Msg + "\n>>> failed to load reference " + toString(std::move(E))); + else + warn(Msg); +} + +void PDBLinker::addObjFile(ObjFile *File, CVIndexMap *ExternIndexMap) { + if (File->Merged) + return; + File->Merged = true; // 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 @@ -1249,19 +1273,13 @@ // If the .debug$T sections fail to merge, assume there is no debug info. if (!IndexMapResult) { - if (!Config->WarnDebugInfoUnusable) { - consumeError(IndexMapResult.takeError()); - return; - } - StringRef FileName = sys::path::filename(Path); - warn("Cannot use debug info for '" + FileName + "' [LNK4099]\n" + - ">>> failed to load reference " + - StringRef(toString(IndexMapResult.takeError()))); + warnUnusable(File, IndexMapResult.takeError()); return; } ScopedTimer T(SymbolMergingTimer); + pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder(); DebugSHandler DSH(*this, *File, *IndexMapResult); // Now do all live .debug$S and .debug$F sections. for (SectionChunk *DebugChunk : File->getDebugChunks()) { @@ -1315,6 +1333,9 @@ // TpiData. void PDBLinker::addObjectsToPDB() { ScopedTimer T1(AddObjectsTimer); + + createModuleDBI(Builder); + for (ObjFile *File : ObjFile::Instances) addObjFile(File);