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_MODULEDEBUGLINEFRAGMENT_H 11#define LLVM_DEBUGINFO_CODEVIEW_MODULEDEBUGLINEFRAGMENT_H 12 13#include "llvm/DebugInfo/CodeView/DebugSubsection.h" 14#include "llvm/DebugInfo/CodeView/Line.h" 15#include "llvm/Support/BinaryStreamArray.h" 16#include "llvm/Support/BinaryStreamReader.h" 17#include "llvm/Support/Error.h" 18 19namespace llvm { 20namespace codeview { 21 22class DebugChecksumsSubsection; 23class DebugStringTableSubsection; 24 25// Corresponds to the `CV_DebugSLinesHeader_t` structure. 26struct 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. 34struct 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 48struct 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 54struct ColumnNumberEntry { 55 support::ulittle16_t StartColumn; 56 support::ulittle16_t EndColumn; 57}; 58 59struct LineColumnEntry { 60 support::ulittle32_t NameIndex; 61 FixedStreamArray<LineNumberEntry> LineNumbers; 62 FixedStreamArray<ColumnNumberEntry> Columns; 63}; 64 65class LineColumnExtractor { 66public: 67 Error operator()(BinaryStreamRef Stream, uint32_t &Len, 68 LineColumnEntry &Item); 69 70 const LineFragmentHeader *Header = nullptr; 71}; 72 73class DebugLinesSubsectionRef final : public DebugSubsectionRef { 74 friend class LineColumnExtractor; 75 typedef VarStreamArray<LineColumnEntry, LineColumnExtractor> LineInfoArray; 76 typedef LineInfoArray::Iterator Iterator; 77 78public: 79 DebugLinesSubsectionRef(); 80 81 static bool classof(const DebugSubsectionRef *S) { 82 return S->kind() == DebugSubsectionKind::Lines; 83 } 84 85 Error initialize(BinaryStreamReader Reader); 86 87 Iterator begin() const { return LinesAndColumns.begin(); } 88 Iterator end() const { return LinesAndColumns.end(); } 89 90 const LineFragmentHeader *header() const { return Header; } 91 92 bool hasColumnInfo() const; 93 94private: 95 const LineFragmentHeader *Header = nullptr; 96 LineInfoArray LinesAndColumns; 97}; 98 99class DebugLinesSubsection final : public DebugSubsection { 100 struct Block { 101 Block(uint32_t ChecksumBufferOffset) 102 : ChecksumBufferOffset(ChecksumBufferOffset) {} 103 104 uint32_t ChecksumBufferOffset; 105 std::vector<LineNumberEntry> Lines; 106 std::vector<ColumnNumberEntry> Columns; 107 }; 108 109public: 110 DebugLinesSubsection(DebugChecksumsSubsection &Checksums, 111 DebugStringTableSubsection &Strings); 112 113 static bool classof(const DebugSubsection *S) { 114 return S->kind() == DebugSubsectionKind::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 calculateSerializedSize() const override; 123 Error commit(BinaryStreamWriter &Writer) const override; 124 125 void setRelocationAddress(uint16_t Segment, uint32_t Offset); 126 void setCodeSize(uint32_t Size); 127 void setFlags(LineFlags Flags); 128 129 bool hasColumnInfo() const; 130 131private: 132 DebugChecksumsSubsection &Checksums; 133 134 uint32_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 144