[COFF] Generate a codeview build id signature for MinGW even when not creating a PDB

GNU ld, which doesn't generate PDBs, can optionally generate a
build id by passing the --build-id option. LLD's MinGW frontend knows
about this option but ignores it, as I had falsely assumed that LLD
already generated build IDs even in those cases.

If debug info is requested and no PDB path is set, generate a
build id signature as a hash of the binary itself. This allows
associating a binary to a minidump, even if debug info isn't
written in PDB form by the linker.

Differential Revision: https://reviews.llvm.org/D54828

llvm-svn: 347645
This commit is contained in:
Martin Storsjo 2018-11-27 09:20:55 +00:00
parent b0a9b75e2a
commit 3c046af5a9
2 changed files with 42 additions and 1 deletions

View File

@ -1557,8 +1557,25 @@ void Writer::writeBuildId() {
Buffer->getBufferSize());
uint32_t Timestamp = Config->Timestamp;
uint64_t Hash = 0;
bool GenerateSyntheticBuildId =
Config->MinGW && Config->Debug && Config->PDBPath.empty();
if (Config->Repro || GenerateSyntheticBuildId)
Hash = xxHash64(OutputFileData);
if (Config->Repro)
Timestamp = static_cast<uint32_t>(xxHash64(OutputFileData));
Timestamp = static_cast<uint32_t>(Hash);
if (GenerateSyntheticBuildId) {
// For MinGW builds without a PDB file, we still generate a build id
// to allow associating a crash dump to the executable.
BuildId->BuildId->PDB70.CVSignature = OMF::Signature::PDB70;
BuildId->BuildId->PDB70.Age = 1;
memcpy(BuildId->BuildId->PDB70.Signature, &Hash, 8);
// xxhash only gives us 8 bytes, so put some fixed data in the other half.
memcpy(&BuildId->BuildId->PDB70.Signature[8], "LLD PDB.", 8);
}
if (DebugDirectory)
DebugDirectory->setTimeDateStamp(Timestamp);

View File

@ -22,6 +22,10 @@
# 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
# RUN: rm -f %t.dll %t.pdb
# RUN: lld-link /lldmingw /debug:dwarf /dll /out:%t.dll /entry:DllMain %t.obj
# RUN: llvm-readobj -coff-debug-directory %t.dll | FileCheck --check-prefix MINGW %s
# CHECK: File: [[FILE:.*]].dll
# CHECK: DebugDirectory [
# CHECK: DebugEntry {
@ -143,6 +147,26 @@
# REPRODEBUG: PointerToRawData: 0x0
# REPRODEBUG: }
# REPRODEBUG: ]
# MINGW: File: {{.*}}.dll
# MINGW: DebugDirectory [
# MINGW: DebugEntry {
# MINGW: Characteristics: 0x0
# MINGW: TimeDateStamp:
# MINGW: MajorVersion: 0x0
# MINGW: MinorVersion: 0x0
# MINGW: Type: CodeView (0x2)
# MINGW: SizeOfData: 0x{{[^0]}}
# MINGW: AddressOfRawData: 0x{{[^0]}}
# MINGW: PointerToRawData: 0x{{[^0]}}
# MINGW: PDBInfo {
# MINGW: PDBSignature: 0x53445352
# MINGW: PDBGUID: [[GUID:\(([A-Za-z0-9]{2} ?){16}\)]]
# MINGW: PDBAge: 1
# MINGW: PDBFileName:
# MINGW: }
# MINGW: }
# MINGW: ]
--- !COFF
header:
Machine: IMAGE_FILE_MACHINE_I386