Line data Source code
1 : //===--- DWARFVisitor.cpp ---------------------------------------*- C++ -*-===//
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 : //===----------------------------------------------------------------------===//
11 :
12 : #include "DWARFVisitor.h"
13 : #include "llvm/ObjectYAML/DWARFYAML.h"
14 :
15 : using namespace llvm;
16 :
17 : template <typename T>
18 114 : void DWARFYAML::VisitorImpl<T>::onVariableSizeValue(uint64_t U, unsigned Size) {
19 114 : switch (Size) {
20 43 : case 8:
21 43 : onValue((uint64_t)U);
22 43 : break;
23 71 : case 4:
24 71 : onValue((uint32_t)U);
25 71 : break;
26 0 : case 2:
27 0 : onValue((uint16_t)U);
28 0 : break;
29 0 : case 1:
30 0 : onValue((uint8_t)U);
31 0 : break;
32 0 : default:
33 0 : llvm_unreachable("Invalid integer write size.");
34 : }
35 114 : }
36 114 :
37 114 : static unsigned getOffsetSize(const DWARFYAML::Unit &Unit) {
38 43 : return Unit.Length.isDWARF64() ? 8 : 4;
39 43 : }
40 43 :
41 71 : static unsigned getRefSize(const DWARFYAML::Unit &Unit) {
42 71 : if (Unit.Version == 2)
43 71 : return Unit.AddrSize;
44 0 : return getOffsetSize(Unit);
45 0 : }
46 0 :
47 0 : template <typename T> void DWARFYAML::VisitorImpl<T>::traverseDebugInfo() {
48 0 : for (auto &Unit : DebugInfo.CompileUnits) {
49 0 : onStartCompileUnit(Unit);
50 0 : auto FirstAbbrevCode = Unit.Entries[0].AbbrCode;
51 0 :
52 : for (auto &Entry : Unit.Entries) {
53 114 : onStartDIE(Unit, Entry);
54 0 : if (Entry.AbbrCode == 0u)
55 0 : continue;
56 0 : auto &Abbrev = DebugInfo.AbbrevDecls[Entry.AbbrCode - FirstAbbrevCode];
57 0 : auto FormVal = Entry.Values.begin();
58 0 : auto AbbrForm = Abbrev.Attributes.begin();
59 0 : for (;
60 0 : FormVal != Entry.Values.end() && AbbrForm != Abbrev.Attributes.end();
61 0 : ++FormVal, ++AbbrForm) {
62 0 : onForm(*AbbrForm, *FormVal);
63 0 : dwarf::Form Form = AbbrForm->Form;
64 0 : bool Indirect;
65 0 : do {
66 0 : Indirect = false;
67 0 : switch (Form) {
68 0 : case dwarf::DW_FORM_addr:
69 0 : onVariableSizeValue(FormVal->Value, Unit.AddrSize);
70 : break;
71 0 : case dwarf::DW_FORM_ref_addr:
72 : onVariableSizeValue(FormVal->Value, getRefSize(Unit));
73 : break;
74 71 : case dwarf::DW_FORM_exprloc:
75 : case dwarf::DW_FORM_block:
76 : onValue((uint64_t)FormVal->BlockData.size(), true);
77 : onValue(
78 3 : MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0],
79 1 : FormVal->BlockData.size()),
80 : ""));
81 : break;
82 : case dwarf::DW_FORM_block1: {
83 31 : auto writeSize = FormVal->BlockData.size();
84 56 : onValue((uint8_t)writeSize);
85 25 : onValue(
86 25 : MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0],
87 : FormVal->BlockData.size()),
88 109 : ""));
89 84 : break;
90 84 : }
91 : case dwarf::DW_FORM_block2: {
92 62 : auto writeSize = FormVal->BlockData.size();
93 61 : onValue((uint16_t)writeSize);
94 61 : onValue(
95 : MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0],
96 266 : FormVal->BlockData.size()),
97 : ""));
98 204 : break;
99 204 : }
100 : case dwarf::DW_FORM_block4: {
101 : auto writeSize = FormVal->BlockData.size();
102 : onValue((uint32_t)writeSize);
103 204 : onValue(
104 42 : MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0],
105 42 : FormVal->BlockData.size()),
106 : ""));
107 : break;
108 3 : }
109 : case dwarf::DW_FORM_data1:
110 10 : case dwarf::DW_FORM_ref1:
111 : case dwarf::DW_FORM_flag:
112 20 : case dwarf::DW_FORM_strx1:
113 20 : case dwarf::DW_FORM_addrx1:
114 : onValue((uint8_t)FormVal->Value);
115 : break;
116 : case dwarf::DW_FORM_data2:
117 : case dwarf::DW_FORM_ref2:
118 1 : case dwarf::DW_FORM_strx2:
119 1 : case dwarf::DW_FORM_addrx2:
120 1 : onValue((uint16_t)FormVal->Value);
121 2 : break;
122 : case dwarf::DW_FORM_data4:
123 : case dwarf::DW_FORM_ref4:
124 : case dwarf::DW_FORM_ref_sup4:
125 : case dwarf::DW_FORM_strx4:
126 : case dwarf::DW_FORM_addrx4:
127 1 : onValue((uint32_t)FormVal->Value);
128 1 : break;
129 1 : case dwarf::DW_FORM_data8:
130 2 : case dwarf::DW_FORM_ref8:
131 : case dwarf::DW_FORM_ref_sup8:
132 : onValue((uint64_t)FormVal->Value);
133 : break;
134 : case dwarf::DW_FORM_sdata:
135 : onValue((int64_t)FormVal->Value, true);
136 1 : break;
137 1 : case dwarf::DW_FORM_udata:
138 1 : case dwarf::DW_FORM_ref_udata:
139 2 : onValue((uint64_t)FormVal->Value, true);
140 : break;
141 : case dwarf::DW_FORM_string:
142 : onValue(FormVal->CStr);
143 : break;
144 : case dwarf::DW_FORM_indirect:
145 34 : onValue((uint64_t)FormVal->Value, true);
146 : Indirect = true;
147 : Form = static_cast<dwarf::Form>((uint64_t)FormVal->Value);
148 : ++FormVal;
149 : break;
150 34 : case dwarf::DW_FORM_strp:
151 : case dwarf::DW_FORM_sec_offset:
152 5 : case dwarf::DW_FORM_GNU_ref_alt:
153 : case dwarf::DW_FORM_GNU_strp_alt:
154 : case dwarf::DW_FORM_line_strp:
155 : case dwarf::DW_FORM_strp_sup:
156 5 : onVariableSizeValue(FormVal->Value, getOffsetSize(Unit));
157 : break;
158 24 : case dwarf::DW_FORM_ref_sig8:
159 : onValue((uint64_t)FormVal->Value);
160 : break;
161 : case dwarf::DW_FORM_GNU_addr_index:
162 : case dwarf::DW_FORM_GNU_str_index:
163 24 : onValue((uint64_t)FormVal->Value, true);
164 : break;
165 2 : default:
166 : break;
167 : }
168 2 : } while (Indirect);
169 : }
170 1 : onEndDIE(Unit, Entry);
171 1 : }
172 : onEndCompileUnit(Unit);
173 2 : }
174 : }
175 2 :
176 : // Explicitly instantiate the two template expansions.
177 1 : template class DWARFYAML::VisitorImpl<DWARFYAML::Data>;
178 1 : template class DWARFYAML::VisitorImpl<const DWARFYAML::Data>;
|