1 //===-- DWARFDebugAbbrev.cpp ------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "DWARFDebugAbbrev.h"
11 #include "DWARFDataExtractor.h"
12 #include "lldb/Core/Stream.h"
15 using namespace lldb_private;
18 //----------------------------------------------------------------------
19 // DWARFAbbreviationDeclarationSet::Clear()
20 //----------------------------------------------------------------------
22 DWARFAbbreviationDeclarationSet::Clear()
29 //----------------------------------------------------------------------
30 // DWARFAbbreviationDeclarationSet::Extract()
31 //----------------------------------------------------------------------
33 DWARFAbbreviationDeclarationSet::Extract(const DWARFDataExtractor& data, lldb::offset_t *offset_ptr)
35 const lldb::offset_t begin_offset = *offset_ptr;
36 m_offset = begin_offset;
38 DWARFAbbreviationDeclaration abbrevDeclaration;
39 dw_uleb128_t prev_abbr_code = 0;
40 while (abbrevDeclaration.Extract(data, offset_ptr))
42 m_decls.push_back(abbrevDeclaration);
43 if (m_idx_offset == 0)
44 m_idx_offset = abbrevDeclaration.Code();
47 if (prev_abbr_code + 1 != abbrevDeclaration.Code())
48 m_idx_offset = UINT32_MAX; // Out of order indexes, we can't do O(1) lookups...
50 prev_abbr_code = abbrevDeclaration.Code();
52 return begin_offset != *offset_ptr;
56 //----------------------------------------------------------------------
57 // DWARFAbbreviationDeclarationSet::Dump()
58 //----------------------------------------------------------------------
60 DWARFAbbreviationDeclarationSet::Dump(Stream *s) const
62 std::for_each (m_decls.begin(), m_decls.end(), bind2nd(std::mem_fun_ref(&DWARFAbbreviationDeclaration::Dump),s));
66 //----------------------------------------------------------------------
67 // DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration()
68 //----------------------------------------------------------------------
69 const DWARFAbbreviationDeclaration*
70 DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const
72 if (m_idx_offset == UINT32_MAX)
74 DWARFAbbreviationDeclarationCollConstIter pos;
75 DWARFAbbreviationDeclarationCollConstIter end = m_decls.end();
76 for (pos = m_decls.begin(); pos != end; ++pos)
78 if (pos->Code() == abbrCode)
84 uint32_t idx = abbrCode - m_idx_offset;
85 if (idx < m_decls.size())
91 //----------------------------------------------------------------------
92 // DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential()
94 // Append an abbreviation declaration with a sequential code for O(n)
95 // lookups. Handy when creating an DWARFAbbreviationDeclarationSet.
96 //----------------------------------------------------------------------
98 DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential(const DWARFAbbreviationDeclaration& abbrevDecl)
100 // Get the next abbreviation code based on our current array size
101 dw_uleb128_t code = m_decls.size()+1;
103 // Push the new declaration on the back
104 m_decls.push_back(abbrevDecl);
106 // Update the code for this new declaration
107 m_decls.back().SetCode(code);
109 return code; // return the new abbreviation code!
113 //----------------------------------------------------------------------
116 // Encode the abbreviation table onto the end of the buffer provided
117 // into a byte representation as would be found in a ".debug_abbrev"
118 // debug information section.
119 //----------------------------------------------------------------------
121 //DWARFAbbreviationDeclarationSet::Encode(BinaryStreamBuf& debug_abbrev_buf) const
123 // DWARFAbbreviationDeclarationCollConstIter pos;
124 // DWARFAbbreviationDeclarationCollConstIter end = m_decls.end();
125 // for (pos = m_decls.begin(); pos != end; ++pos)
126 // pos->Append(debug_abbrev_buf);
127 // debug_abbrev_buf.Append8(0);
131 //----------------------------------------------------------------------
132 // DWARFDebugAbbrev constructor
133 //----------------------------------------------------------------------
134 DWARFDebugAbbrev::DWARFDebugAbbrev() :
136 m_prev_abbr_offset_pos(m_abbrevCollMap.end())
141 //----------------------------------------------------------------------
142 // DWARFDebugAbbrev::Parse()
143 //----------------------------------------------------------------------
145 DWARFDebugAbbrev::Parse(const DWARFDataExtractor& data)
147 lldb::offset_t offset = 0;
149 while (data.ValidOffset(offset))
151 uint32_t initial_cu_offset = offset;
152 DWARFAbbreviationDeclarationSet abbrevDeclSet;
154 if (abbrevDeclSet.Extract(data, &offset))
155 m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet;
159 m_prev_abbr_offset_pos = m_abbrevCollMap.end();
162 //----------------------------------------------------------------------
163 // DWARFDebugAbbrev::Dump()
164 //----------------------------------------------------------------------
166 DWARFDebugAbbrev::Dump(Stream *s) const
168 if (m_abbrevCollMap.empty())
170 s->PutCString("< EMPTY >\n");
174 DWARFAbbreviationDeclarationCollMapConstIter pos;
175 for (pos = m_abbrevCollMap.begin(); pos != m_abbrevCollMap.end(); ++pos)
177 s->Printf("Abbrev table for offset: 0x%8.8x\n", pos->first);
183 //----------------------------------------------------------------------
184 // DWARFDebugAbbrev::GetAbbreviationDeclarationSet()
185 //----------------------------------------------------------------------
186 const DWARFAbbreviationDeclarationSet*
187 DWARFDebugAbbrev::GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const
189 DWARFAbbreviationDeclarationCollMapConstIter end = m_abbrevCollMap.end();
190 DWARFAbbreviationDeclarationCollMapConstIter pos;
191 if (m_prev_abbr_offset_pos != end && m_prev_abbr_offset_pos->first == cu_abbr_offset)
192 return &(m_prev_abbr_offset_pos->second);
195 pos = m_abbrevCollMap.find(cu_abbr_offset);
196 m_prev_abbr_offset_pos = pos;
199 if (pos != m_abbrevCollMap.end())
200 return &(pos->second);