[PDB] Fix section contributions

Summary:
PDB section contributions are supposed to use output section indices and
offsets, not input section indices and offsets.

This allows the debugger to look up the index of the module that it
should look up in the modules stream for symbol information. With this
change, windbg can now find line tables, but it still cannot print local
variables.

Fixes PR34048

Reviewers: zturner

Subscribers: hiraditya, ruiu, llvm-commits

Differential Revision: https://reviews.llvm.org/D36285

llvm-svn: 309987
diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp
index 2f2a9cf..2b9d4f2 100644
--- a/lld/COFF/PDB.cpp
+++ b/lld/COFF/PDB.cpp
@@ -98,7 +98,11 @@
                                             TypeServer2Record &TS);
 
   /// Add the section map and section contributions to the PDB.
-  void addSections(ArrayRef<uint8_t> SectionTable);
+  void addSections(ArrayRef<OutputSection *> OutputSections,
+                   ArrayRef<uint8_t> 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<SectionChunk>(C))
-      DbiBuilder.addSectionContrib(SC->File->ModuleDBI, SC->Header);
-}
-
 static SectionChunk *findByName(std::vector<SectionChunk *> &Sections,
                                 StringRef Name) {
   for (SectionChunk *C : Sections)
@@ -648,12 +644,14 @@
 }
 
 // Creates a PDB file.
-void coff::createPDB(SymbolTable *Symtab, ArrayRef<uint8_t> SectionTable,
+void coff::createPDB(SymbolTable *Symtab,
+                     ArrayRef<OutputSection *> OutputSections,
+                     ArrayRef<uint8_t> 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<uint8_t> SectionTable) {
-  // Add Section Contributions.
-  pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder();
-  addSectionContribs(Symtab, DbiBuilder);
+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<SectionChunk>(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);
+}
 
-  // Add Section Map stream.
-  ArrayRef<object::coff_section> Sections = {
-      (const object::coff_section *)SectionTable.data(),
-      SectionTable.size() / sizeof(object::coff_section)};
-  SectionMap = pdb::DbiStreamBuilder::createSectionMap(Sections);
-  DbiBuilder.setSectionMap(SectionMap);
-
+void PDBLinker::addSections(ArrayRef<OutputSection *> OutputSections,
+                            ArrayRef<uint8_t> 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<object::coff_section> 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));