DWARFDebugMacro.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- DWARFDebugMacro.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_DWARF_DWARFDEBUGMACRO_H
  14. #define LLVM_DEBUGINFO_DWARF_DWARFDEBUGMACRO_H
  15. #include "llvm/ADT/SmallVector.h"
  16. #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
  17. #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
  18. #include "llvm/Support/Error.h"
  19. #include <cstdint>
  20. namespace llvm {
  21. class raw_ostream;
  22. class DwarfStreamer;
  23. class DWARFDebugMacro {
  24. friend DwarfStreamer;
  25. /// DWARFv5 section 6.3.1 Macro Information Header.
  26. enum HeaderFlagMask {
  27. #define HANDLE_MACRO_FLAG(ID, NAME) MACRO_##NAME = ID,
  28. #include "llvm/BinaryFormat/Dwarf.def"
  29. };
  30. struct MacroHeader {
  31. /// Macro version information number.
  32. uint16_t Version = 0;
  33. /// The bits of the flags field are interpreted as a set of flags, some of
  34. /// which may indicate that additional fields follow. The following flags,
  35. /// beginning with the least significant bit, are defined:
  36. /// offset_size_flag:
  37. /// If the offset_size_flag is zero, the header is for a 32-bit DWARF
  38. /// format macro section and all offsets are 4 bytes long; if it is one,
  39. /// the header is for a 64-bit DWARF format macro section and all offsets
  40. /// are 8 bytes long.
  41. /// debug_line_offset_flag:
  42. /// If the debug_line_offset_flag is one, the debug_line_offset field (see
  43. /// below) is present. If zero, that field is omitted.
  44. /// opcode_operands_table_flag:
  45. /// If the opcode_operands_table_flag is one, the opcode_operands_table
  46. /// field (see below) is present. If zero, that field is omitted.
  47. uint8_t Flags = 0;
  48. /// debug_line_offset
  49. /// An offset in the .debug_line section of the beginning of the line
  50. /// number information in the containing compilation unit, encoded as a
  51. /// 4-byte offset for a 32-bit DWARF format macro section and an 8-byte
  52. /// offset for a 64-bit DWARF format macro section.
  53. uint64_t DebugLineOffset;
  54. /// Print the macro header from the debug_macro section.
  55. void dumpMacroHeader(raw_ostream &OS) const;
  56. /// Parse the debug_macro header.
  57. Error parseMacroHeader(DWARFDataExtractor Data, uint64_t *Offset);
  58. /// Get the DWARF format according to the flags.
  59. dwarf::DwarfFormat getDwarfFormat() const;
  60. /// Get the size of a reference according to the DWARF format.
  61. uint8_t getOffsetByteSize() const;
  62. };
  63. /// A single macro entry within a macro list.
  64. struct Entry {
  65. /// The type of the macro entry.
  66. uint32_t Type;
  67. union {
  68. /// The source line where the macro is defined.
  69. uint64_t Line;
  70. /// Vendor extension constant value.
  71. uint64_t ExtConstant;
  72. /// Macro unit import offset.
  73. uint64_t ImportOffset;
  74. };
  75. union {
  76. /// The string (name, value) of the macro entry.
  77. const char *MacroStr;
  78. // An unsigned integer indicating the identity of the source file.
  79. uint64_t File;
  80. /// Vendor extension string.
  81. const char *ExtStr;
  82. };
  83. };
  84. struct MacroList {
  85. // A value 0 in the `Header.Version` field indicates that we're parsing
  86. // a macinfo[.dwo] section which doesn't have header itself, hence
  87. // for that case other fields in the `Header` are uninitialized.
  88. MacroHeader Header;
  89. SmallVector<Entry, 4> Macros;
  90. uint64_t Offset;
  91. /// Whether or not this is a .debug_macro section.
  92. bool IsDebugMacro;
  93. };
  94. /// A list of all the macro entries in the debug_macinfo section.
  95. std::vector<MacroList> MacroLists;
  96. public:
  97. DWARFDebugMacro() = default;
  98. /// Print the macro list found within the debug_macinfo/debug_macro section.
  99. void dump(raw_ostream &OS) const;
  100. Error parseMacro(DWARFUnitVector::compile_unit_range Units,
  101. DataExtractor StringExtractor,
  102. DWARFDataExtractor MacroData) {
  103. return parseImpl(Units, StringExtractor, MacroData, /*IsMacro=*/true);
  104. }
  105. Error parseMacinfo(DWARFDataExtractor MacroData) {
  106. return parseImpl(std::nullopt, std::nullopt, MacroData, /*IsMacro=*/false);
  107. }
  108. /// Return whether the section has any entries.
  109. bool empty() const { return MacroLists.empty(); }
  110. bool hasEntryForOffset(uint64_t Offset) const {
  111. for (const MacroList &List : MacroLists)
  112. if (Offset == List.Offset)
  113. return true;
  114. return false;
  115. }
  116. private:
  117. /// Parse the debug_macinfo/debug_macro section accessible via the 'MacroData'
  118. /// parameter.
  119. Error parseImpl(std::optional<DWARFUnitVector::compile_unit_range> Units,
  120. std::optional<DataExtractor> StringExtractor,
  121. DWARFDataExtractor Data, bool IsMacro);
  122. };
  123. } // end namespace llvm
  124. #endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGMACRO_H
  125. #ifdef __GNUC__
  126. #pragma GCC diagnostic pop
  127. #endif