diff options
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp')
-rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp | 450 |
1 files changed, 58 insertions, 392 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp index 320500fe608d..f6425a889da8 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -1,4 +1,4 @@ -//===-- DWARFDebugInfoEntry.cpp ---------------------------------*- C++ -*-===// +//===-- DWARFDebugInfoEntry.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -395,152 +395,14 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges( return !ranges.IsEmpty(); } -// Dump -// -// Dumps a debug information entry and all of it's attributes to the specified -// stream. -void DWARFDebugInfoEntry::Dump(const DWARFUnit *cu, Stream &s, - uint32_t recurse_depth) const { - const DWARFDataExtractor &data = cu->GetData(); - lldb::offset_t offset = m_offset; - - if (data.ValidOffset(offset)) { - dw_uleb128_t abbrCode = data.GetULEB128(&offset); - - s.Printf("\n0x%8.8x: ", m_offset); - s.Indent(); - if (abbrCode != m_abbr_idx) { - s.Printf("error: DWARF has been modified\n"); - } else if (abbrCode) { - const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu); - if (abbrevDecl) { - s.PutCString(DW_TAG_value_to_name(abbrevDecl->Tag())); - s.Printf(" [%u] %c\n", abbrCode, abbrevDecl->HasChildren() ? '*' : ' '); - - // Dump all data in the .debug_info/.debug_types for the attributes - const uint32_t numAttributes = abbrevDecl->NumAttributes(); - for (uint32_t i = 0; i < numAttributes; ++i) { - DWARFFormValue form_value(cu); - dw_attr_t attr; - abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value); - - DumpAttribute(cu, data, &offset, s, attr, form_value); - } - - const DWARFDebugInfoEntry *child = GetFirstChild(); - if (recurse_depth > 0 && child) { - s.IndentMore(); - - while (child) { - child->Dump(cu, s, recurse_depth - 1); - child = child->GetSibling(); - } - s.IndentLess(); - } - } else - s.Printf("Abbreviation code note found in 'debug_abbrev' class for " - "code: %u\n", - abbrCode); - } else { - s.Printf("NULL\n"); - } - } -} - -// DumpAttribute -// -// Dumps a debug information entry attribute along with it's form. Any special -// display of attributes is done (disassemble location lists, show enumeration -// values for attributes, etc). -void DWARFDebugInfoEntry::DumpAttribute( - const DWARFUnit *cu, const DWARFDataExtractor &data, - lldb::offset_t *offset_ptr, Stream &s, dw_attr_t attr, - DWARFFormValue &form_value) { - bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm); - - s.Printf(" "); - s.Indent(DW_AT_value_to_name(attr)); - - if (show_form) { - s.Printf("[%s", DW_FORM_value_to_name(form_value.Form())); - } - - if (!form_value.ExtractValue(data, offset_ptr)) - return; - - if (show_form) { - if (form_value.Form() == DW_FORM_indirect) { - s.Printf(" [%s]", DW_FORM_value_to_name(form_value.Form())); - } - - s.PutCString("] "); - } - - s.PutCString("( "); - - // Check to see if we have any special attribute formatters - switch (attr) { - case DW_AT_stmt_list: - s.Printf("0x%8.8" PRIx64, form_value.Unsigned()); - break; - - case DW_AT_language: - s.PutCString(DW_LANG_value_to_name(form_value.Unsigned())); - break; - - case DW_AT_encoding: - s.PutCString(DW_ATE_value_to_name(form_value.Unsigned())); - break; - - case DW_AT_frame_base: - case DW_AT_location: - case DW_AT_data_member_location: { - const uint8_t *blockData = form_value.BlockData(); - if (blockData) { - // Location description is inlined in data in the form value - DWARFDataExtractor locationData(data, - (*offset_ptr) - form_value.Unsigned(), - form_value.Unsigned()); - DWARFExpression::PrintDWARFExpression( - s, locationData, DWARFUnit::GetAddressByteSize(cu), 4, false); - } else { - // We have a location list offset as the value that is the offset into - // the .debug_loc section that describes the value over it's lifetime - uint64_t debug_loc_offset = form_value.Unsigned(); - DWARFExpression::PrintDWARFLocationList(s, cu, cu->GetLocationData(), - debug_loc_offset); - } - } break; - - case DW_AT_abstract_origin: - case DW_AT_specification: { - DWARFDIE abstract_die = form_value.Reference(); - form_value.Dump(s); - // *ostrm_ptr << HEX32 << abstract_die.GetOffset() << " ( "; - abstract_die.GetName(s); - } break; - - case DW_AT_type: { - DWARFDIE type_die = form_value.Reference(); - s.PutCString(" ( "); - type_die.AppendTypeName(s); - s.PutCString(" )"); - } break; - - default: - break; - } - - s.PutCString(" )\n"); -} - // Get all attribute values for a given DIE, including following any // specification or abstract origin attributes and including those in the // results. Any duplicate attributes will have the first instance take // precedence (this can happen for declaration attributes). -size_t DWARFDebugInfoEntry::GetAttributes( - const DWARFUnit *cu, DWARFAttributes &attributes, - uint32_t curr_depth) const { +size_t DWARFDebugInfoEntry::GetAttributes(const DWARFUnit *cu, + DWARFAttributes &attributes, + Recurse recurse, + uint32_t curr_depth) const { const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu); if (abbrevDecl) { const DWARFDataExtractor &data = cu->GetData(); @@ -571,11 +433,13 @@ size_t DWARFDebugInfoEntry::GetAttributes( break; } - if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin)) { + if (recurse == Recurse::yes && + ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin))) { if (form_value.ExtractValue(data, &offset)) { DWARFDIE spec_die = form_value.Reference(); if (spec_die) - spec_die.GetAttributes(attributes, curr_depth + 1); + spec_die.GetDIE()->GetAttributes(spec_die.GetCU(), attributes, + recurse, curr_depth + 1); } } else { llvm::Optional<uint8_t> fixed_skip_size = DWARFFormValue::GetFixedSize(form, cu); @@ -819,34 +683,9 @@ const char *DWARFDebugInfoEntry::GetPubname(const DWARFUnit *cu) const { return name; } -// BuildAddressRangeTable -void DWARFDebugInfoEntry::BuildAddressRangeTable( - const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const { - if (m_tag) { - if (m_tag == DW_TAG_subprogram) { - dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; - dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; - if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) { - /// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x - - /// 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc); - debug_aranges->AppendRange(cu->GetOffset(), lo_pc, hi_pc); - } - } - - const DWARFDebugInfoEntry *child = GetFirstChild(); - while (child) { - child->BuildAddressRangeTable(cu, debug_aranges); - child = child->GetSibling(); - } - } -} - -// BuildFunctionAddressRangeTable -// -// This function is very similar to the BuildAddressRangeTable function except -// that the actual DIE offset for the function is placed in the table instead -// of the compile unit offset (which is the way the standard .debug_aranges -// section does it). +/// This function is builds a table very similar to the standard .debug_aranges +/// table, except that the actual DIE offset for the function is placed in the +/// table instead of the compile unit offset. void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable( const DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const { if (m_tag) { @@ -854,8 +693,6 @@ void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable( dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS)) { - // printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16" PRIx64 " - - // 0x%16.16" PRIx64 ")\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY debug_aranges->AppendRange(GetOffset(), lo_pc, hi_pc); } } @@ -868,25 +705,34 @@ void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable( } } -void DWARFDebugInfoEntry::GetDWARFDeclContext( - DWARFUnit *cu, DWARFDeclContext &dwarf_decl_ctx) const { - const dw_tag_t tag = Tag(); - if (tag != DW_TAG_compile_unit && tag != DW_TAG_partial_unit) { - dwarf_decl_ctx.AppendDeclContext(tag, GetName(cu)); - DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(cu); - if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != this) { - if (parent_decl_ctx_die.Tag() != DW_TAG_compile_unit && - parent_decl_ctx_die.Tag() != DW_TAG_partial_unit) - parent_decl_ctx_die.GetDIE()->GetDWARFDeclContext( - parent_decl_ctx_die.GetCU(), dwarf_decl_ctx); - } +DWARFDeclContext +DWARFDebugInfoEntry::GetDWARFDeclContextStatic(const DWARFDebugInfoEntry *die, + DWARFUnit *cu) { + DWARFDeclContext dwarf_decl_ctx; + for (;;) { + const dw_tag_t tag = die->Tag(); + if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit) + return dwarf_decl_ctx; + dwarf_decl_ctx.AppendDeclContext(tag, die->GetName(cu)); + DWARFDIE parent_decl_ctx_die = die->GetParentDeclContextDIE(cu); + if (!parent_decl_ctx_die || parent_decl_ctx_die.GetDIE() == die) + return dwarf_decl_ctx; + if (parent_decl_ctx_die.Tag() == DW_TAG_compile_unit || + parent_decl_ctx_die.Tag() == DW_TAG_partial_unit) + return dwarf_decl_ctx; + die = parent_decl_ctx_die.GetDIE(); + cu = parent_decl_ctx_die.GetCU(); } } +DWARFDeclContext DWARFDebugInfoEntry::GetDWARFDeclContext(DWARFUnit *cu) const { + return GetDWARFDeclContextStatic(this, cu); +} + DWARFDIE DWARFDebugInfoEntry::GetParentDeclContextDIE(DWARFUnit *cu) const { DWARFAttributes attributes; - GetAttributes(cu, attributes); + GetAttributes(cu, attributes, Recurse::yes); return GetParentDeclContextDIE(cu, attributes); } @@ -936,7 +782,7 @@ DWARFDebugInfoEntry::GetParentDeclContextDIE( const char *DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu, std::string &storage) const { DWARFAttributes attributes; - GetAttributes(cu, attributes); + GetAttributes(cu, attributes, Recurse::yes); return GetQualifiedName(cu, attributes, storage); } @@ -993,209 +839,6 @@ DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu, 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); } @@ -1210,6 +853,29 @@ DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const { return nullptr; } +bool DWARFDebugInfoEntry::IsGlobalOrStaticScopeVariable() const { + if (Tag() != DW_TAG_variable) + return false; + const DWARFDebugInfoEntry *parent_die = GetParent(); + while (parent_die != nullptr) { + switch (parent_die->Tag()) { + case DW_TAG_subprogram: + case DW_TAG_lexical_block: + case DW_TAG_inlined_subroutine: + return false; + + case DW_TAG_compile_unit: + case DW_TAG_partial_unit: + return true; + + default: + break; + } + parent_die = parent_die->GetParent(); + } + return false; +} + bool DWARFDebugInfoEntry::operator==(const DWARFDebugInfoEntry &rhs) const { return m_offset == rhs.m_offset && m_parent_idx == rhs.m_parent_idx && m_sibling_idx == rhs.m_sibling_idx && |