1c221dc71SZachary Turner //===- CodeViewYAMLTypeHashing.cpp - CodeView YAMLIO type hashing ---------===//
2c221dc71SZachary Turner //
3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c221dc71SZachary Turner //
7c221dc71SZachary Turner //===----------------------------------------------------------------------===//
8c221dc71SZachary Turner //
9c221dc71SZachary Turner // This file defines classes for handling the YAML representation of CodeView
10c221dc71SZachary Turner // Debug Info.
11c221dc71SZachary Turner //
12c221dc71SZachary Turner //===----------------------------------------------------------------------===//
13c221dc71SZachary Turner 
14c221dc71SZachary Turner #include "llvm/ObjectYAML/CodeViewYAMLTypeHashing.h"
15c762666eSZachary Turner 
16c762666eSZachary Turner #include "llvm/BinaryFormat/COFF.h"
17c221dc71SZachary Turner #include "llvm/Support/BinaryByteStream.h"
18c221dc71SZachary Turner #include "llvm/Support/BinaryStreamReader.h"
19c221dc71SZachary Turner #include "llvm/Support/BinaryStreamWriter.h"
20c221dc71SZachary Turner 
21c221dc71SZachary Turner using namespace llvm;
22c221dc71SZachary Turner using namespace llvm::codeview;
23c221dc71SZachary Turner using namespace llvm::CodeViewYAML;
24c221dc71SZachary Turner using namespace llvm::yaml;
25c221dc71SZachary Turner 
26c221dc71SZachary Turner namespace llvm {
27c221dc71SZachary Turner namespace yaml {
28c221dc71SZachary Turner 
mapping(IO & io,DebugHSection & DebugH)29c221dc71SZachary Turner void MappingTraits<DebugHSection>::mapping(IO &io, DebugHSection &DebugH) {
30c221dc71SZachary Turner   io.mapRequired("Version", DebugH.Version);
31c221dc71SZachary Turner   io.mapRequired("HashAlgorithm", DebugH.HashAlgorithm);
32c221dc71SZachary Turner   io.mapOptional("HashValues", DebugH.Hashes);
33c221dc71SZachary Turner }
34c221dc71SZachary Turner 
output(const GlobalHash & GH,void * Ctx,raw_ostream & OS)35c221dc71SZachary Turner void ScalarTraits<GlobalHash>::output(const GlobalHash &GH, void *Ctx,
36c221dc71SZachary Turner                                       raw_ostream &OS) {
37c221dc71SZachary Turner   ScalarTraits<BinaryRef>::output(GH.Hash, Ctx, OS);
38c221dc71SZachary Turner }
39c221dc71SZachary Turner 
input(StringRef Scalar,void * Ctx,GlobalHash & GH)40c221dc71SZachary Turner StringRef ScalarTraits<GlobalHash>::input(StringRef Scalar, void *Ctx,
41c221dc71SZachary Turner                                           GlobalHash &GH) {
42c221dc71SZachary Turner   return ScalarTraits<BinaryRef>::input(Scalar, Ctx, GH.Hash);
43c221dc71SZachary Turner }
44c221dc71SZachary Turner 
45c221dc71SZachary Turner } // end namespace yaml
46c221dc71SZachary Turner } // end namespace llvm
47c221dc71SZachary Turner 
fromDebugH(ArrayRef<uint8_t> DebugH)48048f8f99SZachary Turner DebugHSection llvm::CodeViewYAML::fromDebugH(ArrayRef<uint8_t> DebugH) {
49048f8f99SZachary Turner   assert(DebugH.size() >= 8);
50c762666eSZachary Turner   assert((DebugH.size() - 8) % 8 == 0);
51c221dc71SZachary Turner 
52048f8f99SZachary Turner   BinaryStreamReader Reader(DebugH, llvm::support::little);
53c221dc71SZachary Turner   DebugHSection DHS;
54c221dc71SZachary Turner   cantFail(Reader.readInteger(DHS.Magic));
55c221dc71SZachary Turner   cantFail(Reader.readInteger(DHS.Version));
56c221dc71SZachary Turner   cantFail(Reader.readInteger(DHS.HashAlgorithm));
57c762666eSZachary Turner 
58c221dc71SZachary Turner   while (Reader.bytesRemaining() != 0) {
59c221dc71SZachary Turner     ArrayRef<uint8_t> S;
60c762666eSZachary Turner     cantFail(Reader.readBytes(S, 8));
61c221dc71SZachary Turner     DHS.Hashes.emplace_back(S);
62c221dc71SZachary Turner   }
63c221dc71SZachary Turner   assert(Reader.bytesRemaining() == 0);
64c221dc71SZachary Turner   return DHS;
65c221dc71SZachary Turner }
66c221dc71SZachary Turner 
toDebugH(const DebugHSection & DebugH,BumpPtrAllocator & Alloc)67c221dc71SZachary Turner ArrayRef<uint8_t> llvm::CodeViewYAML::toDebugH(const DebugHSection &DebugH,
68c221dc71SZachary Turner                                                BumpPtrAllocator &Alloc) {
69c762666eSZachary Turner   uint32_t Size = 8 + 8 * DebugH.Hashes.size();
70c221dc71SZachary Turner   uint8_t *Data = Alloc.Allocate<uint8_t>(Size);
71c221dc71SZachary Turner   MutableArrayRef<uint8_t> Buffer(Data, Size);
72c221dc71SZachary Turner   BinaryStreamWriter Writer(Buffer, llvm::support::little);
73c762666eSZachary Turner 
74c221dc71SZachary Turner   cantFail(Writer.writeInteger(DebugH.Magic));
75c221dc71SZachary Turner   cantFail(Writer.writeInteger(DebugH.Version));
76c221dc71SZachary Turner   cantFail(Writer.writeInteger(DebugH.HashAlgorithm));
77c762666eSZachary Turner   SmallString<8> Hash;
78c221dc71SZachary Turner   for (const auto &H : DebugH.Hashes) {
79c221dc71SZachary Turner     Hash.clear();
80c221dc71SZachary Turner     raw_svector_ostream OS(Hash);
81c221dc71SZachary Turner     H.Hash.writeAsBinary(OS);
82c762666eSZachary Turner     assert((Hash.size() == 8) && "Invalid hash size!");
83c221dc71SZachary Turner     cantFail(Writer.writeFixedString(Hash));
84c221dc71SZachary Turner   }
85c221dc71SZachary Turner   assert(Writer.bytesRemaining() == 0);
86c221dc71SZachary Turner   return Buffer;
87c221dc71SZachary Turner }
88