• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===--- DWARFVisitor.cpp ---------------------------------------*- C++ -*-===//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //===----------------------------------------------------------------------===//
10 
11 #include "DWARFVisitor.h"
12 #include "llvm/ObjectYAML/DWARFYAML.h"
13 
14 using namespace llvm;
15 
16 template <typename T>
onVariableSizeValue(uint64_t U,unsigned Size)17 void 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 
getOffsetSize(const DWARFYAML::Unit & Unit)36 static unsigned getOffsetSize(const DWARFYAML::Unit &Unit) {
37   return Unit.Length.isDWARF64() ? 8 : 4;
38 }
39 
getRefSize(const DWARFYAML::Unit & Unit)40 static unsigned getRefSize(const DWARFYAML::Unit &Unit) {
41   if (Unit.Version == 2)
42     return Unit.AddrSize;
43   return getOffsetSize(Unit);
44 }
45 
traverseDebugInfo()46 template <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:
111           case dwarf::DW_FORM_strx1:
112           case dwarf::DW_FORM_addrx1:
113             onValue((uint8_t)FormVal->Value);
114             break;
115           case dwarf::DW_FORM_data2:
116           case dwarf::DW_FORM_ref2:
117           case dwarf::DW_FORM_strx2:
118           case dwarf::DW_FORM_addrx2:
119             onValue((uint16_t)FormVal->Value);
120             break;
121           case dwarf::DW_FORM_data4:
122           case dwarf::DW_FORM_ref4:
123           case dwarf::DW_FORM_ref_sup4:
124           case dwarf::DW_FORM_strx4:
125           case dwarf::DW_FORM_addrx4:
126             onValue((uint32_t)FormVal->Value);
127             break;
128           case dwarf::DW_FORM_data8:
129           case dwarf::DW_FORM_ref8:
130           case dwarf::DW_FORM_ref_sup8:
131             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:
155             onVariableSizeValue(FormVal->Value, getOffsetSize(Unit));
156             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.
176 template class DWARFYAML::VisitorImpl<DWARFYAML::Data>;
177 template class DWARFYAML::VisitorImpl<const DWARFYAML::Data>;
178