124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- DWARFDebugAbbrev.cpp ------------------------------------*- C++ -*-===//
224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                     The LLVM Compiler Infrastructure
424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source
624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details.
724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "DWARFDebugAbbrev.h"
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/DataExtractor.h"
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Stream.h"
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb;
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private;
1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace std;
1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DWARFAbbreviationDeclarationSet::Clear()
2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFAbbreviationDeclarationSet::Clear()
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_idx_offset = 0;
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_decls.clear();
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DWARFAbbreviationDeclarationSet::Extract()
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
3336da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg ClaytonDWARFAbbreviationDeclarationSet::Extract(const DataExtractor& data, lldb::offset_t *offset_ptr)
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
3536da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton    const lldb::offset_t begin_offset = *offset_ptr;
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_offset = begin_offset;
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Clear();
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DWARFAbbreviationDeclaration abbrevDeclaration;
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    dw_uleb128_t prev_abbr_code = 0;
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    while (abbrevDeclaration.Extract(data, offset_ptr))
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_decls.push_back(abbrevDeclaration);
4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (m_idx_offset == 0)
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            m_idx_offset = abbrevDeclaration.Code();
4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        else
4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (prev_abbr_code + 1 != abbrevDeclaration.Code())
48178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton                m_idx_offset = UINT32_MAX;    // Out of order indexes, we can't do O(1) lookups...
4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        prev_abbr_code = abbrevDeclaration.Code();
5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return begin_offset != *offset_ptr;
5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DWARFAbbreviationDeclarationSet::Dump()
5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFAbbreviationDeclarationSet::Dump(Stream *s) const
6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    std::for_each (m_decls.begin(), m_decls.end(), bind2nd(std::mem_fun_ref(&DWARFAbbreviationDeclaration::Dump),s));
6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration()
6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerconst DWARFAbbreviationDeclaration*
7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const
7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
72178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton    if (m_idx_offset == UINT32_MAX)
7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DWARFAbbreviationDeclarationCollConstIter pos;
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DWARFAbbreviationDeclarationCollConstIter end = m_decls.end();
7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        for (pos = m_decls.begin(); pos != end; ++pos)
7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (pos->Code() == abbrCode)
7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                return &(*pos);
8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t idx = abbrCode - m_idx_offset;
8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (idx < m_decls.size())
8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return &m_decls[idx];
8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return NULL;
8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential()
9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Append an abbreviation declaration with a sequential code for O(n)
9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// lookups. Handy when creating an DWARFAbbreviationDeclarationSet.
9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerdw_uleb128_t
9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential(const DWARFAbbreviationDeclaration& abbrevDecl)
9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Get the next abbreviation code based on our current array size
10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    dw_uleb128_t code = m_decls.size()+1;
10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Push the new declaration on the back
10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_decls.push_back(abbrevDecl);
10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Update the code for this new declaration
10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_decls.back().SetCode(code);
10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return code;    // return the new abbreviation code!
11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Encode
11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Encode the abbreviation table onto the end of the buffer provided
1175d187e5495ee17f6763337a6ae28c2a7b07e4945Greg Clayton// into a byte representation as would be found in a ".debug_abbrev"
11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// debug information section.
11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//void
12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//DWARFAbbreviationDeclarationSet::Encode(BinaryStreamBuf& debug_abbrev_buf) const
12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//{
12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  DWARFAbbreviationDeclarationCollConstIter pos;
12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  DWARFAbbreviationDeclarationCollConstIter end = m_decls.end();
12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  for (pos = m_decls.begin(); pos != end; ++pos)
12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//      pos->Append(debug_abbrev_buf);
12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  debug_abbrev_buf.Append8(0);
12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//}
12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DWARFDebugAbbrev constructor
13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugAbbrev::DWARFDebugAbbrev() :
13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_abbrevCollMap(),
13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_prev_abbr_offset_pos(m_abbrevCollMap.end())
13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DWARFDebugAbbrev::Parse()
14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugAbbrev::Parse(const DataExtractor& data)
14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
14736da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton    lldb::offset_t offset = 0;
14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    while (data.ValidOffset(offset))
15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t initial_cu_offset = offset;
15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DWARFAbbreviationDeclarationSet abbrevDeclSet;
15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (abbrevDeclSet.Extract(data, &offset))
15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet;
15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        else
15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            break;
15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_prev_abbr_offset_pos = m_abbrevCollMap.end();
16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DWARFDebugAbbrev::Dump()
16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugAbbrev::Dump(Stream *s) const
16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_abbrevCollMap.empty())
16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        s->PutCString("< EMPTY >\n");
17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return;
17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DWARFAbbreviationDeclarationCollMapConstIter pos;
17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (pos = m_abbrevCollMap.begin(); pos != m_abbrevCollMap.end(); ++pos)
17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        s->Printf("Abbrev table for offset: 0x%8.8x\n", pos->first);
17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        pos->second.Dump(s);
17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// DWARFDebugAbbrev::GetAbbreviationDeclarationSet()
18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerconst DWARFAbbreviationDeclarationSet*
18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugAbbrev::GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const
18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DWARFAbbreviationDeclarationCollMapConstIter end = m_abbrevCollMap.end();
19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DWARFAbbreviationDeclarationCollMapConstIter pos;
19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_prev_abbr_offset_pos != end && m_prev_abbr_offset_pos->first == cu_abbr_offset)
19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return &(m_prev_abbr_offset_pos->second);
19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        pos = m_abbrevCollMap.find(cu_abbr_offset);
19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        m_prev_abbr_offset_pos = pos;
19724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
19990bc5c69bb47b35debff1951ebe78ab0cf17f9f1Greg Clayton    if (pos != m_abbrevCollMap.end())
20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return &(pos->second);
20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return NULL;
20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
203