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