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
21using namespace llvm;
22using namespace llvm::codeview;
23using namespace llvm::CodeViewYAML;
24using namespace llvm::yaml;
25
26namespace llvm {
27namespace yaml {
28
29void 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
35void ScalarTraits<GlobalHash>::output(const GlobalHash &GH, void *Ctx,
36                                      raw_ostream &OS) {
37  ScalarTraits<BinaryRef>::output(GH.Hash, Ctx, OS);
38}
39
40StringRef 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
48DebugHSection 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
67ArrayRef<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