10b57cec5SDimitry Andric //===- DWARFDebugMacro.h ----------------------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGMACRO_H 100b57cec5SDimitry Andric #define LLVM_DEBUGINFO_DWARF_DWARFDEBUGMACRO_H 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 135ffd83dbSDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" 145ffd83dbSDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFUnit.h" 155ffd83dbSDimitry Andric #include "llvm/Support/Error.h" 160b57cec5SDimitry Andric #include <cstdint> 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric namespace llvm { 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric class raw_ostream; 211db9f3b2SDimitry Andric 221db9f3b2SDimitry Andric namespace dwarf_linker { 231db9f3b2SDimitry Andric namespace classic { 24bdd1243dSDimitry Andric class DwarfStreamer; 251db9f3b2SDimitry Andric } 261db9f3b2SDimitry Andric } // namespace dwarf_linker 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric class DWARFDebugMacro { 291db9f3b2SDimitry Andric friend dwarf_linker::classic::DwarfStreamer; 301db9f3b2SDimitry Andric friend dwarf_linker::parallel::CompileUnit; 31bdd1243dSDimitry Andric 325ffd83dbSDimitry Andric /// DWARFv5 section 6.3.1 Macro Information Header. 335ffd83dbSDimitry Andric enum HeaderFlagMask { 345ffd83dbSDimitry Andric #define HANDLE_MACRO_FLAG(ID, NAME) MACRO_##NAME = ID, 355ffd83dbSDimitry Andric #include "llvm/BinaryFormat/Dwarf.def" 365ffd83dbSDimitry Andric }; 375ffd83dbSDimitry Andric struct MacroHeader { 385ffd83dbSDimitry Andric /// Macro version information number. 395ffd83dbSDimitry Andric uint16_t Version = 0; 405ffd83dbSDimitry Andric 415ffd83dbSDimitry Andric /// The bits of the flags field are interpreted as a set of flags, some of 425ffd83dbSDimitry Andric /// which may indicate that additional fields follow. The following flags, 435ffd83dbSDimitry Andric /// beginning with the least significant bit, are defined: 445ffd83dbSDimitry Andric /// offset_size_flag: 455ffd83dbSDimitry Andric /// If the offset_size_flag is zero, the header is for a 32-bit DWARF 465ffd83dbSDimitry Andric /// format macro section and all offsets are 4 bytes long; if it is one, 475ffd83dbSDimitry Andric /// the header is for a 64-bit DWARF format macro section and all offsets 485ffd83dbSDimitry Andric /// are 8 bytes long. 495ffd83dbSDimitry Andric /// debug_line_offset_flag: 505ffd83dbSDimitry Andric /// If the debug_line_offset_flag is one, the debug_line_offset field (see 515ffd83dbSDimitry Andric /// below) is present. If zero, that field is omitted. 525ffd83dbSDimitry Andric /// opcode_operands_table_flag: 535ffd83dbSDimitry Andric /// If the opcode_operands_table_flag is one, the opcode_operands_table 545ffd83dbSDimitry Andric /// field (see below) is present. If zero, that field is omitted. 555ffd83dbSDimitry Andric uint8_t Flags = 0; 565ffd83dbSDimitry Andric 575ffd83dbSDimitry Andric /// debug_line_offset 585ffd83dbSDimitry Andric /// An offset in the .debug_line section of the beginning of the line 595ffd83dbSDimitry Andric /// number information in the containing compilation unit, encoded as a 605ffd83dbSDimitry Andric /// 4-byte offset for a 32-bit DWARF format macro section and an 8-byte 615ffd83dbSDimitry Andric /// offset for a 64-bit DWARF format macro section. 625ffd83dbSDimitry Andric uint64_t DebugLineOffset; 635ffd83dbSDimitry Andric 645ffd83dbSDimitry Andric /// Print the macro header from the debug_macro section. 655ffd83dbSDimitry Andric void dumpMacroHeader(raw_ostream &OS) const; 665ffd83dbSDimitry Andric 675ffd83dbSDimitry Andric /// Parse the debug_macro header. 685ffd83dbSDimitry Andric Error parseMacroHeader(DWARFDataExtractor Data, uint64_t *Offset); 695ffd83dbSDimitry Andric 705ffd83dbSDimitry Andric /// Get the DWARF format according to the flags. 715ffd83dbSDimitry Andric dwarf::DwarfFormat getDwarfFormat() const; 725ffd83dbSDimitry Andric 735ffd83dbSDimitry Andric /// Get the size of a reference according to the DWARF format. 745ffd83dbSDimitry Andric uint8_t getOffsetByteSize() const; 755ffd83dbSDimitry Andric }; 765ffd83dbSDimitry Andric 770b57cec5SDimitry Andric /// A single macro entry within a macro list. 780b57cec5SDimitry Andric struct Entry { 790b57cec5SDimitry Andric /// The type of the macro entry. 800b57cec5SDimitry Andric uint32_t Type; 810b57cec5SDimitry Andric union { 820b57cec5SDimitry Andric /// The source line where the macro is defined. 830b57cec5SDimitry Andric uint64_t Line; 840b57cec5SDimitry Andric /// Vendor extension constant value. 850b57cec5SDimitry Andric uint64_t ExtConstant; 865ffd83dbSDimitry Andric /// Macro unit import offset. 875ffd83dbSDimitry Andric uint64_t ImportOffset; 880b57cec5SDimitry Andric }; 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric union { 910b57cec5SDimitry Andric /// The string (name, value) of the macro entry. 920b57cec5SDimitry Andric const char *MacroStr; 930b57cec5SDimitry Andric // An unsigned integer indicating the identity of the source file. 940b57cec5SDimitry Andric uint64_t File; 950b57cec5SDimitry Andric /// Vendor extension string. 960b57cec5SDimitry Andric const char *ExtStr; 970b57cec5SDimitry Andric }; 980b57cec5SDimitry Andric }; 990b57cec5SDimitry Andric 1005ffd83dbSDimitry Andric struct MacroList { 1015ffd83dbSDimitry Andric // A value 0 in the `Header.Version` field indicates that we're parsing 1025ffd83dbSDimitry Andric // a macinfo[.dwo] section which doesn't have header itself, hence 1035ffd83dbSDimitry Andric // for that case other fields in the `Header` are uninitialized. 1045ffd83dbSDimitry Andric MacroHeader Header; 1055ffd83dbSDimitry Andric SmallVector<Entry, 4> Macros; 1065ffd83dbSDimitry Andric uint64_t Offset; 107e8d8bef9SDimitry Andric 108e8d8bef9SDimitry Andric /// Whether or not this is a .debug_macro section. 109e8d8bef9SDimitry Andric bool IsDebugMacro; 1105ffd83dbSDimitry Andric }; 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric /// A list of all the macro entries in the debug_macinfo section. 113480093f4SDimitry Andric std::vector<MacroList> MacroLists; 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andric public: 1160b57cec5SDimitry Andric DWARFDebugMacro() = default; 1170b57cec5SDimitry Andric 1185ffd83dbSDimitry Andric /// Print the macro list found within the debug_macinfo/debug_macro section. 1190b57cec5SDimitry Andric void dump(raw_ostream &OS) const; 1200b57cec5SDimitry Andric parseMacro(DWARFUnitVector::compile_unit_range Units,DataExtractor StringExtractor,DWARFDataExtractor MacroData)121e8d8bef9SDimitry Andric Error parseMacro(DWARFUnitVector::compile_unit_range Units, 1225ffd83dbSDimitry Andric DataExtractor StringExtractor, 1235ffd83dbSDimitry Andric DWARFDataExtractor MacroData) { 1245ffd83dbSDimitry Andric return parseImpl(Units, StringExtractor, MacroData, /*IsMacro=*/true); 1255ffd83dbSDimitry Andric } 1265ffd83dbSDimitry Andric parseMacinfo(DWARFDataExtractor MacroData)1275ffd83dbSDimitry Andric Error parseMacinfo(DWARFDataExtractor MacroData) { 128bdd1243dSDimitry Andric return parseImpl(std::nullopt, std::nullopt, MacroData, /*IsMacro=*/false); 1295ffd83dbSDimitry Andric } 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric /// Return whether the section has any entries. empty()132480093f4SDimitry Andric bool empty() const { return MacroLists.empty(); } 1335ffd83dbSDimitry Andric hasEntryForOffset(uint64_t Offset)134bdd1243dSDimitry Andric bool hasEntryForOffset(uint64_t Offset) const { 135bdd1243dSDimitry Andric for (const MacroList &List : MacroLists) 136bdd1243dSDimitry Andric if (Offset == List.Offset) 137bdd1243dSDimitry Andric return true; 138bdd1243dSDimitry Andric 139bdd1243dSDimitry Andric return false; 140bdd1243dSDimitry Andric } 141bdd1243dSDimitry Andric 1425ffd83dbSDimitry Andric private: 1435ffd83dbSDimitry Andric /// Parse the debug_macinfo/debug_macro section accessible via the 'MacroData' 1445ffd83dbSDimitry Andric /// parameter. 145bdd1243dSDimitry Andric Error parseImpl(std::optional<DWARFUnitVector::compile_unit_range> Units, 146bdd1243dSDimitry Andric std::optional<DataExtractor> StringExtractor, 1475ffd83dbSDimitry Andric DWARFDataExtractor Data, bool IsMacro); 1480b57cec5SDimitry Andric }; 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric } // end namespace llvm 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric #endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGMACRO_H 153