]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp
Vendor import of lldb trunk r290819:
[FreeBSD/FreeBSD.git] / source / Plugins / SymbolFile / DWARF / DWARFDebugAbbrev.cpp
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
14 using namespace lldb;
15 using namespace lldb_private;
16 using namespace std;
17
18 //----------------------------------------------------------------------
19 // DWARFAbbreviationDeclarationSet::Clear()
20 //----------------------------------------------------------------------
21 void DWARFAbbreviationDeclarationSet::Clear() {
22   m_idx_offset = 0;
23   m_decls.clear();
24 }
25
26 //----------------------------------------------------------------------
27 // DWARFAbbreviationDeclarationSet::Extract()
28 //----------------------------------------------------------------------
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 //----------------------------------------------------------------------
53 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 *
63 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)
84 // lookups. Handy when creating an DWARFAbbreviationDeclarationSet.
85 //----------------------------------------------------------------------
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 // 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 //----------------------------------------------------------------------
121 DWARFDebugAbbrev::DWARFDebugAbbrev()
122     : m_abbrevCollMap(), m_prev_abbr_offset_pos(m_abbrevCollMap.end()) {}
123
124 //----------------------------------------------------------------------
125 // DWARFDebugAbbrev::Parse()
126 //----------------------------------------------------------------------
127 void 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 //----------------------------------------------------------------------
145 void 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 //----------------------------------------------------------------------
161 const DWARFAbbreviationDeclarationSet *
162 DWARFDebugAbbrev::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 }