Line data Source code
1 : //===- DebugSubsectionRecord.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_DEBUGSUBSECTIONRECORD_H
11 : #define LLVM_DEBUGINFO_CODEVIEW_DEBUGSUBSECTIONRECORD_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/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 1453 : class DebugSubsectionRecord {
37 : public:
38 : DebugSubsectionRecord();
39 : DebugSubsectionRecord(DebugSubsectionKind Kind, BinaryStreamRef Data,
40 : CodeViewContainer Container);
41 :
42 : static Error initialize(BinaryStreamRef Stream, DebugSubsectionRecord &Info,
43 : CodeViewContainer Container);
44 :
45 : uint32_t getRecordLength() const;
46 : DebugSubsectionKind kind() const;
47 : BinaryStreamRef getRecordData() const;
48 :
49 : private:
50 : CodeViewContainer Container = CodeViewContainer::ObjectFile;
51 : DebugSubsectionKind Kind = DebugSubsectionKind::None;
52 : BinaryStreamRef Data;
53 : };
54 :
55 569 : class DebugSubsectionRecordBuilder {
56 : public:
57 : DebugSubsectionRecordBuilder(std::shared_ptr<DebugSubsection> Subsection,
58 : CodeViewContainer Container);
59 :
60 : /// Use this to copy existing subsections directly from source to destination.
61 : /// For example, line table subsections in an object file only need to be
62 : /// relocated before being copied into the PDB.
63 : DebugSubsectionRecordBuilder(const DebugSubsectionRecord &Contents,
64 : CodeViewContainer Container);
65 :
66 : uint32_t calculateSerializedLength();
67 : Error commit(BinaryStreamWriter &Writer) const;
68 :
69 : private:
70 : /// The subsection to build. Will be null if Contents is non-empty.
71 : std::shared_ptr<DebugSubsection> Subsection;
72 :
73 : /// The bytes of the subsection. Only non-empty if Subsection is null.
74 : DebugSubsectionRecord Contents;
75 :
76 : CodeViewContainer Container;
77 : };
78 :
79 : } // end namespace codeview
80 :
81 : template <> struct VarStreamArrayExtractor<codeview::DebugSubsectionRecord> {
82 988 : Error operator()(BinaryStreamRef Stream, uint32_t &Length,
83 : codeview::DebugSubsectionRecord &Info) {
84 : // FIXME: We need to pass the container type through to this function. In
85 : // practice this isn't super important since the subsection header describes
86 : // its length and we can just skip it. It's more important when writing.
87 988 : if (auto EC = codeview::DebugSubsectionRecord::initialize(
88 1976 : Stream, Info, codeview::CodeViewContainer::Pdb))
89 : return EC;
90 988 : Length = alignTo(Info.getRecordLength(), 4);
91 : return Error::success();
92 : }
93 : };
94 :
95 : namespace codeview {
96 :
97 : using DebugSubsectionArray = VarStreamArray<DebugSubsectionRecord>;
98 :
99 : } // end namespace codeview
100 :
101 : } // end namespace llvm
102 :
103 : #endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGSUBSECTIONRECORD_H
|