DWARFDebugAbbrev.cpp revision 263363
1209878Snwhitehorn//===-- DWARFDebugAbbrev.cpp ------------------------------------*- C++ -*-===//
2209878Snwhitehorn//
3209878Snwhitehorn//                     The LLVM Compiler Infrastructure
4209878Snwhitehorn//
5209878Snwhitehorn// This file is distributed under the University of Illinois Open Source
6209878Snwhitehorn// License. See LICENSE.TXT for details.
7209878Snwhitehorn//
8209878Snwhitehorn//===----------------------------------------------------------------------===//
9209878Snwhitehorn
10209878Snwhitehorn#include "DWARFDebugAbbrev.h"
11209878Snwhitehorn#include "DWARFDataExtractor.h"
12209878Snwhitehorn#include "lldb/Core/Stream.h"
13209878Snwhitehorn
14209878Snwhitehornusing namespace lldb;
15209878Snwhitehornusing namespace lldb_private;
16209878Snwhitehornusing namespace std;
17209878Snwhitehorn
18209878Snwhitehorn//----------------------------------------------------------------------
19209878Snwhitehorn// DWARFAbbreviationDeclarationSet::Clear()
20209878Snwhitehorn//----------------------------------------------------------------------
21209878Snwhitehornvoid
22209878SnwhitehornDWARFAbbreviationDeclarationSet::Clear()
23209878Snwhitehorn{
24209878Snwhitehorn    m_idx_offset = 0;
25209878Snwhitehorn    m_decls.clear();
26209878Snwhitehorn}
27209878Snwhitehorn
28209878Snwhitehorn
29209878Snwhitehorn//----------------------------------------------------------------------
30209878Snwhitehorn// DWARFAbbreviationDeclarationSet::Extract()
31209878Snwhitehorn//----------------------------------------------------------------------
32209878Snwhitehornbool
33209878SnwhitehornDWARFAbbreviationDeclarationSet::Extract(const DWARFDataExtractor& data, lldb::offset_t *offset_ptr)
34209878Snwhitehorn{
35209878Snwhitehorn    const lldb::offset_t begin_offset = *offset_ptr;
36209878Snwhitehorn    m_offset = begin_offset;
37209878Snwhitehorn    Clear();
38209878Snwhitehorn    DWARFAbbreviationDeclaration abbrevDeclaration;
39209878Snwhitehorn    dw_uleb128_t prev_abbr_code = 0;
40209878Snwhitehorn    while (abbrevDeclaration.Extract(data, offset_ptr))
41209878Snwhitehorn    {
42209878Snwhitehorn        m_decls.push_back(abbrevDeclaration);
43209878Snwhitehorn        if (m_idx_offset == 0)
44209878Snwhitehorn            m_idx_offset = abbrevDeclaration.Code();
45209878Snwhitehorn        else
46209878Snwhitehorn        {
47209878Snwhitehorn            if (prev_abbr_code + 1 != abbrevDeclaration.Code())
48209878Snwhitehorn                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//----------------------------------------------------------------------
59void
60DWARFAbbreviationDeclarationSet::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//----------------------------------------------------------------------
69const DWARFAbbreviationDeclaration*
70DWARFAbbreviationDeclarationSet::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//----------------------------------------------------------------------
97dw_uleb128_t
98DWARFAbbreviationDeclarationSet::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//----------------------------------------------------------------------
134DWARFDebugAbbrev::DWARFDebugAbbrev() :
135    m_abbrevCollMap(),
136    m_prev_abbr_offset_pos(m_abbrevCollMap.end())
137{
138}
139
140
141//----------------------------------------------------------------------
142// DWARFDebugAbbrev::Parse()
143//----------------------------------------------------------------------
144void
145DWARFDebugAbbrev::Parse(const DWARFDataExtractor& 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//----------------------------------------------------------------------
165void
166DWARFDebugAbbrev::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//----------------------------------------------------------------------
186const DWARFAbbreviationDeclarationSet*
187DWARFDebugAbbrev::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