blob: e6114c85ac0b9ac5a7797ce3003b94d8aa0168bd [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
Benjamin Kramer49a49fe2017-08-20 13:03:48 +000037static unsigned getOffsetSize(const DWARFYAML::Unit &Unit) {
Chris Bienemana03cbcc2017-03-07 21:34:35 +000038 return Unit.Length.isDWARF64() ? 8 : 4;
39}
40
Benjamin Kramer49a49fe2017-08-20 13:03:48 +000041static unsigned getRefSize(const DWARFYAML::Unit &Unit) {
Chris Bieneman8f471f72017-03-06 20:52:12 +000042 if (Unit.Version == 2)
43 return Unit.AddrSize;
Chris Bienemana03cbcc2017-03-07 21:34:35 +000044 return getOffsetSize(Unit);
Chris Bieneman8f471f72017-03-06 20:52:12 +000045}
46
47template <typename T> void DWARFYAML::VisitorImpl<T>::traverseDebugInfo() {
48 for (auto &Unit : DebugInfo.CompileUnits) {
49 onStartCompileUnit(Unit);
50 auto FirstAbbrevCode = Unit.Entries[0].AbbrCode;
51
52 for (auto &Entry : Unit.Entries) {
53 onStartDIE(Unit, Entry);
54 if (Entry.AbbrCode == 0u)
55 continue;
56 auto &Abbrev = DebugInfo.AbbrevDecls[Entry.AbbrCode - FirstAbbrevCode];
57 auto FormVal = Entry.Values.begin();
58 auto AbbrForm = Abbrev.Attributes.begin();
59 for (;
60 FormVal != Entry.Values.end() && AbbrForm != Abbrev.Attributes.end();
61 ++FormVal, ++AbbrForm) {
62 onForm(*AbbrForm, *FormVal);
63 dwarf::Form Form = AbbrForm->Form;
64 bool Indirect;
65 do {
66 Indirect = false;
67 switch (Form) {
68 case dwarf::DW_FORM_addr:
69 onVariableSizeValue(FormVal->Value, Unit.AddrSize);
70 break;
71 case dwarf::DW_FORM_ref_addr:
72 onVariableSizeValue(FormVal->Value, getRefSize(Unit));
73 break;
74 case dwarf::DW_FORM_exprloc:
75 case dwarf::DW_FORM_block:
76 onValue((uint64_t)FormVal->BlockData.size(), true);
77 onValue(
78 MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0],
79 FormVal->BlockData.size()),
80 ""));
81 break;
82 case dwarf::DW_FORM_block1: {
83 auto writeSize = FormVal->BlockData.size();
84 onValue((uint8_t)writeSize);
85 onValue(
86 MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0],
87 FormVal->BlockData.size()),
88 ""));
89 break;
90 }
91 case dwarf::DW_FORM_block2: {
92 auto writeSize = FormVal->BlockData.size();
93 onValue((uint16_t)writeSize);
94 onValue(
95 MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0],
96 FormVal->BlockData.size()),
97 ""));
98 break;
99 }
100 case dwarf::DW_FORM_block4: {
101 auto writeSize = FormVal->BlockData.size();
102 onValue((uint32_t)writeSize);
103 onValue(
104 MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0],
105 FormVal->BlockData.size()),
106 ""));
107 break;
108 }
109 case dwarf::DW_FORM_data1:
110 case dwarf::DW_FORM_ref1:
111 case dwarf::DW_FORM_flag:
Paul Robinsonf96e21a2017-03-06 22:20:03 +0000112 case dwarf::DW_FORM_strx1:
113 case dwarf::DW_FORM_addrx1:
Chris Bieneman8f471f72017-03-06 20:52:12 +0000114 onValue((uint8_t)FormVal->Value);
115 break;
116 case dwarf::DW_FORM_data2:
117 case dwarf::DW_FORM_ref2:
Paul Robinsonf96e21a2017-03-06 22:20:03 +0000118 case dwarf::DW_FORM_strx2:
119 case dwarf::DW_FORM_addrx2:
Chris Bieneman8f471f72017-03-06 20:52:12 +0000120 onValue((uint16_t)FormVal->Value);
121 break;
122 case dwarf::DW_FORM_data4:
123 case dwarf::DW_FORM_ref4:
Paul Robinsonf96e21a2017-03-06 22:20:03 +0000124 case dwarf::DW_FORM_ref_sup4:
125 case dwarf::DW_FORM_strx4:
126 case dwarf::DW_FORM_addrx4:
Chris Bieneman8f471f72017-03-06 20:52:12 +0000127 onValue((uint32_t)FormVal->Value);
128 break;
129 case dwarf::DW_FORM_data8:
130 case dwarf::DW_FORM_ref8:
Paul Robinsonf96e21a2017-03-06 22:20:03 +0000131 case dwarf::DW_FORM_ref_sup8:
Chris Bieneman8f471f72017-03-06 20:52:12 +0000132 onValue((uint64_t)FormVal->Value);
133 break;
134 case dwarf::DW_FORM_sdata:
135 onValue((int64_t)FormVal->Value, true);
136 break;
137 case dwarf::DW_FORM_udata:
138 case dwarf::DW_FORM_ref_udata:
139 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 onValue((uint64_t)FormVal->Value, true);
146 Indirect = true;
147 Form = static_cast<dwarf::Form>((uint64_t)FormVal->Value);
148 ++FormVal;
149 break;
150 case dwarf::DW_FORM_strp:
151 case dwarf::DW_FORM_sec_offset:
152 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:
Chris Bienemana03cbcc2017-03-07 21:34:35 +0000156 onVariableSizeValue(FormVal->Value, getOffsetSize(Unit));
Chris Bieneman8f471f72017-03-06 20:52:12 +0000157 break;
158 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 onValue((uint64_t)FormVal->Value, true);
164 break;
165 default:
166 break;
167 }
168 } while (Indirect);
169 }
170 onEndDIE(Unit, Entry);
171 }
172 onEndCompileUnit(Unit);
173 }
174}
175
176// Explicitly instantiate the two template expansions.
177template class DWARFYAML::VisitorImpl<DWARFYAML::Data>;
178template class DWARFYAML::VisitorImpl<const DWARFYAML::Data>;