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 @@ -1213,31 +1213,9 @@ } void PDBLinker::addObjFile(ObjFile *File, CVIndexMap *ExternIndexMap) { - if (File->wasProcessedForPDB()) + if (File->Merged) 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. - bool InArchive = !File->ParentName.empty(); - SmallString<128> Path = InArchive ? File->ParentName : File->getName(); - pdbMakeAbsolute(Path); - StringRef Name = InArchive ? File->getName() : StringRef(Path); - - pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder(); - File->ModuleDBI = &ExitOnErr(DbiBuilder.addModuleInfo(Name)); - File->ModuleDBI->setObjFileName(Path); - - 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; - } + 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 @@ -1253,8 +1231,7 @@ consumeError(IndexMapResult.takeError()); return; } - StringRef FileName = sys::path::filename(Path); - warn("Cannot use debug info for '" + FileName + "' [LNK4099]\n" + + warn("Cannot use debug info for '" + toString(File) + "' [LNK4099]\n" + ">>> failed to load reference " + StringRef(toString(IndexMapResult.takeError()))); return; @@ -1262,6 +1239,7 @@ 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()) { @@ -1294,6 +1272,38 @@ DSH.finish(); } +// 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(); + SmallString<128> ObjName; + + for (ObjFile *File : ObjFile::Instances) { + + bool InArchive = !File->ParentName.empty(); + ObjName = InArchive ? File->ParentName : File->getName(); + pdbMakeAbsolute(ObjName); + StringRef ModName = InArchive ? File->getName() : StringRef(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; + } + } +} + static PublicSym32 createPublic(Defined *Def) { PublicSym32 Pub(SymbolKind::S_PUB32); Pub.Name = Def->getName(); @@ -1315,6 +1325,9 @@ // TpiData. void PDBLinker::addObjectsToPDB() { ScopedTimer T1(AddObjectsTimer); + + createModuleDBI(Builder); + for (ObjFile *File : ObjFile::Instances) addObjFile(File); Index: test/COFF/precomp-link.test =================================================================== --- test/COFF/precomp-link.test +++ test/COFF/precomp-link.test @@ -8,10 +8,10 @@ RUN: not lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf 2>&1 | FileCheck %s -check-prefix FAILURE-MISSING-PRECOMPOBJ -FAILURE: warning: Cannot use debug info for 'precomp-invalid.obj' [LNK4099] +FAILURE: warning: Cannot use debug info for '{{.*}}precomp-invalid.obj' [LNK4099] FAILURE-NEXT: failed to load reference '{{.*}}precomp.obj': The signature does not match; the file(s) might be out of date. -FAILURE-MISSING-PRECOMPOBJ: warning: Cannot use debug info for 'precomp-a.obj' [LNK4099] +FAILURE-MISSING-PRECOMPOBJ: warning: Cannot use debug info for '{{.*}}precomp-a.obj' [LNK4099] FAILURE-MISSING-PRECOMPOBJ-NEXT: failed to load reference '{{.*}}precomp.obj': The path to this file must be provided on the command-line CHECK: Types (TPI Stream)