arlosi created this revision. Herald added subscribers: jansvoboda11, dexonsmith, dang. arlosi requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Adds clang-cl support for the /ZH: option used to select MD5, SHA1, or SHA_256 hashing algorithms in debug info. Previously only the MD5 algorithm was supported. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D98438 Files: clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Basic/CodeGenOptions.h clang/include/clang/Driver/Options.td clang/lib/CodeGen/CGDebugInfo.cpp clang/lib/CodeGen/CGDebugInfo.h clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp
Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -1928,6 +1928,20 @@ else if (Args.hasArg(options::OPT_fno_finite_loops)) Opts.FiniteLoops = CodeGenOptions::FiniteLoopsKind::Never; + if (Arg *A = Args.getLastArg(OPT_gsrc_hash_algorithm_EQ)) { + unsigned Val = llvm::StringSwitch<unsigned>(A->getValue()) + .Case("md5", CodeGenOptions::CSK_MD5) + .Case("sha1", CodeGenOptions::CSK_SHA1) + .Case("sha256", CodeGenOptions::CSK_SHA256) + .Default(~0U); + if (Val == ~0U) + Diags.Report(diag::err_drv_invalid_value) + << A->getAsString(Args) << A->getValue(); + else + Opts.setDebugSrcHashAlgorithm( + static_cast<CodeGenOptions::SrcHashAlgorithm>(Val)); + } + return Success && Diags.getNumErrors() == NumErrorsBefore; } Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -7107,6 +7107,19 @@ D.Diag(diag::err_drv_invalid_value) << A->getSpelling() << GuardArgs; } } + + if (Arg *A = Args.getLastArg(options::OPT__SLASH_ZH)) { + StringRef Val = A->getValue(); + if (Val.equals("MD5")) { + CmdArgs.push_back("-gsrc-hash-algorithm=md5"); + } else if (Val.equals("SHA1")) { + CmdArgs.push_back("-gsrc-hash-algorithm=sha1"); + } else if (Val.equals("SHA_256")) { + CmdArgs.push_back("-gsrc-hash-algorithm=sha256"); + } else { + D.Diag(diag::err_drv_invalid_value) << A->getAsString(Args) << Val; + } + } } const char *Clang::getBaseInputName(const ArgList &Args, Index: clang/lib/CodeGen/CGDebugInfo.h =================================================================== --- clang/lib/CodeGen/CGDebugInfo.h +++ clang/lib/CodeGen/CGDebugInfo.h @@ -572,8 +572,9 @@ void CreateCompileUnit(); /// Compute the file checksum debug info for input file ID. - Optional<llvm::DIFile::ChecksumKind> - computeChecksum(FileID FID, SmallString<32> &Checksum) const; + /// Storage of the checksum string is owned by the caller. + Optional<llvm::DIFile::ChecksumInfo<StringRef>> + computeChecksum(FileID FID, SmallString<64> &Checksum) const; /// Get the source of the given file ID. Optional<StringRef> getSource(const SourceManager &SM, FileID FID); Index: clang/lib/CodeGen/CGDebugInfo.cpp =================================================================== --- clang/lib/CodeGen/CGDebugInfo.cpp +++ clang/lib/CodeGen/CGDebugInfo.cpp @@ -44,9 +44,13 @@ #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Format.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" +#include "llvm/Support/raw_ostream.h" using namespace clang; using namespace clang::CodeGen; @@ -361,10 +365,12 @@ return StringRef(); } -Optional<llvm::DIFile::ChecksumKind> -CGDebugInfo::computeChecksum(FileID FID, SmallString<32> &Checksum) const { +Optional<llvm::DIFile::ChecksumInfo<StringRef>> +CGDebugInfo::computeChecksum(FileID FID, SmallString<64> &Checksum) const { Checksum.clear(); + llvm::DIFile::ChecksumKind CSKind; + Optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo; if (!CGM.getCodeGenOpts().EmitCodeView && CGM.getCodeGenOpts().DwarfVersion < 5) return None; @@ -374,14 +380,42 @@ if (!MemBuffer) return None; - llvm::MD5 Hash; - llvm::MD5::MD5Result Result; - - Hash.update(MemBuffer->getBuffer()); - Hash.final(Result); + switch (CGM.getCodeGenOpts().getDebugSrcHashAlgorithm()) { + case clang::CodeGenOptions::CSK_MD5: { + CSKind = llvm::DIFile::CSK_MD5; + llvm::MD5 Hash; + llvm::MD5::MD5Result Result; + Hash.update(MemBuffer->getBuffer()); + Hash.final(Result); + Checksum = Result.digest(); + break; + } + case clang::CodeGenOptions::CSK_SHA1: { + CSKind = llvm::DIFile::CSK_SHA1; + llvm::SHA1 Hash; + Hash.update(MemBuffer->getBuffer()); + StringRef Result = Hash.final(); + llvm::raw_svector_ostream Res(Checksum); + for (int i = 0; i < 20; ++i) + Res << llvm::format("%.2x", static_cast<uint8_t>(Result[i])); + break; + } + case clang::CodeGenOptions::CSK_SHA256: { + CSKind = llvm::DIFile::CSK_SHA256; + llvm::SHA256 Hash; + Hash.update(MemBuffer->getBuffer()); + StringRef Result = Hash.final(); + llvm::raw_svector_ostream Res(Checksum); + for (int i = 0; i < 32; ++i) + Res << llvm::format("%.2x", static_cast<uint8_t>(Result[i])); + break; + } + default: + return None; + } - Hash.stringifyResult(Result, Checksum); - return llvm::DIFile::CSK_MD5; + CSInfo.emplace(CSKind, Checksum); + return CSInfo; } Optional<StringRef> CGDebugInfo::getSource(const SourceManager &SM, @@ -428,12 +462,10 @@ return cast<llvm::DIFile>(V); } - SmallString<32> Checksum; + SmallString<64> Checksum; + Optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo = + computeChecksum(FID, Checksum); - Optional<llvm::DIFile::ChecksumKind> CSKind = computeChecksum(FID, Checksum); - Optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo; - if (CSKind) - CSInfo.emplace(*CSKind, Checksum); return createFile(FileName, CSInfo, getSource(SM, SM.getFileID(Loc))); } @@ -519,8 +551,7 @@ } void CGDebugInfo::CreateCompileUnit() { - SmallString<32> Checksum; - Optional<llvm::DIFile::ChecksumKind> CSKind; + SmallString<64> Checksum; Optional<llvm::DIFile::ChecksumInfo<StringRef>> CSInfo; // Should we be asking the SourceManager for the main file name, instead of @@ -558,8 +589,7 @@ MainFile->getName().rsplit('.').second) .isPreprocessed()) MainFileName = CGM.getModule().getName().str(); - - CSKind = computeChecksum(SM.getMainFileID(), Checksum); + CSInfo = computeChecksum(SM.getMainFileID(), Checksum); } llvm::dwarf::SourceLanguage LangTag; @@ -616,8 +646,6 @@ // file. Its directory part specifies what becomes the // DW_AT_comp_dir (the compilation directory), even if the source // file was specified with an absolute path. - if (CSKind) - CSInfo.emplace(*CSKind, Checksum); llvm::DIFile *CUFile = DBuilder.createFile( remapDIPath(MainFileName), remapDIPath(getCurrentDirname()), CSInfo, getSource(SM, SM.getMainFileID())); Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -2772,6 +2772,9 @@ HelpText<"Set DWARF fission mode to either 'split' or 'single'">, Values<"split,single">; def gno_split_dwarf : Flag<["-"], "gno-split-dwarf">, Group<g_flags_Group>; +def gsrc_hash_algorithm_EQ : Joined<["-"], "gsrc-hash-algorithm=">, Group<g_flags_Group>, Flags<[CC1Option]>, + HelpText<"Hashing algorithm for file checksum in debug info 'md5', 'sha1', or 'sha256'">, + Values<"md5,sha1,sha256">; def ggnu_pubnames : Flag<["-"], "ggnu-pubnames">, Group<g_flags_Group>, Flags<[CC1Option]>; def gno_gnu_pubnames : Flag<["-"], "gno-gnu-pubnames">, Group<g_flags_Group>; def gpubnames : Flag<["-"], "gpubnames">, Group<g_flags_Group>, Flags<[CC1Option]>; @@ -5835,6 +5838,9 @@ Alias<fdelayed_template_parsing>; def _SLASH_Z7 : CLFlag<"Z7">, HelpText<"Enable CodeView debug information in object files">; +def _SLASH_ZH : CLCompileJoined<"ZH:">, + HelpText<"Hash algorithm for file checksum in debug info (MD5, SHA1, or SHA_256)">, + Values<"MD5,SHA1,SHA_256">; def _SLASH_Zi : CLFlag<"Zi">, Alias<_SLASH_Z7>, HelpText<"Like /Z7">; def _SLASH_Zp : CLJoined<"Zp">, @@ -6006,9 +6012,6 @@ def _SLASH_Zc_rvalueCast : CLIgnoredFlag<"Zc:rvalueCast">; def _SLASH_Zc_ternary : CLIgnoredFlag<"Zc:ternary">; def _SLASH_Zc_wchar_t : CLIgnoredFlag<"Zc:wchar_t">; -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-">; Index: clang/include/clang/Basic/CodeGenOptions.h =================================================================== --- clang/include/clang/Basic/CodeGenOptions.h +++ clang/include/clang/Basic/CodeGenOptions.h @@ -113,6 +113,12 @@ Embed_Marker // Embed a marker as a placeholder for bitcode. }; + enum SrcHashAlgorithm { + CSK_MD5, + CSK_SHA1, + CSK_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=<file>", "none"}. Index: clang/include/clang/Basic/CodeGenOptions.def =================================================================== --- clang/include/clang/Basic/CodeGenOptions.def +++ clang/include/clang/Basic/CodeGenOptions.def @@ -299,6 +299,9 @@ ///< contain explicit imports for ///< anonymous namespaces +/// Set debug info source file hashing algorithm +ENUM_CODEGENOPT(DebugSrcHashAlgorithm, SrcHashAlgorithm, 4, CSK_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.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits