diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp index 4c7c4d8747fb..dd797b43553d 100644 --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -11,7 +11,6 @@ #include "Config.h" #include "Error.h" #include "InputFiles.h" -#include "PDB.h" #include "SymbolTable.h" #include "Symbols.h" #include "Writer.h" @@ -374,10 +373,8 @@ void LinkerDriver::link(llvm::ArrayRef ArgsArr) { } // Create a dummy PDB file to satisfy build sytem rules. - if (auto *Arg = Args.getLastArg(OPT_pdb)) { + if (auto *Arg = Args.getLastArg(OPT_pdb)) Config->PDBPath = Arg->getValue(); - createPDB(Config->PDBPath); - } // Handle /noentry if (Args.hasArg(OPT_noentry)) { diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp index bbc8296f013d..53f50f300950 100644 --- a/lld/COFF/PDB.cpp +++ b/lld/COFF/PDB.cpp @@ -30,7 +30,7 @@ using namespace llvm::support::endian; static ExitOnError ExitOnErr; -void coff::createPDB(StringRef Path) { +void coff::createPDB(StringRef Path, ArrayRef SectionTable) { BumpPtrAllocator Alloc; pdb::PDBFileBuilder Builder(Alloc); ExitOnErr(Builder.initialize(4096)); // 4096 is blocksize @@ -63,6 +63,10 @@ void coff::createPDB(StringRef Path) { auto &IpiBuilder = Builder.getIpiBuilder(); IpiBuilder.setVersionHeader(pdb::PdbTpiV80); + // Add COFF section header stream. + ExitOnErr( + DbiBuilder.addDbgStream(pdb::DbgHeaderType::SectionHdr, SectionTable)); + // Write to a file. ExitOnErr(Builder.commit(Path)); } diff --git a/lld/COFF/PDB.h b/lld/COFF/PDB.h index 97f69355e6d9..3b084b8b5f5a 100644 --- a/lld/COFF/PDB.h +++ b/lld/COFF/PDB.h @@ -10,11 +10,12 @@ #ifndef LLD_COFF_PDB_H #define LLD_COFF_PDB_H +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" namespace lld { namespace coff { -void createPDB(llvm::StringRef Path); +void createPDB(llvm::StringRef Path, llvm::ArrayRef SectionTable); } } diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp index 2b02041796d5..8fb532e5a4de 100644 --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -7,13 +7,14 @@ // //===----------------------------------------------------------------------===// +#include "Writer.h" #include "Config.h" #include "DLL.h" #include "Error.h" #include "InputFiles.h" +#include "PDB.h" #include "SymbolTable.h" #include "Symbols.h" -#include "Writer.h" #include "lld/Core/Parallel.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/STLExtras.h" @@ -147,6 +148,7 @@ private: std::unique_ptr DebugDirectory; std::vector> DebugRecords; CVDebugRecordChunk *BuildId = nullptr; + ArrayRef SectionTable; uint64_t FileSize; uint32_t PointerToSymbolTable = 0; @@ -301,6 +303,10 @@ void Writer::run() { writeSections(); sortExceptionTable(); writeBuildId(); + + if (!Config->PDBPath.empty()) + createPDB(Config->PDBPath, SectionTable); + if (auto EC = Buffer->commit()) fatal(EC, "failed to write the output file"); } @@ -719,6 +725,8 @@ template void Writer::writeHeader() { Sec->writeHeaderTo(Buf); Buf += sizeof(coff_section); } + SectionTable = ArrayRef( + Buf - OutputSections.size() * sizeof(coff_section), Buf); if (OutputSymtab.empty()) return; diff --git a/lld/COFF/Writer.h b/lld/COFF/Writer.h index 0473315ae50a..0d26090177d8 100644 --- a/lld/COFF/Writer.h +++ b/lld/COFF/Writer.h @@ -14,9 +14,7 @@ namespace lld { namespace coff { - -class Chunk; -class OutputSection; +class SymbolTable; void writeResult(SymbolTable *T); diff --git a/lld/test/COFF/pdb.test b/lld/test/COFF/pdb.test index 1bbac22edb85..e9326866036f 100644 --- a/lld/test/COFF/pdb.test +++ b/lld/test/COFF/pdb.test @@ -3,25 +3,28 @@ # RUN: llvm-pdbdump pdb2yaml -stream-metadata -stream-directory -pdb-stream \ # RUN: -dbi-stream -ipi-stream %t.pdb | FileCheck %s +# RUN: llvm-pdbdump raw -section-headers %t.pdb | FileCheck -check-prefix RAW %s + # CHECK: MSF: # CHECK-NEXT: SuperBlock: # CHECK-NEXT: BlockSize: 4096 # CHECK-NEXT: FreeBlockMap: -# CHECK-NEXT: NumBlocks: 9 -# CHECK-NEXT: NumDirectoryBytes: 40 +# CHECK-NEXT: NumBlocks: 10 +# CHECK-NEXT: NumDirectoryBytes: 48 # CHECK-NEXT: Unknown1: 0 # CHECK-NEXT: BlockMapAddr: 3 # CHECK-NEXT: NumDirectoryBlocks: 1 -# CHECK-NEXT: DirectoryBlocks: [ 8 ] -# CHECK-NEXT: NumStreams: 5 -# CHECK-NEXT: FileSize: 36864 -# CHECK-NEXT: StreamSizes: [ 0, 48, 56, 68, 56 ] +# CHECK-NEXT: DirectoryBlocks: [ 9 ] +# CHECK-NEXT: NumStreams: 6 +# CHECK-NEXT: FileSize: 40960 +# CHECK-NEXT: StreamSizes: [ 0, 48, 56, 90, 56, 80 ] # CHECK-NEXT: StreamMap: -# CHECK-NEXT: - Stream: [ ] -# CHECK-NEXT: - Stream: [ 4 ] -# CHECK-NEXT: - Stream: [ 6 ] +# CHECK-NEXT: - Stream: [ ] # CHECK-NEXT: - Stream: [ 5 ] # CHECK-NEXT: - Stream: [ 7 ] +# CHECK-NEXT: - Stream: [ 6 ] +# CHECK-NEXT: - Stream: [ 8 ] +# CHECK-NEXT: - Stream: [ 4 ] # CHECK-NEXT: PdbStream: # CHECK-NEXT: Age: 1 # CHECK-NEXT: Guid: '{00000000-0000-0000-0000-000000000000}' @@ -40,6 +43,40 @@ # CHECK-NEXT: Version: VC80 # CHECK-NEXT: Records: +# RAW: Section Headers [ +# RAW-NEXT: { +# RAW-NEXT: Name: .text +# RAW-NEXT: Virtual Size: 3 +# RAW-NEXT: Virtual Address: 4096 +# RAW-NEXT: Size of Raw Data: 512 +# RAW-NEXT: File Pointer to Raw Data: 512 +# RAW-NEXT: File Pointer to Relocations: 0 +# RAW-NEXT: File Pointer to Linenumbers: 0 +# RAW-NEXT: Number of Relocations: 0 +# RAW-NEXT: Number of Linenumbers: 0 +# RAW-NEXT: Characteristics [ (0x60000020) +# 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: } +# RAW-NEXT: { +# RAW-NEXT: Name: .rdata +# RAW-NEXT: Virtual Size: 107 +# RAW-NEXT: Virtual Address: 8192 +# RAW-NEXT: Size of Raw Data: 512 +# RAW-NEXT: File Pointer to Raw Data: 1024 +# RAW-NEXT: File Pointer to Relocations: 0 +# RAW-NEXT: File Pointer to Linenumbers: 0 +# RAW-NEXT: Number of Relocations: 0 +# RAW-NEXT: Number of Linenumbers: 0 +# RAW-NEXT: Characteristics [ (0x40000040) +# RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40) +# RAW-NEXT: IMAGE_SCN_MEM_READ (0x40000000) +# RAW-NEXT: ] +# RAW-NEXT: } +# RAW-NEXT: ] + --- !COFF header: Machine: IMAGE_FILE_MACHINE_I386