DWARFDebugAbbrev.cpp revision 314564
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/Core/Stream.h"
13
14using namespace lldb;
15using namespace lldb_private;
16using namespace std;
17
18//----------------------------------------------------------------------
19// DWARFAbbreviationDeclarationSet::Clear()
20//----------------------------------------------------------------------
21void DWARFAbbreviationDeclarationSet::Clear() {
22  m_idx_offset = 0;
23  m_decls.clear();
24}
25
26//----------------------------------------------------------------------
27// DWARFAbbreviationDeclarationSet::Extract()
28//----------------------------------------------------------------------
29bool 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//----------------------------------------------------------------------
53void 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//----------------------------------------------------------------------
62const DWARFAbbreviationDeclaration *
63DWARFAbbreviationDeclarationSet::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)
84// lookups. Handy when creating an DWARFAbbreviationDeclarationSet.
85//----------------------------------------------------------------------
86dw_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// Encode
102//
103// Encode the abbreviation table onto the end of the buffer provided
104// into a byte representation as would be found in a ".debug_abbrev"
105// debug information section.
106//----------------------------------------------------------------------
107// void
108// DWARFAbbreviationDeclarationSet::Encode(BinaryStreamBuf& debug_abbrev_buf)
109// const
110//{
111//  DWARFAbbreviationDeclarationCollConstIter pos;
112//  DWARFAbbreviationDeclarationCollConstIter end = m_decls.end();
113//  for (pos = m_decls.begin(); pos != end; ++pos)
114//      pos->Append(debug_abbrev_buf);
115//  debug_abbrev_buf.Append8(0);
116//}
117
118//----------------------------------------------------------------------
119// DWARFDebugAbbrev constructor
120//----------------------------------------------------------------------
121DWARFDebugAbbrev::DWARFDebugAbbrev()
122    : m_abbrevCollMap(), m_prev_abbr_offset_pos(m_abbrevCollMap.end()) {}
123
124//----------------------------------------------------------------------
125// DWARFDebugAbbrev::Parse()
126//----------------------------------------------------------------------
127void DWARFDebugAbbrev::Parse(const DWARFDataExtractor &data) {
128  lldb::offset_t offset = 0;
129
130  while (data.ValidOffset(offset)) {
131    uint32_t initial_cu_offset = offset;
132    DWARFAbbreviationDeclarationSet abbrevDeclSet;
133
134    if (abbrevDeclSet.Extract(data, &offset))
135      m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet;
136    else
137      break;
138  }
139  m_prev_abbr_offset_pos = m_abbrevCollMap.end();
140}
141
142//----------------------------------------------------------------------
143// DWARFDebugAbbrev::Dump()
144//----------------------------------------------------------------------
145void DWARFDebugAbbrev::Dump(Stream *s) const {
146  if (m_abbrevCollMap.empty()) {
147    s->PutCString("< EMPTY >\n");
148    return;
149  }
150
151  DWARFAbbreviationDeclarationCollMapConstIter pos;
152  for (pos = m_abbrevCollMap.begin(); pos != m_abbrevCollMap.end(); ++pos) {
153    s->Printf("Abbrev table for offset: 0x%8.8x\n", pos->first);
154    pos->second.Dump(s);
155  }
156}
157
158//----------------------------------------------------------------------
159// DWARFDebugAbbrev::GetAbbreviationDeclarationSet()
160//----------------------------------------------------------------------
161const DWARFAbbreviationDeclarationSet *
162DWARFDebugAbbrev::GetAbbreviationDeclarationSet(
163    dw_offset_t cu_abbr_offset) const {
164  DWARFAbbreviationDeclarationCollMapConstIter end = m_abbrevCollMap.end();
165  DWARFAbbreviationDeclarationCollMapConstIter pos;
166  if (m_prev_abbr_offset_pos != end &&
167      m_prev_abbr_offset_pos->first == cu_abbr_offset)
168    return &(m_prev_abbr_offset_pos->second);
169  else {
170    pos = m_abbrevCollMap.find(cu_abbr_offset);
171    m_prev_abbr_offset_pos = pos;
172  }
173
174  if (pos != m_abbrevCollMap.end())
175    return &(pos->second);
176  return NULL;
177}
178