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 25namespace llvm { 26namespace codeview { 27 28class DebugChecksumsSubsection; 29class DebugStringTableSubsection; 30 31// Corresponds to the `CV_DebugSLinesHeader_t` structure. 32struct 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. 40struct 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 54struct 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 60struct ColumnNumberEntry { 61 support::ulittle16_t StartColumn; 62 support::ulittle16_t EndColumn; 63}; 64 65struct LineColumnEntry { 66 support::ulittle32_t NameIndex; 67 FixedStreamArray<LineNumberEntry> LineNumbers; 68 FixedStreamArray<ColumnNumberEntry> Columns; 69}; 70 71class LineColumnExtractor { 72public: 73 Error operator()(BinaryStreamRef Stream, uint32_t &Len, 74 LineColumnEntry &Item); 75 76 const LineFragmentHeader *Header = nullptr; 77}; 78 79class DebugLinesSubsectionRef final : public DebugSubsectionRef { 80 friend class LineColumnExtractor; 81 82 using LineInfoArray = VarStreamArray<LineColumnEntry, LineColumnExtractor>; 83 using Iterator = LineInfoArray::Iterator; 84 85public: 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 Iterator begin() const { return LinesAndColumns.begin(); } 95 Iterator end() const { return LinesAndColumns.end(); } 96 97 const LineFragmentHeader *header() const { return Header; } 98 99 bool hasColumnInfo() const; 100 101private: 102 const LineFragmentHeader *Header = nullptr; 103 LineInfoArray LinesAndColumns; 104}; 105 106class DebugLinesSubsection final : public DebugSubsection { 107 struct Block { 108 Block(uint32_t ChecksumBufferOffset) 109 : ChecksumBufferOffset(ChecksumBufferOffset) {} 110 111 uint32_t ChecksumBufferOffset; 112 std::vector<LineNumberEntry> Lines; 113 std::vector<ColumnNumberEntry> Columns; 114 }; 115 116public: 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 138private: 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 151