1254721Semaste//===-- DWARFDebugPubnamesSet.cpp -------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "DWARFDebugPubnamesSet.h" 11254721Semaste 12254721Semaste#include "lldb/Core/RegularExpression.h" 13254721Semaste#include "lldb/Core/Log.h" 14254721Semaste 15254721Semaste#include "SymbolFileDWARF.h" 16254721Semaste 17254721Semasteusing namespace lldb_private; 18254721Semaste 19254721SemasteDWARFDebugPubnamesSet::DWARFDebugPubnamesSet() : 20254721Semaste m_offset(DW_INVALID_OFFSET), 21254721Semaste m_header(), 22254721Semaste m_descriptors(), 23254721Semaste m_name_to_descriptor_index() 24254721Semaste{ 25254721Semaste} 26254721Semaste 27254721SemasteDWARFDebugPubnamesSet::DWARFDebugPubnamesSet(dw_offset_t debug_aranges_offset, dw_offset_t cu_die_offset, dw_offset_t cu_die_length) : 28254721Semaste m_offset(debug_aranges_offset), 29254721Semaste m_header(), 30254721Semaste m_descriptors(), 31254721Semaste m_name_to_descriptor_index() 32254721Semaste{ 33254721Semaste m_header.length = 10; // set the length to only include the header right for now 34254721Semaste m_header.version = 2; // The DWARF version number 35254721Semaste m_header.die_offset = cu_die_offset;// compile unit .debug_info offset 36254721Semaste m_header.die_length = cu_die_length;// compile unit .debug_info length 37254721Semaste} 38254721Semaste 39254721Semastevoid 40254721SemasteDWARFDebugPubnamesSet::AddDescriptor(dw_offset_t cu_rel_offset, const char* name) 41254721Semaste{ 42254721Semaste if (name && name[0]) 43254721Semaste { 44254721Semaste // Adjust our header length 45254721Semaste m_header.length += strlen(name) + 1 + sizeof(dw_offset_t); 46254721Semaste Descriptor pubnameDesc(cu_rel_offset, name); 47254721Semaste m_descriptors.push_back(pubnameDesc); 48254721Semaste } 49254721Semaste} 50254721Semaste 51254721Semastevoid 52254721SemasteDWARFDebugPubnamesSet::Clear() 53254721Semaste{ 54254721Semaste m_offset = DW_INVALID_OFFSET; 55254721Semaste m_header.length = 10; 56254721Semaste m_header.version = 2; 57254721Semaste m_header.die_offset = DW_INVALID_OFFSET; 58254721Semaste m_header.die_length = 0; 59254721Semaste m_descriptors.clear(); 60254721Semaste} 61254721Semaste 62254721Semaste 63254721Semaste//---------------------------------------------------------------------- 64254721Semaste// InitNameIndexes 65254721Semaste//---------------------------------------------------------------------- 66254721Semastevoid 67254721SemasteDWARFDebugPubnamesSet::InitNameIndexes() const 68254721Semaste{ 69254721Semaste // Create the name index vector to be able to quickly search by name 70254721Semaste const size_t count = m_descriptors.size(); 71254721Semaste for (uint32_t idx = 0; idx < count; ++idx) 72254721Semaste { 73254721Semaste const char* name = m_descriptors[idx].name.c_str(); 74254721Semaste if (name && name[0]) 75254721Semaste m_name_to_descriptor_index.insert(cstr_to_index_mmap::value_type(name, idx)); 76254721Semaste } 77254721Semaste} 78254721Semaste 79254721Semaste 80254721Semastebool 81258054SemasteDWARFDebugPubnamesSet::Extract(const DWARFDataExtractor& data, lldb::offset_t *offset_ptr) 82254721Semaste{ 83254721Semaste if (data.ValidOffset(*offset_ptr)) 84254721Semaste { 85254721Semaste m_descriptors.clear(); 86254721Semaste m_offset = *offset_ptr; 87258054Semaste m_header.length = data.GetDWARFInitialLength(offset_ptr); 88254721Semaste m_header.version = data.GetU16(offset_ptr); 89258054Semaste m_header.die_offset = data.GetDWARFOffset(offset_ptr); 90258054Semaste m_header.die_length = data.GetDWARFOffset(offset_ptr); 91254721Semaste 92254721Semaste Descriptor pubnameDesc; 93254721Semaste while (data.ValidOffset(*offset_ptr)) 94254721Semaste { 95258054Semaste pubnameDesc.offset = data.GetDWARFOffset(offset_ptr); 96254721Semaste 97254721Semaste if (pubnameDesc.offset) 98254721Semaste { 99254721Semaste const char* name = data.GetCStr(offset_ptr); 100254721Semaste if (name && name[0]) 101254721Semaste { 102254721Semaste pubnameDesc.name = name; 103254721Semaste m_descriptors.push_back(pubnameDesc); 104254721Semaste } 105254721Semaste } 106254721Semaste else 107254721Semaste break; // We are done if we get a zero 4 byte offset 108254721Semaste } 109254721Semaste 110254721Semaste return !m_descriptors.empty(); 111254721Semaste } 112254721Semaste return false; 113254721Semaste} 114254721Semaste 115254721Semastedw_offset_t 116254721SemasteDWARFDebugPubnamesSet::GetOffsetOfNextEntry() const 117254721Semaste{ 118254721Semaste return m_offset + m_header.length + 4; 119254721Semaste} 120254721Semaste 121254721Semastevoid 122254721SemasteDWARFDebugPubnamesSet::Dump(Log *log) const 123254721Semaste{ 124254721Semaste log->Printf("Pubnames Header: length = 0x%8.8x, version = 0x%4.4x, die_offset = 0x%8.8x, die_length = 0x%8.8x", 125254721Semaste m_header.length, 126254721Semaste m_header.version, 127254721Semaste m_header.die_offset, 128254721Semaste m_header.die_length); 129254721Semaste 130254721Semaste bool verbose = log->GetVerbose(); 131254721Semaste 132254721Semaste DescriptorConstIter pos; 133254721Semaste DescriptorConstIter end = m_descriptors.end(); 134254721Semaste for (pos = m_descriptors.begin(); pos != end; ++pos) 135254721Semaste { 136254721Semaste if (verbose) 137254721Semaste 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()); 138254721Semaste else 139254721Semaste log->Printf("0x%8.8x: %s", pos->offset + m_header.die_offset, pos->name.c_str()); 140254721Semaste } 141254721Semaste} 142254721Semaste 143254721Semaste 144254721Semastevoid 145254721SemasteDWARFDebugPubnamesSet::Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offset_coll) const 146254721Semaste{ 147254721Semaste if (!m_descriptors.empty() && m_name_to_descriptor_index.empty()) 148254721Semaste InitNameIndexes(); 149254721Semaste 150254721Semaste std::pair<cstr_to_index_mmap::const_iterator, cstr_to_index_mmap::const_iterator> range(m_name_to_descriptor_index.equal_range(name)); 151254721Semaste for (cstr_to_index_mmap::const_iterator pos = range.first; pos != range.second; ++pos) 152254721Semaste die_offset_coll.push_back(m_header.die_offset + m_descriptors[(*pos).second].offset); 153254721Semaste} 154254721Semaste 155254721Semastevoid 156254721SemasteDWARFDebugPubnamesSet::Find(const RegularExpression& regex, std::vector<dw_offset_t>& die_offset_coll) const 157254721Semaste{ 158254721Semaste DescriptorConstIter pos; 159254721Semaste DescriptorConstIter end = m_descriptors.end(); 160254721Semaste for (pos = m_descriptors.begin(); pos != end; ++pos) 161254721Semaste { 162254721Semaste if ( regex.Execute(pos->name.c_str()) ) 163254721Semaste die_offset_coll.push_back(m_header.die_offset + pos->offset); 164254721Semaste } 165254721Semaste} 166254721Semaste 167