[lld] r280012 - COFF: add beginnings of debug directory creation

Saleem Abdulrasool via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 29 14:20:46 PDT 2016


Author: compnerd
Date: Mon Aug 29 16:20:46 2016
New Revision: 280012

URL: http://llvm.org/viewvc/llvm-project?rev=280012&view=rev
Log:
COFF: add beginnings of debug directory creation

The IMAGE_FILE_HEADER structure contains a (RVA, size) to an array of
COFF_DEBUG_DIRECTORY records. Each one of these records contains an RVA to a OMF
Debug Directory. These OMF debug directories are derived into newer types such
as PDB70, PDB20, etc. This constructs a PDB70 structure which will allow us to
associate a GUID with a build to actually tie debug information.

Added:
    lld/trunk/test/COFF/rsds.test
Modified:
    lld/trunk/COFF/Config.h
    lld/trunk/COFF/Driver.cpp
    lld/trunk/COFF/Writer.cpp
    lld/trunk/test/COFF/delayimports32.test
    lld/trunk/test/COFF/symtab.test

Modified: lld/trunk/COFF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Config.h?rev=280012&r1=280011&r2=280012&view=diff
==============================================================================
--- lld/trunk/COFF/Config.h (original)
+++ lld/trunk/COFF/Config.h Mon Aug 29 16:20:46 2016
@@ -86,6 +86,7 @@ struct Configuration {
   bool Debug = false;
   bool WriteSymtab = true;
   unsigned DebugTypes = static_cast<unsigned>(DebugType::None);
+  StringRef PDBPath;
 
   // Symbols in this set are considered as live by the garbage collector.
   std::set<Undefined *> GCRoot;

Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=280012&r1=280011&r2=280012&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Mon Aug 29 16:20:46 2016
@@ -372,6 +372,12 @@ void LinkerDriver::link(llvm::ArrayRef<c
             : getDefaultDebugType(Args);
   }
 
+  // Create a dummy PDB file to satisfy build sytem rules.
+  if (auto *Arg = Args.getLastArg(OPT_pdb)) {
+    Config->PDBPath = Arg->getValue();
+    createPDB(Config->PDBPath);
+  }
+
   // Handle /noentry
   if (Args.hasArg(OPT_noentry)) {
     if (!Args.hasArg(OPT_dll))
@@ -743,10 +749,6 @@ void LinkerDriver::link(llvm::ArrayRef<c
   if (Config->Manifest == Configuration::SideBySide)
     createSideBySideManifest();
 
-  // Create a dummy PDB file to satisfy build sytem rules.
-  if (auto *Arg = Args.getLastArg(OPT_pdb))
-    createPDB(Arg->getValue());
-
   // Identify unreferenced COMDAT sections.
   if (Config->DoGC)
     markLive(Symtab.getChunks());

Modified: lld/trunk/COFF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=280012&r1=280011&r2=280012&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.cpp (original)
+++ lld/trunk/COFF/Writer.cpp Mon Aug 29 16:20:46 2016
@@ -21,6 +21,7 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/FileOutputBuffer.h"
+#include "llvm/Support/RandomNumberGenerator.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
 #include <cstdio>
@@ -42,6 +43,61 @@ static const int DOSStubSize = 64;
 static const int NumberfOfDataDirectory = 16;
 
 namespace {
+
+class DebugDirectoryChunk : public Chunk {
+public:
+  DebugDirectoryChunk(const std::vector<std::unique_ptr<Chunk>> &R)
+      : Records(R) {}
+
+  size_t getSize() const override {
+    return Records.size() * sizeof(debug_directory);
+  }
+
+  void writeTo(uint8_t *B) const override {
+    auto *D = reinterpret_cast<debug_directory *>(B + OutputSectionOff);
+
+    for (const std::unique_ptr<Chunk> &Record : Records) {
+      D->Characteristics = 0;
+      D->TimeDateStamp = 0;
+      D->MajorVersion = 0;
+      D->MinorVersion = 0;
+      D->Type = COFF::IMAGE_DEBUG_TYPE_CODEVIEW;
+      D->SizeOfData = Record->getSize();
+      D->AddressOfRawData = Record->getRVA();
+      // TODO(compnerd) get the file offset
+      D->PointerToRawData = 0;
+
+      ++D;
+    }
+  }
+
+private:
+  const std::vector<std::unique_ptr<Chunk>> &Records;
+};
+
+class CVDebugRecordChunk : public Chunk {
+  size_t getSize() const override {
+    return sizeof(codeview::DebugInfo) + Config->PDBPath.size() + 1;
+  }
+
+  void writeTo(uint8_t *B) const override {
+    auto *R = reinterpret_cast<codeview::DebugInfo *>(B + OutputSectionOff);
+
+    R->Signature.CVSignature = OMF::Signature::PDB70;
+    // TODO(compnerd) fill in a GUID by hashing the contents of the binary to
+    // get a reproducible build
+    if (getRandomBytes(R->PDB70.Signature, sizeof(R->PDB70.Signature)))
+      fatal("entropy source failure");
+    // TODO(compnerd) track the Age
+    R->PDB70.Age = 1;
+
+    // variable sized field (PDB Path)
+    auto *P = reinterpret_cast<char *>(B + OutputSectionOff + sizeof(*R));
+    memcpy(P, Config->PDBPath.data(), Config->PDBPath.size());
+    P[Config->PDBPath.size()] = '\0';
+  }
+};
+
 // The writer writes a SymbolTable result to a file.
 class Writer {
 public:
@@ -87,6 +143,9 @@ private:
   EdataContents Edata;
   std::unique_ptr<SEHTableChunk> SEHTable;
 
+  std::unique_ptr<Chunk> DebugDirectory;
+  std::vector<std::unique_ptr<Chunk>> DebugRecords;
+
   uint64_t FileSize;
   uint32_t PointerToSymbolTable = 0;
   uint64_t SizeOfImage;
@@ -294,6 +353,19 @@ void Writer::createMiscChunks() {
       RData->addChunk(C);
   }
 
+  // Create Debug Information Chunks
+  if (Config->Debug) {
+    DebugDirectory = make_unique<DebugDirectoryChunk>(DebugRecords);
+
+    // TODO(compnerd) create a coffgrp entry if DebugType::CV is not enabled
+    if (Config->DebugTypes & static_cast<unsigned>(coff::DebugType::CV))
+      DebugRecords.push_back(make_unique<CVDebugRecordChunk>());
+
+    RData->addChunk(DebugDirectory.get());
+    for (const std::unique_ptr<Chunk> &C : DebugRecords)
+      RData->addChunk(C.get());
+  }
+
   // Create SEH table. x86-only.
   if (Config->Machine != I386)
     return;
@@ -608,6 +680,10 @@ template <typename PEHeaderTy> void Writ
                                 : sizeof(object::coff_tls_directory32);
     }
   }
+  if (Config->Debug) {
+    Dir[DEBUG_DIRECTORY].RelativeVirtualAddress = DebugDirectory->getRVA();
+    Dir[DEBUG_DIRECTORY].Size = DebugDirectory->getSize();
+  }
   if (Symbol *Sym = Symtab->findUnderscore("_load_config_used")) {
     if (auto *B = dyn_cast<DefinedRegular>(Sym->Body)) {
       SectionChunk *SC = B->getChunk();

Modified: lld/trunk/test/COFF/delayimports32.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/delayimports32.test?rev=280012&r1=280011&r2=280012&view=diff
==============================================================================
--- lld/trunk/test/COFF/delayimports32.test (original)
+++ lld/trunk/test/COFF/delayimports32.test Mon Aug 29 16:20:46 2016
@@ -14,7 +14,7 @@ IMPORT-NEXT:   Name: std32.dll
 IMPORT-NEXT:   Attributes: 0x1
 IMPORT-NEXT:   ModuleHandle: 0x1018
 IMPORT-NEXT:   ImportAddressTable: 0x1020
-IMPORT-NEXT:   ImportNameTable: 0x3040
+IMPORT-NEXT:   ImportNameTable: 0x4040
 IMPORT-NEXT:   BoundDelayImportTable: 0x0
 IMPORT-NEXT:   UnloadDelayImportTable: 0x0
 IMPORT-NEXT:   Import {
@@ -71,7 +71,7 @@ BASEREL-NEXT:   }
 BASEREL-NEXT: ]
 
 DISASM:      202b:      68 20 10 40 00  pushl   $4198432
-DISASM-NEXT: 2030:      68 00 30 40 00  pushl   $4206592
+DISASM-NEXT: 2030:      68 00 40 40 00  pushl   $4210688
 DISASM-NEXT: 2035:      e8 c6 ff ff ff  calll   -58 <_main at 0>
 DISASM-NEXT: 203a:      5a      popl    %edx
 DISASM-NEXT: 203b:      59      popl    %ecx
@@ -79,7 +79,7 @@ DISASM-NEXT: 203c:      ff e0   jmpl
 DISASM-NEXT: 203e:      51      pushl   %ecx
 DISASM-NEXT: 203f:      52      pushl   %edx
 DISASM-NEXT: 2040:      68 24 10 40 00  pushl   $4198436
-DISASM-NEXT: 2045:      68 00 30 40 00  pushl   $4206592
+DISASM-NEXT: 2045:      68 00 40 40 00  pushl   $4210688
 DISASM-NEXT: 204a:      e8 b1 ff ff ff  calll   -79 <_main at 0>
 DISASM-NEXT: 204f:      5a      popl    %edx
 DISASM-NEXT: 2050:      59      popl    %ecx

Added: lld/trunk/test/COFF/rsds.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/rsds.test?rev=280012&view=auto
==============================================================================
--- lld/trunk/test/COFF/rsds.test (added)
+++ lld/trunk/test/COFF/rsds.test Mon Aug 29 16:20:46 2016
@@ -0,0 +1,113 @@
+# RUN: yaml2obj %s > %t.obj
+
+# RUN: lld-link /debug /dll /out:%t.dll /entry:DllMain %t.obj
+# RUN: llvm-readobj -coff-debug-directory %t.dll | FileCheck %s
+
+# RUN: lld-link /debug /pdb:%t.pdb /dll /out:%t.dll /entry:DllMain %t.obj
+# RUN: llvm-readobj -coff-debug-directory %t.dll | FileCheck %s -check-prefix CHECK-PDB
+
+# CHECK: DebugDirectory [
+# CHECK:   DebugEntry {
+# CHECK:     Characteristics: 0x0
+# CHECK:     TimeDateStamp: 1970-01-01 00:00:00 (0x0)
+# CHECK:     MajorVersion: 0x0
+# CHECK:     MinorVersion: 0x0
+# CHECK:     Type: CodeView (0x2)
+# CHECK:     SizeOfData: 0x19
+# CHECK:     AddressOfRawData:
+# CHECK:     PointerToRawData:
+# CHECK:     PDBInfo {
+# CHECK:       PDBSignature: 0x53445352
+# CHECK:       PDBGUID:
+# CHECK:       PDBAge: 1
+# CHECK:       PDBFileName: {{$}}
+# CHECK:     }
+# CHECK:   }
+# CHECK: ]
+
+# CHECK-PDB: DebugDirectory [
+# CHECK-PDB:   DebugEntry {
+# CHECK-PDB:     Characteristics: 0x0
+# CHECK-PDB:     TimeDateStamp: 1970-01-01 00:00:00 (0x0)
+# CHECK-PDB:     MajorVersion: 0x0
+# CHECK-PDB:     MinorVersion: 0x0
+# CHECK-PDB:     Type: CodeView (0x2)
+# CHECK-PDB:     SizeOfData:
+# CHECK-PDB:     AddressOfRawData:
+# CHECK-PDB:     PointerToRawData:
+# CHECK-PDB:     PDBInfo {
+# CHECK-PDB:       PDBSignature: 0x53445352
+# CHECK-PDB:       PDBGUID:
+# CHECK-PDB:       PDBAge: 1
+# CHECK-PDB:       PDBFileName: {{.*}}.pdb
+# CHECK-PDB:     }
+# CHECK-PDB:   }
+# CHECK-PDB: ]
+
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_I386
+  Characteristics: [  ]
+sections:
+  - Name:            .text
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    SectionData:     31C0C3
+  - Name:            .data
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       4
+    SectionData:     ''
+  - Name:            .bss
+    Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       4
+    SectionData:     ''
+symbols:
+  - Name:            .text
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          3
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        3963538403
+      Number:          1
+  - Name:            .data
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          0
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          2
+  - Name:            .bss
+    Value:           0
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          0
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          3
+  - Name:            '@feat.00'
+    Value:           1
+    SectionNumber:   -1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+  - Name:            _DllMain
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...

Modified: lld/trunk/test/COFF/symtab.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/symtab.test?rev=280012&r1=280011&r2=280012&view=diff
==============================================================================
--- lld/trunk/test/COFF/symtab.test (original)
+++ lld/trunk/test/COFF/symtab.test Mon Aug 29 16:20:46 2016
@@ -74,7 +74,7 @@
 # CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Name: __imp_ExitProcess
 # CHECK-NEXT:     Value: 64
-# CHECK-NEXT:     Section: .idata (4)
+# CHECK-NEXT:     Section: .idata (5)
 # CHECK-NEXT:     BaseType: Null (0x0)
 # CHECK-NEXT:     ComplexType: Null (0x0)
 # CHECK-NEXT:     StorageClass: External (0x2)
@@ -92,7 +92,7 @@
 # CHECK-NEXT:   Symbol {
 # CHECK-NEXT:     Name: __imp_MessageBoxA
 # CHECK-NEXT:     Value: 72
-# CHECK-NEXT:     Section: .idata (4)
+# CHECK-NEXT:     Section: .idata (5)
 # CHECK-NEXT:     BaseType: Null (0x0)
 # CHECK-NEXT:     ComplexType: Null (0x0)
 # CHECK-NEXT:     StorageClass: External (0x2)




More information about the llvm-commits mailing list