xref: /freebsd/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/DebugSubsectionRecord.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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