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