1 //===-- DWARFDebugAbbrev.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 #include "DWARFDebugAbbrev.h"
11 #include "DWARFDataExtractor.h"
12 #include "lldb/Utility/Stream.h"
13
14 using namespace lldb;
15 using namespace lldb_private;
16 using namespace std;
17
18 //----------------------------------------------------------------------
19 // DWARFAbbreviationDeclarationSet::Clear()
20 //----------------------------------------------------------------------
Clear()21 void DWARFAbbreviationDeclarationSet::Clear() {
22 m_idx_offset = 0;
23 m_decls.clear();
24 }
25
26 //----------------------------------------------------------------------
27 // DWARFAbbreviationDeclarationSet::Extract()
28 //----------------------------------------------------------------------
Extract(const DWARFDataExtractor & data,lldb::offset_t * offset_ptr)29 bool DWARFAbbreviationDeclarationSet::Extract(const DWARFDataExtractor &data,
30 lldb::offset_t *offset_ptr) {
31 const lldb::offset_t begin_offset = *offset_ptr;
32 m_offset = begin_offset;
33 Clear();
34 DWARFAbbreviationDeclaration abbrevDeclaration;
35 dw_uleb128_t prev_abbr_code = 0;
36 while (abbrevDeclaration.Extract(data, offset_ptr)) {
37 m_decls.push_back(abbrevDeclaration);
38 if (m_idx_offset == 0)
39 m_idx_offset = abbrevDeclaration.Code();
40 else {
41 if (prev_abbr_code + 1 != abbrevDeclaration.Code())
42 m_idx_offset =
43 UINT32_MAX; // Out of order indexes, we can't do O(1) lookups...
44 }
45 prev_abbr_code = abbrevDeclaration.Code();
46 }
47 return begin_offset != *offset_ptr;
48 }
49
50 //----------------------------------------------------------------------
51 // DWARFAbbreviationDeclarationSet::Dump()
52 //----------------------------------------------------------------------
Dump(Stream * s) const53 void DWARFAbbreviationDeclarationSet::Dump(Stream *s) const {
54 std::for_each(
55 m_decls.begin(), m_decls.end(),
56 bind2nd(std::mem_fun_ref(&DWARFAbbreviationDeclaration::Dump), s));
57 }
58
59 //----------------------------------------------------------------------
60 // DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration()
61 //----------------------------------------------------------------------
62 const DWARFAbbreviationDeclaration *
GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const63 DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration(
64 dw_uleb128_t abbrCode) const {
65 if (m_idx_offset == UINT32_MAX) {
66 DWARFAbbreviationDeclarationCollConstIter pos;
67 DWARFAbbreviationDeclarationCollConstIter end = m_decls.end();
68 for (pos = m_decls.begin(); pos != end; ++pos) {
69 if (pos->Code() == abbrCode)
70 return &(*pos);
71 }
72 } else {
73 uint32_t idx = abbrCode - m_idx_offset;
74 if (idx < m_decls.size())
75 return &m_decls[idx];
76 }
77 return NULL;
78 }
79
80 //----------------------------------------------------------------------
81 // DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential()
82 //
83 // Append an abbreviation declaration with a sequential code for O(n) lookups.
84 // Handy when creating an DWARFAbbreviationDeclarationSet.
85 //----------------------------------------------------------------------
AppendAbbrevDeclSequential(const DWARFAbbreviationDeclaration & abbrevDecl)86 dw_uleb128_t DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential(
87 const DWARFAbbreviationDeclaration &abbrevDecl) {
88 // Get the next abbreviation code based on our current array size
89 dw_uleb128_t code = m_decls.size() + 1;
90
91 // Push the new declaration on the back
92 m_decls.push_back(abbrevDecl);
93
94 // Update the code for this new declaration
95 m_decls.back().SetCode(code);
96
97 return code; // return the new abbreviation code!
98 }
99
100 //----------------------------------------------------------------------
101 // DWARFAbbreviationDeclarationSet::GetUnsupportedForms()
102 //----------------------------------------------------------------------
GetUnsupportedForms(std::set<dw_form_t> & invalid_forms) const103 void DWARFAbbreviationDeclarationSet::GetUnsupportedForms(
104 std::set<dw_form_t> &invalid_forms) const {
105 for (const auto &abbr_decl : m_decls) {
106 const size_t num_attrs = abbr_decl.NumAttributes();
107 for (size_t i=0; i<num_attrs; ++i) {
108 dw_form_t form = abbr_decl.GetFormByIndex(i);
109 if (!DWARFFormValue::FormIsSupported(form))
110 invalid_forms.insert(form);
111 }
112 }
113 }
114
115 //----------------------------------------------------------------------
116 // Encode
117 //
118 // Encode the abbreviation table onto the end of the buffer provided into a
119 // byte representation as would be found in a ".debug_abbrev" debug information
120 // section.
121 //----------------------------------------------------------------------
122 // void
123 // DWARFAbbreviationDeclarationSet::Encode(BinaryStreamBuf& debug_abbrev_buf)
124 // const
125 //{
126 // DWARFAbbreviationDeclarationCollConstIter pos;
127 // DWARFAbbreviationDeclarationCollConstIter end = m_decls.end();
128 // for (pos = m_decls.begin(); pos != end; ++pos)
129 // pos->Append(debug_abbrev_buf);
130 // debug_abbrev_buf.Append8(0);
131 //}
132
133 //----------------------------------------------------------------------
134 // DWARFDebugAbbrev constructor
135 //----------------------------------------------------------------------
DWARFDebugAbbrev()136 DWARFDebugAbbrev::DWARFDebugAbbrev()
137 : m_abbrevCollMap(), m_prev_abbr_offset_pos(m_abbrevCollMap.end()) {}
138
139 //----------------------------------------------------------------------
140 // DWARFDebugAbbrev::Parse()
141 //----------------------------------------------------------------------
Parse(const DWARFDataExtractor & data)142 void DWARFDebugAbbrev::Parse(const DWARFDataExtractor &data) {
143 lldb::offset_t offset = 0;
144
145 while (data.ValidOffset(offset)) {
146 uint32_t initial_cu_offset = offset;
147 DWARFAbbreviationDeclarationSet abbrevDeclSet;
148
149 if (abbrevDeclSet.Extract(data, &offset))
150 m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet;
151 else
152 break;
153 }
154 m_prev_abbr_offset_pos = m_abbrevCollMap.end();
155 }
156
157 //----------------------------------------------------------------------
158 // DWARFDebugAbbrev::Dump()
159 //----------------------------------------------------------------------
Dump(Stream * s) const160 void DWARFDebugAbbrev::Dump(Stream *s) const {
161 if (m_abbrevCollMap.empty()) {
162 s->PutCString("< EMPTY >\n");
163 return;
164 }
165
166 DWARFAbbreviationDeclarationCollMapConstIter pos;
167 for (pos = m_abbrevCollMap.begin(); pos != m_abbrevCollMap.end(); ++pos) {
168 s->Printf("Abbrev table for offset: 0x%8.8x\n", pos->first);
169 pos->second.Dump(s);
170 }
171 }
172
173 //----------------------------------------------------------------------
174 // DWARFDebugAbbrev::GetAbbreviationDeclarationSet()
175 //----------------------------------------------------------------------
176 const DWARFAbbreviationDeclarationSet *
GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const177 DWARFDebugAbbrev::GetAbbreviationDeclarationSet(
178 dw_offset_t cu_abbr_offset) const {
179 DWARFAbbreviationDeclarationCollMapConstIter end = m_abbrevCollMap.end();
180 DWARFAbbreviationDeclarationCollMapConstIter pos;
181 if (m_prev_abbr_offset_pos != end &&
182 m_prev_abbr_offset_pos->first == cu_abbr_offset)
183 return &(m_prev_abbr_offset_pos->second);
184 else {
185 pos = m_abbrevCollMap.find(cu_abbr_offset);
186 m_prev_abbr_offset_pos = pos;
187 }
188
189 if (pos != m_abbrevCollMap.end())
190 return &(pos->second);
191 return NULL;
192 }
193
194 //----------------------------------------------------------------------
195 // DWARFDebugAbbrev::GetUnsupportedForms()
196 //----------------------------------------------------------------------
GetUnsupportedForms(std::set<dw_form_t> & invalid_forms) const197 void DWARFDebugAbbrev::GetUnsupportedForms(
198 std::set<dw_form_t> &invalid_forms) const {
199 for (const auto &pair : m_abbrevCollMap)
200 pair.second.GetUnsupportedForms(invalid_forms);
201 }
202