167 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			167 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			C++
		
	
	
	
//===-- DWARFDebugPubnamesSet.cpp -------------------------------*- C++ -*-===//
 | 
						|
//
 | 
						|
//                     The LLVM Compiler Infrastructure
 | 
						|
//
 | 
						|
// This file is distributed under the University of Illinois Open Source
 | 
						|
// License. See LICENSE.TXT for details.
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
#include "DWARFDebugPubnamesSet.h"
 | 
						|
 | 
						|
#include "lldb/Core/RegularExpression.h"
 | 
						|
#include "lldb/Core/Log.h"
 | 
						|
 | 
						|
#include "SymbolFileDWARF.h"
 | 
						|
 | 
						|
using namespace lldb_private;
 | 
						|
 | 
						|
DWARFDebugPubnamesSet::DWARFDebugPubnamesSet() :
 | 
						|
    m_offset(DW_INVALID_OFFSET),
 | 
						|
    m_header(),
 | 
						|
    m_descriptors(),
 | 
						|
    m_name_to_descriptor_index()
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
DWARFDebugPubnamesSet::DWARFDebugPubnamesSet(dw_offset_t debug_aranges_offset, dw_offset_t cu_die_offset, dw_offset_t cu_die_length) :
 | 
						|
    m_offset(debug_aranges_offset),
 | 
						|
    m_header(),
 | 
						|
    m_descriptors(),
 | 
						|
    m_name_to_descriptor_index()
 | 
						|
{
 | 
						|
    m_header.length = 10;               // set the length to only include the header right for now
 | 
						|
    m_header.version = 2;               // The DWARF version number
 | 
						|
    m_header.die_offset = cu_die_offset;// compile unit .debug_info offset
 | 
						|
    m_header.die_length = cu_die_length;// compile unit .debug_info length
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
DWARFDebugPubnamesSet::AddDescriptor(dw_offset_t cu_rel_offset, const char* name)
 | 
						|
{
 | 
						|
    if (name && name[0])
 | 
						|
    {
 | 
						|
        // Adjust our header length
 | 
						|
        m_header.length += strlen(name) + 1 + sizeof(dw_offset_t);
 | 
						|
        Descriptor pubnameDesc(cu_rel_offset, name);
 | 
						|
        m_descriptors.push_back(pubnameDesc);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
DWARFDebugPubnamesSet::Clear()
 | 
						|
{
 | 
						|
    m_offset = DW_INVALID_OFFSET;
 | 
						|
    m_header.length = 10;
 | 
						|
    m_header.version = 2;
 | 
						|
    m_header.die_offset = DW_INVALID_OFFSET;
 | 
						|
    m_header.die_length = 0;
 | 
						|
    m_descriptors.clear();
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
//----------------------------------------------------------------------
 | 
						|
// InitNameIndexes
 | 
						|
//----------------------------------------------------------------------
 | 
						|
void
 | 
						|
DWARFDebugPubnamesSet::InitNameIndexes() const
 | 
						|
{
 | 
						|
    // Create the name index vector to be able to quickly search by name
 | 
						|
    const size_t count = m_descriptors.size();
 | 
						|
    for (uint32_t idx = 0; idx < count; ++idx)
 | 
						|
    {
 | 
						|
        const char* name = m_descriptors[idx].name.c_str();
 | 
						|
        if (name && name[0])
 | 
						|
            m_name_to_descriptor_index.insert(cstr_to_index_mmap::value_type(name, idx));
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
bool
 | 
						|
DWARFDebugPubnamesSet::Extract(const DataExtractor& data, lldb::offset_t *offset_ptr)
 | 
						|
{
 | 
						|
    if (data.ValidOffset(*offset_ptr))
 | 
						|
    {
 | 
						|
        m_descriptors.clear();
 | 
						|
        m_offset = *offset_ptr;
 | 
						|
        m_header.length     = data.GetU32(offset_ptr);
 | 
						|
        m_header.version    = data.GetU16(offset_ptr);
 | 
						|
        m_header.die_offset = data.GetU32(offset_ptr);
 | 
						|
        m_header.die_length = data.GetU32(offset_ptr);
 | 
						|
 | 
						|
        Descriptor pubnameDesc;
 | 
						|
        while (data.ValidOffset(*offset_ptr))
 | 
						|
        {
 | 
						|
            pubnameDesc.offset  = data.GetU32(offset_ptr);
 | 
						|
 | 
						|
            if (pubnameDesc.offset)
 | 
						|
            {
 | 
						|
                const char* name = data.GetCStr(offset_ptr);
 | 
						|
                if (name && name[0])
 | 
						|
                {
 | 
						|
                    pubnameDesc.name = name;
 | 
						|
                    m_descriptors.push_back(pubnameDesc);
 | 
						|
                }
 | 
						|
            }
 | 
						|
            else
 | 
						|
                break;  // We are done if we get a zero 4 byte offset
 | 
						|
        }
 | 
						|
 | 
						|
        return !m_descriptors.empty();
 | 
						|
    }
 | 
						|
    return false;
 | 
						|
}
 | 
						|
 | 
						|
dw_offset_t
 | 
						|
DWARFDebugPubnamesSet::GetOffsetOfNextEntry() const
 | 
						|
{
 | 
						|
    return m_offset + m_header.length + 4;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
DWARFDebugPubnamesSet::Dump(Log *log) const
 | 
						|
{
 | 
						|
    log->Printf("Pubnames Header: length = 0x%8.8x, version = 0x%4.4x, die_offset = 0x%8.8x, die_length = 0x%8.8x",
 | 
						|
        m_header.length,
 | 
						|
        m_header.version,
 | 
						|
        m_header.die_offset,
 | 
						|
        m_header.die_length);
 | 
						|
 | 
						|
    bool verbose = log->GetVerbose();
 | 
						|
 | 
						|
    DescriptorConstIter pos;
 | 
						|
    DescriptorConstIter end = m_descriptors.end();
 | 
						|
    for (pos = m_descriptors.begin(); pos != end; ++pos)
 | 
						|
    {
 | 
						|
        if (verbose)
 | 
						|
            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());
 | 
						|
        else
 | 
						|
            log->Printf("0x%8.8x: %s", pos->offset + m_header.die_offset, pos->name.c_str());
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void
 | 
						|
DWARFDebugPubnamesSet::Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offset_coll) const
 | 
						|
{
 | 
						|
    if (!m_descriptors.empty() && m_name_to_descriptor_index.empty())
 | 
						|
        InitNameIndexes();
 | 
						|
 | 
						|
    std::pair<cstr_to_index_mmap::const_iterator, cstr_to_index_mmap::const_iterator> range(m_name_to_descriptor_index.equal_range(name));
 | 
						|
    for (cstr_to_index_mmap::const_iterator pos = range.first; pos != range.second; ++pos)
 | 
						|
        die_offset_coll.push_back(m_header.die_offset + m_descriptors[(*pos).second].offset);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
DWARFDebugPubnamesSet::Find(const RegularExpression& regex, std::vector<dw_offset_t>& die_offset_coll) const
 | 
						|
{
 | 
						|
    DescriptorConstIter pos;
 | 
						|
    DescriptorConstIter end = m_descriptors.end();
 | 
						|
    for (pos = m_descriptors.begin(); pos != end; ++pos)
 | 
						|
    {
 | 
						|
        if ( regex.Execute(pos->name.c_str()) )
 | 
						|
            die_offset_coll.push_back(m_header.die_offset + pos->offset);
 | 
						|
    }
 | 
						|
}
 | 
						|
 |