1 //===- DebugSubsectionRecord.h ----------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGSUBSECTIONRECORD_H
10 #define LLVM_DEBUGINFO_CODEVIEW_DEBUGSUBSECTIONRECORD_H
12 #include "llvm/DebugInfo/CodeView/CodeView.h"
13 #include "llvm/Support/BinaryStreamArray.h"
14 #include "llvm/Support/BinaryStreamRef.h"
15 #include "llvm/Support/Endian.h"
16 #include "llvm/Support/Error.h"
17 #include "llvm/Support/MathExtras.h"
23 class BinaryStreamWriter
;
27 class DebugSubsection
;
29 // Corresponds to the `CV_DebugSSubsectionHeader_t` structure.
30 struct DebugSubsectionHeader
{
31 support::ulittle32_t Kind
; // codeview::DebugSubsectionKind enum
32 support::ulittle32_t Length
; // number of bytes occupied by this record.
35 class DebugSubsectionRecord
{
37 DebugSubsectionRecord();
38 DebugSubsectionRecord(DebugSubsectionKind Kind
, BinaryStreamRef Data
,
39 CodeViewContainer Container
);
41 static Error
initialize(BinaryStreamRef Stream
, DebugSubsectionRecord
&Info
,
42 CodeViewContainer Container
);
44 uint32_t getRecordLength() const;
45 DebugSubsectionKind
kind() const;
46 BinaryStreamRef
getRecordData() const;
49 CodeViewContainer Container
= CodeViewContainer::ObjectFile
;
50 DebugSubsectionKind Kind
= DebugSubsectionKind::None
;
54 class DebugSubsectionRecordBuilder
{
56 DebugSubsectionRecordBuilder(std::shared_ptr
<DebugSubsection
> Subsection
,
57 CodeViewContainer Container
);
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 DebugSubsectionRecordBuilder(const DebugSubsectionRecord
&Contents
,
63 CodeViewContainer Container
);
65 uint32_t calculateSerializedLength();
66 Error
commit(BinaryStreamWriter
&Writer
) const;
69 /// The subsection to build. Will be null if Contents is non-empty.
70 std::shared_ptr
<DebugSubsection
> Subsection
;
72 /// The bytes of the subsection. Only non-empty if Subsection is null.
73 DebugSubsectionRecord Contents
;
75 CodeViewContainer Container
;
78 } // end namespace codeview
80 template <> struct VarStreamArrayExtractor
<codeview::DebugSubsectionRecord
> {
81 Error
operator()(BinaryStreamRef Stream
, uint32_t &Length
,
82 codeview::DebugSubsectionRecord
&Info
) {
83 // FIXME: We need to pass the container type through to this function. In
84 // practice this isn't super important since the subsection header describes
85 // its length and we can just skip it. It's more important when writing.
86 if (auto EC
= codeview::DebugSubsectionRecord::initialize(
87 Stream
, Info
, codeview::CodeViewContainer::Pdb
))
89 Length
= alignTo(Info
.getRecordLength(), 4);
90 return Error::success();
96 using DebugSubsectionArray
= VarStreamArray
<DebugSubsectionRecord
>;
98 } // end namespace codeview
100 } // end namespace llvm
102 #endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGSUBSECTIONRECORD_H