Home | History | Annotate | Download | only in DWARF
      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 "lldb/Core/DataExtractor.h"
     12 #include "lldb/Core/Stream.h"
     13 
     14 using namespace lldb;
     15 using namespace lldb_private;
     16 using namespace std;
     17 
     18 //----------------------------------------------------------------------
     19 // DWARFAbbreviationDeclarationSet::Clear()
     20 //----------------------------------------------------------------------
     21 void
     22 DWARFAbbreviationDeclarationSet::Clear()
     23 {
     24     m_idx_offset = 0;
     25     m_decls.clear();
     26 }
     27 
     28 
     29 //----------------------------------------------------------------------
     30 // DWARFAbbreviationDeclarationSet::Extract()
     31 //----------------------------------------------------------------------
     32 bool
     33 DWARFAbbreviationDeclarationSet::Extract(const DataExtractor& data, lldb::offset_t *offset_ptr)
     34 {
     35     const lldb::offset_t begin_offset = *offset_ptr;
     36     m_offset = begin_offset;
     37     Clear();
     38     DWARFAbbreviationDeclaration abbrevDeclaration;
     39     dw_uleb128_t prev_abbr_code = 0;
     40     while (abbrevDeclaration.Extract(data, offset_ptr))
     41     {
     42         m_decls.push_back(abbrevDeclaration);
     43         if (m_idx_offset == 0)
     44             m_idx_offset = abbrevDeclaration.Code();
     45         else
     46         {
     47             if (prev_abbr_code + 1 != abbrevDeclaration.Code())
     48                 m_idx_offset = UINT32_MAX;    // Out of order indexes, we can't do O(1) lookups...
     49         }
     50         prev_abbr_code = abbrevDeclaration.Code();
     51     }
     52     return begin_offset != *offset_ptr;
     53 }
     54 
     55 
     56 //----------------------------------------------------------------------
     57 // DWARFAbbreviationDeclarationSet::Dump()
     58 //----------------------------------------------------------------------
     59 void
     60 DWARFAbbreviationDeclarationSet::Dump(Stream *s) const
     61 {
     62     std::for_each (m_decls.begin(), m_decls.end(), bind2nd(std::mem_fun_ref(&DWARFAbbreviationDeclaration::Dump),s));
     63 }
     64 
     65 
     66 //----------------------------------------------------------------------
     67 // DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration()
     68 //----------------------------------------------------------------------
     69 const DWARFAbbreviationDeclaration*
     70 DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const
     71 {
     72     if (m_idx_offset == UINT32_MAX)
     73     {
     74         DWARFAbbreviationDeclarationCollConstIter pos;
     75         DWARFAbbreviationDeclarationCollConstIter end = m_decls.end();
     76         for (pos = m_decls.begin(); pos != end; ++pos)
     77         {
     78             if (pos->Code() == abbrCode)
     79                 return &(*pos);
     80         }
     81     }
     82     else
     83     {
     84         uint32_t idx = abbrCode - m_idx_offset;
     85         if (idx < m_decls.size())
     86             return &m_decls[idx];
     87     }
     88     return NULL;
     89 }
     90 
     91 //----------------------------------------------------------------------
     92 // DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential()
     93 //
     94 // Append an abbreviation declaration with a sequential code for O(n)
     95 // lookups. Handy when creating an DWARFAbbreviationDeclarationSet.
     96 //----------------------------------------------------------------------
     97 dw_uleb128_t
     98 DWARFAbbreviationDeclarationSet::AppendAbbrevDeclSequential(const DWARFAbbreviationDeclaration& abbrevDecl)
     99 {
    100     // Get the next abbreviation code based on our current array size
    101     dw_uleb128_t code = m_decls.size()+1;
    102 
    103     // Push the new declaration on the back
    104     m_decls.push_back(abbrevDecl);
    105 
    106     // Update the code for this new declaration
    107     m_decls.back().SetCode(code);
    108 
    109     return code;    // return the new abbreviation code!
    110 }
    111 
    112 
    113 //----------------------------------------------------------------------
    114 // Encode
    115 //
    116 // Encode the abbreviation table onto the end of the buffer provided
    117 // into a byte representation as would be found in a ".debug_abbrev"
    118 // debug information section.
    119 //----------------------------------------------------------------------
    120 //void
    121 //DWARFAbbreviationDeclarationSet::Encode(BinaryStreamBuf& debug_abbrev_buf) const
    122 //{
    123 //  DWARFAbbreviationDeclarationCollConstIter pos;
    124 //  DWARFAbbreviationDeclarationCollConstIter end = m_decls.end();
    125 //  for (pos = m_decls.begin(); pos != end; ++pos)
    126 //      pos->Append(debug_abbrev_buf);
    127 //  debug_abbrev_buf.Append8(0);
    128 //}
    129 
    130 
    131 //----------------------------------------------------------------------
    132 // DWARFDebugAbbrev constructor
    133 //----------------------------------------------------------------------
    134 DWARFDebugAbbrev::DWARFDebugAbbrev() :
    135     m_abbrevCollMap(),
    136     m_prev_abbr_offset_pos(m_abbrevCollMap.end())
    137 {
    138 }
    139 
    140 
    141 //----------------------------------------------------------------------
    142 // DWARFDebugAbbrev::Parse()
    143 //----------------------------------------------------------------------
    144 void
    145 DWARFDebugAbbrev::Parse(const DataExtractor& data)
    146 {
    147     lldb::offset_t offset = 0;
    148 
    149     while (data.ValidOffset(offset))
    150     {
    151         uint32_t initial_cu_offset = offset;
    152         DWARFAbbreviationDeclarationSet abbrevDeclSet;
    153 
    154         if (abbrevDeclSet.Extract(data, &offset))
    155             m_abbrevCollMap[initial_cu_offset] = abbrevDeclSet;
    156         else
    157             break;
    158     }
    159     m_prev_abbr_offset_pos = m_abbrevCollMap.end();
    160 }
    161 
    162 //----------------------------------------------------------------------
    163 // DWARFDebugAbbrev::Dump()
    164 //----------------------------------------------------------------------
    165 void
    166 DWARFDebugAbbrev::Dump(Stream *s) const
    167 {
    168     if (m_abbrevCollMap.empty())
    169     {
    170         s->PutCString("< EMPTY >\n");
    171         return;
    172     }
    173 
    174     DWARFAbbreviationDeclarationCollMapConstIter pos;
    175     for (pos = m_abbrevCollMap.begin(); pos != m_abbrevCollMap.end(); ++pos)
    176     {
    177         s->Printf("Abbrev table for offset: 0x%8.8x\n", pos->first);
    178         pos->second.Dump(s);
    179     }
    180 }
    181 
    182 
    183 //----------------------------------------------------------------------
    184 // DWARFDebugAbbrev::GetAbbreviationDeclarationSet()
    185 //----------------------------------------------------------------------
    186 const DWARFAbbreviationDeclarationSet*
    187 DWARFDebugAbbrev::GetAbbreviationDeclarationSet(dw_offset_t cu_abbr_offset) const
    188 {
    189     DWARFAbbreviationDeclarationCollMapConstIter end = m_abbrevCollMap.end();
    190     DWARFAbbreviationDeclarationCollMapConstIter pos;
    191     if (m_prev_abbr_offset_pos != end && m_prev_abbr_offset_pos->first == cu_abbr_offset)
    192         return &(m_prev_abbr_offset_pos->second);
    193     else
    194     {
    195         pos = m_abbrevCollMap.find(cu_abbr_offset);
    196         m_prev_abbr_offset_pos = pos;
    197     }
    198 
    199     if (pos != m_abbrevCollMap.end())
    200         return &(pos->second);
    201     return NULL;
    202 }
    203