| //===-- 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); |
| } |
| } |
| |