blob: 8135b8bd6516c4962bc7ca09ca9f83b81d789c0b [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:
108 onValue((uint8_t)FormVal->Value);
109 break;
110 case dwarf::DW_FORM_data2:
111 case dwarf::DW_FORM_ref2:
112 onValue((uint16_t)FormVal->Value);
113 break;
114 case dwarf::DW_FORM_data4:
115 case dwarf::DW_FORM_ref4:
116 onValue((uint32_t)FormVal->Value);
117 break;
118 case dwarf::DW_FORM_data8:
119 case dwarf::DW_FORM_ref8:
120 onValue((uint64_t)FormVal->Value);
121 break;
122 case dwarf::DW_FORM_sdata:
123 onValue((int64_t)FormVal->Value, true);
124 break;
125 case dwarf::DW_FORM_udata:
126 case dwarf::DW_FORM_ref_udata:
127 onValue((uint64_t)FormVal->Value, true);
128 break;
129 case dwarf::DW_FORM_string:
130 onValue(FormVal->CStr);
131 break;
132 case dwarf::DW_FORM_indirect:
133 onValue((uint64_t)FormVal->Value, true);
134 Indirect = true;
135 Form = static_cast<dwarf::Form>((uint64_t)FormVal->Value);
136 ++FormVal;
137 break;
138 case dwarf::DW_FORM_strp:
139 case dwarf::DW_FORM_sec_offset:
140 case dwarf::DW_FORM_GNU_ref_alt:
141 case dwarf::DW_FORM_GNU_strp_alt:
142 case dwarf::DW_FORM_line_strp:
143 case dwarf::DW_FORM_strp_sup:
144 case dwarf::DW_FORM_ref_sup:
145 onVariableSizeValue(FormVal->Value, getRefSize(Unit));
146 break;
147 case dwarf::DW_FORM_ref_sig8:
148 onValue((uint64_t)FormVal->Value);
149 break;
150 case dwarf::DW_FORM_GNU_addr_index:
151 case dwarf::DW_FORM_GNU_str_index:
152 onValue((uint64_t)FormVal->Value, true);
153 break;
154 default:
155 break;
156 }
157 } while (Indirect);
158 }
159 onEndDIE(Unit, Entry);
160 }
161 onEndCompileUnit(Unit);
162 }
163}
164
165// Explicitly instantiate the two template expansions.
166template class DWARFYAML::VisitorImpl<DWARFYAML::Data>;
167template class DWARFYAML::VisitorImpl<const DWARFYAML::Data>;