diff options
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp')
-rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp | 436 |
1 files changed, 205 insertions, 231 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp index 63fcebef1cf..d4281bac79a 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugPubnames.cpp @@ -12,268 +12,242 @@ #include "lldb/Core/Stream.h" #include "lldb/Core/Timer.h" -#include "DWARFDebugInfo.h" +#include "DWARFCompileUnit.h" #include "DWARFDIECollection.h" +#include "DWARFDebugInfo.h" #include "DWARFFormValue.h" -#include "DWARFCompileUnit.h" #include "LogChannelDWARF.h" #include "SymbolFileDWARF.h" - using namespace lldb; using namespace lldb_private; -DWARFDebugPubnames::DWARFDebugPubnames() : - m_sets() -{ -} - -bool -DWARFDebugPubnames::Extract(const DWARFDataExtractor& data) -{ - Timer scoped_timer (LLVM_PRETTY_FUNCTION, - "DWARFDebugPubnames::Extract (byte_size = %" PRIu64 ")", - (uint64_t)data.GetByteSize()); - Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES)); - if (log) - log->Printf("DWARFDebugPubnames::Extract (byte_size = %" PRIu64 ")", (uint64_t)data.GetByteSize()); - - if (data.ValidOffset(0)) - { - lldb::offset_t offset = 0; - - DWARFDebugPubnamesSet set; - while (data.ValidOffset(offset)) - { - if (set.Extract(data, &offset)) - { - m_sets.push_back(set); - offset = set.GetOffsetOfNextEntry(); - } - else - break; - } - if (log) - Dump (log); - return true; +DWARFDebugPubnames::DWARFDebugPubnames() : m_sets() {} + +bool DWARFDebugPubnames::Extract(const DWARFDataExtractor &data) { + Timer scoped_timer(LLVM_PRETTY_FUNCTION, + "DWARFDebugPubnames::Extract (byte_size = %" PRIu64 ")", + (uint64_t)data.GetByteSize()); + Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES)); + if (log) + log->Printf("DWARFDebugPubnames::Extract (byte_size = %" PRIu64 ")", + (uint64_t)data.GetByteSize()); + + if (data.ValidOffset(0)) { + lldb::offset_t offset = 0; + + DWARFDebugPubnamesSet set; + while (data.ValidOffset(offset)) { + if (set.Extract(data, &offset)) { + m_sets.push_back(set); + offset = set.GetOffsetOfNextEntry(); + } else + break; } - return false; -} - - -bool -DWARFDebugPubnames::GeneratePubnames(SymbolFileDWARF* dwarf2Data) -{ - Timer scoped_timer (LLVM_PRETTY_FUNCTION, - "DWARFDebugPubnames::GeneratePubnames (data = %p)", - static_cast<void*>(dwarf2Data)); - - Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES)); if (log) - log->Printf("DWARFDebugPubnames::GeneratePubnames (data = %p)", - static_cast<void*>(dwarf2Data)); - - m_sets.clear(); - DWARFDebugInfo* debug_info = dwarf2Data->DebugInfo(); - if (debug_info) - { - uint32_t cu_idx = 0; - const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits(); - for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) - { - - DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx); - - DWARFFormValue::FixedFormSizes fixed_form_sizes = - DWARFFormValue::GetFixedFormSizesForAddressSize (cu->GetAddressByteSize(), - cu->IsDWARF64()); - - bool clear_dies = cu->ExtractDIEsIfNeeded (false) > 1; - - DWARFDIECollection dies; - const size_t die_count = cu->AppendDIEsWithTag (DW_TAG_subprogram, dies) + - cu->AppendDIEsWithTag (DW_TAG_variable, dies); - - dw_offset_t cu_offset = cu->GetOffset(); - DWARFDebugPubnamesSet pubnames_set(DW_INVALID_OFFSET, cu_offset, cu->GetNextCompileUnitOffset() - cu_offset); - - size_t die_idx; - for (die_idx = 0; die_idx < die_count; ++die_idx) - { - DWARFDIE die = dies.GetDIEAtIndex(die_idx); - DWARFAttributes attributes; - const char *name = NULL; - const char *mangled = NULL; - bool add_die = false; - const size_t num_attributes = die.GetDIE()->GetAttributes(die.GetCU(), fixed_form_sizes, attributes); - if (num_attributes > 0) - { - uint32_t i; - - dw_tag_t tag = die.Tag(); - - for (i=0; i<num_attributes; ++i) - { - dw_attr_t attr = attributes.AttributeAtIndex(i); - DWARFFormValue form_value; - switch (attr) - { - case DW_AT_name: - if (attributes.ExtractFormValueAtIndex(i, form_value)) - name = form_value.AsCString(); - break; - - case DW_AT_MIPS_linkage_name: - case DW_AT_linkage_name: - if (attributes.ExtractFormValueAtIndex(i, form_value)) - mangled = form_value.AsCString(); - break; - - case DW_AT_low_pc: - case DW_AT_ranges: - case DW_AT_entry_pc: - if (tag == DW_TAG_subprogram) - add_die = true; - break; - - case DW_AT_location: - if (tag == DW_TAG_variable) - { - DWARFDIE parent_die = die.GetParent(); - while ( parent_die ) - { - switch (parent_die.Tag()) - { - case DW_TAG_subprogram: - case DW_TAG_lexical_block: - case DW_TAG_inlined_subroutine: - // Even if this is a function level static, we don't add it. We could theoretically - // add these if we wanted to by introspecting into the DW_AT_location and seeing - // if the location describes a hard coded address, but we don't want the performance - // penalty of that right now. - add_die = false; - parent_die.Clear(); // Terminate the while loop. - break; - - case DW_TAG_compile_unit: - add_die = true; - parent_die.Clear(); // Terminate the while loop. - break; - - default: - parent_die = parent_die.GetParent(); // Keep going in the while loop. - break; - } - } - } - break; - } - } - } + Dump(log); + return true; + } + return false; +} - if (add_die && (name || mangled)) - { - pubnames_set.AddDescriptor(die.GetCompileUnitRelativeOffset(), mangled ? mangled : name); +bool DWARFDebugPubnames::GeneratePubnames(SymbolFileDWARF *dwarf2Data) { + Timer scoped_timer(LLVM_PRETTY_FUNCTION, + "DWARFDebugPubnames::GeneratePubnames (data = %p)", + static_cast<void *>(dwarf2Data)); + + Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_PUBNAMES)); + if (log) + log->Printf("DWARFDebugPubnames::GeneratePubnames (data = %p)", + static_cast<void *>(dwarf2Data)); + + m_sets.clear(); + DWARFDebugInfo *debug_info = dwarf2Data->DebugInfo(); + if (debug_info) { + uint32_t cu_idx = 0; + const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits(); + for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) { + + DWARFCompileUnit *cu = debug_info->GetCompileUnitAtIndex(cu_idx); + + DWARFFormValue::FixedFormSizes fixed_form_sizes = + DWARFFormValue::GetFixedFormSizesForAddressSize( + cu->GetAddressByteSize(), cu->IsDWARF64()); + + bool clear_dies = cu->ExtractDIEsIfNeeded(false) > 1; + + DWARFDIECollection dies; + const size_t die_count = cu->AppendDIEsWithTag(DW_TAG_subprogram, dies) + + cu->AppendDIEsWithTag(DW_TAG_variable, dies); + + dw_offset_t cu_offset = cu->GetOffset(); + DWARFDebugPubnamesSet pubnames_set(DW_INVALID_OFFSET, cu_offset, + cu->GetNextCompileUnitOffset() - + cu_offset); + + size_t die_idx; + for (die_idx = 0; die_idx < die_count; ++die_idx) { + DWARFDIE die = dies.GetDIEAtIndex(die_idx); + DWARFAttributes attributes; + const char *name = NULL; + const char *mangled = NULL; + bool add_die = false; + const size_t num_attributes = die.GetDIE()->GetAttributes( + die.GetCU(), fixed_form_sizes, attributes); + if (num_attributes > 0) { + uint32_t i; + + dw_tag_t tag = die.Tag(); + + for (i = 0; i < num_attributes; ++i) { + dw_attr_t attr = attributes.AttributeAtIndex(i); + DWARFFormValue form_value; + switch (attr) { + case DW_AT_name: + if (attributes.ExtractFormValueAtIndex(i, form_value)) + name = form_value.AsCString(); + break; + + case DW_AT_MIPS_linkage_name: + case DW_AT_linkage_name: + if (attributes.ExtractFormValueAtIndex(i, form_value)) + mangled = form_value.AsCString(); + break; + + case DW_AT_low_pc: + case DW_AT_ranges: + case DW_AT_entry_pc: + if (tag == DW_TAG_subprogram) + add_die = true; + break; + + case DW_AT_location: + if (tag == DW_TAG_variable) { + DWARFDIE parent_die = die.GetParent(); + while (parent_die) { + switch (parent_die.Tag()) { + case DW_TAG_subprogram: + case DW_TAG_lexical_block: + case DW_TAG_inlined_subroutine: + // Even if this is a function level static, we don't add it. + // We could theoretically + // add these if we wanted to by introspecting into the + // DW_AT_location and seeing + // if the location describes a hard coded address, but we + // don't want the performance + // penalty of that right now. + add_die = false; + parent_die.Clear(); // Terminate the while loop. + break; + + case DW_TAG_compile_unit: + add_die = true; + parent_die.Clear(); // Terminate the while loop. + break; + + default: + parent_die = + parent_die.GetParent(); // Keep going in the while loop. + break; + } } + } + break; } + } + } - if (pubnames_set.NumDescriptors() > 0) - { - m_sets.push_back(pubnames_set); - } - - // Keep memory down by clearing DIEs if this generate function - // caused them to be parsed - if (clear_dies) - cu->ClearDIEs (true); + if (add_die && (name || mangled)) { + pubnames_set.AddDescriptor(die.GetCompileUnitRelativeOffset(), + mangled ? mangled : name); } - } - if (m_sets.empty()) - return false; - if (log) - Dump (log); - return true; -} + } -bool -DWARFDebugPubnames::GeneratePubBaseTypes(SymbolFileDWARF* dwarf2Data) -{ - m_sets.clear(); - DWARFDebugInfo* debug_info = dwarf2Data->DebugInfo(); - if (debug_info) - { - uint32_t cu_idx = 0; - const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits(); - for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) - { - DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx); - DWARFDIECollection dies; - const size_t die_count = cu->AppendDIEsWithTag (DW_TAG_base_type, dies); - dw_offset_t cu_offset = cu->GetOffset(); - DWARFDebugPubnamesSet pubnames_set(DW_INVALID_OFFSET, cu_offset, cu->GetNextCompileUnitOffset() - cu_offset); - - size_t die_idx; - for (die_idx = 0; die_idx < die_count; ++die_idx) - { - DWARFDIE die = dies.GetDIEAtIndex (die_idx); - const char *name = die.GetName(); - - if (name) - pubnames_set.AddDescriptor(die.GetCompileUnitRelativeOffset(), name); - } + if (pubnames_set.NumDescriptors() > 0) { + m_sets.push_back(pubnames_set); + } - if (pubnames_set.NumDescriptors() > 0) - { - m_sets.push_back(pubnames_set); - } - } + // Keep memory down by clearing DIEs if this generate function + // caused them to be parsed + if (clear_dies) + cu->ClearDIEs(true); } - return !m_sets.empty(); + } + if (m_sets.empty()) + return false; + if (log) + Dump(log); + return true; } -void -DWARFDebugPubnames::Dump(Log *s) const -{ - if (m_sets.empty()) - s->PutCString("< EMPTY >\n"); - else - { - const_iterator pos; - const_iterator end = m_sets.end(); - - for (pos = m_sets.begin(); pos != end; ++pos) - (*pos).Dump(s); +bool DWARFDebugPubnames::GeneratePubBaseTypes(SymbolFileDWARF *dwarf2Data) { + m_sets.clear(); + DWARFDebugInfo *debug_info = dwarf2Data->DebugInfo(); + if (debug_info) { + uint32_t cu_idx = 0; + const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits(); + for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) { + DWARFCompileUnit *cu = debug_info->GetCompileUnitAtIndex(cu_idx); + DWARFDIECollection dies; + const size_t die_count = cu->AppendDIEsWithTag(DW_TAG_base_type, dies); + dw_offset_t cu_offset = cu->GetOffset(); + DWARFDebugPubnamesSet pubnames_set(DW_INVALID_OFFSET, cu_offset, + cu->GetNextCompileUnitOffset() - + cu_offset); + + size_t die_idx; + for (die_idx = 0; die_idx < die_count; ++die_idx) { + DWARFDIE die = dies.GetDIEAtIndex(die_idx); + const char *name = die.GetName(); + + if (name) + pubnames_set.AddDescriptor(die.GetCompileUnitRelativeOffset(), name); + } + + if (pubnames_set.NumDescriptors() > 0) { + m_sets.push_back(pubnames_set); + } } + } + return !m_sets.empty(); } -bool -DWARFDebugPubnames::Find(const char* name, bool ignore_case, std::vector<dw_offset_t>& die_offsets) const -{ +void DWARFDebugPubnames::Dump(Log *s) const { + if (m_sets.empty()) + s->PutCString("< EMPTY >\n"); + else { const_iterator pos; const_iterator end = m_sets.end(); - die_offsets.clear(); - for (pos = m_sets.begin(); pos != end; ++pos) - { - (*pos).Find(name, ignore_case, die_offsets); - } + (*pos).Dump(s); + } +} + +bool DWARFDebugPubnames::Find(const char *name, bool ignore_case, + std::vector<dw_offset_t> &die_offsets) const { + const_iterator pos; + const_iterator end = m_sets.end(); + + die_offsets.clear(); + + for (pos = m_sets.begin(); pos != end; ++pos) { + (*pos).Find(name, ignore_case, die_offsets); + } - return !die_offsets.empty(); + return !die_offsets.empty(); } -bool -DWARFDebugPubnames::Find(const RegularExpression& regex, std::vector<dw_offset_t>& die_offsets) const -{ - const_iterator pos; - const_iterator end = m_sets.end(); +bool DWARFDebugPubnames::Find(const RegularExpression ®ex, + std::vector<dw_offset_t> &die_offsets) const { + const_iterator pos; + const_iterator end = m_sets.end(); - die_offsets.clear(); + die_offsets.clear(); - for (pos = m_sets.begin(); pos != end; ++pos) - { - (*pos).Find(regex, die_offsets); - } + for (pos = m_sets.begin(); pos != end; ++pos) { + (*pos).Find(regex, die_offsets); + } - return !die_offsets.empty(); + return !die_offsets.empty(); } |