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 OS << format("0x%08" PRIx64 ":\n", Macros.Offset); 22 for (const Entry &E : Macros.Macros) { 23 // There should not be DW_MACINFO_end_file when IndLevel is Zero. However, 24 // this check handles the case of corrupted ".debug_macinfo" section. 25 if (IndLevel > 0) 26 IndLevel -= (E.Type == DW_MACINFO_end_file); 27 // Print indentation. 28 for (unsigned I = 0; I < IndLevel; I++) 29 OS << " "; 30 IndLevel += (E.Type == DW_MACINFO_start_file); 31 32 WithColor(OS, HighlightColor::Macro).get() << MacinfoString(E.Type); 33 switch (E.Type) { 34 default: 35 // Got a corrupted ".debug_macinfo" section (invalid macinfo type). 36 break; 37 case DW_MACINFO_define: 38 case DW_MACINFO_undef: 39 OS << " - lineno: " << E.Line; 40 OS << " macro: " << E.MacroStr; 41 break; 42 case DW_MACINFO_start_file: 43 OS << " - lineno: " << E.Line; 44 OS << " filenum: " << E.File; 45 break; 46 case DW_MACINFO_end_file: 47 break; 48 case DW_MACINFO_vendor_ext: 49 OS << " - constant: " << E.ExtConstant; 50 OS << " string: " << E.ExtStr; 51 break; 52 } 53 OS << "\n"; 54 } 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 M->Offset = Offset; 66 } 67 // A macro list entry consists of: 68 M->Macros.emplace_back(); 69 Entry &E = M->Macros.back(); 70 // 1. Macinfo type 71 E.Type = data.getULEB128(&Offset); 72 73 if (E.Type == 0) { 74 // Reached end of a ".debug_macinfo" section contribution. 75 M = nullptr; 76 continue; 77 } 78 79 switch (E.Type) { 80 default: 81 // Got a corrupted ".debug_macinfo" section (invalid macinfo type). 82 // Push the corrupted entry to the list and halt parsing. 83 E.Type = DW_MACINFO_invalid; 84 return; 85 case DW_MACINFO_define: 86 case DW_MACINFO_undef: 87 // 2. Source line 88 E.Line = data.getULEB128(&Offset); 89 // 3. Macro string 90 E.MacroStr = data.getCStr(&Offset); 91 break; 92 case DW_MACINFO_start_file: 93 // 2. Source line 94 E.Line = data.getULEB128(&Offset); 95 // 3. Source file id 96 E.File = data.getULEB128(&Offset); 97 break; 98 case DW_MACINFO_end_file: 99 break; 100 case DW_MACINFO_vendor_ext: 101 // 2. Vendor extension constant 102 E.ExtConstant = data.getULEB128(&Offset); 103 // 3. Vendor extension string 104 E.ExtStr = data.getCStr(&Offset); 105 break; 106 } 107 } 108 } 109