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
19namespace llvm {
20
21class raw_ostream;
22
23class 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
107public:
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
126private:
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