1 //===- DebugSubsectionRecord.h ----------------------------------*- C++ -*-===// 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 #ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGSUBSECTIONRECORD_H 10 #define LLVM_DEBUGINFO_CODEVIEW_DEBUGSUBSECTIONRECORD_H 11 12 #include "llvm/DebugInfo/CodeView/CodeView.h" 13 #include "llvm/Support/BinaryStreamArray.h" 14 #include "llvm/Support/BinaryStreamRef.h" 15 #include "llvm/Support/Compiler.h" 16 #include "llvm/Support/Endian.h" 17 #include "llvm/Support/Error.h" 18 #include "llvm/Support/MathExtras.h" 19 #include <cstdint> 20 #include <memory> 21 22 namespace llvm { 23 24 class BinaryStreamWriter; 25 26 namespace codeview { 27 28 class DebugSubsection; 29 30 // Corresponds to the `CV_DebugSSubsectionHeader_t` structure. 31 struct DebugSubsectionHeader { 32 support::ulittle32_t Kind; // codeview::DebugSubsectionKind enum 33 support::ulittle32_t Length; // number of bytes occupied by this record. 34 }; 35 36 class DebugSubsectionRecord { 37 public: 38 LLVM_ABI DebugSubsectionRecord(); 39 LLVM_ABI DebugSubsectionRecord(DebugSubsectionKind Kind, 40 BinaryStreamRef Data); 41 42 LLVM_ABI static Error initialize(BinaryStreamRef Stream, 43 DebugSubsectionRecord &Info); 44 45 LLVM_ABI uint32_t getRecordLength() const; 46 LLVM_ABI DebugSubsectionKind kind() const; 47 LLVM_ABI BinaryStreamRef getRecordData() const; 48 49 private: 50 DebugSubsectionKind Kind = DebugSubsectionKind::None; 51 BinaryStreamRef Data; 52 }; 53 54 class DebugSubsectionRecordBuilder { 55 public: 56 LLVM_ABI 57 DebugSubsectionRecordBuilder(std::shared_ptr<DebugSubsection> Subsection); 58 59 /// Use this to copy existing subsections directly from source to destination. 60 /// For example, line table subsections in an object file only need to be 61 /// relocated before being copied into the PDB. 62 LLVM_ABI DebugSubsectionRecordBuilder(const DebugSubsectionRecord &Contents); 63 64 LLVM_ABI uint32_t calculateSerializedLength() const; 65 LLVM_ABI Error commit(BinaryStreamWriter &Writer, 66 CodeViewContainer Container) const; 67 68 private: 69 /// The subsection to build. Will be null if Contents is non-empty. 70 std::shared_ptr<DebugSubsection> Subsection; 71 72 /// The bytes of the subsection. Only non-empty if Subsection is null. 73 /// FIXME: Reduce the size of this. 74 DebugSubsectionRecord Contents; 75 }; 76 77 } // end namespace codeview 78 79 template <> struct VarStreamArrayExtractor<codeview::DebugSubsectionRecord> { 80 Error operator()(BinaryStreamRef Stream, uint32_t &Length, 81 codeview::DebugSubsectionRecord &Info) { 82 // FIXME: We need to pass the container type through to this function. In 83 // practice this isn't super important since the subsection header describes 84 // its length and we can just skip it. It's more important when writing. 85 if (auto EC = codeview::DebugSubsectionRecord::initialize(Stream, Info)) 86 return EC; 87 Length = alignTo(Info.getRecordLength(), 4); 88 return Error::success(); 89 } 90 }; 91 92 namespace codeview { 93 94 using DebugSubsectionArray = VarStreamArray<DebugSubsectionRecord>; 95 96 } // end namespace codeview 97 98 } // end namespace llvm 99 100 #endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGSUBSECTIONRECORD_H 101