Index: COFF/Chunks.h =================================================================== --- COFF/Chunks.h +++ COFF/Chunks.h @@ -187,11 +187,12 @@ // Auxiliary Format 5: Section Definitions. Used for ICF. uint32_t Checksum = 0; + const coff_section *Header; + private: // A file this chunk was created from. ObjectFile *File; - const coff_section *Header; StringRef SectionName; std::vector AssocChildren; llvm::iterator_range Relocs; Index: COFF/Chunks.cpp =================================================================== --- COFF/Chunks.cpp +++ COFF/Chunks.cpp @@ -28,7 +28,7 @@ namespace coff { SectionChunk::SectionChunk(ObjectFile *F, const coff_section *H) - : Chunk(SectionKind), Repl(this), File(F), Header(H), + : Chunk(SectionKind), Repl(this), Header(H), File(F), Relocs(File->getCOFFObj()->getRelocations(Header)), NumRelocs(std::distance(Relocs.begin(), Relocs.end())) { // Initialize SectionName. Index: COFF/PDB.h =================================================================== --- COFF/PDB.h +++ COFF/PDB.h @@ -15,7 +15,10 @@ namespace lld { namespace coff { -void createPDB(llvm::StringRef Path, llvm::ArrayRef SectionTable); +class SymbolTable; + +void createPDB(llvm::StringRef Path, SymbolTable *Symtab, + llvm::ArrayRef SectionTable); } } Index: COFF/PDB.cpp =================================================================== --- COFF/PDB.cpp +++ COFF/PDB.cpp @@ -8,7 +8,10 @@ //===----------------------------------------------------------------------===// #include "PDB.h" +#include "Chunks.h" #include "Error.h" +#include "SymbolTable.h" +#include "Symbols.h" #include "llvm/DebugInfo/MSF/MSFBuilder.h" #include "llvm/DebugInfo/MSF/MSFCommon.h" #include "llvm/DebugInfo/PDB/Raw/DbiStream.h" @@ -25,13 +28,27 @@ #include using namespace lld; +using namespace lld::coff; using namespace llvm; using namespace llvm::support; using namespace llvm::support::endian; +using llvm::object::coff_section; + static ExitOnError ExitOnErr; -void coff::createPDB(StringRef Path, ArrayRef SectionTable) { +// Returns a list of all SectionChunks. +static std::vector getInputSections(SymbolTable *Symtab) { + std::vector V; + for (Chunk *C : Symtab->getChunks()) + if (auto *SC = dyn_cast(C)) + V.push_back(*SC->Header); + return V; +} + +// Creates a PDB file. +void coff::createPDB(StringRef Path, SymbolTable *Symtab, + ArrayRef SectionTable) { BumpPtrAllocator Alloc; pdb::PDBFileBuilder Builder(Alloc); ExitOnErr(Builder.initialize(4096)); // 4096 is blocksize @@ -64,12 +81,18 @@ auto &IpiBuilder = Builder.getIpiBuilder(); IpiBuilder.setVersionHeader(pdb::PdbTpiV80); + // Add Section Contributions. + ArrayRef InputSections = getInputSections(Symtab); + std::vector Contribs = + pdb::DbiStreamBuilder::createSectionContribs(InputSections); + DbiBuilder.setSectionContribs(Contribs); + // Add Section Map stream. - ArrayRef Sections = { - (object::coff_section *)SectionTable.data(), - SectionTable.size() / sizeof(object::coff_section)}; + ArrayRef OutputSections = {(coff_section *)SectionTable.data(), + SectionTable.size() / + sizeof(coff_section)}; std::vector SectionMap = - pdb::DbiStreamBuilder::createSectionMap(Sections); + pdb::DbiStreamBuilder::createSectionMap(OutputSections); DbiBuilder.setSectionMap(SectionMap); // Add COFF section header stream. Index: COFF/Writer.cpp =================================================================== --- COFF/Writer.cpp +++ COFF/Writer.cpp @@ -305,7 +305,7 @@ writeBuildId(); if (!Config->PDBPath.empty()) - createPDB(Config->PDBPath, SectionTable); + createPDB(Config->PDBPath, Symtab, SectionTable); if (auto EC = Buffer->commit()) fatal(EC, "failed to write the output file"); Index: test/COFF/pdb.test =================================================================== --- test/COFF/pdb.test +++ test/COFF/pdb.test @@ -3,8 +3,8 @@ # RUN: llvm-pdbdump pdb2yaml -stream-metadata -stream-directory -pdb-stream \ # RUN: -dbi-stream -ipi-stream %t.pdb | FileCheck %s -# RUN: llvm-pdbdump raw -section-map -section-headers %t.pdb | \ -# RUN: FileCheck -check-prefix RAW %s +# RUN: llvm-pdbdump raw -section-map -section-headers -section-contribs %t.pdb \ +# RUN: | FileCheck -check-prefix RAW %s # CHECK: MSF: # CHECK-NEXT: SuperBlock: @@ -18,7 +18,7 @@ # CHECK-NEXT: DirectoryBlocks: [ 9 ] # CHECK-NEXT: NumStreams: 6 # CHECK-NEXT: FileSize: 40960 -# CHECK-NEXT: StreamSizes: [ 0, 48, 56, 154, 56, 80 ] +# CHECK-NEXT: StreamSizes: [ 0, 48, 56, 242, 56, 80 ] # CHECK-NEXT: StreamMap: # CHECK-NEXT: - Stream: [ ] # CHECK-NEXT: - Stream: [ 5 ] @@ -44,10 +44,60 @@ # CHECK-NEXT: Version: VC80 # CHECK-NEXT: Records: -# RAW: Section Map [ -# RAW-NEXT: Entry { -# RAW-NEXT: Flags [ (0x10D) -# RAW-NEXT: AddressIs32Bit (0x8) +# RAW: Section Contributions [ +# RAW-NEXT: Contribution { +# RAW-NEXT: ISect: 0 +# RAW-NEXT: Off: 140 +# RAW-NEXT: Size: 3 +# RAW-NEXT: Characteristics [ (0x60300020) +# RAW-NEXT: IMAGE_SCN_ALIGN_4BYTES (0x300000) +# RAW-NEXT: IMAGE_SCN_CNT_CODE (0x20) +# RAW-NEXT: IMAGE_SCN_MEM_EXECUTE (0x20000000) +# RAW-NEXT: IMAGE_SCN_MEM_READ (0x40000000) +# RAW-NEXT: ] +# RAW-NEXT: Module { +# RAW-NEXT: Index: 0 +# RAW-NEXT: } +# RAW-NEXT: Data CRC: 0 +# RAW-NEXT: Reloc CRC: 0 +# RAW-NEXT: } +# RAW-NEXT: Contribution { +# RAW-NEXT: ISect: 0 +# RAW-NEXT: Off: 0 +# RAW-NEXT: Size: 0 +# RAW-NEXT: Characteristics [ (0xC0300040) +# RAW-NEXT: IMAGE_SCN_ALIGN_4BYTES (0x300000) +# RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) +# RAW-NEXT: IMAGE_SCN_MEM_READ (0x40000000) +# RAW-NEXT: IMAGE_SCN_MEM_WRITE (0x80000000) +# RAW-NEXT: ] +# RAW-NEXT: Module { +# RAW-NEXT: Index: 0 +# RAW-NEXT: } +# RAW-NEXT: Data CRC: 0 +# RAW-NEXT: Reloc CRC: 0 +# RAW-NEXT: } +# RAW-NEXT: Contribution { +# RAW-NEXT: ISect: 0 +# RAW-NEXT: Off: 0 +# RAW-NEXT: Size: 0 +# RAW-NEXT: Characteristics [ (0xC0300080) +# RAW-NEXT: IMAGE_SCN_ALIGN_4BYTES (0x300000) +# RAW-NEXT: IMAGE_SCN_CNT_UNINITIALIZED_DATA (0x80) +# RAW-NEXT: IMAGE_SCN_MEM_READ (0x40000000) +# RAW-NEXT: IMAGE_SCN_MEM_WRITE (0x80000000) +# RAW-NEXT: ] +# RAW-NEXT: Module { +# RAW-NEXT: Index: 0 +# RAW-NEXT: } +# RAW-NEXT: Data CRC: 0 +# RAW-NEXT: Reloc CRC: 0 +# RAW-NEXT: } +# RAW-NEXT: ] +# RAW-NEXT: Section Map [ +# RAW-NEXT: Entry { +# RAW-NEXT: Flags [ (0x10D) +# RAW-NEXT: AddressIs32Bit (0x8) # RAW-NEXT: Execute (0x4) # RAW-NEXT: IsSelector (0x100) # RAW-NEXT: Read (0x1)