summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp')
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp136
1 files changed, 136 insertions, 0 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
new file mode 100644
index 00000000000..6eb249bfc34
--- /dev/null
+++ b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
@@ -0,0 +1,136 @@
+//===-- HashedNameToDIE.cpp -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "HashedNameToDIE.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Core/RegularExpression.h"
+#include "lldb/Symbol/ObjectFile.h"
+
+#include "DWARFCompileUnit.h"
+#include "DWARFDebugInfo.h"
+#include "DWARFDebugInfoEntry.h"
+#include "SymbolFileDWARF.h"
+using namespace lldb;
+using namespace lldb_private;
+
+static uint32_t
+dl_new_hash (const char *s)
+{
+ uint32_t h = 5381;
+
+ for (unsigned char c = *s; c; c = *++s)
+ h = ((h << 5) + h) + c;
+
+ return h;
+}
+
+HashedNameToDIE::HashedNameToDIE (SymbolFileDWARF *dwarf, const DataExtractor &data) :
+ m_dwarf (dwarf),
+ m_data (data),
+ m_header ()
+{
+ uint32_t offset = 0;
+ m_header.version = m_data.GetU16(&offset);
+ m_header.hash_type = m_data.GetU8(&offset);
+ m_header.hash_index_bitsize = m_data.GetU8(&offset);
+ m_header.num_buckets = m_data.GetU32(&offset);
+ m_header.num_hashes = m_data.GetU32(&offset);
+ m_header.die_offset_base = m_data.GetU32(&offset);
+}
+
+
+size_t
+HashedNameToDIE::Find (const ConstString &name, DIEArray &die_ofsets) const
+{
+ const size_t initial_size = die_ofsets.size();
+ const char *name_cstr = name.GetCString();
+ if (name_cstr && name_cstr[0])
+ {
+ // Hash the C string
+ const uint32_t name_hash = dl_new_hash (name_cstr);
+
+ // Find the correct bucket for the using the hash value
+ const uint32_t bucket_idx = name_hash % m_header.num_buckets;
+
+ // Calculate the offset for the bucket entry for the bucket index
+ uint32_t offset = GetOffsetForBucket (bucket_idx);
+
+ // Extract the bucket entry.
+ const uint32_t bucket_entry = m_data.GetU32 (&offset);
+ if (bucket_entry)
+ {
+ // The bucket entry is non-zero which means it isn't empty.
+ // The bucket entry is made up of a hash index whose bit width
+ // is m_header.hash_index_bitsize, and a hash count whose value
+ // is the remaining bits in the 32 bit value. Below we extract
+ // the hash index and the hash count
+ const uint32_t hash_idx = bucket_entry & GetHashIndexMask();
+ const uint32_t hash_count = bucket_entry >> m_header.hash_index_bitsize;
+ const uint32_t hash_end_idx = hash_idx + hash_count;
+ // Figure out the offset to the hash value by index
+ uint32_t hash_offset = GetOffsetForHash (hash_idx);
+ for (uint32_t idx = hash_idx; idx < hash_end_idx; ++idx)
+ {
+ // Extract the hash value and see if it matches our string
+ const uint32_t hash = m_data.GetU32 (&hash_offset);
+ if (hash == name_hash)
+ {
+ // The hash matches, but we still need to verify that the
+ // C string matches in case we have a hash collision. Figure
+ // out the offset for the data associated with this hash entry
+ offset = GetOffsetForOffset (hash_idx);
+ // Extract the first 32 bit value which is the .debug_str offset
+ // of the string we need
+ const uint32_t str_offset = m_data.GetU32 (&offset);
+ // Extract the C string and comapare it
+ const char *cstr_name = m_dwarf->get_debug_str_data().PeekCStr(str_offset);
+ if (strcmp(name_cstr, cstr_name) == 0)
+ {
+ // We have a match, now extract the DIE count
+ const uint32_t die_count = m_data.GetU32 (&offset);
+ // Now extract "die_count" DIE offsets and put them into the
+ // results
+ for (uint32_t die_idx = 0; die_idx < die_count; ++die_idx)
+ die_ofsets.push_back(m_data.GetU32 (&offset));
+ }
+ }
+ }
+ }
+ }
+ return die_ofsets.size() - initial_size;
+}
+
+size_t
+HashedNameToDIE::Find (const RegularExpression& regex, DIEArray &die_ofsets) const
+{
+// const size_t initial_info_array_size = info_array.size();
+// collection::const_iterator pos, end = m_collection.end();
+// for (pos = m_collection.begin(); pos != end; ++pos)
+// {
+// if (regex.Execute(pos->first))
+// info_array.push_back (pos->second);
+// }
+// return info_array.size() - initial_info_array_size;
+ return 0;
+}
+
+void
+HashedNameToDIE::Dump (Stream *s)
+{
+// collection::const_iterator pos, end = m_collection.end();
+// for (pos = m_collection.begin(); pos != end; ++pos)
+// {
+// s->Printf("%p: 0x%8.8x 0x%8.8x \"%s\"\n", pos->first, pos->second.cu_idx, pos->second.die_idx, pos->first);
+// }
+}
+
+
OpenPOWER on IntegriCloud