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