1 //===- DWARFDebugMacro.cpp ------------------------------------------------===// 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 #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h" 10 #include "llvm/BinaryFormat/Dwarf.h" 11 #include "llvm/Support/WithColor.h" 12 #include "llvm/Support/raw_ostream.h" 13 #include <cstdint> 14 15 using namespace llvm; 16 using namespace dwarf; 17 18 void DWARFDebugMacro::dump(raw_ostream &OS) const { 19 unsigned IndLevel = 0; 20 for (const auto &Macros : MacroLists) { 21 for (const Entry &E : Macros) { 22 // There should not be DW_MACINFO_end_file when IndLevel is Zero. However, 23 // this check handles the case of corrupted ".debug_macinfo" section. 24 if (IndLevel > 0) 25 IndLevel -= (E.Type == DW_MACINFO_end_file); 26 // Print indentation. 27 for (unsigned I = 0; I < IndLevel; I++) 28 OS << " "; 29 IndLevel += (E.Type == DW_MACINFO_start_file); 30 31 WithColor(OS, HighlightColor::Macro).get() << MacinfoString(E.Type); 32 switch (E.Type) { 33 default: 34 // Got a corrupted ".debug_macinfo" section (invalid macinfo type). 35 break; 36 case DW_MACINFO_define: 37 case DW_MACINFO_undef: 38 OS << " - lineno: " << E.Line; 39 OS << " macro: " << E.MacroStr; 40 break; 41 case DW_MACINFO_start_file: 42 OS << " - lineno: " << E.Line; 43 OS << " filenum: " << E.File; 44 break; 45 case DW_MACINFO_end_file: 46 break; 47 case DW_MACINFO_vendor_ext: 48 OS << " - constant: " << E.ExtConstant; 49 OS << " string: " << E.ExtStr; 50 break; 51 } 52 OS << "\n"; 53 } 54 OS << "\n"; 55 } 56 } 57 58 void DWARFDebugMacro::parse(DataExtractor data) { 59 uint64_t Offset = 0; 60 MacroList *M = nullptr; 61 while (data.isValidOffset(Offset)) { 62 if (!M) { 63 MacroLists.emplace_back(); 64 M = &MacroLists.back(); 65 } 66 // A macro list entry consists of: 67 M->emplace_back(); 68 Entry &E = M->back(); 69 // 1. Macinfo type 70 E.Type = data.getULEB128(&Offset); 71 72 if (E.Type == 0) { 73 // Reached end of a ".debug_macinfo" section contribution. 74 continue; 75 } 76 77 switch (E.Type) { 78 default: 79 // Got a corrupted ".debug_macinfo" section (invalid macinfo type). 80 // Push the corrupted entry to the list and halt parsing. 81 E.Type = DW_MACINFO_invalid; 82 return; 83 case DW_MACINFO_define: 84 case DW_MACINFO_undef: 85 // 2. Source line 86 E.Line = data.getULEB128(&Offset); 87 // 3. Macro string 88 E.MacroStr = data.getCStr(&Offset); 89 break; 90 case DW_MACINFO_start_file: 91 // 2. Source line 92 E.Line = data.getULEB128(&Offset); 93 // 3. Source file id 94 E.File = data.getULEB128(&Offset); 95 break; 96 case DW_MACINFO_end_file: 97 break; 98 case DW_MACINFO_vendor_ext: 99 // 2. Vendor extension constant 100 E.ExtConstant = data.getULEB128(&Offset); 101 // 3. Vendor extension string 102 E.ExtStr = data.getCStr(&Offset); 103 break; 104 } 105 } 106 } 107