DWARFDebugAbbrev.cpp revision 254729
160484Sobrien//===-- DWARFDebugAbbrev.cpp ------------------------------------*- C++ -*-===// 260484Sobrien// 360484Sobrien// The LLVM Compiler Infrastructure 460484Sobrien// 560484Sobrien// This file is distributed under the University of Illinois Open Source 660484Sobrien// License. See LICENSE.TXT for details. 760484Sobrien// 860484Sobrien//===----------------------------------------------------------------------===// 960484Sobrien 1060484Sobrien#include "DWARFDebugAbbrev.h" 1160484Sobrien#include "lldb/Core/DataExtractor.h" 1260484Sobrien#include "lldb/Core/Stream.h" 1360484Sobrien 1460484Sobrienusing namespace lldb; 1560484Sobrienusing namespace lldb_private; 1660484Sobrienusing namespace std; 1760484Sobrien 1860484Sobrien//---------------------------------------------------------------------- 1960484Sobrien// DWARFAbbreviationDeclarationSet::Clear() 2060484Sobrien//---------------------------------------------------------------------- 2160484Sobrienvoid 2260484SobrienDWARFAbbreviationDeclarationSet::Clear() 2360484Sobrien{ 2460484Sobrien m_idx_offset = 0; 2560484Sobrien m_decls.clear(); 2660484Sobrien} 2760484Sobrien 2860484Sobrien 2960484Sobrien//---------------------------------------------------------------------- 3060484Sobrien// DWARFAbbreviationDeclarationSet::Extract() 3160484Sobrien//---------------------------------------------------------------------- 3260484Sobrienbool 3360484SobrienDWARFAbbreviationDeclarationSet::Extract(const DataExtractor& data, lldb::offset_t *offset_ptr) 3460484Sobrien{ 3560484Sobrien const lldb::offset_t begin_offset = *offset_ptr; 3660484Sobrien m_offset = begin_offset; 3760484Sobrien Clear(); 3860484Sobrien DWARFAbbreviationDeclaration abbrevDeclaration; 3960484Sobrien dw_uleb128_t prev_abbr_code = 0; 4060484Sobrien while (abbrevDeclaration.Extract(data, offset_ptr)) 4160484Sobrien { 4260484Sobrien m_decls.push_back(abbrevDeclaration); 4360484Sobrien if (m_idx_offset == 0) 4460484Sobrien m_idx_offset = abbrevDeclaration.Code(); 4560484Sobrien else 4660484Sobrien { 4760484Sobrien if (prev_abbr_code + 1 != abbrevDeclaration.Code()) 4860484Sobrien m_idx_offset = UINT32_MAX; // Out of order indexes, we can't do O(1) lookups... 4960484Sobrien } 5060484Sobrien prev_abbr_code = abbrevDeclaration.Code(); 5160484Sobrien } 5260484Sobrien return begin_offset != *offset_ptr; 5360484Sobrien} 5460484Sobrien 5560484Sobrien 5660484Sobrien//---------------------------------------------------------------------- 5760484Sobrien// DWARFAbbreviationDeclarationSet::Dump() 5860484Sobrien//---------------------------------------------------------------------- 5960484Sobrienvoid 6060484SobrienDWARFAbbreviationDeclarationSet::Dump(Stream *s) const 6160484Sobrien{ 6260484Sobrien std::for_each (m_decls.begin(), m_decls.end(), bind2nd(std::mem_fun_ref(&DWARFAbbreviationDeclaration::Dump),s)); 6360484Sobrien} 6460484Sobrien 6560484Sobrien 6660484Sobrien//---------------------------------------------------------------------- 6760484Sobrien// DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration() 6860484Sobrien//---------------------------------------------------------------------- 6960484Sobrienconst DWARFAbbreviationDeclaration* 7060484SobrienDWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const 7160484Sobrien{ 7260484Sobrien if (m_idx_offset == UINT32_MAX) 7360484Sobrien { 7460484Sobrien DWARFAbbreviationDeclarationCollConstIter pos; 7560484Sobrien DWARFAbbreviationDeclarationCollConstIter end = m_decls.end(); 7660484Sobrien for (pos = m_decls.begin(); pos != end; ++pos) 7760484Sobrien { 7860484Sobrien if (pos->Code() == abbrCode) 7960484Sobrien return &(*pos); 8060484Sobrien } 8160484Sobrien } 8260484Sobrien else 8360484Sobrien { 8460484Sobrien uint32_t idx = abbrCode - m_idx_offset; 8560484Sobrien if (idx < m_decls.size()) 8660484Sobrien return &m_decls[idx]; 8760484Sobrien } 8860484Sobrien return NULL; 8960484Sobrien} 9060484Sobrien 9160484Sobrien//---------------------------------------------------------------------- 9260484Sobrien// DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential() 9360484Sobrien// 9460484Sobrien// Append an abbreviation declaration with a sequential code for O(n) 9560484Sobrien// lookups. Handy when creating an DWARFAbbreviationDeclarationSet. 9660484Sobrien//---------------------------------------------------------------------- 9760484Sobriendw_uleb128_t 9860484SobrienDWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential(const DWARFAbbreviationDeclaration& abbrevDecl) 9960484Sobrien{ 10060484Sobrien // Get the next abbreviation code based on our current array size 10160484Sobrien dw_uleb128_t code = m_decls.size()+1; 10260484Sobrien 10360484Sobrien // Push the new declaration on the back 10460484Sobrien m_decls.push_back(abbrevDecl); 10560484Sobrien 10660484Sobrien // Update the code for this new declaration 10760484Sobrien m_decls.back().SetCode(code); 10860484Sobrien 10960484Sobrien return code; // return the new abbreviation code! 11060484Sobrien} 11160484Sobrien 11260484Sobrien 11360484Sobrien//---------------------------------------------------------------------- 11460484Sobrien// Encode 11560484Sobrien// 11660484Sobrien// Encode the abbreviation table onto the end of the buffer provided 11760484Sobrien// into a byte representation as would be found in a ".debug_abbrev" 11860484Sobrien// debug information section. 11960484Sobrien//---------------------------------------------------------------------- 12060484Sobrien//void 12160484Sobrien//DWARFAbbreviationDeclarationSet::Encode(BinaryStreamBuf& debug_abbrev_buf) const 12260484Sobrien//{ 12360484Sobrien// DWARFAbbreviationDeclarationCollConstIter pos; 12460484Sobrien// DWARFAbbreviationDeclarationCollConstIter end = m_decls.end(); 12560484Sobrien// for (pos = m_decls.begin(); pos != end; ++pos) 12660484Sobrien// pos->Append(debug_abbrev_buf); 12760484Sobrien// debug_abbrev_buf.Append8(0); 12860484Sobrien//} 12960484Sobrien 13060484Sobrien 13160484Sobrien//---------------------------------------------------------------------- 13260484Sobrien// DWARFDebugAbbrev constructor 13360484Sobrien//---------------------------------------------------------------------- 13460484SobrienDWARFDebugAbbrev::DWARFDebugAbbrev() : 13560484Sobrien m_abbrevCollMap(), 13660484Sobrien m_prev_abbr_offset_pos(m_abbrevCollMap.end()) 13760484Sobrien{ 13860484Sobrien} 13960484Sobrien 14060484Sobrien 14160484Sobrien//---------------------------------------------------------------------- 14260484Sobrien// DWARFDebugAbbrev::Parse() 14360484Sobrien//---------------------------------------------------------------------- 14460484Sobrienvoid 14560484SobrienDWARFDebugAbbrev::Parse(const DataExtractor& data) 14660484Sobrien{ 14760484Sobrien lldb::offset_t offset = 0; 14860484Sobrien 14960484Sobrien while (data.ValidOffset(offset)) 15060484Sobrien { 15160484Sobrien uint32_t initial_cu_offset = offset; 15260484Sobrien DWARFAbbreviationDeclarationSet abbrevDeclSet; 15360484Sobrien 15489857Sobrien if (abbrevDeclSet.Extract(data, &offset)) 15589857Sobrien m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet; 15660484Sobrien else 15760484Sobrien break; 15860484Sobrien } 15960484Sobrien m_prev_abbr_offset_pos = m_abbrevCollMap.end(); 16060484Sobrien} 16160484Sobrien 16260484Sobrien//---------------------------------------------------------------------- 16360484Sobrien// DWARFDebugAbbrev::Dump() 16460484Sobrien//---------------------------------------------------------------------- 16560484Sobrienvoid 16660484SobrienDWARFDebugAbbrev::Dump(Stream *s) const 16760484Sobrien{ 16860484Sobrien if (m_abbrevCollMap.empty()) 16960484Sobrien { 17060484Sobrien s->PutCString("< EMPTY >\n"); 17160484Sobrien return; 17260484Sobrien } 17360484Sobrien 17460484Sobrien DWARFAbbreviationDeclarationCollMapConstIter pos; 17560484Sobrien for (pos = m_abbrevCollMap.begin(); pos != m_abbrevCollMap.end(); ++pos) 17660484Sobrien { 17760484Sobrien s->Printf("Abbrev table for offset: 0x%8.8x\n", pos->first); 17860484Sobrien pos->second.Dump(s); 17960484Sobrien } 18060484Sobrien} 18160484Sobrien 18260484Sobrien 18360484Sobrien//---------------------------------------------------------------------- 18460484Sobrien// DWARFDebugAbbrev::GetAbbreviationDeclarationSet() 18560484Sobrien//---------------------------------------------------------------------- 18660484Sobrienconst DWARFAbbreviationDeclarationSet* 18760484SobrienDWARFDebugAbbrev::GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const 18860484Sobrien{ 18960484Sobrien DWARFAbbreviationDeclarationCollMapConstIter end = m_abbrevCollMap.end(); 19060484Sobrien DWARFAbbreviationDeclarationCollMapConstIter pos; 19160484Sobrien if (m_prev_abbr_offset_pos != end && m_prev_abbr_offset_pos->first == cu_abbr_offset) 19260484Sobrien return &(m_prev_abbr_offset_pos->second); 19360484Sobrien else 19460484Sobrien { 19560484Sobrien pos = m_abbrevCollMap.find(cu_abbr_offset); 19660484Sobrien m_prev_abbr_offset_pos = pos; 19760484Sobrien } 19860484Sobrien 19960484Sobrien if (pos != m_abbrevCollMap.end()) 20060484Sobrien return &(pos->second); 20160484Sobrien return NULL; 20260484Sobrien} 20360484Sobrien