Index: llvm/include/llvm/ObjectYAML/COFFYAML.h =================================================================== --- llvm/include/llvm/ObjectYAML/COFFYAML.h +++ llvm/include/llvm/ObjectYAML/COFFYAML.h @@ -18,6 +18,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/COFF.h" #include "llvm/ObjectYAML/CodeViewYAMLDebugSections.h" +#include "llvm/ObjectYAML/CodeViewYAMLTypeHashing.h" #include "llvm/ObjectYAML/CodeViewYAMLTypes.h" #include "llvm/ObjectYAML/YAML.h" #include @@ -66,6 +67,7 @@ yaml::BinaryRef SectionData; std::vector DebugS; std::vector DebugT; + Optional DebugH; std::vector Relocations; StringRef Name; Index: llvm/include/llvm/ObjectYAML/CodeViewYAMLTypeHashing.h =================================================================== --- /dev/null +++ llvm/include/llvm/ObjectYAML/CodeViewYAMLTypeHashing.h @@ -0,0 +1,61 @@ +//==- CodeViewYAMLTypeHashing.h - CodeView YAMLIO Type hashing ----*- C++-*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines classes for handling the YAML representation of CodeView +// Debug Info. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OBJECTYAML_CODEVIEWYAMLTYPEHASHING_H +#define LLVM_OBJECTYAML_CODEVIEWYAMLTYPEHASHING_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/DebugInfo/CodeView/TypeHashing.h" +#include "llvm/ObjectYAML/YAML.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/YAMLTraits.h" +#include +#include +#include + +namespace llvm { + +namespace CodeViewYAML { + +struct GlobalHash { + GlobalHash() = default; + explicit GlobalHash(StringRef S) : Hash(S) { + assert(S.size() == 20 && "Invalid hash size!"); + } + explicit GlobalHash(ArrayRef S) : Hash(S) { + assert(S.size() == 20 && "Invalid hash size!"); + } + yaml::BinaryRef Hash; +}; + +struct DebugHSection { + uint16_t Version; + uint16_t HashAlgorithm; + std::vector Hashes; +}; + +DebugHSection fromDebugH(ArrayRef DebugT); +ArrayRef toDebugH(const DebugHSection &DebugH, + BumpPtrAllocator &Alloc); + +} // end namespace CodeViewYAML + +} // end namespace llvm + +LLVM_YAML_DECLARE_MAPPING_TRAITS(CodeViewYAML::DebugHSection) +LLVM_YAML_DECLARE_SCALAR_TRAITS(CodeViewYAML::GlobalHash, false) +LLVM_YAML_IS_SEQUENCE_VECTOR(CodeViewYAML::GlobalHash) + +#endif // LLVM_OBJECTYAML_CODEVIEWYAMLTYPES_H Index: llvm/lib/ObjectYAML/CMakeLists.txt =================================================================== --- llvm/lib/ObjectYAML/CMakeLists.txt +++ llvm/lib/ObjectYAML/CMakeLists.txt @@ -1,7 +1,8 @@ add_llvm_library(LLVMObjectYAML - CodeViewYAMLTypes.cpp - CodeViewYAMLSymbols.cpp CodeViewYAMLDebugSections.cpp + CodeViewYAMLSymbols.cpp + CodeViewYAMLTypeHashing.cpp + CodeViewYAMLTypes.cpp COFFYAML.cpp DWARFEmitter.cpp DWARFVisitor.cpp Index: llvm/lib/ObjectYAML/COFFYAML.cpp =================================================================== --- llvm/lib/ObjectYAML/COFFYAML.cpp +++ llvm/lib/ObjectYAML/COFFYAML.cpp @@ -562,14 +562,16 @@ IO.mapOptional("VirtualSize", Sec.Header.VirtualSize, 0U); IO.mapOptional("Alignment", Sec.Alignment, 0U); - // If this is a .debug$S or .debug$T section parse the semantic representation - // of the symbols/types. If it is any other kind of section, just deal in raw - // bytes. + // If this is a .debug$S .debug$T, or .debug$H section parse the semantic + // representation of the symbols/types. If it is any other kind of section, + // just deal in raw bytes. IO.mapOptional("SectionData", Sec.SectionData); if (Sec.Name == ".debug$S") IO.mapOptional("Subsections", Sec.DebugS); else if (Sec.Name == ".debug$T") IO.mapOptional("Types", Sec.DebugT); + else if (Sec.Name == ".debug$H") + IO.mapOptional("GlobalHashes", Sec.DebugH); IO.mapOptional("Relocations", Sec.Relocations); } Index: llvm/lib/ObjectYAML/CodeViewYAMLTypeHashing.cpp =================================================================== --- /dev/null +++ llvm/lib/ObjectYAML/CodeViewYAMLTypeHashing.cpp @@ -0,0 +1,82 @@ +//===- CodeViewYAMLTypeHashing.cpp - CodeView YAMLIO type hashing ---------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines classes for handling the YAML representation of CodeView +// Debug Info. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ObjectYAML/CodeViewYAMLTypeHashing.h" +#include "llvm/Support/BinaryByteStream.h" +#include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/BinaryStreamWriter.h" + +using namespace llvm; +using namespace llvm::codeview; +using namespace llvm::CodeViewYAML; +using namespace llvm::yaml; + +namespace llvm { +namespace yaml { + +void MappingTraits::mapping(IO &io, DebugHSection &DebugH) { + io.mapRequired("Version", DebugH.Version); + io.mapRequired("HashAlgorithm", DebugH.HashAlgorithm); + io.mapOptional("HashValues", DebugH.Hashes); +} + +void ScalarTraits::output(const GlobalHash &GH, void *Ctx, + raw_ostream &OS) { + ScalarTraits::output(GH.Hash, Ctx, OS); +} + +StringRef ScalarTraits::input(StringRef Scalar, void *Ctx, + GlobalHash &GH) { + return ScalarTraits::input(Scalar, Ctx, GH.Hash); +} + +} // end namespace yaml +} // end namespace llvm + +DebugHSection llvm::CodeViewYAML::fromDebugH(ArrayRef DebugT) { + assert(DebugT.size() >= 4); + assert((DebugT.size() - 4) % 20 == 0); + + BinaryStreamReader Reader(DebugT, llvm::support::little); + DebugHSection DHS; + cantFail(Reader.readInteger(DHS.Version)); + cantFail(Reader.readInteger(DHS.HashAlgorithm)); + while (Reader.bytesRemaining() != 0) { + ArrayRef S; + cantFail(Reader.readBytes(S, 20)); + DHS.Hashes.emplace_back(S); + } + assert(Reader.bytesRemaining() == 0); + return DHS; +} + +ArrayRef llvm::CodeViewYAML::toDebugH(const DebugHSection &DebugH, + BumpPtrAllocator &Alloc) { + uint32_t Size = 4 + 20 * DebugH.Hashes.size(); + uint8_t *Data = Alloc.Allocate(Size); + MutableArrayRef Buffer(Data, Size); + BinaryStreamWriter Writer(Buffer, llvm::support::little); + cantFail(Writer.writeInteger(DebugH.Version)); + cantFail(Writer.writeInteger(DebugH.HashAlgorithm)); + SmallString<20> Hash; + for (const auto &H : DebugH.Hashes) { + Hash.clear(); + raw_svector_ostream OS(Hash); + H.Hash.writeAsBinary(OS); + assert((Hash.size() == 20) && "Invalid hash size!"); + cantFail(Writer.writeFixedString(Hash)); + } + assert(Writer.bytesRemaining() == 0); + return Buffer; +} Index: llvm/test/ObjectYAML/CodeView/type-hashes.yaml =================================================================== --- /dev/null +++ llvm/test/ObjectYAML/CodeView/type-hashes.yaml @@ -0,0 +1,62 @@ +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_I386 + Characteristics: [ ] +sections: + - Name: '.debug$T' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 4 + Types: + # char** + - Kind: LF_POINTER + Pointer: + ReferentType: 272 + Attrs: 32778 + # int** + - Kind: LF_POINTER + Pointer: + ReferentType: 372 + Attrs: 32778 + # int*** + - Kind: LF_POINTER + Pointer: + ReferentType: 4097 + Attrs: 32778 + # (char**, int***) + - Kind: LF_ARGLIST + ArgList: + ArgIndices: [ 4096, 4098 ] + # int** (char**, int***) + - Kind: LF_PROCEDURE + Procedure: + ReturnType: 4097 + CallConv: NearC + Options: [ None ] + ParameterCount: 2 + ArgumentList: 4099 + - Name: '.debug$H' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 4 + GlobalHashes: + Version: 0 + HashAlgorithm: 0 + HashValues: + - 1522A98D88FAF71B618D97BCAC2B89A424EC4805 + - 8B2BA87CC27BF9D290A31A6070FA296AAA577E53 + - EC11CE9F78D6BF61F8D913A9E2C98293782A7EB4 + - 1088AD64CEBC88D9E015058A159516AF20B79286 + - 457ABCB8AB70407594B5D72BF471B6BDECC99BC9 +symbols: + - Name: '.debug$T' + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 68 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 2189213922 + Number: 1 +... Index: llvm/tools/obj2yaml/coff2yaml.cpp =================================================================== --- llvm/tools/obj2yaml/coff2yaml.cpp +++ llvm/tools/obj2yaml/coff2yaml.cpp @@ -172,6 +172,8 @@ NewYAMLSection.DebugS = CodeViewYAML::fromDebugS(sectionData, SC); else if (NewYAMLSection.Name == ".debug$T") NewYAMLSection.DebugT = CodeViewYAML::fromDebugT(sectionData); + else if (NewYAMLSection.Name == ".debug$H") + NewYAMLSection.DebugH = CodeViewYAML::fromDebugH(sectionData); std::vector Relocations; for (const auto &Reloc : ObjSection.relocations()) { Index: llvm/tools/yaml2obj/yaml2coff.cpp =================================================================== --- llvm/tools/yaml2obj/yaml2coff.cpp +++ llvm/tools/yaml2obj/yaml2coff.cpp @@ -234,6 +234,9 @@ } else if (S.Name == ".debug$T") { if (S.SectionData.binary_size() == 0) S.SectionData = CodeViewYAML::toDebugT(S.DebugT, CP.Allocator); + } else if (S.Name == ".debug$H") { + if (S.DebugH.hasValue() && S.SectionData.binary_size() == 0) + S.SectionData = CodeViewYAML::toDebugH(*S.DebugH, CP.Allocator); } if (S.SectionData.binary_size() > 0) {