1 //===- DebugSubsection.h ------------------------------------*- C++ -*-===// 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 #ifndef LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTRECORD_H 11 #define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTRECORD_H 12 13 #include "llvm/DebugInfo/CodeView/CodeView.h" 14 #include "llvm/Support/BinaryStreamArray.h" 15 #include "llvm/Support/BinaryStreamRef.h" 16 #include "llvm/Support/BinaryStreamWriter.h" 17 #include "llvm/Support/Endian.h" 18 #include "llvm/Support/Error.h" 19 20 namespace llvm { 21 namespace codeview { 22 23 class DebugSubsection; 24 25 // Corresponds to the `CV_DebugSSubsectionHeader_t` structure. 26 struct DebugSubsectionHeader { 27 support::ulittle32_t Kind; // codeview::DebugSubsectionKind enum 28 support::ulittle32_t Length; // number of bytes occupied by this record. 29 }; 30 31 class DebugSubsectionRecord { 32 public: 33 DebugSubsectionRecord(); 34 DebugSubsectionRecord(DebugSubsectionKind Kind, BinaryStreamRef Data, 35 CodeViewContainer Container); 36 37 static Error initialize(BinaryStreamRef Stream, DebugSubsectionRecord &Info, 38 CodeViewContainer Container); 39 40 uint32_t getRecordLength() const; 41 DebugSubsectionKind kind() const; 42 BinaryStreamRef getRecordData() const; 43 44 private: 45 CodeViewContainer Container; 46 DebugSubsectionKind Kind; 47 BinaryStreamRef Data; 48 }; 49 50 class DebugSubsectionRecordBuilder { 51 public: 52 DebugSubsectionRecordBuilder(std::shared_ptr<DebugSubsection> Subsection, 53 CodeViewContainer Container); 54 uint32_t calculateSerializedLength(); 55 Error commit(BinaryStreamWriter &Writer) const; 56 57 private: 58 std::shared_ptr<DebugSubsection> Subsection; 59 CodeViewContainer Container; 60 }; 61 62 } // namespace codeview 63 64 template <> struct VarStreamArrayExtractor<codeview::DebugSubsectionRecord> { 65 Error operator()(BinaryStreamRef Stream, uint32_t &Length, 66 codeview::DebugSubsectionRecord &Info) { 67 // FIXME: We need to pass the container type through to this function. In 68 // practice this isn't super important since the subsection header describes 69 // its length and we can just skip it. It's more important when writing. 70 if (auto EC = codeview::DebugSubsectionRecord::initialize( 71 Stream, Info, codeview::CodeViewContainer::Pdb)) 72 return EC; 73 Length = alignTo(Info.getRecordLength(), 4); 74 return Error::success(); 75 } 76 }; 77 78 namespace codeview { 79 typedef VarStreamArray<DebugSubsectionRecord> DebugSubsectionArray; 80 } 81 } // namespace llvm 82 83 #endif // LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGFRAGMENTRECORD_H 84