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