]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Plugins/SymbolFile/DWARF/DWARFDebugPubnamesSet.cpp
Vendor import of lldb trunk r290819:
[FreeBSD/FreeBSD.git] / source / Plugins / SymbolFile / DWARF / DWARFDebugPubnamesSet.cpp
1 //===-- DWARFDebugPubnamesSet.cpp -------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "DWARFDebugPubnamesSet.h"
11
12 #include "lldb/Core/Log.h"
13 #include "lldb/Core/RegularExpression.h"
14
15 #include "SymbolFileDWARF.h"
16
17 using namespace lldb_private;
18
19 DWARFDebugPubnamesSet::DWARFDebugPubnamesSet()
20     : m_offset(DW_INVALID_OFFSET), m_header(), m_descriptors(),
21       m_name_to_descriptor_index() {}
22
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() {
28   m_header.length =
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
33 }
34
35 void DWARFDebugPubnamesSet::AddDescriptor(dw_offset_t cu_rel_offset,
36                                           const char *name) {
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);
42   }
43 }
44
45 void DWARFDebugPubnamesSet::Clear() {
46   m_offset = DW_INVALID_OFFSET;
47   m_header.length = 10;
48   m_header.version = 2;
49   m_header.die_offset = DW_INVALID_OFFSET;
50   m_header.die_length = 0;
51   m_descriptors.clear();
52 }
53
54 //----------------------------------------------------------------------
55 // InitNameIndexes
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();
62     if (name && name[0])
63       m_name_to_descriptor_index.insert(
64           cstr_to_index_mmap::value_type(name, idx));
65   }
66 }
67
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);
77
78     Descriptor pubnameDesc;
79     while (data.ValidOffset(*offset_ptr)) {
80       pubnameDesc.offset = data.GetDWARFOffset(offset_ptr);
81
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);
87         }
88       } else
89         break; // We are done if we get a zero 4 byte offset
90     }
91
92     return !m_descriptors.empty();
93   }
94   return false;
95 }
96
97 dw_offset_t DWARFDebugPubnamesSet::GetOffsetOfNextEntry() const {
98   return m_offset + m_header.length + 4;
99 }
100
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);
106
107   bool verbose = log->GetVerbose();
108
109   DescriptorConstIter pos;
110   DescriptorConstIter end = m_descriptors.end();
111   for (pos = m_descriptors.begin(); pos != end; ++pos) {
112     if (verbose)
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,
115                   pos->name.c_str());
116     else
117       log->Printf("0x%8.8x: %s", pos->offset + m_header.die_offset,
118                   pos->name.c_str());
119   }
120 }
121
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())
126     InitNameIndexes();
127
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);
135 }
136
137 void DWARFDebugPubnamesSet::Find(
138     const RegularExpression &regex,
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);
145   }
146 }