DebugLinesSubsection.h 4.9 KB

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