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