From 194be871b9f903f75c427f022875adf19244bf6e Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Fri, 20 Apr 2018 18:00:46 +0000 Subject: [PATCH] [LLD/PDB] Emit first section contribution for DBI Module Descriptor. Part of the DBI stream is a list of variable length structures describing each module that contributes to the final executable. One member of this structure is a section contribution entry that describes the first section contribution in the output file for the given module. We have been leaving this structure unpopulated until now, so with this patch it is now filled out correctly. Differential Revision: https://reviews.llvm.org/D45832 llvm-svn: 330457 --- lld/COFF/PDB.cpp | 73 +++++++++++++--------- lld/test/COFF/pdb.test | 10 +-- .../PDB/Native/DbiModuleDescriptorBuilder.h | 1 + .../PDB/Native/DbiModuleDescriptorBuilder.cpp | 5 ++ 4 files changed, 55 insertions(+), 34 deletions(-) diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp index 1f5e11d..a3548ad 100644 --- a/lld/COFF/PDB.cpp +++ b/lld/COFF/PDB.cpp @@ -125,9 +125,6 @@ public: void addSections(ArrayRef OutputSections, ArrayRef SectionTable); - void addSectionContrib(pdb::DbiModuleDescriptorBuilder &LinkerModule, - OutputSection *OS, Chunk *C); - /// Write the PDB to disk. void commit(); @@ -780,6 +777,32 @@ static ArrayRef relocateDebugChunk(BumpPtrAllocator &Alloc, ".debug$S"); } +static pdb::SectionContrib createSectionContrib(const Chunk *C, uint32_t Modi) { + OutputSection *OS = C->getOutputSection(); + pdb::SectionContrib SC; + memset(&SC, 0, sizeof(SC)); + SC.ISect = OS->SectionIndex; + SC.Off = C->getRVA() - OS->getRVA(); + SC.Size = C->getSize(); + if (auto *SecChunk = dyn_cast(C)) { + SC.Characteristics = SecChunk->Header->Characteristics; + SC.Imod = SecChunk->File->ModuleDBI->getModuleIndex(); + ArrayRef Contents = SecChunk->getContents(); + JamCRC CRC(0); + ArrayRef CharContents = makeArrayRef( + reinterpret_cast(Contents.data()), Contents.size()); + CRC.update(CharContents); + SC.DataCrc = CRC.getCRC(); + } else { + SC.Characteristics = OS->Header.Characteristics; + // FIXME: When we start creating DBI for import libraries, use those here. + SC.Imod = Modi; + } + SC.RelocCrc = 0; // FIXME + + return SC; +} + void PDBLinker::addObjFile(ObjFile *File) { // 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 @@ -794,6 +817,18 @@ void PDBLinker::addObjFile(ObjFile *File) { File->ModuleDBI = &ExitOnErr(Builder.getDbiBuilder().addModuleInfo(Name)); File->ModuleDBI->setObjFileName(Path); + auto Chunks = File->getChunks(); + assert(!Chunks.empty()); + uint32_t Modi = File->ModuleDBI->getModuleIndex(); + for (Chunk *C : Chunks) { + auto *SecChunk = dyn_cast(C); + if (!SecChunk || !SecChunk->isLive()) + continue; + pdb::SectionContrib SC = createSectionContrib(SecChunk, Modi); + File->ModuleDBI->setFirstSectionContrib(SC); + break; + } + // 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 @@ -1110,31 +1145,6 @@ void PDBLinker::initialize(const llvm::codeview::DebugInfo &BuildId) { DbiBuilder.setBuildNumber(14, 11); } -void PDBLinker::addSectionContrib(pdb::DbiModuleDescriptorBuilder &LinkerModule, - OutputSection *OS, Chunk *C) { - pdb::SectionContrib SC; - memset(&SC, 0, sizeof(SC)); - SC.ISect = OS->SectionIndex; - SC.Off = C->getRVA() - OS->getRVA(); - SC.Size = C->getSize(); - if (auto *SecChunk = dyn_cast(C)) { - SC.Characteristics = SecChunk->Header->Characteristics; - SC.Imod = SecChunk->File->ModuleDBI->getModuleIndex(); - ArrayRef Contents = SecChunk->getContents(); - JamCRC CRC(0); - ArrayRef CharContents = makeArrayRef( - reinterpret_cast(Contents.data()), Contents.size()); - CRC.update(CharContents); - SC.DataCrc = CRC.getCRC(); - } else { - SC.Characteristics = OS->Header.Characteristics; - // FIXME: When we start creating DBI for import libraries, use those here. - SC.Imod = LinkerModule.getModuleIndex(); - } - SC.RelocCrc = 0; // FIXME - Builder.getDbiBuilder().addSectionContrib(SC); -} - void PDBLinker::addSections(ArrayRef OutputSections, ArrayRef SectionTable) { // It's not entirely clear what this is, but the * Linker * module uses it. @@ -1150,8 +1160,11 @@ void PDBLinker::addSections(ArrayRef OutputSections, // Add section contributions. They must be ordered by ascending RVA. for (OutputSection *OS : OutputSections) { addLinkerModuleSectionSymbol(LinkerModule, *OS, Alloc); - for (Chunk *C : OS->getChunks()) - addSectionContrib(LinkerModule, OS, C); + for (Chunk *C : OS->getChunks()) { + pdb::SectionContrib SC = + createSectionContrib(C, LinkerModule.getModuleIndex()); + Builder.getDbiBuilder().addSectionContrib(SC); + } } // Add Section Map stream. diff --git a/lld/test/COFF/pdb.test b/lld/test/COFF/pdb.test index 2650627..e091fd4 100644 --- a/lld/test/COFF/pdb.test +++ b/lld/test/COFF/pdb.test @@ -120,14 +120,16 @@ RAW: Modules RAW-NEXT: ============================================================ RAW-NEXT: Mod 0000 | `{{.*}}pdb.test.tmp1.obj`: -RAW-NEXT: SC[???] | mod = 0, 0000:0000, size = 0, data crc = 0, reloc crc = 0 -RAW-NEXT: none +RAW-NEXT: SC[.text] | mod = 0, 0001:0000, size = 14, data crc = 1682752513, reloc crc = 0 +RAW-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_MEM_EXECUTE | +RAW-NEXT: IMAGE_SCN_MEM_READ RAW-NEXT: Obj: `{{.*}}pdb.test.tmp1.obj`: RAW-NEXT: debug stream: 11, # files: 1, has ec info: false RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 `` RAW-NEXT: Mod 0001 | `{{.*}}pdb.test.tmp2.obj`: -RAW-NEXT: SC[???] | mod = 1, 0000:0000, size = 0, data crc = 0, reloc crc = 0 -RAW-NEXT: none +RAW-NEXT: SC[.text] | mod = 1, 0001:0016, size = 6, data crc = 2139436471, reloc crc = 0 +RAW-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_MEM_EXECUTE | +RAW-NEXT: IMAGE_SCN_MEM_READ RAW-NEXT: Obj: `{{.*}}pdb.test.tmp2.obj`: RAW-NEXT: debug stream: 12, # files: 1, has ec info: false RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 `` diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h b/llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h index c918a5d..ce4d079 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h +++ b/llvm/include/llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h @@ -49,6 +49,7 @@ public: void setPdbFilePathNI(uint32_t NI); void setObjFileName(StringRef Name); + void setFirstSectionContrib(const SectionContrib &SC); void addSymbol(codeview::CVSymbol Symbol); void diff --git a/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp index 1da2c39..b97f1e9 100644 --- a/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp @@ -60,6 +60,11 @@ void DbiModuleDescriptorBuilder::setPdbFilePathNI(uint32_t NI) { PdbFilePathNI = NI; } +void DbiModuleDescriptorBuilder::setFirstSectionContrib( + const SectionContrib &SC) { + Layout.SC = SC; +} + void DbiModuleDescriptorBuilder::addSymbol(CVSymbol Symbol) { Symbols.push_back(Symbol); // Symbols written to a PDB file are required to be 4 byte aligned. The same -- 2.7.4