Fix use after free in BinaryStream library.
[lldb.git] / llvm / include / llvm / DebugInfo / CodeView / ModuleDebugInlineeLinesFragment.h
1 //===- ModuleDebugInlineeLinesFragment.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_MODULEDEBUGINLINEELINESFRAGMENT_H
11 #define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGINLINEELINESFRAGMENT_H
12
13 #include "llvm/DebugInfo/CodeView/Line.h"
14 #include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
15 #include "llvm/Support/BinaryStreamArray.h"
16 #include "llvm/Support/BinaryStreamReader.h"
17 #include "llvm/Support/Error.h"
18
19 namespace llvm {
20 namespace codeview {
21
22 class ModuleDebugInlineeLineFragmentRef;
23
24 enum class InlineeLinesSignature : uint32_t {
25   Normal,    // CV_INLINEE_SOURCE_LINE_SIGNATURE
26   ExtraFiles // CV_INLINEE_SOURCE_LINE_SIGNATURE_EX
27 };
28
29 struct InlineeSourceLineHeader {
30   TypeIndex Inlinee;                  // ID of the function that was inlined.
31   support::ulittle32_t FileID;        // Offset into FileChecksums subsection.
32   support::ulittle32_t SourceLineNum; // First line of inlined code.
33                                       // If extra files present:
34                                       //   ulittle32_t ExtraFileCount;
35                                       //   ulittle32_t Files[];
36 };
37
38 struct InlineeSourceLine {
39   const InlineeSourceLineHeader *Header;
40   FixedStreamArray<support::ulittle32_t> ExtraFiles;
41 };
42 }
43
44 template <> struct VarStreamArrayExtractor<codeview::InlineeSourceLine> {
45   typedef bool ContextType;
46
47   static Error extract(BinaryStreamRef Stream, uint32_t &Len,
48                        codeview::InlineeSourceLine &Item, bool HasExtraFiles);
49 };
50
51 namespace codeview {
52 class ModuleDebugInlineeLineFragmentRef final : public ModuleDebugFragmentRef {
53   typedef VarStreamArray<InlineeSourceLine> LinesArray;
54   typedef LinesArray::Iterator Iterator;
55
56 public:
57   ModuleDebugInlineeLineFragmentRef();
58
59   static bool classof(const ModuleDebugFragmentRef *S) {
60     return S->kind() == ModuleDebugFragmentKind::InlineeLines;
61   }
62
63   Error initialize(BinaryStreamReader Reader);
64   bool hasExtraFiles() const;
65
66   Iterator begin() const { return Lines.begin(); }
67   Iterator end() const { return Lines.end(); }
68
69 private:
70   InlineeLinesSignature Signature;
71   VarStreamArray<InlineeSourceLine> Lines;
72 };
73
74 class ModuleDebugInlineeLineFragment final : public ModuleDebugFragment {
75 public:
76   explicit ModuleDebugInlineeLineFragment(bool HasExtraFiles);
77
78   static bool classof(const ModuleDebugFragment *S) {
79     return S->kind() == ModuleDebugFragmentKind::InlineeLines;
80   }
81
82   Error commit(BinaryStreamWriter &Writer) override;
83   uint32_t calculateSerializedLength() override;
84
85   void addInlineSite(TypeIndex FuncId, uint32_t FileOffset,
86                      uint32_t SourceLine);
87   void addExtraFile(uint32_t FileOffset);
88
89 private:
90   bool HasExtraFiles = false;
91   uint32_t ExtraFileCount = 0;
92
93   struct Entry {
94     std::vector<support::ulittle32_t> ExtraFiles;
95     InlineeSourceLineHeader Header;
96   };
97   std::vector<Entry> Entries;
98 };
99 }
100 }
101
102 #endif