From 74d5b3322235e72d951f45aa427443b2addcb931 Mon Sep 17 00:00:00 2001 From: Alexandre Ganea Date: Fri, 22 Mar 2019 22:07:27 +0000 Subject: [PATCH] [LLD][COFF] Separate module descriptors creation from type/symbol merging Take module DBI creation out of PDBLinker::addObjFile() into its own function. This is groundwork towards parallelizable type merging, as proposed in D59226. Differential Revision: https://reviews.llvm.org/D59261 llvm-svn: 356815 --- lld/COFF/InputFiles.h | 6 ++-- lld/COFF/PDB.cpp | 65 ++++++++++++++++++++++++----------------- lld/test/COFF/precomp-link.test | 4 +-- 3 files changed, 44 insertions(+), 31 deletions(-) diff --git a/lld/COFF/InputFiles.h b/lld/COFF/InputFiles.h index 08b7306..45ab4b3 100644 --- a/lld/COFF/InputFiles.h +++ b/lld/COFF/InputFiles.h @@ -127,9 +127,6 @@ public: // 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 @@ -160,6 +157,9 @@ public: // Tells whether this file was compiled with /hotpatch bool HotPatchable = false; + // Whether the object was already merged into the final PDB or not + bool MergedIntoPDB = false; + private: const coff_section* getSection(uint32_t I); const coff_section *getSection(COFFSymbolRef Sym) { diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp index 8d97432..9ef43c7 100644 --- a/lld/COFF/PDB.cpp +++ b/lld/COFF/PDB.cpp @@ -1224,31 +1224,9 @@ void DebugSHandler::finish() { } void PDBLinker::addObjFile(ObjFile *File, CVIndexMap *ExternIndexMap) { - if (File->wasProcessedForPDB()) + if (File->MergedIntoPDB) 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->MergedIntoPDB = 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 @@ -1264,8 +1242,7 @@ void PDBLinker::addObjFile(ObjFile *File, CVIndexMap *ExternIndexMap) { 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; @@ -1273,6 +1250,7 @@ void PDBLinker::addObjFile(ObjFile *File, CVIndexMap *ExternIndexMap) { 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()) { @@ -1305,6 +1283,38 @@ void PDBLinker::addObjFile(ObjFile *File, CVIndexMap *ExternIndexMap) { 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(); @@ -1326,6 +1336,9 @@ static PublicSym32 createPublic(Defined *Def) { // TpiData. void PDBLinker::addObjectsToPDB() { ScopedTimer T1(AddObjectsTimer); + + createModuleDBI(Builder); + for (ObjFile *File : ObjFile::Instances) addObjFile(File); diff --git a/lld/test/COFF/precomp-link.test b/lld/test/COFF/precomp-link.test index 77d99e0..e0ab300 100644 --- a/lld/test/COFF/precomp-link.test +++ b/lld/test/COFF/precomp-link.test @@ -8,10 +8,10 @@ RUN: lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-invalid.obj %S/Inputs/pr 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) -- 2.7.4