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