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