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