| //===- DebugLinesSubsection.h -----------------------------------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGLINESSUBSECTION_H |
| #define LLVM_DEBUGINFO_CODEVIEW_DEBUGLINESSUBSECTION_H |
| |
| #include "llvm/ADT/StringRef.h" |
| #include "llvm/DebugInfo/CodeView/CodeView.h" |
| #include "llvm/DebugInfo/CodeView/DebugSubsection.h" |
| #include "llvm/DebugInfo/CodeView/Line.h" |
| #include "llvm/Support/BinaryStreamArray.h" |
| #include "llvm/Support/BinaryStreamReader.h" |
| #include "llvm/Support/BinaryStreamRef.h" |
| #include "llvm/Support/Endian.h" |
| #include "llvm/Support/Error.h" |
| #include <cstdint> |
| #include <vector> |
| |
| namespace llvm { |
| namespace codeview { |
| |
| class DebugChecksumsSubsection; |
| class DebugStringTableSubsection; |
| |
| // Corresponds to the `CV_DebugSLinesHeader_t` structure. |
| struct LineFragmentHeader { |
| support::ulittle32_t RelocOffset; // Code offset of line contribution. |
| support::ulittle16_t RelocSegment; // Code segment of line contribution. |
| support::ulittle16_t Flags; // See LineFlags enumeration. |
| support::ulittle32_t CodeSize; // Code size of this line contribution. |
| }; |
| |
| // Corresponds to the `CV_DebugSLinesFileBlockHeader_t` structure. |
| struct LineBlockFragmentHeader { |
| support::ulittle32_t NameIndex; // Offset of FileChecksum entry in File |
| // checksums buffer. The checksum entry then |
| // contains another offset into the string |
| // table of the actual name. |
| support::ulittle32_t NumLines; // Number of lines |
| support::ulittle32_t BlockSize; // Code size of block, in bytes. |
| // The following two variable length arrays appear immediately after the |
| // header. The structure definitions follow. |
| // LineNumberEntry Lines[NumLines]; |
| // ColumnNumberEntry Columns[NumLines]; |
| }; |
| |
| // Corresponds to `CV_Line_t` structure |
| struct LineNumberEntry { |
| support::ulittle32_t Offset; // Offset to start of code bytes for line number |
| support::ulittle32_t Flags; // Start:24, End:7, IsStatement:1 |
| }; |
| |
| // Corresponds to `CV_Column_t` structure |
| struct ColumnNumberEntry { |
| support::ulittle16_t StartColumn; |
| support::ulittle16_t EndColumn; |
| }; |
| |
| struct LineColumnEntry { |
| support::ulittle32_t NameIndex; |
| FixedStreamArray<LineNumberEntry> LineNumbers; |
| FixedStreamArray<ColumnNumberEntry> Columns; |
| }; |
| |
| class LineColumnExtractor { |
| public: |
| Error operator()(BinaryStreamRef Stream, uint32_t &Len, |
| LineColumnEntry &Item); |
| |
| const LineFragmentHeader *Header = nullptr; |
| }; |
| |
| class DebugLinesSubsectionRef final : public DebugSubsectionRef { |
| friend class LineColumnExtractor; |
| |
| using LineInfoArray = VarStreamArray<LineColumnEntry, LineColumnExtractor>; |
| using Iterator = LineInfoArray::Iterator; |
| |
| public: |
| DebugLinesSubsectionRef(); |
| |
| static bool classof(const DebugSubsectionRef *S) { |
| return S->kind() == DebugSubsectionKind::Lines; |
| } |
| |
| Error initialize(BinaryStreamReader Reader); |
| |
| Iterator begin() const { return LinesAndColumns.begin(); } |
| Iterator end() const { return LinesAndColumns.end(); } |
| |
| const LineFragmentHeader *header() const { return Header; } |
| |
| bool hasColumnInfo() const; |
| |
| private: |
| const LineFragmentHeader *Header = nullptr; |
| LineInfoArray LinesAndColumns; |
| }; |
| |
| class DebugLinesSubsection final : public DebugSubsection { |
| struct Block { |
| Block(uint32_t ChecksumBufferOffset) |
| : ChecksumBufferOffset(ChecksumBufferOffset) {} |
| |
| uint32_t ChecksumBufferOffset; |
| std::vector<LineNumberEntry> Lines; |
| std::vector<ColumnNumberEntry> Columns; |
| }; |
| |
| public: |
| DebugLinesSubsection(DebugChecksumsSubsection &Checksums, |
| DebugStringTableSubsection &Strings); |
| |
| static bool classof(const DebugSubsection *S) { |
| return S->kind() == DebugSubsectionKind::Lines; |
| } |
| |
| void createBlock(StringRef FileName); |
| void addLineInfo(uint32_t Offset, const LineInfo &Line); |
| void addLineAndColumnInfo(uint32_t Offset, const LineInfo &Line, |
| uint32_t ColStart, uint32_t ColEnd); |
| |
| uint32_t calculateSerializedSize() const override; |
| Error commit(BinaryStreamWriter &Writer) const override; |
| |
| void setRelocationAddress(uint16_t Segment, uint32_t Offset); |
| void setCodeSize(uint32_t Size); |
| void setFlags(LineFlags Flags); |
| |
| bool hasColumnInfo() const; |
| |
| private: |
| DebugChecksumsSubsection &Checksums; |
| uint32_t RelocOffset = 0; |
| uint16_t RelocSegment = 0; |
| uint32_t CodeSize = 0; |
| LineFlags Flags = LF_None; |
| std::vector<Block> Blocks; |
| }; |
| |
| } // end namespace codeview |
| } // end namespace llvm |
| |
| #endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGLINESSUBSECTION_H |