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