Index: lld/trunk/COFF/PDB.h =================================================================== --- lld/trunk/COFF/PDB.h +++ lld/trunk/COFF/PDB.h @@ -21,9 +21,12 @@ namespace lld { namespace coff { +class OutputSection; class SymbolTable; -void createPDB(SymbolTable *Symtab, llvm::ArrayRef SectionTable, +void createPDB(SymbolTable *Symtab, + llvm::ArrayRef OutputSections, + llvm::ArrayRef SectionTable, const llvm::codeview::DebugInfo *DI); } } Index: lld/trunk/COFF/PDB.cpp =================================================================== --- lld/trunk/COFF/PDB.cpp +++ lld/trunk/COFF/PDB.cpp @@ -98,7 +98,11 @@ TypeServer2Record &TS); /// Add the section map and section contributions to the PDB. - void addSections(ArrayRef SectionTable); + void addSections(ArrayRef OutputSections, + ArrayRef SectionTable); + + void addSectionContrib(pdb::DbiModuleDescriptorBuilder &LinkerModule, + OutputSection *OS, Chunk *C); /// Write the PDB to disk. void commit(); @@ -129,14 +133,6 @@ }; } -// Returns a list of all SectionChunks. -static void addSectionContribs(SymbolTable *Symtab, - pdb::DbiStreamBuilder &DbiBuilder) { - for (Chunk *C : Symtab->getChunks()) - if (auto *SC = dyn_cast(C)) - DbiBuilder.addSectionContrib(SC->File->ModuleDBI, SC->Header); -} - static SectionChunk *findByName(std::vector &Sections, StringRef Name) { for (SectionChunk *C : Sections) @@ -648,12 +644,14 @@ } // Creates a PDB file. -void coff::createPDB(SymbolTable *Symtab, ArrayRef SectionTable, +void coff::createPDB(SymbolTable *Symtab, + ArrayRef OutputSections, + ArrayRef SectionTable, const llvm::codeview::DebugInfo *DI) { PDBLinker PDB(Symtab); PDB.initialize(DI); PDB.addObjectsToPDB(); - PDB.addSections(SectionTable); + PDB.addSections(OutputSections, SectionTable); PDB.commit(); } @@ -682,19 +680,30 @@ ExitOnErr(DbiBuilder.addDbgStream(pdb::DbgHeaderType::NewFPO, {})); } -void PDBLinker::addSections(ArrayRef SectionTable) { - // Add Section Contributions. - pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder(); - addSectionContribs(Symtab, DbiBuilder); - - // Add Section Map stream. - ArrayRef Sections = { - (const object::coff_section *)SectionTable.data(), - SectionTable.size() / sizeof(object::coff_section)}; - SectionMap = pdb::DbiStreamBuilder::createSectionMap(Sections); - DbiBuilder.setSectionMap(SectionMap); +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(); + } else { + SC.Characteristics = OS->getCharacteristics(); + // FIXME: When we start creating DBI for import libraries, use those here. + SC.Imod = LinkerModule.getModuleIndex(); + } + SC.DataCrc = 0; // FIXME + 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. + pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder(); NativePath = Config->PDBPath; sys::fs::make_absolute(NativePath); sys::path::native(NativePath, sys::path::Style::windows); @@ -703,6 +712,18 @@ LinkerModule.setPdbFilePathNI(PdbFilePathNI); addLinkerModuleSymbols(NativePath, LinkerModule, Alloc); + // Add section contributions. They must be ordered by ascending RVA. + for (OutputSection *OS : OutputSections) + for (Chunk *C : OS->getChunks()) + addSectionContrib(LinkerModule, OS, C); + + // Add Section Map stream. + ArrayRef Sections = { + (const object::coff_section *)SectionTable.data(), + SectionTable.size() / sizeof(object::coff_section)}; + SectionMap = pdb::DbiStreamBuilder::createSectionMap(Sections); + DbiBuilder.setSectionMap(SectionMap); + // Add COFF section header stream. ExitOnErr( DbiBuilder.addDbgStream(pdb::DbgHeaderType::SectionHdr, SectionTable)); Index: lld/trunk/COFF/Writer.cpp =================================================================== --- lld/trunk/COFF/Writer.cpp +++ lld/trunk/COFF/Writer.cpp @@ -240,7 +240,7 @@ const llvm::codeview::DebugInfo *DI = nullptr; if (Config->DebugTypes & static_cast(coff::DebugType::CV)) DI = BuildId->DI; - createPDB(Symtab, SectionTable, DI); + createPDB(Symtab, OutputSections, SectionTable, DI); } writeMapFile(OutputSections); Index: lld/trunk/test/COFF/pdb-publics-import.test =================================================================== --- lld/trunk/test/COFF/pdb-publics-import.test +++ lld/trunk/test/COFF/pdb-publics-import.test @@ -7,7 +7,7 @@ RUN: /export:exportfn1 /export:exportfn2 RUN: yaml2obj < %p/Inputs/import.yaml > %t2.obj RUN: lld-link /out:%t2.exe /pdb:%t2.pdb /debug /entry:main %t2.obj %t1.lib -RUN: llvm-pdbutil dump %t2.pdb -publics | FileCheck %s +RUN: llvm-pdbutil dump %t2.pdb -publics -section-contribs | FileCheck %s CHECK: Public Symbols CHECK-NEXT: ============================================================ @@ -21,3 +21,21 @@ CHECK-NEXT: flags = none, addr = 0003:0072 CHECK-NEXT: 0 | S_PUB32 [size = 32] `__imp_exportfn1` CHECK-NEXT: flags = none, addr = 0003:0064 + +CHECK: Section Contributions +CHECK-NEXT: ============================================================ + main +CHECK-NEXT: SC | mod = 0, 0001:0000, size = 8, data crc = 0, reloc crc = 0 +CHECK-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_EXECUTE | +CHECK-NEXT: IMAGE_SCN_MEM_READ + exportfn1 thunk +CHECK-NEXT: SC | mod = 1, 0001:0016, size = 6, data crc = 0, reloc crc = 0 +CHECK-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ + exportfn2 thunk +CHECK-NEXT: SC | mod = 1, 0001:0032, size = 6, data crc = 0, reloc crc = 0 +CHECK-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ + .rdata debug directory data chunks +CHECK-NEXT: SC | mod = 1, 0002:0000, size = 28, data crc = 0, reloc crc = 0 +CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ +CHECK-NEXT: SC | mod = 1, 0002:0028, size = 110, data crc = 0, reloc crc = 0 +CHECK-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ Index: lld/trunk/test/COFF/pdb.test =================================================================== --- lld/trunk/test/COFF/pdb.test +++ lld/trunk/test/COFF/pdb.test @@ -190,16 +190,16 @@ RAW-NEXT: off = 0 RAW: Section Contributions RAW-NEXT: ============================================================ -RAW-NEXT: SC | mod = 0, 65535:1288, size = 14, data crc = 0, reloc crc = 0 +RAW-NEXT: SC | mod = 0, 0001:0000, size = 12, data crc = 0, reloc crc = 0 +RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ +RAW-NEXT: SC | mod = 0, 0002:0000, size = 14, data crc = 0, 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: SC | mod = 0, 65535:1312, size = 8, data crc = 0, reloc crc = 0 -RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ -RAW-NEXT: SC | mod = 0, 65535:1320, size = 12, data crc = 0, reloc crc = 0 -RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ -RAW-NEXT: SC | mod = 1, 65535:1144, size = 6, data crc = 0, reloc crc = 0 +RAW-NEXT: SC | mod = 1, 0002:0016, size = 6, data crc = 0, 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: SC | mod = 0, 0003:0000, size = 8, data crc = 0, reloc crc = 0 +RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ RAW: Section Map RAW-NEXT: ============================================================ RAW-NEXT: Section 0000 | ovl = 0, group = 0, frame = 0, name = 1 Index: llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h +++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h @@ -72,8 +72,9 @@ Error commit(const msf::MSFLayout &Layout, WritableBinaryStreamRef MsfBuffer); - void addSectionContrib(DbiModuleDescriptorBuilder *ModuleDbi, - const llvm::object::coff_section *SecHdr); + void addSectionContrib(const SectionContrib &SC) { + SectionContribs.emplace_back(SC); + } // A helper function to create a Section Map from a COFF section header. static std::vector Index: llvm/trunk/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp +++ llvm/trunk/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp @@ -311,19 +311,6 @@ return Ret; } -void DbiStreamBuilder::addSectionContrib(DbiModuleDescriptorBuilder *ModuleDbi, - const object::coff_section *SecHdr) { - SectionContrib SC; - memset(&SC, 0, sizeof(SC)); - SC.ISect = (uint16_t)~0U; // This represents nil. - SC.Off = SecHdr->PointerToRawData; - SC.Size = SecHdr->SizeOfRawData; - SC.Characteristics = SecHdr->Characteristics; - // Use the module index in the module dbi stream or nil (-1). - SC.Imod = ModuleDbi ? ModuleDbi->getModuleIndex() : (uint16_t)~0U; - SectionContribs.emplace_back(SC); -} - // A utility function to create a Section Map for a given list of COFF sections. // // A Section Map seem to be a copy of a COFF section list in other format.