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/RegularExpression.h" 13 #include "lldb/Core/Log.h" 14 15 #include "SymbolFileDWARF.h" 16 17 using namespace lldb_private; 18 19 DWARFDebugPubnamesSet::DWARFDebugPubnamesSet() : 20 m_offset(DW_INVALID_OFFSET), 21 m_header(), 22 m_descriptors(), 23 m_name_to_descriptor_index() 24 { 25 } 26 27 DWARFDebugPubnamesSet::DWARFDebugPubnamesSet(dw_offset_t debug_aranges_offset, dw_offset_t cu_die_offset, dw_offset_t cu_die_length) : 28 m_offset(debug_aranges_offset), 29 m_header(), 30 m_descriptors(), 31 m_name_to_descriptor_index() 32 { 33 m_header.length = 10; // set the length to only include the header right for now 34 m_header.version = 2; // The DWARF version number 35 m_header.die_offset = cu_die_offset;// compile unit .debug_info offset 36 m_header.die_length = cu_die_length;// compile unit .debug_info length 37 } 38 39 void 40 DWARFDebugPubnamesSet::AddDescriptor(dw_offset_t cu_rel_offset, const char* name) 41 { 42 if (name && name[0]) 43 { 44 // Adjust our header length 45 m_header.length += strlen(name) + 1 + sizeof(dw_offset_t); 46 Descriptor pubnameDesc(cu_rel_offset, name); 47 m_descriptors.push_back(pubnameDesc); 48 } 49 } 50 51 void 52 DWARFDebugPubnamesSet::Clear() 53 { 54 m_offset = DW_INVALID_OFFSET; 55 m_header.length = 10; 56 m_header.version = 2; 57 m_header.die_offset = DW_INVALID_OFFSET; 58 m_header.die_length = 0; 59 m_descriptors.clear(); 60 } 61 62 63 //---------------------------------------------------------------------- 64 // InitNameIndexes 65 //---------------------------------------------------------------------- 66 void 67 DWARFDebugPubnamesSet::InitNameIndexes() const 68 { 69 // Create the name index vector to be able to quickly search by name 70 const size_t count = m_descriptors.size(); 71 for (uint32_t idx = 0; idx < count; ++idx) 72 { 73 const char* name = m_descriptors[idx].name.c_str(); 74 if (name && name[0]) 75 m_name_to_descriptor_index.insert(cstr_to_index_mmap::value_type(name, idx)); 76 } 77 } 78 79 80 bool 81 DWARFDebugPubnamesSet::Extract(const DataExtractor& data, lldb::offset_t *offset_ptr) 82 { 83 if (data.ValidOffset(*offset_ptr)) 84 { 85 m_descriptors.clear(); 86 m_offset = *offset_ptr; 87 m_header.length = data.GetU32(offset_ptr); 88 m_header.version = data.GetU16(offset_ptr); 89 m_header.die_offset = data.GetU32(offset_ptr); 90 m_header.die_length = data.GetU32(offset_ptr); 91 92 Descriptor pubnameDesc; 93 while (data.ValidOffset(*offset_ptr)) 94 { 95 pubnameDesc.offset = data.GetU32(offset_ptr); 96 97 if (pubnameDesc.offset) 98 { 99 const char* name = data.GetCStr(offset_ptr); 100 if (name && name[0]) 101 { 102 pubnameDesc.name = name; 103 m_descriptors.push_back(pubnameDesc); 104 } 105 } 106 else 107 break; // We are done if we get a zero 4 byte offset 108 } 109 110 return !m_descriptors.empty(); 111 } 112 return false; 113 } 114 115 dw_offset_t 116 DWARFDebugPubnamesSet::GetOffsetOfNextEntry() const 117 { 118 return m_offset + m_header.length + 4; 119 } 120 121 void 122 DWARFDebugPubnamesSet::Dump(Log *log) const 123 { 124 log->Printf("Pubnames Header: length = 0x%8.8x, version = 0x%4.4x, die_offset = 0x%8.8x, die_length = 0x%8.8x", 125 m_header.length, 126 m_header.version, 127 m_header.die_offset, 128 m_header.die_length); 129 130 bool verbose = log->GetVerbose(); 131 132 DescriptorConstIter pos; 133 DescriptorConstIter end = m_descriptors.end(); 134 for (pos = m_descriptors.begin(); pos != end; ++pos) 135 { 136 if (verbose) 137 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()); 138 else 139 log->Printf("0x%8.8x: %s", pos->offset + m_header.die_offset, pos->name.c_str()); 140 } 141 } 142 143 144 void 145 DWARFDebugPubnamesSet::Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offset_coll) const 146 { 147 if (!m_descriptors.empty() && m_name_to_descriptor_index.empty()) 148 InitNameIndexes(); 149 150 std::pair<cstr_to_index_mmap::const_iterator, cstr_to_index_mmap::const_iterator> range(m_name_to_descriptor_index.equal_range(name)); 151 for (cstr_to_index_mmap::const_iterator pos = range.first; pos != range.second; ++pos) 152 die_offset_coll.push_back(m_header.die_offset + m_descriptors[(*pos).second].offset); 153 } 154 155 void 156 DWARFDebugPubnamesSet::Find(const RegularExpression& regex, std::vector<dw_offset_t>& die_offset_coll) const 157 { 158 DescriptorConstIter pos; 159 DescriptorConstIter end = m_descriptors.end(); 160 for (pos = m_descriptors.begin(); pos != end; ++pos) 161 { 162 if ( regex.Execute(pos->name.c_str()) ) 163 die_offset_coll.push_back(m_header.die_offset + pos->offset); 164 } 165 } 166 167