Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:39

0001 //===- DebugLinesSubsection.h -----------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGLINESSUBSECTION_H
0010 #define LLVM_DEBUGINFO_CODEVIEW_DEBUGLINESSUBSECTION_H
0011 
0012 #include "llvm/ADT/StringRef.h"
0013 #include "llvm/DebugInfo/CodeView/CodeView.h"
0014 #include "llvm/DebugInfo/CodeView/DebugSubsection.h"
0015 #include "llvm/DebugInfo/CodeView/Line.h"
0016 #include "llvm/Support/BinaryStreamArray.h"
0017 #include "llvm/Support/BinaryStreamRef.h"
0018 #include "llvm/Support/Endian.h"
0019 #include "llvm/Support/Error.h"
0020 #include <cstdint>
0021 #include <vector>
0022 
0023 namespace llvm {
0024 class BinaryStreamReader;
0025 class BinaryStreamWriter;
0026 namespace codeview {
0027 
0028 class DebugChecksumsSubsection;
0029 class DebugStringTableSubsection;
0030 
0031 // Corresponds to the `CV_DebugSLinesHeader_t` structure.
0032 struct LineFragmentHeader {
0033   support::ulittle32_t RelocOffset;  // Code offset of line contribution.
0034   support::ulittle16_t RelocSegment; // Code segment of line contribution.
0035   support::ulittle16_t Flags;        // See LineFlags enumeration.
0036   support::ulittle32_t CodeSize;     // Code size of this line contribution.
0037 };
0038 
0039 // Corresponds to the `CV_DebugSLinesFileBlockHeader_t` structure.
0040 struct LineBlockFragmentHeader {
0041   support::ulittle32_t NameIndex; // Offset of FileChecksum entry in File
0042                                   // checksums buffer.  The checksum entry then
0043                                   // contains another offset into the string
0044                                   // table of the actual name.
0045   support::ulittle32_t NumLines;  // Number of lines
0046   support::ulittle32_t BlockSize; // Code size of block, in bytes.
0047   // The following two variable length arrays appear immediately after the
0048   // header.  The structure definitions follow.
0049   // LineNumberEntry   Lines[NumLines];
0050   // ColumnNumberEntry Columns[NumLines];
0051 };
0052 
0053 // Corresponds to `CV_Line_t` structure
0054 struct LineNumberEntry {
0055   support::ulittle32_t Offset; // Offset to start of code bytes for line number
0056   support::ulittle32_t Flags;  // Start:24, End:7, IsStatement:1
0057 };
0058 
0059 // Corresponds to `CV_Column_t` structure
0060 struct ColumnNumberEntry {
0061   support::ulittle16_t StartColumn;
0062   support::ulittle16_t EndColumn;
0063 };
0064 
0065 struct LineColumnEntry {
0066   support::ulittle32_t NameIndex;
0067   FixedStreamArray<LineNumberEntry> LineNumbers;
0068   FixedStreamArray<ColumnNumberEntry> Columns;
0069 };
0070 
0071 class LineColumnExtractor {
0072 public:
0073   Error operator()(BinaryStreamRef Stream, uint32_t &Len,
0074                    LineColumnEntry &Item);
0075 
0076   const LineFragmentHeader *Header = nullptr;
0077 };
0078 
0079 class DebugLinesSubsectionRef final : public DebugSubsectionRef {
0080   friend class LineColumnExtractor;
0081 
0082   using LineInfoArray = VarStreamArray<LineColumnEntry, LineColumnExtractor>;
0083   using Iterator = LineInfoArray::Iterator;
0084 
0085 public:
0086   DebugLinesSubsectionRef();
0087 
0088   static bool classof(const DebugSubsectionRef *S) {
0089     return S->kind() == DebugSubsectionKind::Lines;
0090   }
0091 
0092   Error initialize(BinaryStreamReader Reader);
0093 
0094   Iterator begin() const { return LinesAndColumns.begin(); }
0095   Iterator end() const { return LinesAndColumns.end(); }
0096 
0097   const LineFragmentHeader *header() const { return Header; }
0098 
0099   bool hasColumnInfo() const;
0100 
0101 private:
0102   const LineFragmentHeader *Header = nullptr;
0103   LineInfoArray LinesAndColumns;
0104 };
0105 
0106 class DebugLinesSubsection final : public DebugSubsection {
0107   struct Block {
0108     Block(uint32_t ChecksumBufferOffset)
0109         : ChecksumBufferOffset(ChecksumBufferOffset) {}
0110 
0111     uint32_t ChecksumBufferOffset;
0112     std::vector<LineNumberEntry> Lines;
0113     std::vector<ColumnNumberEntry> Columns;
0114   };
0115 
0116 public:
0117   DebugLinesSubsection(DebugChecksumsSubsection &Checksums,
0118                        DebugStringTableSubsection &Strings);
0119 
0120   static bool classof(const DebugSubsection *S) {
0121     return S->kind() == DebugSubsectionKind::Lines;
0122   }
0123 
0124   void createBlock(StringRef FileName);
0125   void addLineInfo(uint32_t Offset, const LineInfo &Line);
0126   void addLineAndColumnInfo(uint32_t Offset, const LineInfo &Line,
0127                             uint32_t ColStart, uint32_t ColEnd);
0128 
0129   uint32_t calculateSerializedSize() const override;
0130   Error commit(BinaryStreamWriter &Writer) const override;
0131 
0132   void setRelocationAddress(uint16_t Segment, uint32_t Offset);
0133   void setCodeSize(uint32_t Size);
0134   void setFlags(LineFlags Flags);
0135 
0136   bool hasColumnInfo() const;
0137 
0138 private:
0139   DebugChecksumsSubsection &Checksums;
0140   uint32_t RelocOffset = 0;
0141   uint16_t RelocSegment = 0;
0142   uint32_t CodeSize = 0;
0143   LineFlags Flags = LF_None;
0144   std::vector<Block> Blocks;
0145 };
0146 
0147 } // end namespace codeview
0148 } // end namespace llvm
0149 
0150 #endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGLINESSUBSECTION_H