DebugLinesSubsection.h 4.8 KB

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