1 //===-- DWARFDebugMacro.cpp -----------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
11 #include "SyntaxHighlighting.h"
12 #include "llvm/Support/Dwarf.h"
13 #include "llvm/Support/Format.h"
14 #include "llvm/Support/raw_ostream.h"
15 
16 using namespace llvm;
17 using namespace dwarf;
18 using namespace syntax;
19 
dump(raw_ostream & OS) const20 void DWARFDebugMacro::dump(raw_ostream &OS) const {
21   unsigned IndLevel = 0;
22   for (const Entry &E : 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, syntax::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 
parse(DataExtractor data)57 void DWARFDebugMacro::parse(DataExtractor data) {
58   uint32_t Offset = 0;
59   while (data.isValidOffset(Offset)) {
60     // A macro list entry consists of:
61     Entry E;
62     // 1. Macinfo type
63     E.Type = data.getULEB128(&Offset);
64 
65     if (E.Type == 0) {
66       // Reached end of ".debug_macinfo" section.
67       return;
68     }
69 
70     switch (E.Type) {
71     default:
72       // Got a corrupted ".debug_macinfo" section (invalid macinfo type).
73       // Push the corrupted entry to the list and halt parsing.
74       E.Type = DW_MACINFO_invalid;
75       Macros.push_back(E);
76       return;
77     case DW_MACINFO_define:
78     case DW_MACINFO_undef:
79       // 2. Source line
80       E.Line = data.getULEB128(&Offset);
81       // 3. Macro string
82       E.MacroStr = data.getCStr(&Offset);
83       break;
84     case DW_MACINFO_start_file:
85       // 2. Source line
86       E.Line = data.getULEB128(&Offset);
87       // 3. Source file id
88       E.File = data.getULEB128(&Offset);
89       break;
90     case DW_MACINFO_end_file:
91       break;
92     case DW_MACINFO_vendor_ext:
93       // 2. Vendor extension constant
94       E.ExtConstant = data.getULEB128(&Offset);
95       // 3. Vendor extension string
96       E.ExtStr = data.getCStr(&Offset);
97       break;
98     }
99 
100     Macros.push_back(E);
101   }
102 }
103