[lld] r341486 - lld-link: Write an empty "repro" debug directory entry if /Brepro is passed
Nico Weber via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 5 11:02:43 PDT 2018
Author: nico
Date: Wed Sep 5 11:02:43 2018
New Revision: 341486
URL: http://llvm.org/viewvc/llvm-project?rev=341486&view=rev
Log:
lld-link: Write an empty "repro" debug directory entry if /Brepro is passed
If the coff timestamp is set to a hash, like lld-link does if /Brepro is
passed, the coff spec suggests that a IMAGE_DEBUG_TYPE_REPRO entry is in the
debug directory. This lets lld-link write such a section.
Fixes PR38429, see bug for details.
Differential Revision: https://reviews.llvm.org/D51652
Modified:
lld/trunk/COFF/Writer.cpp
lld/trunk/test/COFF/rsds.test
Modified: lld/trunk/COFF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=341486&r1=341485&r2=341486&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.cpp (original)
+++ lld/trunk/COFF/Writer.cpp Wed Sep 5 11:02:43 2018
@@ -83,30 +83,32 @@ namespace {
class DebugDirectoryChunk : public Chunk {
public:
- DebugDirectoryChunk(const std::vector<Chunk *> &R) : Records(R) {}
+ DebugDirectoryChunk(const std::vector<Chunk *> &R, bool WriteRepro)
+ : Records(R), WriteRepro(WriteRepro) {}
size_t getSize() const override {
- return Records.size() * sizeof(debug_directory);
+ return (Records.size() + int(WriteRepro)) * sizeof(debug_directory);
}
void writeTo(uint8_t *B) const override {
auto *D = reinterpret_cast<debug_directory *>(B + OutputSectionOff);
for (const 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();
OutputSection *OS = Record->getOutputSection();
uint64_t Offs = OS->getFileOff() + (Record->getRVA() - OS->getRVA());
- D->PointerToRawData = Offs;
-
- TimeDateStamps.push_back(&D->TimeDateStamp);
+ fillEntry(D, COFF::IMAGE_DEBUG_TYPE_CODEVIEW, Record->getSize(),
+ Record->getRVA(), Offs);
++D;
}
+
+ if (WriteRepro) {
+ // FIXME: The COFF spec allows either a 0-sized entry to just say
+ // "the timestamp field is really a hash", or a 4-byte size field
+ // followed by that many bytes containing a longer hash (with the
+ // lowest 4 bytes usually being the timestamp in little-endian order).
+ // Consider storing the full 8 bytes computed by xxHash64 here.
+ fillEntry(D, COFF::IMAGE_DEBUG_TYPE_REPRO, 0, 0, 0);
+ }
}
void setTimeDateStamp(uint32_t TimeDateStamp) {
@@ -115,8 +117,23 @@ public:
}
private:
+ void fillEntry(debug_directory *D, COFF::DebugType DebugType, size_t Size,
+ uint64_t RVA, uint64_t Offs) const {
+ D->Characteristics = 0;
+ D->TimeDateStamp = 0;
+ D->MajorVersion = 0;
+ D->MinorVersion = 0;
+ D->Type = DebugType;
+ D->SizeOfData = Size;
+ D->AddressOfRawData = RVA;
+ D->PointerToRawData = Offs;
+
+ TimeDateStamps.push_back(&D->TimeDateStamp);
+ }
+
mutable std::vector<support::ulittle32_t *> TimeDateStamps;
const std::vector<Chunk *> &Records;
+ bool WriteRepro;
};
class CVDebugRecordChunk : public Chunk {
@@ -500,11 +517,13 @@ void Writer::createMiscChunks() {
}
// Create Debug Information Chunks
- if (Config->Debug) {
- DebugDirectory = make<DebugDirectoryChunk>(DebugRecords);
-
- OutputSection *DebugInfoSec = Config->MinGW ? BuildidSec : RdataSec;
+ OutputSection *DebugInfoSec = Config->MinGW ? BuildidSec : RdataSec;
+ if (Config->Debug || Config->Repro) {
+ DebugDirectory = make<DebugDirectoryChunk>(DebugRecords, Config->Repro);
+ DebugInfoSec->addChunk(DebugDirectory);
+ }
+ if (Config->Debug) {
// 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
@@ -513,7 +532,6 @@ void Writer::createMiscChunks() {
BuildId = CVChunk;
DebugRecords.push_back(CVChunk);
- DebugInfoSec->addChunk(DebugDirectory);
for (Chunk *C : DebugRecords)
DebugInfoSec->addChunk(C);
}
@@ -911,7 +929,7 @@ template <typename PEHeaderTy> void Writ
: sizeof(object::coff_tls_directory32);
}
}
- if (Config->Debug) {
+ if (DebugDirectory) {
Dir[DEBUG_DIRECTORY].RelativeVirtualAddress = DebugDirectory->getRVA();
Dir[DEBUG_DIRECTORY].Size = DebugDirectory->getSize();
}
Modified: lld/trunk/test/COFF/rsds.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/rsds.test?rev=341486&r1=341485&r2=341486&view=diff
==============================================================================
--- lld/trunk/test/COFF/rsds.test (original)
+++ lld/trunk/test/COFF/rsds.test Wed Sep 5 11:02:43 2018
@@ -14,6 +14,14 @@
# RUN: llvm-readobj -coff-debug-directory %t.dll > %t.4.txt
# RUN: cat %t.3.txt %t.4.txt | FileCheck %s
+# RUN: rm -f %t.dll %t.pdb
+# RUN: lld-link /Brepro /dll /out:%t.dll /entry:DllMain %t.obj
+# RUN: llvm-readobj -coff-debug-directory %t.dll | FileCheck --check-prefix REPRO %s
+
+# RUN: rm -f %t.dll %t.pdb
+# RUN: lld-link /Brepro /debug /dll /out:%t.dll /entry:DllMain %t.obj
+# RUN: llvm-readobj -coff-debug-directory %t.dll | FileCheck --check-prefix REPRODEBUG %s
+
# CHECK: File: [[FILE:.*]].dll
# CHECK: DebugDirectory [
# CHECK: DebugEntry {
@@ -53,6 +61,49 @@
# CHECK: }
# CHECK: ]
+# REPRO: File: {{.*}}.dll
+# REPRO: DebugDirectory [
+# REPRO: DebugEntry {
+# REPRO: Characteristics: 0x0
+# REPRO: TimeDateStamp:
+# REPRO: MajorVersion: 0x0
+# REPRO: MinorVersion: 0x0
+# REPRO: Type: Repro (0x10)
+# REPRO: SizeOfData: 0x0
+# REPRO: AddressOfRawData: 0x0
+# REPRO: PointerToRawData: 0x0
+# REPRO: }
+# REPRO: ]
+
+# REPRODEBUG: File: {{.*}}.dll
+# REPRODEBUG: DebugDirectory [
+# REPRODEBUG: DebugEntry {
+# REPRODEBUG: Characteristics: 0x0
+# REPRODEBUG: TimeDateStamp:
+# REPRODEBUG: MajorVersion: 0x0
+# REPRODEBUG: MinorVersion: 0x0
+# REPRODEBUG: Type: CodeView (0x2)
+# REPRODEBUG: SizeOfData: 0x{{[^0]}}
+# REPRODEBUG: AddressOfRawData: 0x{{[^0]}}
+# REPRODEBUG: PointerToRawData: 0x{{[^0]}}
+# REPRODEBUG: PDBInfo {
+# REPRODEBUG: PDBSignature: 0x53445352
+# REPRODEBUG: PDBGUID:
+# REPRODEBUG: PDBAge: 1
+# REPRODEBUG: PDBFileName:
+# REPRODEBUG: }
+# REPRODEBUG: }
+# REPRODEBUG: DebugEntry {
+# REPRODEBUG: Characteristics: 0x0
+# REPRODEBUG: TimeDateStamp:
+# REPRODEBUG: MajorVersion: 0x0
+# REPRODEBUG: MinorVersion: 0x0
+# REPRODEBUG: Type: Repro (0x10)
+# REPRODEBUG: SizeOfData: 0x0
+# REPRODEBUG: AddressOfRawData: 0x0
+# REPRODEBUG: PointerToRawData: 0x0
+# REPRODEBUG: }
+# REPRODEBUG: ]
--- !COFF
header:
Machine: IMAGE_FILE_MACHINE_I386
More information about the llvm-commits
mailing list