diff --git a/llvm/include/llvm/DebugInfo/CodeView/Line.h b/llvm/include/llvm/DebugInfo/CodeView/Line.h index e630b38eac01..0e7057fb5402 100644 --- a/llvm/include/llvm/DebugInfo/CodeView/Line.h +++ b/llvm/include/llvm/DebugInfo/CodeView/Line.h @@ -137,6 +137,20 @@ struct InlineeSourceLine { // ulittle32_t Files[]; }; +enum class FileChecksumKind : uint8_t { + None, + MD5, + SHA1, + SHA256 +}; + +struct FileChecksum { + ulittle32_t FileNameOffset; // Offset of filename in string table substream. + uint8_t ChecksumSize; + uint8_t ChecksumKind; // FileChecksumKind + // Checksum bytes follow. +}; + } // namespace codeview } // namespace llvm diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp index ba7ac9140b92..f0699cecfbd0 100644 --- a/llvm/tools/llvm-readobj/COFFDumper.cpp +++ b/llvm/tools/llvm-readobj/COFFDumper.cpp @@ -94,6 +94,8 @@ private: const SectionRef &Section, StringRef SectionContents); + void printCodeViewFileChecksums(StringRef Subsection); + void printCodeViewInlineeLines(StringRef Subsection); void printMemberAttributes(MemberAttributes Attrs); @@ -767,6 +769,13 @@ static const EnumEntry FunctionOptionEnum[] = { LLVM_READOBJ_ENUM_CLASS_ENT(FunctionOptions, ConstructorWithVirtualBases), }; +static const EnumEntry FileChecksumKindNames[] = { + LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, None), + LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, MD5), + LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, SHA1), + LLVM_READOBJ_ENUM_CLASS_ENT(FileChecksumKind, SHA256), +}; + template static std::error_code getSymbolAuxData(const COFFObjectFile *Obj, COFFSymbolRef Symbol, @@ -1030,6 +1039,10 @@ void COFFDumper::printCodeViewSymbolSection(StringRef SectionName, printCodeViewInlineeLines(Contents); break; + case ModuleSubstreamKind::FileChecksums: + printCodeViewFileChecksums(Contents); + break; + case ModuleSubstreamKind::Lines: { // Holds a PC to file:line table. Some data to parse this subsection is // stored in the other subsections, so just check sanity and store the @@ -1701,6 +1714,31 @@ void COFFDumper::printCodeViewSymbolsSubsection(StringRef Subsection, } } +void COFFDumper::printCodeViewFileChecksums(StringRef Subsection) { + StringRef Data = Subsection; + while (!Data.empty()) { + DictScope S(W, "FileChecksum"); + const FileChecksum *FC; + error(consumeObject(Data, FC)); + if (FC->FileNameOffset >= CVStringTable.size()) + error(object_error::parse_failed); + StringRef Filename = + CVStringTable.drop_front(FC->FileNameOffset).split('\0').first; + W.printHex("Filename", Filename, FC->FileNameOffset); + W.printHex("ChecksumSize", FC->ChecksumSize); + W.printEnum("ChecksumKind", uint8_t(FC->ChecksumKind), + makeArrayRef(FileChecksumKindNames)); + if (FC->ChecksumSize >= Data.size()) + error(object_error::parse_failed); + StringRef ChecksumBytes = Data.substr(0, FC->ChecksumSize); + W.printBinary("ChecksumBytes", ChecksumBytes); + unsigned PaddedSize = + RoundUpToAlignment(FC->ChecksumSize + sizeof(FileChecksum), 4) - + sizeof(FileChecksum); + Data = Data.drop_front(PaddedSize); + } +} + void COFFDumper::printCodeViewInlineeLines(StringRef Subsection) { StringRef Data = Subsection; uint32_t Signature;