diff options
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp')
-rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp new file mode 100644 index 00000000000..0421ced55d4 --- /dev/null +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp @@ -0,0 +1,166 @@ +//===-- 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, uint32_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); + } +} + |