diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp @@ -140,25 +140,64 @@ } DWARFDIE -DWARFDIE::LookupDeepestBlock(lldb::addr_t file_addr) const { - if (IsValid()) { - SymbolFileDWARF *dwarf = GetDWARF(); - DWARFUnit *cu = GetCU(); - DWARFDebugInfoEntry *function_die = nullptr; - DWARFDebugInfoEntry *block_die = nullptr; - if (m_die->LookupAddress(file_addr, cu, &function_die, &block_die)) { - if (block_die && block_die != function_die) { - if (cu->ContainsDIEOffset(block_die->GetOffset())) - return DWARFDIE(cu, block_die); - else - return DWARFDIE(dwarf->DebugInfo()->GetUnit(DIERef( - cu->GetSymbolFileDWARF().GetDwoNum(), - cu->GetDebugSection(), block_die->GetOffset())), - block_die); +DWARFDIE::LookupDeepestBlock(lldb::addr_t address) const { + if (!IsValid()) + return DWARFDIE(); + + DWARFDIE result; + bool check_children = false; + bool match_addr_range = false; + switch (Tag()) { + case DW_TAG_class_type: + case DW_TAG_namespace: + case DW_TAG_structure_type: + case DW_TAG_common_block: + check_children = true; + break; + case DW_TAG_compile_unit: + case DW_TAG_module: + case DW_TAG_catch_block: + case DW_TAG_subprogram: + case DW_TAG_try_block: + case DW_TAG_partial_unit: + match_addr_range = true; + break; + case DW_TAG_lexical_block: + case DW_TAG_inlined_subroutine: + check_children = true; + match_addr_range = true; + break; + default: + break; + } + + if (match_addr_range) { + DWARFRangeList ranges; + if (m_die->GetAttributeAddressRanges(m_cu, ranges, + /*check_hi_lo_pc=*/true) && + ranges.FindEntryThatContains(address)) { + check_children = true; + switch (Tag()) { + default: + break; + + case DW_TAG_inlined_subroutine: // Inlined Function + case DW_TAG_lexical_block: // Block { } in code + result = *this; + break; } + } else { + check_children = false; } } - return DWARFDIE(); + + if (check_children) { + for (DWARFDIE child = GetFirstChild(); child; child = child.GetSibling()) { + if (DWARFDIE child_result = child.LookupDeepestBlock(address)) + return child_result; + } + } + return result; } const char *DWARFDIE::GetMangledName() const { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h @@ -50,10 +50,6 @@ bool Extract(const lldb_private::DWARFDataExtractor &data, const DWARFUnit *cu, lldb::offset_t *offset_ptr); - bool LookupAddress(const dw_addr_t address, DWARFUnit *cu, - DWARFDebugInfoEntry **function_die, - DWARFDebugInfoEntry **block_die); - size_t GetAttributes(const DWARFUnit *cu, DWARFAttributes &attrs, uint32_t curr_depth = 0) diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -993,209 +993,6 @@ return storage.c_str(); } -bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address, DWARFUnit *cu, - DWARFDebugInfoEntry **function_die, - DWARFDebugInfoEntry **block_die) { - bool found_address = false; - if (m_tag) { - bool check_children = false; - bool match_addr_range = false; - // printf("0x%8.8x: %30s: address = 0x%8.8x - ", m_offset, - // DW_TAG_value_to_name(tag), address); - switch (m_tag) { - case DW_TAG_array_type: - break; - case DW_TAG_class_type: - check_children = true; - break; - case DW_TAG_entry_point: - case DW_TAG_enumeration_type: - case DW_TAG_formal_parameter: - case DW_TAG_imported_declaration: - case DW_TAG_label: - break; - case DW_TAG_lexical_block: - check_children = true; - match_addr_range = true; - break; - case DW_TAG_member: - case DW_TAG_pointer_type: - case DW_TAG_reference_type: - break; - case DW_TAG_compile_unit: - match_addr_range = true; - break; - case DW_TAG_string_type: - break; - case DW_TAG_structure_type: - check_children = true; - break; - case DW_TAG_subroutine_type: - case DW_TAG_typedef: - case DW_TAG_union_type: - case DW_TAG_unspecified_parameters: - case DW_TAG_variant: - break; - case DW_TAG_common_block: - check_children = true; - break; - case DW_TAG_common_inclusion: - case DW_TAG_inheritance: - break; - case DW_TAG_inlined_subroutine: - check_children = true; - match_addr_range = true; - break; - case DW_TAG_module: - match_addr_range = true; - break; - case DW_TAG_ptr_to_member_type: - case DW_TAG_set_type: - case DW_TAG_subrange_type: - case DW_TAG_with_stmt: - case DW_TAG_access_declaration: - case DW_TAG_base_type: - break; - case DW_TAG_catch_block: - match_addr_range = true; - break; - case DW_TAG_const_type: - case DW_TAG_constant: - case DW_TAG_enumerator: - case DW_TAG_file_type: - case DW_TAG_friend: - case DW_TAG_namelist: - case DW_TAG_namelist_item: - case DW_TAG_packed_type: - break; - case DW_TAG_subprogram: - match_addr_range = true; - break; - case DW_TAG_template_type_parameter: - case DW_TAG_template_value_parameter: - case DW_TAG_GNU_template_parameter_pack: - case DW_TAG_thrown_type: - break; - case DW_TAG_try_block: - match_addr_range = true; - break; - case DW_TAG_variant_part: - case DW_TAG_variable: - case DW_TAG_volatile_type: - case DW_TAG_dwarf_procedure: - case DW_TAG_restrict_type: - case DW_TAG_interface_type: - break; - case DW_TAG_namespace: - check_children = true; - break; - case DW_TAG_imported_module: - case DW_TAG_unspecified_type: - break; - case DW_TAG_partial_unit: - match_addr_range = true; - break; - case DW_TAG_imported_unit: - case DW_TAG_shared_type: - default: - break; - } - - if (match_addr_range) { - dw_addr_t lo_pc = - GetAttributeValueAsAddress(cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS); - if (lo_pc != LLDB_INVALID_ADDRESS) { - dw_addr_t hi_pc = GetAttributeHighPC(cu, lo_pc, LLDB_INVALID_ADDRESS); - if (hi_pc != LLDB_INVALID_ADDRESS) { - // printf("\n0x%8.8x: %30s: address = 0x%8.8x [0x%8.8x - 0x%8.8x) ", - // m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc); - if ((lo_pc <= address) && (address < hi_pc)) { - found_address = true; - // puts("***MATCH***"); - switch (m_tag) { - case DW_TAG_compile_unit: // File - case DW_TAG_partial_unit: // File - check_children = - ((function_die != nullptr) || (block_die != nullptr)); - break; - - case DW_TAG_subprogram: // Function - if (function_die) - *function_die = this; - check_children = (block_die != nullptr); - break; - - case DW_TAG_inlined_subroutine: // Inlined Function - case DW_TAG_lexical_block: // Block { } in code - if (block_die) { - *block_die = this; - check_children = true; - } - break; - - default: - check_children = true; - break; - } - } - } else { - // Compile units may not have a valid high/low pc when there - // are address gaps in subroutines so we must always search - // if there is no valid high and low PC. - check_children = - (m_tag == DW_TAG_compile_unit || m_tag == DW_TAG_partial_unit) && - ((function_die != nullptr) || (block_die != nullptr)); - } - } else { - DWARFRangeList ranges; - if (GetAttributeAddressRanges(cu, ranges, /*check_hi_lo_pc*/ false) && - ranges.FindEntryThatContains(address)) { - found_address = true; - // puts("***MATCH***"); - switch (m_tag) { - case DW_TAG_compile_unit: // File - case DW_TAG_partial_unit: // File - check_children = - ((function_die != nullptr) || (block_die != nullptr)); - break; - - case DW_TAG_subprogram: // Function - if (function_die) - *function_die = this; - check_children = (block_die != nullptr); - break; - - case DW_TAG_inlined_subroutine: // Inlined Function - case DW_TAG_lexical_block: // Block { } in code - if (block_die) { - *block_die = this; - check_children = true; - } - break; - - default: - check_children = true; - break; - } - } else { - check_children = false; - } - } - } - - if (check_children) { - // printf("checking children\n"); - DWARFDebugInfoEntry *child = GetFirstChild(); - while (child) { - if (child->LookupAddress(address, cu, function_die, block_die)) - return true; - child = child->GetSibling(); - } - } - } - return found_address; -} - lldb::offset_t DWARFDebugInfoEntry::GetFirstAttributeOffset() const { return GetOffset() + llvm::getULEB128Size(m_abbr_idx); }