| //===- DWARFDebugMacro.cpp ------------------------------------------------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h" | |
| #include "llvm/BinaryFormat/Dwarf.h" | |
| #include "llvm/Support/WithColor.h" | |
| #include "llvm/Support/raw_ostream.h" | |
| #include <cstdint> | |
| using namespace llvm; | |
| using namespace dwarf; | |
| void DWARFDebugMacro::dump(raw_ostream &OS) const { | |
| unsigned IndLevel = 0; | |
| for (const auto &Macros : MacroLists) { | |
| for (const Entry &E : Macros) { | |
| // There should not be DW_MACINFO_end_file when IndLevel is Zero. However, | |
| // this check handles the case of corrupted ".debug_macinfo" section. | |
| if (IndLevel > 0) | |
| IndLevel -= (E.Type == DW_MACINFO_end_file); | |
| // Print indentation. | |
| for (unsigned I = 0; I < IndLevel; I++) | |
| OS << " "; | |
| IndLevel += (E.Type == DW_MACINFO_start_file); | |
| WithColor(OS, HighlightColor::Macro).get() << MacinfoString(E.Type); | |
| switch (E.Type) { | |
| default: | |
| // Got a corrupted ".debug_macinfo" section (invalid macinfo type). | |
| break; | |
| case DW_MACINFO_define: | |
| case DW_MACINFO_undef: | |
| OS << " - lineno: " << E.Line; | |
| OS << " macro: " << E.MacroStr; | |
| break; | |
| case DW_MACINFO_start_file: | |
| OS << " - lineno: " << E.Line; | |
| OS << " filenum: " << E.File; | |
| break; | |
| case DW_MACINFO_end_file: | |
| break; | |
| case DW_MACINFO_vendor_ext: | |
| OS << " - constant: " << E.ExtConstant; | |
| OS << " string: " << E.ExtStr; | |
| break; | |
| } | |
| OS << "\n"; | |
| } | |
| OS << "\n"; | |
| } | |
| } | |
| void DWARFDebugMacro::parse(DataExtractor data) { | |
| uint64_t Offset = 0; | |
| MacroList *M = nullptr; | |
| while (data.isValidOffset(Offset)) { | |
| if (!M) { | |
| MacroLists.emplace_back(); | |
| M = &MacroLists.back(); | |
| } | |
| // A macro list entry consists of: | |
| M->emplace_back(); | |
| Entry &E = M->back(); | |
| // 1. Macinfo type | |
| E.Type = data.getULEB128(&Offset); | |
| if (E.Type == 0) { | |
| // Reached end of a ".debug_macinfo" section contribution. | |
| continue; | |
| } | |
| switch (E.Type) { | |
| default: | |
| // Got a corrupted ".debug_macinfo" section (invalid macinfo type). | |
| // Push the corrupted entry to the list and halt parsing. | |
| E.Type = DW_MACINFO_invalid; | |
| return; | |
| case DW_MACINFO_define: | |
| case DW_MACINFO_undef: | |
| // 2. Source line | |
| E.Line = data.getULEB128(&Offset); | |
| // 3. Macro string | |
| E.MacroStr = data.getCStr(&Offset); | |
| break; | |
| case DW_MACINFO_start_file: | |
| // 2. Source line | |
| E.Line = data.getULEB128(&Offset); | |
| // 3. Source file id | |
| E.File = data.getULEB128(&Offset); | |
| break; | |
| case DW_MACINFO_end_file: | |
| break; | |
| case DW_MACINFO_vendor_ext: | |
| // 2. Vendor extension constant | |
| E.ExtConstant = data.getULEB128(&Offset); | |
| // 3. Vendor extension string | |
| E.ExtStr = data.getCStr(&Offset); | |
| break; | |
| } | |
| } | |
| } |