1 //===-- DWARFDebugPubnamesSet.cpp -------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "DWARFDebugPubnamesSet.h"
12 #include "lldb/Utility/Log.h"
13 #include "lldb/Utility/RegularExpression.h"
15 #include "SymbolFileDWARF.h"
17 using namespace lldb_private;
19 DWARFDebugPubnamesSet::DWARFDebugPubnamesSet()
20 : m_offset(DW_INVALID_OFFSET), m_header(), m_descriptors(),
21 m_name_to_descriptor_index() {}
23 DWARFDebugPubnamesSet::DWARFDebugPubnamesSet(dw_offset_t debug_aranges_offset,
24 dw_offset_t cu_die_offset,
25 dw_offset_t cu_die_length)
26 : m_offset(debug_aranges_offset), m_header(), m_descriptors(),
27 m_name_to_descriptor_index() {
29 10; // set the length to only include the header right for now
30 m_header.version = 2; // The DWARF version number
31 m_header.die_offset = cu_die_offset; // compile unit .debug_info offset
32 m_header.die_length = cu_die_length; // compile unit .debug_info length
35 void DWARFDebugPubnamesSet::AddDescriptor(dw_offset_t cu_rel_offset,
37 if (name && name[0]) {
38 // Adjust our header length
39 m_header.length += strlen(name) + 1 + sizeof(dw_offset_t);
40 Descriptor pubnameDesc(cu_rel_offset, name);
41 m_descriptors.push_back(pubnameDesc);
45 void DWARFDebugPubnamesSet::Clear() {
46 m_offset = DW_INVALID_OFFSET;
49 m_header.die_offset = DW_INVALID_OFFSET;
50 m_header.die_length = 0;
51 m_descriptors.clear();
54 //----------------------------------------------------------------------
56 //----------------------------------------------------------------------
57 void DWARFDebugPubnamesSet::InitNameIndexes() const {
58 // Create the name index vector to be able to quickly search by name
59 const size_t count = m_descriptors.size();
60 for (uint32_t idx = 0; idx < count; ++idx) {
61 const char *name = m_descriptors[idx].name.c_str();
63 m_name_to_descriptor_index.insert(
64 cstr_to_index_mmap::value_type(name, idx));
68 bool DWARFDebugPubnamesSet::Extract(const DWARFDataExtractor &data,
69 lldb::offset_t *offset_ptr) {
70 if (data.ValidOffset(*offset_ptr)) {
71 m_descriptors.clear();
72 m_offset = *offset_ptr;
73 m_header.length = data.GetDWARFInitialLength(offset_ptr);
74 m_header.version = data.GetU16(offset_ptr);
75 m_header.die_offset = data.GetDWARFOffset(offset_ptr);
76 m_header.die_length = data.GetDWARFOffset(offset_ptr);
78 Descriptor pubnameDesc;
79 while (data.ValidOffset(*offset_ptr)) {
80 pubnameDesc.offset = data.GetDWARFOffset(offset_ptr);
82 if (pubnameDesc.offset) {
83 const char *name = data.GetCStr(offset_ptr);
84 if (name && name[0]) {
85 pubnameDesc.name = name;
86 m_descriptors.push_back(pubnameDesc);
89 break; // We are done if we get a zero 4 byte offset
92 return !m_descriptors.empty();
97 dw_offset_t DWARFDebugPubnamesSet::GetOffsetOfNextEntry() const {
98 return m_offset + m_header.length + 4;
101 void DWARFDebugPubnamesSet::Dump(Log *log) const {
102 log->Printf("Pubnames Header: length = 0x%8.8x, version = 0x%4.4x, "
103 "die_offset = 0x%8.8x, die_length = 0x%8.8x",
104 m_header.length, m_header.version, m_header.die_offset,
105 m_header.die_length);
107 bool verbose = log->GetVerbose();
109 DescriptorConstIter pos;
110 DescriptorConstIter end = m_descriptors.end();
111 for (pos = m_descriptors.begin(); pos != end; ++pos) {
113 log->Printf("0x%8.8x + 0x%8.8x = 0x%8.8x: %s", pos->offset,
114 m_header.die_offset, pos->offset + m_header.die_offset,
117 log->Printf("0x%8.8x: %s", pos->offset + m_header.die_offset,
122 void DWARFDebugPubnamesSet::Find(
123 const char *name, bool ignore_case,
124 std::vector<dw_offset_t> &die_offset_coll) const {
125 if (!m_descriptors.empty() && m_name_to_descriptor_index.empty())
128 std::pair<cstr_to_index_mmap::const_iterator,
129 cstr_to_index_mmap::const_iterator>
130 range(m_name_to_descriptor_index.equal_range(name));
131 for (cstr_to_index_mmap::const_iterator pos = range.first;
132 pos != range.second; ++pos)
133 die_offset_coll.push_back(m_header.die_offset +
134 m_descriptors[(*pos).second].offset);
137 void DWARFDebugPubnamesSet::Find(
138 const RegularExpression ®ex,
139 std::vector<dw_offset_t> &die_offset_coll) const {
140 DescriptorConstIter pos;
141 DescriptorConstIter end = m_descriptors.end();
142 for (pos = m_descriptors.begin(); pos != end; ++pos) {
143 if (regex.Execute(pos->name))
144 die_offset_coll.push_back(m_header.die_offset + pos->offset);