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 22 DWARFAbbreviationDeclarationSet::Clear() 23 { 24 m_idx_offset = 0; 25 m_decls.clear(); 26 } 27 28 29 //---------------------------------------------------------------------- 30 // DWARFAbbreviationDeclarationSet::Extract() 31 //---------------------------------------------------------------------- 32 bool 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 60 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* 70 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 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 //---------------------------------------------------------------------- 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 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 166 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* 187 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