From 1267568ace2f62c5901a0fd5ddfd03516489bd42 Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Wed, 6 Dec 2017 18:58:48 +0000 Subject: [PATCH] Update obj2yaml and yaml2obj for .debug$H section. Differential Revision: https://reviews.llvm.org/D40842 llvm-svn: 319925 --- include/llvm/BinaryFormat/COFF.h | 1 + include/llvm/ObjectYAML/COFFYAML.h | 2 + .../llvm/ObjectYAML/CodeViewYAMLTypeHashing.h | 62 ++++++++++ lib/ObjectYAML/CMakeLists.txt | 5 +- lib/ObjectYAML/COFFYAML.cpp | 8 +- lib/ObjectYAML/CodeViewYAMLTypeHashing.cpp | 84 +++++++++++++ test/ObjectYAML/CodeView/guid.yaml | 59 --------- test/ObjectYAML/CodeView/sections.yaml | 112 ++++++++++++++++++ tools/obj2yaml/coff2yaml.cpp | 2 + tools/yaml2obj/yaml2coff.cpp | 3 + 10 files changed, 274 insertions(+), 64 deletions(-) create mode 100644 include/llvm/ObjectYAML/CodeViewYAMLTypeHashing.h create mode 100644 lib/ObjectYAML/CodeViewYAMLTypeHashing.cpp delete mode 100644 test/ObjectYAML/CodeView/guid.yaml create mode 100644 test/ObjectYAML/CodeView/sections.yaml diff --git a/include/llvm/BinaryFormat/COFF.h b/include/llvm/BinaryFormat/COFF.h index b395db6eaa8..8023f917178 100644 --- a/include/llvm/BinaryFormat/COFF.h +++ b/include/llvm/BinaryFormat/COFF.h @@ -707,6 +707,7 @@ struct ImportHeader { enum CodeViewIdentifiers { DEBUG_SECTION_MAGIC = 0x4, + DEBUG_HASHES_SECTION_MAGIC = 0x133C9C5 }; inline bool isReservedSectionNumber(int32_t SectionNumber) { diff --git a/include/llvm/ObjectYAML/COFFYAML.h b/include/llvm/ObjectYAML/COFFYAML.h index 1fce46c125f..8794eaa6d59 100644 --- a/include/llvm/ObjectYAML/COFFYAML.h +++ b/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 @@ struct Section { yaml::BinaryRef SectionData; std::vector DebugS; std::vector DebugT; + Optional DebugH; std::vector Relocations; StringRef Name; diff --git a/include/llvm/ObjectYAML/CodeViewYAMLTypeHashing.h b/include/llvm/ObjectYAML/CodeViewYAMLTypeHashing.h new file mode 100644 index 00000000000..50a11603d62 --- /dev/null +++ b/include/llvm/ObjectYAML/CodeViewYAMLTypeHashing.h @@ -0,0 +1,62 @@ +//==- 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 { + uint32_t Magic; + 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 diff --git a/lib/ObjectYAML/CMakeLists.txt b/lib/ObjectYAML/CMakeLists.txt index 7af0b9c194e..d24f879836f 100644 --- a/lib/ObjectYAML/CMakeLists.txt +++ b/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 diff --git a/lib/ObjectYAML/COFFYAML.cpp b/lib/ObjectYAML/COFFYAML.cpp index 056a1aa3ca1..937b8dc029f 100644 --- a/lib/ObjectYAML/COFFYAML.cpp +++ b/lib/ObjectYAML/COFFYAML.cpp @@ -562,14 +562,16 @@ void MappingTraits::mapping(IO &IO, COFFYAML::Section &Sec) { 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); } diff --git a/lib/ObjectYAML/CodeViewYAMLTypeHashing.cpp b/lib/ObjectYAML/CodeViewYAMLTypeHashing.cpp new file mode 100644 index 00000000000..b35e8ab05ad --- /dev/null +++ b/lib/ObjectYAML/CodeViewYAMLTypeHashing.cpp @@ -0,0 +1,84 @@ +//===- 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() >= 8); + assert((DebugT.size() - 8) % 20 == 0); + + BinaryStreamReader Reader(DebugT, llvm::support::little); + DebugHSection DHS; + cantFail(Reader.readInteger(DHS.Magic)); + 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 = 8 + 20 * DebugH.Hashes.size(); + uint8_t *Data = Alloc.Allocate(Size); + MutableArrayRef Buffer(Data, Size); + BinaryStreamWriter Writer(Buffer, llvm::support::little); + cantFail(Writer.writeInteger(DebugH.Magic)); + 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; +} diff --git a/test/ObjectYAML/CodeView/guid.yaml b/test/ObjectYAML/CodeView/guid.yaml deleted file mode 100644 index 8d8d0142c5e..00000000000 --- a/test/ObjectYAML/CodeView/guid.yaml +++ /dev/null @@ -1,59 +0,0 @@ -# RUN: yaml2obj %s | obj2yaml | FileCheck %s - ---- !COFF -header: - Machine: IMAGE_FILE_MACHINE_AMD64 - Characteristics: [ ] -sections: - - Name: '.debug$T' - Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] - Alignment: 1 - Types: - - Kind: LF_TYPESERVER2 - TypeServer2: - Guid: '{01DF191B-22BF-6B42-96CE-5258B8329FE5}' - Age: 24 - Name: 'C:\src\llvm-project\build\vc140.pdb' -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: 64 - NumberOfRelocations: 0 - NumberOfLinenumbers: 0 - CheckSum: 0 - Number: 0 -... - -# CHECK: --- !COFF -# CHECK: header: -# CHECK: Machine: IMAGE_FILE_MACHINE_AMD64 -# CHECK: Characteristics: [ ] -# CHECK: sections: -# CHECK: - Name: '.debug$T' -# CHECK: Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] -# CHECK: Alignment: 1 -# CHECK: Types: -# CHECK: - Kind: LF_TYPESERVER2 -# CHECK: TypeServer2: -# CHECK: Guid: '{01DF191B-22BF-6B42-96CE-5258B8329FE5}' -# CHECK: Age: 24 -# CHECK: Name: 'C:\src\llvm-project\build\vc140.pdb' -# CHECK: symbols: -# CHECK: - Name: '.debug$T' -# CHECK: Value: 0 -# CHECK: SectionNumber: 1 -# CHECK: SimpleType: IMAGE_SYM_TYPE_NULL -# CHECK: ComplexType: IMAGE_SYM_DTYPE_NULL -# CHECK: StorageClass: IMAGE_SYM_CLASS_STATIC -# CHECK: SectionDefinition: -# CHECK: Length: 64 -# CHECK: NumberOfRelocations: 0 -# CHECK: NumberOfLinenumbers: 0 -# CHECK: CheckSum: 0 -# CHECK: Number: 0 -# CHECK: ... diff --git a/test/ObjectYAML/CodeView/sections.yaml b/test/ObjectYAML/CodeView/sections.yaml new file mode 100644 index 00000000000..7a58f88029f --- /dev/null +++ b/test/ObjectYAML/CodeView/sections.yaml @@ -0,0 +1,112 @@ +# RUN: yaml2obj %s > %t.obj +# RUN: obj2yaml %t.obj | FileCheck --check-prefix=CHECK %s +# RUN: llvm-objdump -section-headers %t.obj | FileCheck --check-prefix=HEADERS %s + +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [ ] +sections: + - Name: '.debug$T' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 1 + Types: + - Kind: LF_TYPESERVER2 + TypeServer2: + Guid: '{01DF191B-22BF-6B42-96CE-5258B8329FE5}' + Age: 24 + Name: 'C:\src\llvm-project\build\vc140.pdb' + - 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: 64 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 + - Name: '.debug$H' + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 108 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 2189213922 + Number: 1 +... + +# CHECK: --- !COFF +# CHECK: header: +# CHECK: Machine: IMAGE_FILE_MACHINE_AMD64 +# CHECK: Characteristics: [ ] +# CHECK: sections: +# CHECK: - Name: '.debug$T' +# CHECK: Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] +# CHECK: Alignment: 1 +# CHECK: Types: +# CHECK: - Kind: LF_TYPESERVER2 +# CHECK: TypeServer2: +# CHECK: Guid: '{01DF191B-22BF-6B42-96CE-5258B8329FE5}' +# CHECK: Age: 24 +# CHECK: Name: 'C:\src\llvm-project\build\vc140.pdb' +# CHECK: - Name: '.debug$H' +# CHECK: Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] +# CHECK: Alignment: 4 +# CHECK: GlobalHashes: +# CHECK: Version: 0 +# CHECK: HashAlgorithm: 0 +# CHECK: HashValues: +# CHECK: - 1522A98D88FAF71B618D97BCAC2B89A424EC4805 +# CHECK: - 8B2BA87CC27BF9D290A31A6070FA296AAA577E53 +# CHECK: - EC11CE9F78D6BF61F8D913A9E2C98293782A7EB4 +# CHECK: - 1088AD64CEBC88D9E015058A159516AF20B79286 +# CHECK: - 457ABCB8AB70407594B5D72BF471B6BDECC99BC9 +# CHECK: symbols: +# CHECK: - Name: '.debug$T' +# CHECK: Value: 0 +# CHECK: SectionNumber: 1 +# CHECK: SimpleType: IMAGE_SYM_TYPE_NULL +# CHECK: ComplexType: IMAGE_SYM_DTYPE_NULL +# CHECK: StorageClass: IMAGE_SYM_CLASS_STATIC +# CHECK: SectionDefinition: +# CHECK: Length: 64 +# CHECK: NumberOfRelocations: 0 +# CHECK: NumberOfLinenumbers: 0 +# CHECK: CheckSum: 0 +# CHECK: Number: 0 +# CHECK: - Name: '.debug$H' +# CHECK: Value: 0 +# CHECK: SectionNumber: 2 +# CHECK: SimpleType: IMAGE_SYM_TYPE_NULL +# CHECK: ComplexType: IMAGE_SYM_DTYPE_NULL +# CHECK: StorageClass: IMAGE_SYM_CLASS_STATIC +# CHECK: SectionDefinition: +# CHECK: Length: 108 +# CHECK: NumberOfRelocations: 0 +# CHECK: NumberOfLinenumbers: 0 +# CHECK: CheckSum: 2189213922 +# CHECK: Number: 1 +# CHECK: ... + +# HEADERS: 0 .debug$T 00000040 0000000000000000 DATA +# HEADERS: 1 .debug$H 0000006c 0000000000000000 DATA diff --git a/tools/obj2yaml/coff2yaml.cpp b/tools/obj2yaml/coff2yaml.cpp index b1a06bca1a7..acd81c9241f 100644 --- a/tools/obj2yaml/coff2yaml.cpp +++ b/tools/obj2yaml/coff2yaml.cpp @@ -172,6 +172,8 @@ void COFFDumper::dumpSections(unsigned NumSections) { 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()) { diff --git a/tools/yaml2obj/yaml2coff.cpp b/tools/yaml2obj/yaml2coff.cpp index 1f302fdc45a..648317e97bb 100644 --- a/tools/yaml2obj/yaml2coff.cpp +++ b/tools/yaml2obj/yaml2coff.cpp @@ -234,6 +234,9 @@ static bool layoutCOFF(COFFParser &CP) { } 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) {