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