Home | History | Annotate | Download | only in DWARF
      1 //===-- DWARFDebugPubnamesSet.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 "DWARFDebugPubnamesSet.h"
     11 
     12 #include "lldb/Core/RegularExpression.h"
     13 #include "lldb/Core/Log.h"
     14 
     15 #include "SymbolFileDWARF.h"
     16 
     17 using namespace lldb_private;
     18 
     19 DWARFDebugPubnamesSet::DWARFDebugPubnamesSet() :
     20     m_offset(DW_INVALID_OFFSET),
     21     m_header(),
     22     m_descriptors(),
     23     m_name_to_descriptor_index()
     24 {
     25 }
     26 
     27 DWARFDebugPubnamesSet::DWARFDebugPubnamesSet(dw_offset_t debug_aranges_offset, dw_offset_t cu_die_offset, dw_offset_t cu_die_length) :
     28     m_offset(debug_aranges_offset),
     29     m_header(),
     30     m_descriptors(),
     31     m_name_to_descriptor_index()
     32 {
     33     m_header.length = 10;               // set the length to only include the header right for now
     34     m_header.version = 2;               // The DWARF version number
     35     m_header.die_offset = cu_die_offset;// compile unit .debug_info offset
     36     m_header.die_length = cu_die_length;// compile unit .debug_info length
     37 }
     38 
     39 void
     40 DWARFDebugPubnamesSet::AddDescriptor(dw_offset_t cu_rel_offset, const char* name)
     41 {
     42     if (name && name[0])
     43     {
     44         // Adjust our header length
     45         m_header.length += strlen(name) + 1 + sizeof(dw_offset_t);
     46         Descriptor pubnameDesc(cu_rel_offset, name);
     47         m_descriptors.push_back(pubnameDesc);
     48     }
     49 }
     50 
     51 void
     52 DWARFDebugPubnamesSet::Clear()
     53 {
     54     m_offset = DW_INVALID_OFFSET;
     55     m_header.length = 10;
     56     m_header.version = 2;
     57     m_header.die_offset = DW_INVALID_OFFSET;
     58     m_header.die_length = 0;
     59     m_descriptors.clear();
     60 }
     61 
     62 
     63 //----------------------------------------------------------------------
     64 // InitNameIndexes
     65 //----------------------------------------------------------------------
     66 void
     67 DWARFDebugPubnamesSet::InitNameIndexes() const
     68 {
     69     // Create the name index vector to be able to quickly search by name
     70     const size_t count = m_descriptors.size();
     71     for (uint32_t idx = 0; idx < count; ++idx)
     72     {
     73         const char* name = m_descriptors[idx].name.c_str();
     74         if (name && name[0])
     75             m_name_to_descriptor_index.insert(cstr_to_index_mmap::value_type(name, idx));
     76     }
     77 }
     78 
     79 
     80 bool
     81 DWARFDebugPubnamesSet::Extract(const DataExtractor& data, lldb::offset_t *offset_ptr)
     82 {
     83     if (data.ValidOffset(*offset_ptr))
     84     {
     85         m_descriptors.clear();
     86         m_offset = *offset_ptr;
     87         m_header.length     = data.GetU32(offset_ptr);
     88         m_header.version    = data.GetU16(offset_ptr);
     89         m_header.die_offset = data.GetU32(offset_ptr);
     90         m_header.die_length = data.GetU32(offset_ptr);
     91 
     92         Descriptor pubnameDesc;
     93         while (data.ValidOffset(*offset_ptr))
     94         {
     95             pubnameDesc.offset  = data.GetU32(offset_ptr);
     96 
     97             if (pubnameDesc.offset)
     98             {
     99                 const char* name = data.GetCStr(offset_ptr);
    100                 if (name && name[0])
    101                 {
    102                     pubnameDesc.name = name;
    103                     m_descriptors.push_back(pubnameDesc);
    104                 }
    105             }
    106             else
    107                 break;  // We are done if we get a zero 4 byte offset
    108         }
    109 
    110         return !m_descriptors.empty();
    111     }
    112     return false;
    113 }
    114 
    115 dw_offset_t
    116 DWARFDebugPubnamesSet::GetOffsetOfNextEntry() const
    117 {
    118     return m_offset + m_header.length + 4;
    119 }
    120 
    121 void
    122 DWARFDebugPubnamesSet::Dump(Log *log) const
    123 {
    124     log->Printf("Pubnames Header: length = 0x%8.8x, version = 0x%4.4x, die_offset = 0x%8.8x, die_length = 0x%8.8x",
    125         m_header.length,
    126         m_header.version,
    127         m_header.die_offset,
    128         m_header.die_length);
    129 
    130     bool verbose = log->GetVerbose();
    131 
    132     DescriptorConstIter pos;
    133     DescriptorConstIter end = m_descriptors.end();
    134     for (pos = m_descriptors.begin(); pos != end; ++pos)
    135     {
    136         if (verbose)
    137             log->Printf("0x%8.8x + 0x%8.8x = 0x%8.8x: %s", pos->offset, m_header.die_offset, pos->offset + m_header.die_offset, pos->name.c_str());
    138         else
    139             log->Printf("0x%8.8x: %s", pos->offset + m_header.die_offset, pos->name.c_str());
    140     }
    141 }
    142 
    143 
    144 void
    145 DWARFDebugPubnamesSet::Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offset_coll) const
    146 {
    147     if (!m_descriptors.empty() && m_name_to_descriptor_index.empty())
    148         InitNameIndexes();
    149 
    150     std::pair<cstr_to_index_mmap::const_iterator, cstr_to_index_mmap::const_iterator> range(m_name_to_descriptor_index.equal_range(name));
    151     for (cstr_to_index_mmap::const_iterator pos = range.first; pos != range.second; ++pos)
    152         die_offset_coll.push_back(m_header.die_offset + m_descriptors[(*pos).second].offset);
    153 }
    154 
    155 void
    156 DWARFDebugPubnamesSet::Find(const RegularExpression& regex, std::vector<dw_offset_t>& die_offset_coll) const
    157 {
    158     DescriptorConstIter pos;
    159     DescriptorConstIter end = m_descriptors.end();
    160     for (pos = m_descriptors.begin(); pos != end; ++pos)
    161     {
    162         if ( regex.Execute(pos->name.c_str()) )
    163             die_offset_coll.push_back(m_header.die_offset + pos->offset);
    164     }
    165 }
    166 
    167