summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp')
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp166
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);
+ }
+}
+
OpenPOWER on IntegriCloud