summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2017-08-15 21:31:41 +0000
committerZachary Turner <zturner@google.com>2017-08-15 21:31:41 +0000
commit024323cb126f99a4261365b06c49f671d0dc78c5 (patch)
treebbb434a0c4b2c5dbcea7c60b1c94c2f4cd9103bc
parentfe9f1e60c517e71bd819cab9e90b110457ca42b6 (diff)
downloadbcm5719-llvm-024323cb126f99a4261365b06c49f671d0dc78c5.tar.gz
bcm5719-llvm-024323cb126f99a4261365b06c49f671d0dc78c5.zip
[LLD COFF/PDB] Incrementally update the build id.
Previously, our algorithm to compute a build id involved hashing the executable and storing that as the GUID in the CV Debug Record chunk, and setting the age to 1. This breaks down in one very obvious case: a user adds some newlines to a file, rebuilds, but changes nothing else. This causes new line information and new file checksums to get written to the PDB, meaning that the debug info is different, but the generated code would be the same, so we would write the same build over again with an age of 1. Anyone using a symbol cache would have a problem now, because the debugger would open the executable, look at the age and guid, find a matching PDB in the symbol cache and then load it. It would never copy the new PDB to the symbol cache. This patch implements the canonical Windows algorithm for updating a build id, which is to check the existing executable first, and re-use an existing GUID while bumping the age if it already exists. Differential Revision: https://reviews.llvm.org/D36758 llvm-svn: 310961
-rw-r--r--lld/COFF/PDB.cpp16
-rw-r--r--lld/COFF/PDB.h2
-rw-r--r--lld/COFF/Writer.cpp135
-rw-r--r--lld/test/COFF/pdb-diff.test7
-rw-r--r--lld/test/COFF/pdb-none.test3
-rw-r--r--lld/test/COFF/pdb-source-lines.test35
-rw-r--r--lld/test/COFF/pdb.test1
-rw-r--r--lld/test/COFF/rsds.test34
8 files changed, 164 insertions, 69 deletions
diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp
index 29cf7b521a3..37b8053f022 100644
--- a/lld/COFF/PDB.cpp
+++ b/lld/COFF/PDB.cpp
@@ -76,7 +76,7 @@ public:
IDTable(Alloc) {}
/// Emit the basic PDB structure: initial streams, headers, etc.
- void initialize(const llvm::codeview::DebugInfo *DI);
+ void initialize(const llvm::codeview::DebugInfo &BuildId);
/// Link CodeView from each object file in the symbol table into the PDB.
void addObjectsToPDB();
@@ -808,15 +808,15 @@ static void addLinkerModuleSectionSymbol(pdb::DbiModuleDescriptorBuilder &Mod,
void coff::createPDB(SymbolTable *Symtab,
ArrayRef<OutputSection *> OutputSections,
ArrayRef<uint8_t> SectionTable,
- const llvm::codeview::DebugInfo *DI) {
+ const llvm::codeview::DebugInfo &BuildId) {
PDBLinker PDB(Symtab);
- PDB.initialize(DI);
+ PDB.initialize(BuildId);
PDB.addObjectsToPDB();
PDB.addSections(OutputSections, SectionTable);
PDB.commit();
}
-void PDBLinker::initialize(const llvm::codeview::DebugInfo *DI) {
+void PDBLinker::initialize(const llvm::codeview::DebugInfo &BuildId) {
ExitOnErr(Builder.initialize(4096)); // 4096 is blocksize
// Create streams in MSF for predefined streams, namely
@@ -826,17 +826,17 @@ void PDBLinker::initialize(const llvm::codeview::DebugInfo *DI) {
// Add an Info stream.
auto &InfoBuilder = Builder.getInfoBuilder();
- InfoBuilder.setAge(DI ? DI->PDB70.Age : 0);
+ InfoBuilder.setAge(BuildId.PDB70.Age);
- GUID uuid{};
- if (DI)
- memcpy(&uuid, &DI->PDB70.Signature, sizeof(uuid));
+ GUID uuid;
+ memcpy(&uuid, &BuildId.PDB70.Signature, sizeof(uuid));
InfoBuilder.setGuid(uuid);
InfoBuilder.setSignature(time(nullptr));
InfoBuilder.setVersion(pdb::PdbRaw_ImplVer::PdbImplVC70);
// Add an empty DBI stream.
pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder();
+ DbiBuilder.setAge(BuildId.PDB70.Age);
DbiBuilder.setVersionHeader(pdb::PdbDbiV70);
ExitOnErr(DbiBuilder.addDbgStream(pdb::DbgHeaderType::NewFPO, {}));
}
diff --git a/lld/COFF/PDB.h b/lld/COFF/PDB.h
index 3f8e92cb818..defd7d23679 100644
--- a/lld/COFF/PDB.h
+++ b/lld/COFF/PDB.h
@@ -27,7 +27,7 @@ class SymbolTable;
void createPDB(SymbolTable *Symtab,
llvm::ArrayRef<OutputSection *> OutputSections,
llvm::ArrayRef<uint8_t> SectionTable,
- const llvm::codeview::DebugInfo *DI);
+ const llvm::codeview::DebugInfo &BuildId);
}
}
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index 8272e2259ce..6a19882c1e3 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -20,6 +20,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/FileOutputBuffer.h"
@@ -92,19 +93,17 @@ public:
void writeTo(uint8_t *B) const override {
// Save off the DebugInfo entry to backfill the file signature (build id)
// in Writer::writeBuildId
- DI = reinterpret_cast<codeview::DebugInfo *>(B + OutputSectionOff);
-
- DI->Signature.CVSignature = OMF::Signature::PDB70;
+ BuildId = reinterpret_cast<codeview::DebugInfo *>(B + OutputSectionOff);
// variable sized field (PDB Path)
- auto *P = reinterpret_cast<char *>(B + OutputSectionOff + sizeof(*DI));
+ char *P = reinterpret_cast<char *>(B + OutputSectionOff + sizeof(*BuildId));
if (!PDBAbsPath.empty())
memcpy(P, PDBAbsPath.data(), PDBAbsPath.size());
P[PDBAbsPath.size()] = '\0';
}
SmallString<128> PDBAbsPath;
- mutable codeview::DebugInfo *DI = nullptr;
+ mutable codeview::DebugInfo *BuildId = nullptr;
};
// The writer writes a SymbolTable result to a file.
@@ -126,8 +125,8 @@ private:
void fixSafeSEHSymbols();
void setSectionPermissions();
void writeSections();
- void sortExceptionTable();
void writeBuildId();
+ void sortExceptionTable();
llvm::Optional<coff_symbol16> createSymbol(Defined *D);
size_t addEntryToStringTable(StringRef Str);
@@ -153,6 +152,7 @@ private:
Chunk *DebugDirectory = nullptr;
std::vector<Chunk *> DebugRecords;
CVDebugRecordChunk *BuildId = nullptr;
+ Optional<codeview::DebugInfo> PreviousBuildId;
ArrayRef<uint8_t> SectionTable;
uint64_t FileSize;
@@ -220,6 +220,65 @@ void OutputSection::writeHeaderTo(uint8_t *Buf) {
} // namespace coff
} // namespace lld
+// PDBs are matched against executables using a build id which consists of three
+// components:
+// 1. A 16-bit GUID
+// 2. An age
+// 3. A time stamp.
+//
+// Debuggers and symbol servers match executables against debug info by checking
+// each of these components of the EXE/DLL against the corresponding value in
+// the PDB and failing a match if any of the components differ. In the case of
+// symbol servers, symbols are cached in a folder that is a function of the
+// GUID. As a result, in order to avoid symbol cache pollution where every
+// incremental build copies a new PDB to the symbol cache, we must try to re-use
+// the existing GUID if one exists, but bump the age. This way the match will
+// fail, so the symbol cache knows to use the new PDB, but the GUID matches, so
+// it overwrites the existing item in the symbol cache rather than making a new
+// one.
+static Optional<codeview::DebugInfo> loadExistingBuildId(StringRef Path) {
+ // We don't need to incrementally update a previous build id if we're not
+ // writing codeview debug info.
+ if (!Config->Debug)
+ return None;
+
+ auto ExpectedBinary = llvm::object::createBinary(Path);
+ if (!ExpectedBinary) {
+ consumeError(ExpectedBinary.takeError());
+ return None;
+ }
+
+ auto Binary = std::move(*ExpectedBinary);
+ if (!Binary.getBinary()->isCOFF())
+ return None;
+
+ std::error_code EC;
+ COFFObjectFile File(Binary.getBinary()->getMemoryBufferRef(), EC);
+ if (EC)
+ return None;
+
+ // If the machine of the binary we're outputting doesn't match the machine
+ // of the existing binary, don't try to re-use the build id.
+ if (File.is64() != Config->is64() || File.getMachine() != Config->Machine)
+ return None;
+
+ for (const auto &DebugDir : File.debug_directories()) {
+ if (DebugDir.Type != IMAGE_DEBUG_TYPE_CODEVIEW)
+ continue;
+
+ const codeview::DebugInfo *ExistingDI = nullptr;
+ StringRef PDBFileName;
+ if (auto EC = File.getDebugPDBInfo(ExistingDI, PDBFileName))
+ return None;
+ // We only support writing PDBs in v70 format. So if this is not a build
+ // id that we recognize / support, ignore it.
+ if (ExistingDI->Signature.CVSignature != OMF::Signature::PDB70)
+ return None;
+ return *ExistingDI;
+ }
+ return None;
+}
+
// The main function of the writer.
void Writer::run() {
createSections();
@@ -232,6 +291,10 @@ void Writer::run() {
removeEmptySections();
setSectionPermissions();
createSymbolAndStringTable();
+
+ // We must do this before opening the output file, as it depends on being able
+ // to read the contents of the existing output file.
+ PreviousBuildId = loadExistingBuildId(Config->OutputFile);
openFile(Config->OutputFile);
if (Config->is64()) {
writeHeader<pe32plus_header>();
@@ -244,10 +307,9 @@ void Writer::run() {
writeBuildId();
if (!Config->PDBPath.empty() && Config->Debug) {
- const llvm::codeview::DebugInfo *DI = nullptr;
- if (Config->DebugTypes & static_cast<unsigned>(coff::DebugType::CV))
- DI = BuildId->DI;
- createPDB(Symtab, OutputSections, SectionTable, DI);
+
+ assert(BuildId);
+ createPDB(Symtab, OutputSections, SectionTable, *BuildId->BuildId);
}
writeMapFile(OutputSections);
@@ -311,13 +373,13 @@ void Writer::createMiscChunks() {
if (Config->Debug) {
DebugDirectory = make<DebugDirectoryChunk>(DebugRecords);
- // TODO(compnerd) create a coffgrp entry if DebugType::CV is not enabled
- if (Config->DebugTypes & static_cast<unsigned>(coff::DebugType::CV)) {
- auto *Chunk = make<CVDebugRecordChunk>();
-
- BuildId = Chunk;
- DebugRecords.push_back(Chunk);
- }
+ // Make a CVDebugRecordChunk even when /DEBUG:CV is not specified. We
+ // output a PDB no matter what, and this chunk provides the only means of
+ // allowing a debugger to match a PDB and an executable. So we need it even
+ // if we're ultimately not going to write CodeView data to the PDB.
+ auto *CVChunk = make<CVDebugRecordChunk>();
+ BuildId = CVChunk;
+ DebugRecords.push_back(CVChunk);
RData->addChunk(DebugDirectory);
for (Chunk *C : DebugRecords)
@@ -782,6 +844,25 @@ void Writer::writeSections() {
}
}
+void Writer::writeBuildId() {
+ // If we're not writing a build id (e.g. because /debug is not specified),
+ // then just return;
+ if (!Config->Debug)
+ return;
+
+ assert(BuildId && "BuildId is not set!");
+
+ if (PreviousBuildId.hasValue()) {
+ *BuildId->BuildId = *PreviousBuildId;
+ BuildId->BuildId->PDB70.Age = BuildId->BuildId->PDB70.Age + 1;
+ return;
+ }
+
+ BuildId->BuildId->Signature.CVSignature = OMF::Signature::PDB70;
+ BuildId->BuildId->PDB70.Age = 1;
+ llvm::getRandomBytes(BuildId->BuildId->PDB70.Signature, 16);
+}
+
// Sort .pdata section contents according to PE/COFF spec 5.5.
void Writer::sortExceptionTable() {
OutputSection *Sec = findSection(".pdata");
@@ -805,26 +886,6 @@ void Writer::sortExceptionTable() {
errs() << "warning: don't know how to handle .pdata.\n";
}
-// Backfill the CVSignature in a PDB70 Debug Record. This backfilling allows us
-// to get reproducible builds.
-void Writer::writeBuildId() {
- // There is nothing to backfill if BuildId was not setup.
- if (BuildId == nullptr)
- return;
-
- assert(BuildId->DI->Signature.CVSignature == OMF::Signature::PDB70 &&
- "only PDB 7.0 is supported");
- assert(sizeof(BuildId->DI->PDB70.Signature) == 16 &&
- "signature size mismatch");
-
- // Compute an MD5 hash.
- ArrayRef<uint8_t> Buf(Buffer->getBufferStart(), Buffer->getBufferEnd());
- memcpy(BuildId->DI->PDB70.Signature, MD5::hash(Buf).data(), 16);
-
- // TODO(compnerd) track the Age
- BuildId->DI->PDB70.Age = 1;
-}
-
OutputSection *Writer::findSection(StringRef Name) {
for (OutputSection *Sec : OutputSections)
if (Sec->getName() == Name)
diff --git a/lld/test/COFF/pdb-diff.test b/lld/test/COFF/pdb-diff.test
index 9853ed90d06..9d984e1e091 100644
--- a/lld/test/COFF/pdb-diff.test
+++ b/lld/test/COFF/pdb-diff.test
@@ -4,8 +4,11 @@ as the "baseline" for us to measure against. Then we link the same object
file with LLD and compare the two PDBs. Since the baseline object file and
PDB are already checked in, we just run LLD on the object file.
-RUN: lld-link /debug /pdb:%T/pdb-diff-lld.pdb /nodefaultlib /entry:main %S/Inputs/pdb-diff.obj
-RUN: llvm-pdbutil diff -result -values=false -left-bin-root=%S -right-bin-root=D:/src/llvm-mono/lld/test/COFF/ %T/pdb-diff-lld.pdb %S/Inputs/pdb-diff-cl.pdb | FileCheck %s
+RUN: rm -f %T/pdb-diff-lld.pdb %T/pdb-diff-lld.exe
+RUN: lld-link /debug /pdb:%T/pdb-diff-lld.pdb /out:%T/pdb-diff-lld.exe /nodefaultlib \
+RUN: /entry:main %S/Inputs/pdb-diff.obj
+RUN: llvm-pdbutil diff -result -values=false -left-bin-root=%S -right-bin-root=D:/src/llvm-mono/lld/test/COFF/ \
+RUN: %T/pdb-diff-lld.pdb %S/Inputs/pdb-diff-cl.pdb | FileCheck %s
CHECK: ----------------------
CHECK-NEXT: | MSF Super Block |
diff --git a/lld/test/COFF/pdb-none.test b/lld/test/COFF/pdb-none.test
index c1becbad7a3..4f5ba0ebb4d 100644
--- a/lld/test/COFF/pdb-none.test
+++ b/lld/test/COFF/pdb-none.test
@@ -1,12 +1,13 @@
# RUN: yaml2obj < %p/Inputs/pdb1.yaml > %t1.obj
# RUN: yaml2obj < %p/Inputs/pdb2.yaml > %t2.obj
+# RUN: rm -f %t.pdb %t.dll
# RUN: lld-link /debug /debugtype:pdata /pdb:%t.pdb /dll /out:%t.dll /entry:main /nodefaultlib \
# RUN: %t1.obj %t2.obj
# RUN: llvm-pdbutil pdb2yaml -pdb-stream %t.pdb | FileCheck %s
# CHECK: PdbStream:
-# CHECK-NEXT: Age: 0
+# CHECK-NEXT: Age: 1
# CHECK-NEXT: Guid:
# CHECK-NEXT: Signature:
# CHECK-NEXT: Features: [ VC140 ]
diff --git a/lld/test/COFF/pdb-source-lines.test b/lld/test/COFF/pdb-source-lines.test
index f9e0e5c7487..389d91f20ef 100644
--- a/lld/test/COFF/pdb-source-lines.test
+++ b/lld/test/COFF/pdb-source-lines.test
@@ -19,10 +19,11 @@ $ cl -c -Z7 pdb_lines*.c
RUN: yaml2obj %S/Inputs/pdb_lines_1.yaml -o %t.pdb_lines_1.obj
RUN: yaml2obj %S/Inputs/pdb_lines_2.yaml -o %t.pdb_lines_2.obj
+RUN: rm -f %t.exe %t.pdb
RUN: lld-link -debug -entry:main -nodefaultlib -out:%t.exe -pdb:%t.pdb %t.pdb_lines_1.obj %t.pdb_lines_2.obj
RUN: llvm-pdbutil pdb2yaml -modules -module-files -subsections=lines,fc %t.pdb | FileCheck %s
-CHECK-LABEL: DbiStream:
+CHECK-LABEL: DbiStream:
CHECK-NEXT: VerHeader: V70
CHECK-NEXT: Age: 1
CHECK-NEXT: BuildNumber: 0
@@ -30,22 +31,22 @@ CHECK-NEXT: PdbDllVersion: 0
CHECK-NEXT: PdbDllRbld: 0
CHECK-NEXT: Flags: 0
CHECK-NEXT: MachineType: x86
-CHECK-NEXT: Modules:
+CHECK-NEXT: Modules:
CHECK-LABEL: - Module: {{.*}}pdb_lines_1.obj
CHECK-NEXT: ObjFile: {{.*}}pdb_lines_1.obj
-CHECK-NEXT: SourceFiles:
+CHECK-NEXT: SourceFiles:
CHECK-NEXT: - '{{.*}}pdb_lines_1.c'
CHECK-NEXT: - '{{.*}}foo.h'
-CHECK-NEXT: Subsections:
+CHECK-NEXT: Subsections:
CHECK-NEXT: - !Lines
CHECK-NEXT: CodeSize: 19
CHECK-NEXT: Flags: [ ]
CHECK-NEXT: RelocOffset: 0
CHECK-NEXT: RelocSegment: 2
-CHECK-NEXT: Blocks:
+CHECK-NEXT: Blocks:
CHECK-NEXT: - FileName: '{{.*}}pdb_lines_1.c'
-CHECK-NEXT: Lines:
+CHECK-NEXT: Lines:
CHECK-NEXT: - Offset: 0
CHECK-NEXT: LineStart: 2
CHECK-NEXT: IsStatement: true
@@ -62,9 +63,9 @@ CHECK-NEXT: - Offset: 14
CHECK-NEXT: LineStart: 5
CHECK-NEXT: IsStatement: true
CHECK-NEXT: EndDelta: 0
-CHECK-NEXT: Columns:
+CHECK-NEXT: Columns:
CHECK-NEXT: - !FileChecksums
-CHECK-NEXT: Checksums:
+CHECK-NEXT: Checksums:
CHECK-NEXT: - FileName: '{{.*}}pdb_lines_1.c'
CHECK-NEXT: Kind: MD5
CHECK-NEXT: Checksum: 4EB19DCD86C3BA2238A255C718572E7B
@@ -76,9 +77,9 @@ CHECK-NEXT: CodeSize: 14
CHECK-NEXT: Flags: [ ]
CHECK-NEXT: RelocOffset: 32
CHECK-NEXT: RelocSegment: 2
-CHECK-NEXT: Blocks:
+CHECK-NEXT: Blocks:
CHECK-NEXT: - FileName: '{{.*}}foo.h'
-CHECK-NEXT: Lines:
+CHECK-NEXT: Lines:
CHECK-NEXT: - Offset: 0
CHECK-NEXT: LineStart: 2
CHECK-NEXT: IsStatement: true
@@ -91,21 +92,21 @@ CHECK-NEXT: - Offset: 9
CHECK-NEXT: LineStart: 4
CHECK-NEXT: IsStatement: true
CHECK-NEXT: EndDelta: 0
-CHECK-NEXT: Columns:
+CHECK-NEXT: Columns:
CHECK-LABEL: - Module: {{.*}}pdb_lines_2.obj
CHECK-NEXT: ObjFile: {{.*}}pdb_lines_2.obj
-CHECK-NEXT: SourceFiles:
+CHECK-NEXT: SourceFiles:
CHECK-NEXT: - '{{.*}}pdb_lines_2.c'
-CHECK-NEXT: Subsections:
+CHECK-NEXT: Subsections:
CHECK-NEXT: - !Lines
CHECK-NEXT: CodeSize: 1
CHECK-NEXT: Flags: [ ]
CHECK-NEXT: RelocOffset: 48
CHECK-NEXT: RelocSegment: 2
-CHECK-NEXT: Blocks:
+CHECK-NEXT: Blocks:
CHECK-NEXT: - FileName: '{{.*}}pdb_lines_2.c'
-CHECK-NEXT: Lines:
+CHECK-NEXT: Lines:
CHECK-NEXT: - Offset: 0
CHECK-NEXT: LineStart: 1
CHECK-NEXT: IsStatement: true
@@ -114,9 +115,9 @@ CHECK-NEXT: - Offset: 0
CHECK-NEXT: LineStart: 2
CHECK-NEXT: IsStatement: true
CHECK-NEXT: EndDelta: 0
-CHECK-NEXT: Columns:
+CHECK-NEXT: Columns:
CHECK-NEXT: - !FileChecksums
-CHECK-NEXT: Checksums:
+CHECK-NEXT: Checksums:
CHECK-NEXT: - FileName: '{{.*}}pdb_lines_2.c'
CHECK-NEXT: Kind: MD5
CHECK-NEXT: Checksum: DF91CB3A2B8D917486574BB50CAC4CC7
diff --git a/lld/test/COFF/pdb.test b/lld/test/COFF/pdb.test
index bf91a4b586e..e694c0cdc29 100644
--- a/lld/test/COFF/pdb.test
+++ b/lld/test/COFF/pdb.test
@@ -1,5 +1,6 @@
# RUN: yaml2obj < %p/Inputs/pdb1.yaml > %t1.obj
# RUN: yaml2obj < %p/Inputs/pdb2.yaml > %t2.obj
+# RUN: rm -f %t.dll %t.pdb
# RUN: lld-link /debug /pdb:%t.pdb /dll /out:%t.dll /entry:main /nodefaultlib \
# RUN: %t1.obj %t2.obj
diff --git a/lld/test/COFF/rsds.test b/lld/test/COFF/rsds.test
index 0b19846bb75..17659778684 100644
--- a/lld/test/COFF/rsds.test
+++ b/lld/test/COFF/rsds.test
@@ -1,11 +1,20 @@
# RUN: yaml2obj %s > %t.obj
+# RUN: rm -f %t.dll %t.pdb
# RUN: lld-link /debug /dll /out:%t.dll /entry:DllMain %t.obj
-# RUN: llvm-readobj -coff-debug-directory %t.dll | FileCheck %s
+# RUN: llvm-readobj -coff-debug-directory %t.dll > %t.1.txt
+# RUN: lld-link /debug /dll /out:%t.dll /entry:DllMain %t.obj
+# RUN: llvm-readobj -coff-debug-directory %t.dll > %t.2.txt
+# RUN: cat %t.1.txt %t.2.txt | FileCheck %s
+# RUN: rm -f %t.dll %t.pdb
+# RUN: lld-link /debug /pdb:%t.pdb /dll /out:%t.dll /entry:DllMain %t.obj
+# RUN: llvm-readobj -coff-debug-directory %t.dll > %t.3.txt
# 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
+# RUN: llvm-readobj -coff-debug-directory %t.dll > %t.4.txt
+# RUN: cat %t.3.txt %t.4.txt | FileCheck %s
+# CHECK: File: [[FILE:.*]].dll
# CHECK: DebugDirectory [
# CHECK: DebugEntry {
# CHECK: Characteristics: 0x0
@@ -18,12 +27,31 @@
# CHECK: PointerToRawData: 0x{{[^0]}}
# CHECK: PDBInfo {
# CHECK: PDBSignature: 0x53445352
-# CHECK: PDBGUID:
+# CHECK: PDBGUID: [[GUID:\(([A-Za-z0-9]{2} ?){16}\)]]
# CHECK: PDBAge: 1
# CHECK: PDBFileName: {{.*}}.pdb
# CHECK: }
# CHECK: }
# CHECK: ]
+# CHECK: File: [[FILE]].dll
+# 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: 0x{{[^0]}}
+# CHECK: AddressOfRawData: 0x{{[^0]}}
+# CHECK: PointerToRawData: 0x{{[^0]}}
+# CHECK: PDBInfo {
+# CHECK: PDBSignature: 0x53445352
+# CHECK: PDBGUID: [[GUID]]
+# CHECK: PDBAge: 2
+# CHECK: PDBFileName: {{.*}}.pdb
+# CHECK: }
+# CHECK: }
+# CHECK: ]
--- !COFF
header:
OpenPOWER on IntegriCloud