//===-- 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& die_offset_coll) const { if (!m_descriptors.empty() && m_name_to_descriptor_index.empty()) InitNameIndexes(); std::pair 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& 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); } }