DWARFDebugAbbrev.cpp [plain text]
#include "DWARFDebugAbbrev.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Stream.h"
using namespace lldb;
using namespace lldb_private;
using namespace std;
void
DWARFAbbreviationDeclarationSet::Clear()
{
m_idx_offset = 0;
m_decls.clear();
}
bool
DWARFAbbreviationDeclarationSet::Extract(const DataExtractor& data, uint32_t* offset_ptr)
{
const uint32_t begin_offset = *offset_ptr;
m_offset = begin_offset;
Clear();
DWARFAbbreviationDeclaration abbrevDeclaration;
dw_uleb128_t prev_abbr_code = 0;
while (abbrevDeclaration.Extract(data, offset_ptr))
{
m_decls.push_back(abbrevDeclaration);
if (m_idx_offset == 0)
m_idx_offset = abbrevDeclaration.Code();
else
{
if (prev_abbr_code + 1 != abbrevDeclaration.Code())
m_idx_offset = UINT32_MAX; }
prev_abbr_code = abbrevDeclaration.Code();
}
return begin_offset != *offset_ptr;
}
void
DWARFAbbreviationDeclarationSet::Dump(Stream *s) const
{
std::for_each (m_decls.begin(), m_decls.end(), bind2nd(std::mem_fun_ref(&DWARFAbbreviationDeclaration::Dump),s));
}
const DWARFAbbreviationDeclaration*
DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const
{
if (m_idx_offset == UINT32_MAX)
{
DWARFAbbreviationDeclarationCollConstIter pos;
DWARFAbbreviationDeclarationCollConstIter end = m_decls.end();
for (pos = m_decls.begin(); pos != end; ++pos)
{
if (pos->Code() == abbrCode)
return &(*pos);
}
}
else
{
uint32_t idx = abbrCode - m_idx_offset;
if (idx < m_decls.size())
return &m_decls[idx];
}
return NULL;
}
dw_uleb128_t
DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential(const DWARFAbbreviationDeclaration& abbrevDecl)
{
dw_uleb128_t code = m_decls.size()+1;
m_decls.push_back(abbrevDecl);
m_decls.back().SetCode(code);
return code; }
DWARFDebugAbbrev::DWARFDebugAbbrev() :
m_abbrevCollMap(),
m_prev_abbr_offset_pos(m_abbrevCollMap.end())
{
}
void
DWARFDebugAbbrev::Parse(const DataExtractor& data)
{
uint32_t offset = 0;
while (data.ValidOffset(offset))
{
uint32_t initial_cu_offset = offset;
DWARFAbbreviationDeclarationSet abbrevDeclSet;
if (abbrevDeclSet.Extract(data, &offset))
m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet;
else
break;
}
m_prev_abbr_offset_pos = m_abbrevCollMap.end();
}
void
DWARFDebugAbbrev::Dump(Stream *s) const
{
if (m_abbrevCollMap.empty())
{
s->PutCString("< EMPTY >\n");
return;
}
DWARFAbbreviationDeclarationCollMapConstIter pos;
for (pos = m_abbrevCollMap.begin(); pos != m_abbrevCollMap.end(); ++pos)
{
s->Printf("Abbrev table for offset: 0x%8.8x\n", pos->first);
pos->second.Dump(s);
}
}
const DWARFAbbreviationDeclarationSet*
DWARFDebugAbbrev::GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const
{
DWARFAbbreviationDeclarationCollMapConstIter end = m_abbrevCollMap.end();
DWARFAbbreviationDeclarationCollMapConstIter pos;
if (m_prev_abbr_offset_pos != end && m_prev_abbr_offset_pos->first == cu_abbr_offset)
return &(m_prev_abbr_offset_pos->second);
else
{
pos = m_abbrevCollMap.find(cu_abbr_offset);
m_prev_abbr_offset_pos = pos;
}
if (pos != m_abbrevCollMap.end())
return &(pos->second);
return NULL;
}