[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