diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -102,6 +102,12 @@ IAD_Intel, }; + enum DebugSrcHashKind { + DSH_MD5, + DSH_SHA1, + DSH_SHA256, + }; + // This field stores one of the allowed values for the option // -fbasic-block-sections=. The allowed values with this option are: // {"labels", "all", "list=", "none"}. diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -341,6 +341,9 @@ ///< contain explicit imports for ///< anonymous namespaces +/// Set debug info source file hashing algorithm. +ENUM_CODEGENOPT(DebugSrcHash, DebugSrcHashKind, 2, DSH_MD5) + CODEGENOPT(SplitDwarfInlining, 1, 1) ///< Whether to include inlining info in the ///< skeleton CU to allow for symbolication ///< of inline stack frames without .dwo files. diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3217,6 +3217,12 @@ HelpText<"Use simple template names in DWARF, or include the full " "template name with a modified prefix for validation">, Values<"simple,mangled">, Flags<[CC1Option, NoDriverOption]>; +def gsrc_hash_EQ : Joined<["-"], "gsrc-hash=">, + Group, Flags<[CC1Option, NoDriverOption]>, + Values<"md5,sha1,sha256">, + NormalizedValues<["DSH_MD5", "DSH_SHA1", "DSH_SHA256"]>, + NormalizedValuesScope<"CodeGenOptions">, + MarshallingInfoEnum, "DSH_MD5">; def gno_simple_template_names : Flag<["-"], "gno-simple-template-names">, Group; def ggnu_pubnames : Flag<["-"], "ggnu-pubnames">, Group, Flags<[CC1Option]>; @@ -6657,6 +6663,15 @@ HelpText<"Disable C++ builtin type wchar_t">; def _SLASH_Z7 : CLFlag<"Z7">, HelpText<"Enable CodeView debug information in object files">; +def _SLASH_ZH_MD5 : CLFlag<"ZH:MD5">, + HelpText<"Use MD5 for file checksums in debug info (default)">, + Alias, AliasArgs<["md5"]>; +def _SLASH_ZH_SHA1 : CLFlag<"ZH:SHA1">, + HelpText<"Use SHA1 for file checksums in debug info">, + Alias, AliasArgs<["sha1"]>; +def _SLASH_ZH_SHA_256 : CLFlag<"ZH:SHA_256">, + HelpText<"Use SHA256 for file checksums in debug info">, + Alias, AliasArgs<["sha256"]>; def _SLASH_Zi : CLFlag<"Zi">, Alias<_SLASH_Z7>, HelpText<"Like /Z7">; def _SLASH_Zp : CLJoined<"Zp">, @@ -6842,9 +6857,6 @@ def _SLASH_Zc_inline : CLIgnoredFlag<"Zc:inline">; def _SLASH_Zc_rvalueCast : CLIgnoredFlag<"Zc:rvalueCast">; def _SLASH_Zc_ternary : CLIgnoredFlag<"Zc:ternary">; -def _SLASH_ZH_MD5 : CLIgnoredFlag<"ZH:MD5">; -def _SLASH_ZH_SHA1 : CLIgnoredFlag<"ZH:SHA1">; -def _SLASH_ZH_SHA_256 : CLIgnoredFlag<"ZH:SHA_256">; def _SLASH_Zm : CLIgnoredJoined<"Zm">; def _SLASH_Zo : CLIgnoredFlag<"Zo">; def _SLASH_Zo_ : CLIgnoredFlag<"Zo-">; diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h --- a/clang/lib/CodeGen/CGDebugInfo.h +++ b/clang/lib/CodeGen/CGDebugInfo.h @@ -631,7 +631,7 @@ /// Compute the file checksum debug info for input file ID. Optional - computeChecksum(FileID FID, SmallString<32> &Checksum) const; + computeChecksum(FileID FID, SmallString<64> &Checksum) const; /// Get the source of the given file ID. Optional getSource(const SourceManager &SM, FileID FID); diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -48,6 +48,8 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/MD5.h" #include "llvm/Support/Path.h" +#include "llvm/Support/SHA1.h" +#include "llvm/Support/SHA256.h" #include "llvm/Support/TimeProfiler.h" using namespace clang; using namespace clang::CodeGen; @@ -344,7 +346,7 @@ } Optional -CGDebugInfo::computeChecksum(FileID FID, SmallString<32> &Checksum) const { +CGDebugInfo::computeChecksum(FileID FID, SmallString<64> &Checksum) const { Checksum.clear(); if (!CGM.getCodeGenOpts().EmitCodeView && @@ -356,10 +358,18 @@ if (!MemBuffer) return None; - llvm::toHex( - llvm::MD5::hash(llvm::arrayRefFromStringRef(MemBuffer->getBuffer())), - /*LowerCase*/ true, Checksum); - return llvm::DIFile::CSK_MD5; + auto Data = llvm::arrayRefFromStringRef(MemBuffer->getBuffer()); + switch (CGM.getCodeGenOpts().getDebugSrcHash()) { + case clang::CodeGenOptions::DSH_MD5: + llvm::toHex(llvm::MD5::hash(Data), /*LowerCase=*/true, Checksum); + return llvm::DIFile::CSK_MD5; + case clang::CodeGenOptions::DSH_SHA1: + llvm::toHex(llvm::SHA1::hash(Data), /*LowerCase=*/true, Checksum); + return llvm::DIFile::CSK_SHA1; + case clang::CodeGenOptions::DSH_SHA256: + llvm::toHex(llvm::SHA256::hash(Data), /*LowerCase=*/true, Checksum); + return llvm::DIFile::CSK_SHA256; + } } Optional CGDebugInfo::getSource(const SourceManager &SM, @@ -406,7 +416,7 @@ return cast(V); } - SmallString<32> Checksum; + SmallString<64> Checksum; Optional CSKind = computeChecksum(FID, Checksum); Optional> CSInfo; @@ -500,7 +510,7 @@ } void CGDebugInfo::CreateCompileUnit() { - SmallString<32> Checksum; + SmallString<64> Checksum; Optional CSKind; Optional> CSInfo; diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -4389,6 +4389,11 @@ } } + if (const Arg *A = Args.getLastArg(options::OPT_gsrc_hash_EQ)) { + StringRef v = A->getValue(); + CmdArgs.push_back(Args.MakeArgString("-gsrc-hash=" + v)); + } + if (Args.hasFlag(options::OPT_fdebug_ranges_base_address, options::OPT_fno_debug_ranges_base_address, false)) { CmdArgs.push_back("-fdebug-ranges-base-address"); diff --git a/clang/test/CodeGen/debug-info-file-checksum.c b/clang/test/CodeGen/debug-info-file-checksum.c --- a/clang/test/CodeGen/debug-info-file-checksum.c +++ b/clang/test/CodeGen/debug-info-file-checksum.c @@ -1,9 +1,21 @@ +// RUN: %clang -emit-llvm -S -g -gcodeview -x c \ +// RUN: %S/Inputs/debug-info-file-checksum.c -o - | FileCheck %s +// RUN: %clang -emit-llvm -S -g -gcodeview -Xclang -gsrc-hash=md5 \ +// RUN: -x c %S/Inputs/debug-info-file-checksum.c -o - | FileCheck %s +// RUN: %clang -emit-llvm -S -g -gcodeview -Xclang -gsrc-hash=sha1 \ +// RUN: -x c %S/Inputs/debug-info-file-checksum.c -o - \ +// RUN: | FileCheck --check-prefix=SHA1 %s +// RUN: %clang -emit-llvm -S -g -gcodeview -Xclang -gsrc-hash=sha256 \ +// RUN: -x c %S/Inputs/debug-info-file-checksum.c -o - \ +// RUN: | FileCheck --check-prefix=SHA256 %s // RUN: %clang -emit-llvm -S -g -gcodeview -x c %S/Inputs/debug-info-file-checksum.c -o - | FileCheck %s // RUN: %clang -emit-llvm -S -gdwarf-5 -x c %S/Inputs/debug-info-file-checksum.c -o - | FileCheck %s // Check that "checksum" is created correctly for the compiled file. // CHECK: !DIFile(filename:{{.*}}, directory:{{.*}}, checksumkind: CSK_MD5, checksum: "a3b7d27af071accdeccaa933fc603608") +// SHA1: !DIFile(filename:{{.*}}, directory:{{.*}}, checksumkind: CSK_SHA1, checksum: "6f6eeaba705ad6db6fbb05c2cbcf3cbb3e374bcd") +// SHA256: !DIFile(filename:{{.*}}, directory:{{.*}}, checksumkind: CSK_SHA256, checksum: "2d49b53859e57898a0f8c16ff1fa4d99306b8ec28d65cf7577109761f0d56197") // Ensure #line directives (in already pre-processed files) do not emit checksums // RUN: %clang -emit-llvm -S -g -gcodeview -x c %S/Inputs/debug-info-file-checksum-pre.cpp -o - | FileCheck %s --check-prefix NOCHECKSUM diff --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c --- a/clang/test/Driver/cl-options.c +++ b/clang/test/Driver/cl-options.c @@ -395,9 +395,6 @@ // RUN: /wd1234 \ // RUN: /Wv \ // RUN: /Wv:17 \ -// RUN: /ZH:MD5 \ -// RUN: /ZH:SHA1 \ -// RUN: /ZH:SHA_256 \ // RUN: /Zm \ // RUN: /Zo \ // RUN: /Zo- \ @@ -578,6 +575,17 @@ // Z7_gdwarf: "-debug-info-kind=constructor" // Z7_gdwarf: "-dwarf-version= +// RUN: %clang_cl /ZH:MD5 /c -### -- %s 2>&1 | FileCheck -check-prefix=ZH_MD5 %s +// ZH_MD5: "-gsrc-hash=md5" + +// RUN: %clang_cl /ZH:SHA1 /c -### -- %s 2>&1 \ +// RUN: | FileCheck -check-prefix=ZH_SHA1 %s +// ZH_SHA1: "-gsrc-hash=sha1" + +// RUN: %clang_cl /ZH:SHA_256 /c -### -- %s 2>&1 \ +// RUN: | FileCheck -check-prefix=ZH_SHA256 %s +// ZH_SHA256: "-gsrc-hash=sha256" + // RUN: %clang_cl -fmsc-version=1800 -TP -### -- %s 2>&1 | FileCheck -check-prefix=CXX11 %s // CXX11: -std=c++11