• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "lldb/Core/DataExtractor.h"
12 #include "lldb/Core/Stream.h"
13 
14 using namespace lldb;
15 using namespace lldb_private;
16 using namespace std;
17 
18 //----------------------------------------------------------------------
19 // DWARFAbbreviationDeclarationSet::Clear()
20 //----------------------------------------------------------------------
21 void
Clear()22 DWARFAbbreviationDeclarationSet::Clear()
23 {
24     m_idx_offset = 0;
25     m_decls.clear();
26 }
27 
28 
29 //----------------------------------------------------------------------
30 // DWARFAbbreviationDeclarationSet::Extract()
31 //----------------------------------------------------------------------
32 bool
Extract(const DataExtractor & data,lldb::offset_t * offset_ptr)33 DWARFAbbreviationDeclarationSet::Extract(const DataExtractor& data, lldb::offset_t *offset_ptr)
34 {
35     const lldb::offset_t begin_offset = *offset_ptr;
36     m_offset = begin_offset;
37     Clear();
38     DWARFAbbreviationDeclaration abbrevDeclaration;
39     dw_uleb128_t prev_abbr_code = 0;
40     while (abbrevDeclaration.Extract(data, offset_ptr))
41     {
42         m_decls.push_back(abbrevDeclaration);
43         if (m_idx_offset == 0)
44             m_idx_offset = abbrevDeclaration.Code();
45         else
46         {
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...
49         }
50         prev_abbr_code = abbrevDeclaration.Code();
51     }
52     return begin_offset != *offset_ptr;
53 }
54 
55 
56 //----------------------------------------------------------------------
57 // DWARFAbbreviationDeclarationSet::Dump()
58 //----------------------------------------------------------------------
59 void
Dump(Stream * s) const60 DWARFAbbreviationDeclarationSet::Dump(Stream *s) const
61 {
62     std::for_each (m_decls.begin(), m_decls.end(), bind2nd(std::mem_fun_ref(&DWARFAbbreviationDeclaration::Dump),s));
63 }
64 
65 
66 //----------------------------------------------------------------------
67 // DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration()
68 //----------------------------------------------------------------------
69 const DWARFAbbreviationDeclaration*
GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const70 DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const
71 {
72     if (m_idx_offset == UINT32_MAX)
73     {
74         DWARFAbbreviationDeclarationCollConstIter pos;
75         DWARFAbbreviationDeclarationCollConstIter end = m_decls.end();
76         for (pos = m_decls.begin(); pos != end; ++pos)
77         {
78             if (pos->Code() == abbrCode)
79                 return &(*pos);
80         }
81     }
82     else
83     {
84         uint32_t idx = abbrCode - m_idx_offset;
85         if (idx < m_decls.size())
86             return &m_decls[idx];
87     }
88     return NULL;
89 }
90 
91 //----------------------------------------------------------------------
92 // DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential()
93 //
94 // Append an abbreviation declaration with a sequential code for O(n)
95 // lookups. Handy when creating an DWARFAbbreviationDeclarationSet.
96 //----------------------------------------------------------------------
97 dw_uleb128_t
AppendAbbrevDeclSequential(const DWARFAbbreviationDeclaration & abbrevDecl)98 DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential(const DWARFAbbreviationDeclaration& abbrevDecl)
99 {
100     // Get the next abbreviation code based on our current array size
101     dw_uleb128_t code = m_decls.size()+1;
102 
103     // Push the new declaration on the back
104     m_decls.push_back(abbrevDecl);
105 
106     // Update the code for this new declaration
107     m_decls.back().SetCode(code);
108 
109     return code;    // return the new abbreviation code!
110 }
111 
112 
113 //----------------------------------------------------------------------
114 // Encode
115 //
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 //----------------------------------------------------------------------
120 //void
121 //DWARFAbbreviationDeclarationSet::Encode(BinaryStreamBuf& debug_abbrev_buf) const
122 //{
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);
128 //}
129 
130 
131 //----------------------------------------------------------------------
132 // DWARFDebugAbbrev constructor
133 //----------------------------------------------------------------------
DWARFDebugAbbrev()134 DWARFDebugAbbrev::DWARFDebugAbbrev() :
135     m_abbrevCollMap(),
136     m_prev_abbr_offset_pos(m_abbrevCollMap.end())
137 {
138 }
139 
140 
141 //----------------------------------------------------------------------
142 // DWARFDebugAbbrev::Parse()
143 //----------------------------------------------------------------------
144 void
Parse(const DataExtractor & data)145 DWARFDebugAbbrev::Parse(const DataExtractor& data)
146 {
147     lldb::offset_t offset = 0;
148 
149     while (data.ValidOffset(offset))
150     {
151         uint32_t initial_cu_offset = offset;
152         DWARFAbbreviationDeclarationSet abbrevDeclSet;
153 
154         if (abbrevDeclSet.Extract(data, &offset))
155             m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet;
156         else
157             break;
158     }
159     m_prev_abbr_offset_pos = m_abbrevCollMap.end();
160 }
161 
162 //----------------------------------------------------------------------
163 // DWARFDebugAbbrev::Dump()
164 //----------------------------------------------------------------------
165 void
Dump(Stream * s) const166 DWARFDebugAbbrev::Dump(Stream *s) const
167 {
168     if (m_abbrevCollMap.empty())
169     {
170         s->PutCString("< EMPTY >\n");
171         return;
172     }
173 
174     DWARFAbbreviationDeclarationCollMapConstIter pos;
175     for (pos = m_abbrevCollMap.begin(); pos != m_abbrevCollMap.end(); ++pos)
176     {
177         s->Printf("Abbrev table for offset: 0x%8.8x\n", pos->first);
178         pos->second.Dump(s);
179     }
180 }
181 
182 
183 //----------------------------------------------------------------------
184 // DWARFDebugAbbrev::GetAbbreviationDeclarationSet()
185 //----------------------------------------------------------------------
186 const DWARFAbbreviationDeclarationSet*
GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const187 DWARFDebugAbbrev::GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const
188 {
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);
193     else
194     {
195         pos = m_abbrevCollMap.find(cu_abbr_offset);
196         m_prev_abbr_offset_pos = pos;
197     }
198 
199     if (pos != m_abbrevCollMap.end())
200         return &(pos->second);
201     return NULL;
202 }
203