Line data Source code
1 : //===- ModuleDebugLineFragment.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_MODULEDEBUGLINEFRAGMENT_H
11 : #define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGLINEFRAGMENT_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 ModuleDebugFileChecksumFragment;
23 : class StringTable;
24 :
25 : // Corresponds to the `CV_DebugSLinesHeader_t` structure.
26 1 : struct LineFragmentHeader {
27 : support::ulittle32_t RelocOffset; // Code offset of line contribution.
28 : support::ulittle16_t RelocSegment; // Code segment of line contribution.
29 : support::ulittle16_t Flags; // See LineFlags enumeration.
30 : support::ulittle32_t CodeSize; // Code size of this line contribution.
31 : };
32 :
33 : // Corresponds to the `CV_DebugSLinesFileBlockHeader_t` structure.
34 1 : struct LineBlockFragmentHeader {
35 : support::ulittle32_t NameIndex; // Offset of FileChecksum entry in File
36 : // checksums buffer. The checksum entry then
37 : // contains another offset into the string
38 : // table of the actual name.
39 : support::ulittle32_t NumLines; // Number of lines
40 : support::ulittle32_t BlockSize; // Code size of block, in bytes.
41 : // The following two variable length arrays appear immediately after the
42 : // header. The structure definitions follow.
43 : // LineNumberEntry Lines[NumLines];
44 : // ColumnNumberEntry Columns[NumLines];
45 : };
46 :
47 : // Corresponds to `CV_Line_t` structure
48 3 : struct LineNumberEntry {
49 : support::ulittle32_t Offset; // Offset to start of code bytes for line number
50 : support::ulittle32_t Flags; // Start:24, End:7, IsStatement:1
51 : };
52 :
53 : // Corresponds to `CV_Column_t` structure
54 0 : struct ColumnNumberEntry {
55 : support::ulittle16_t StartColumn;
56 : support::ulittle16_t EndColumn;
57 : };
58 :
59 1416 : struct LineColumnEntry {
60 : support::ulittle32_t NameIndex;
61 : FixedStreamArray<LineNumberEntry> LineNumbers;
62 : FixedStreamArray<ColumnNumberEntry> Columns;
63 : };
64 :
65 : class LineColumnExtractor {
66 : public:
67 : typedef const LineFragmentHeader *ContextType;
68 :
69 : static Error extract(BinaryStreamRef Stream, uint32_t &Len,
70 : LineColumnEntry &Item, const LineFragmentHeader *Ctx);
71 : };
72 :
73 256 : class ModuleDebugLineFragmentRef final : public ModuleDebugFragmentRef {
74 : friend class LineColumnExtractor;
75 : typedef VarStreamArray<LineColumnEntry, LineColumnExtractor> LineInfoArray;
76 : typedef LineInfoArray::Iterator Iterator;
77 :
78 : public:
79 : ModuleDebugLineFragmentRef();
80 :
81 : static bool classof(const ModuleDebugFragmentRef *S) {
82 : return S->kind() == ModuleDebugFragmentKind::Lines;
83 : }
84 :
85 : Error initialize(BinaryStreamReader Reader);
86 :
87 118 : Iterator begin() const { return LinesAndColumns.begin(); }
88 236 : Iterator end() const { return LinesAndColumns.end(); }
89 :
90 : const LineFragmentHeader *header() const { return Header; }
91 :
92 : bool hasColumnInfo() const;
93 :
94 : private:
95 : const LineFragmentHeader *Header = nullptr;
96 : LineInfoArray LinesAndColumns;
97 : };
98 :
99 1 : class ModuleDebugLineFragment final : public ModuleDebugFragment {
100 3 : struct Block {
101 : Block(uint32_t ChecksumBufferOffset)
102 3 : : ChecksumBufferOffset(ChecksumBufferOffset) {}
103 :
104 : uint32_t ChecksumBufferOffset;
105 : std::vector<LineNumberEntry> Lines;
106 : std::vector<ColumnNumberEntry> Columns;
107 : };
108 :
109 : public:
110 : ModuleDebugLineFragment(ModuleDebugFileChecksumFragment &Checksums,
111 : StringTable &Strings);
112 :
113 : static bool classof(const ModuleDebugFragment *S) {
114 : return S->kind() == ModuleDebugFragmentKind::Lines;
115 : }
116 :
117 : void createBlock(StringRef FileName);
118 : void addLineInfo(uint32_t Offset, const LineInfo &Line);
119 : void addLineAndColumnInfo(uint32_t Offset, const LineInfo &Line,
120 : uint32_t ColStart, uint32_t ColEnd);
121 :
122 : uint32_t calculateSerializedLength() override;
123 : Error commit(BinaryStreamWriter &Writer) override;
124 :
125 : void setRelocationAddress(uint16_t Segment, uint16_t Offset);
126 : void setCodeSize(uint32_t Size);
127 : void setFlags(LineFlags Flags);
128 :
129 : bool hasColumnInfo() const;
130 :
131 : private:
132 : ModuleDebugFileChecksumFragment &Checksums;
133 :
134 : uint16_t RelocOffset = 0;
135 : uint16_t RelocSegment = 0;
136 : uint32_t CodeSize = 0;
137 : LineFlags Flags = LF_None;
138 : std::vector<Block> Blocks;
139 : };
140 : }
141 : }
142 :
143 : #endif
|