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