blob: ecb5967ac532d768428a0bf3db9d12c66e3d1e94 [file] [log] [blame]
Chris Bieneman8f471f72017-03-06 20:52:12 +00001//===--- DWARFVisitor.cpp ---------------------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Chris Bieneman8f471f72017-03-06 20:52:12 +00006//
7//===----------------------------------------------------------------------===//
8//
9//===----------------------------------------------------------------------===//
10
11#include "DWARFVisitor.h"
12#include "llvm/ObjectYAML/DWARFYAML.h"
13
14using namespace llvm;
15
16template <typename T>
17void DWARFYAML::VisitorImpl<T>::onVariableSizeValue(uint64_t U, unsigned Size) {
18 switch (Size) {
19 case 8:
20 onValue((uint64_t)U);
21 break;
22 case 4:
23 onValue((uint32_t)U);
24 break;
25 case 2:
26 onValue((uint16_t)U);
27 break;
28 case 1:
29 onValue((uint8_t)U);
30 break;
31 default:
32 llvm_unreachable("Invalid integer write size.");
33 }
34}
35
Benjamin Kramer49a49fe2017-08-20 13:03:48 +000036static unsigned getOffsetSize(const DWARFYAML::Unit &Unit) {
Chris Bienemana03cbcc2017-03-07 21:34:35 +000037 return Unit.Length.isDWARF64() ? 8 : 4;
38}
39
Benjamin Kramer49a49fe2017-08-20 13:03:48 +000040static unsigned getRefSize(const DWARFYAML::Unit &Unit) {
Chris Bieneman8f471f72017-03-06 20:52:12 +000041 if (Unit.Version == 2)
42 return Unit.AddrSize;
Chris Bienemana03cbcc2017-03-07 21:34:35 +000043 return getOffsetSize(Unit);
Chris Bieneman8f471f72017-03-06 20:52:12 +000044}
45
46template <typename T> void DWARFYAML::VisitorImpl<T>::traverseDebugInfo() {
47 for (auto &Unit : DebugInfo.CompileUnits) {
48 onStartCompileUnit(Unit);
49 auto FirstAbbrevCode = Unit.Entries[0].AbbrCode;
50
51 for (auto &Entry : Unit.Entries) {
52 onStartDIE(Unit, Entry);
53 if (Entry.AbbrCode == 0u)
54 continue;
55 auto &Abbrev = DebugInfo.AbbrevDecls[Entry.AbbrCode - FirstAbbrevCode];
56 auto FormVal = Entry.Values.begin();
57 auto AbbrForm = Abbrev.Attributes.begin();
58 for (;
59 FormVal != Entry.Values.end() && AbbrForm != Abbrev.Attributes.end();
60 ++FormVal, ++AbbrForm) {
61 onForm(*AbbrForm, *FormVal);
62 dwarf::Form Form = AbbrForm->Form;
63 bool Indirect;
64 do {
65 Indirect = false;
66 switch (Form) {
67 case dwarf::DW_FORM_addr:
68 onVariableSizeValue(FormVal->Value, Unit.AddrSize);
69 break;
70 case dwarf::DW_FORM_ref_addr:
71 onVariableSizeValue(FormVal->Value, getRefSize(Unit));
72 break;
73 case dwarf::DW_FORM_exprloc:
74 case dwarf::DW_FORM_block:
75 onValue((uint64_t)FormVal->BlockData.size(), true);
76 onValue(
77 MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0],
78 FormVal->BlockData.size()),
79 ""));
80 break;
81 case dwarf::DW_FORM_block1: {
82 auto writeSize = FormVal->BlockData.size();
83 onValue((uint8_t)writeSize);
84 onValue(
85 MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0],
86 FormVal->BlockData.size()),
87 ""));
88 break;
89 }
90 case dwarf::DW_FORM_block2: {
91 auto writeSize = FormVal->BlockData.size();
92 onValue((uint16_t)writeSize);
93 onValue(
94 MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0],
95 FormVal->BlockData.size()),
96 ""));
97 break;
98 }
99 case dwarf::DW_FORM_block4: {
100 auto writeSize = FormVal->BlockData.size();
101 onValue((uint32_t)writeSize);
102 onValue(
103 MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0],
104 FormVal->BlockData.size()),
105 ""));
106 break;
107 }
108 case dwarf::DW_FORM_data1:
109 case dwarf::DW_FORM_ref1:
110 case dwarf::DW_FORM_flag:
Paul Robinsonf96e21a2017-03-06 22:20:03 +0000111 case dwarf::DW_FORM_strx1:
112 case dwarf::DW_FORM_addrx1:
Chris Bieneman8f471f72017-03-06 20:52:12 +0000113 onValue((uint8_t)FormVal->Value);
114 break;
115 case dwarf::DW_FORM_data2:
116 case dwarf::DW_FORM_ref2:
Paul Robinsonf96e21a2017-03-06 22:20:03 +0000117 case dwarf::DW_FORM_strx2:
118 case dwarf::DW_FORM_addrx2:
Chris Bieneman8f471f72017-03-06 20:52:12 +0000119 onValue((uint16_t)FormVal->Value);
120 break;
121 case dwarf::DW_FORM_data4:
122 case dwarf::DW_FORM_ref4:
Paul Robinsonf96e21a2017-03-06 22:20:03 +0000123 case dwarf::DW_FORM_ref_sup4:
124 case dwarf::DW_FORM_strx4:
125 case dwarf::DW_FORM_addrx4:
Chris Bieneman8f471f72017-03-06 20:52:12 +0000126 onValue((uint32_t)FormVal->Value);
127 break;
128 case dwarf::DW_FORM_data8:
129 case dwarf::DW_FORM_ref8:
Paul Robinsonf96e21a2017-03-06 22:20:03 +0000130 case dwarf::DW_FORM_ref_sup8:
Chris Bieneman8f471f72017-03-06 20:52:12 +0000131 onValue((uint64_t)FormVal->Value);
132 break;
133 case dwarf::DW_FORM_sdata:
134 onValue((int64_t)FormVal->Value, true);
135 break;
136 case dwarf::DW_FORM_udata:
137 case dwarf::DW_FORM_ref_udata:
138 onValue((uint64_t)FormVal->Value, true);
139 break;
140 case dwarf::DW_FORM_string:
141 onValue(FormVal->CStr);
142 break;
143 case dwarf::DW_FORM_indirect:
144 onValue((uint64_t)FormVal->Value, true);
145 Indirect = true;
146 Form = static_cast<dwarf::Form>((uint64_t)FormVal->Value);
147 ++FormVal;
148 break;
149 case dwarf::DW_FORM_strp:
150 case dwarf::DW_FORM_sec_offset:
151 case dwarf::DW_FORM_GNU_ref_alt:
152 case dwarf::DW_FORM_GNU_strp_alt:
153 case dwarf::DW_FORM_line_strp:
154 case dwarf::DW_FORM_strp_sup:
Chris Bienemana03cbcc2017-03-07 21:34:35 +0000155 onVariableSizeValue(FormVal->Value, getOffsetSize(Unit));
Chris Bieneman8f471f72017-03-06 20:52:12 +0000156 break;
157 case dwarf::DW_FORM_ref_sig8:
158 onValue((uint64_t)FormVal->Value);
159 break;
160 case dwarf::DW_FORM_GNU_addr_index:
161 case dwarf::DW_FORM_GNU_str_index:
162 onValue((uint64_t)FormVal->Value, true);
163 break;
164 default:
165 break;
166 }
167 } while (Indirect);
168 }
169 onEndDIE(Unit, Entry);
170 }
171 onEndCompileUnit(Unit);
172 }
173}
174
175// Explicitly instantiate the two template expansions.
176template class DWARFYAML::VisitorImpl<DWARFYAML::Data>;
177template class DWARFYAML::VisitorImpl<const DWARFYAML::Data>;