diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h @@ -32,7 +32,8 @@ virtual lldb_private::Function * ParseFunctionFromDWARF(lldb_private::CompileUnit &comp_unit, - const DWARFDIE &die) = 0; + const DWARFDIE &die, + const lldb_private::AddressRange &range) = 0; virtual bool CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -47,7 +47,8 @@ lldb_private::Function * ParseFunctionFromDWARF(lldb_private::CompileUnit &comp_unit, - const DWARFDIE &die) override; + const DWARFDIE &die, + const lldb_private::AddressRange &func_range) override; bool CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -2342,8 +2342,11 @@ return enumerators_added; } -Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit, - const DWARFDIE &die) { +Function * +DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit, + const DWARFDIE &die, + const AddressRange &func_range) { + assert(func_range.GetBaseAddress().IsValid()); DWARFRangeList func_ranges; const char *name = nullptr; const char *mangled = nullptr; @@ -2363,94 +2366,75 @@ if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base)) { + Mangled func_name; + if (mangled) + func_name.SetValue(ConstString(mangled), true); + else if ((die.GetParent().Tag() == DW_TAG_compile_unit || + die.GetParent().Tag() == DW_TAG_partial_unit) && + Language::LanguageIsCPlusPlus( + SymbolFileDWARF::GetLanguage(*die.GetCU())) && + !Language::LanguageIsObjC( + SymbolFileDWARF::GetLanguage(*die.GetCU())) && + name && strcmp(name, "main") != 0) { + // If the mangled name is not present in the DWARF, generate the + // demangled name using the decl context. We skip if the function is + // "main" as its name is never mangled. + bool is_static = false; + bool is_variadic = false; + bool has_template_params = false; + unsigned type_quals = 0; + std::vector param_types; + std::vector param_decls; + StreamString sstr; + + DWARFDeclContext decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die); + sstr << decl_ctx.GetQualifiedName(); - // Union of all ranges in the function DIE (if the function is - // discontiguous) - AddressRange func_range; - lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0); - lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0); - if (lowest_func_addr != LLDB_INVALID_ADDRESS && - lowest_func_addr <= highest_func_addr) { - ModuleSP module_sp(die.GetModule()); - func_range.GetBaseAddress().ResolveAddressUsingFileSections( - lowest_func_addr, module_sp->GetSectionList()); - if (func_range.GetBaseAddress().IsValid()) - func_range.SetByteSize(highest_func_addr - lowest_func_addr); - } - - if (func_range.GetBaseAddress().IsValid()) { - Mangled func_name; - if (mangled) - func_name.SetValue(ConstString(mangled), true); - else if ((die.GetParent().Tag() == DW_TAG_compile_unit || - die.GetParent().Tag() == DW_TAG_partial_unit) && - Language::LanguageIsCPlusPlus( - SymbolFileDWARF::GetLanguage(*die.GetCU())) && - !Language::LanguageIsObjC( - SymbolFileDWARF::GetLanguage(*die.GetCU())) && - name && strcmp(name, "main") != 0) { - // If the mangled name is not present in the DWARF, generate the - // demangled name using the decl context. We skip if the function is - // "main" as its name is never mangled. - bool is_static = false; - bool is_variadic = false; - bool has_template_params = false; - unsigned type_quals = 0; - std::vector param_types; - std::vector param_decls; - StreamString sstr; - - DWARFDeclContext decl_ctx = SymbolFileDWARF::GetDWARFDeclContext(die); - sstr << decl_ctx.GetQualifiedName(); - - clang::DeclContext *containing_decl_ctx = - GetClangDeclContextContainingDIE(die, nullptr); - ParseChildParameters(containing_decl_ctx, die, true, is_static, - is_variadic, has_template_params, param_types, - param_decls, type_quals); - sstr << "("; - for (size_t i = 0; i < param_types.size(); i++) { - if (i > 0) - sstr << ", "; - sstr << param_types[i].GetTypeName(); - } - if (is_variadic) - sstr << ", ..."; - sstr << ")"; - if (type_quals & clang::Qualifiers::Const) - sstr << " const"; - - func_name.SetValue(ConstString(sstr.GetString()), false); - } else - func_name.SetValue(ConstString(name), false); - - FunctionSP func_sp; - std::unique_ptr decl_up; - if (decl_file != 0 || decl_line != 0 || decl_column != 0) - decl_up = std::make_unique(die.GetCU()->GetFile(decl_file), - decl_line, decl_column); - - SymbolFileDWARF *dwarf = die.GetDWARF(); - // Supply the type _only_ if it has already been parsed - Type *func_type = dwarf->GetDIEToType().lookup(die.GetDIE()); - - assert(func_type == nullptr || func_type != DIE_IS_BEING_PARSED); - - if (dwarf->FixupAddress(func_range.GetBaseAddress())) { - const user_id_t func_user_id = die.GetID(); - func_sp = - std::make_shared(&comp_unit, + clang::DeclContext *containing_decl_ctx = + GetClangDeclContextContainingDIE(die, nullptr); + ParseChildParameters(containing_decl_ctx, die, true, is_static, + is_variadic, has_template_params, param_types, + param_decls, type_quals); + sstr << "("; + for (size_t i = 0; i < param_types.size(); i++) { + if (i > 0) + sstr << ", "; + sstr << param_types[i].GetTypeName(); + } + if (is_variadic) + sstr << ", ..."; + sstr << ")"; + if (type_quals & clang::Qualifiers::Const) + sstr << " const"; + + func_name.SetValue(ConstString(sstr.GetString()), false); + } else + func_name.SetValue(ConstString(name), false); + + FunctionSP func_sp; + std::unique_ptr decl_up; + if (decl_file != 0 || decl_line != 0 || decl_column != 0) + decl_up = std::make_unique(die.GetCU()->GetFile(decl_file), + decl_line, decl_column); + + SymbolFileDWARF *dwarf = die.GetDWARF(); + // Supply the type _only_ if it has already been parsed + Type *func_type = dwarf->GetDIEToType().lookup(die.GetDIE()); + + assert(func_type == nullptr || func_type != DIE_IS_BEING_PARSED); + + const user_id_t func_user_id = die.GetID(); + func_sp = + std::make_shared(&comp_unit, func_user_id, // UserID is the DIE offset func_user_id, func_name, func_type, - func_range); // first address range + func_range); // first address range - if (func_sp.get() != nullptr) { - if (frame_base.IsValid()) - func_sp->GetFrameBaseExpression() = frame_base; - comp_unit.AddFunction(func_sp); - return func_sp.get(); - } - } + if (func_sp.get() != nullptr) { + if (frame_base.IsValid()) + func_sp->GetFrameBaseExpression() = frame_base; + comp_unit.AddFunction(func_sp); + return func_sp.get(); } } return nullptr; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -856,7 +856,32 @@ if (!dwarf_ast) return nullptr; - return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die); + DWARFRangeList ranges; + if (die.GetDIE()->GetAttributeAddressRanges(die.GetCU(), ranges, + /*check_hi_lo_pc=*/true) == 0) + return nullptr; + + // Union of all ranges in the function DIE (if the function is + // discontiguous) + AddressRange func_range; + lldb::addr_t lowest_func_addr = ranges.GetMinRangeBase(0); + lldb::addr_t highest_func_addr = ranges.GetMaxRangeEnd(0); + if (lowest_func_addr == LLDB_INVALID_ADDRESS || + lowest_func_addr >= highest_func_addr || + lowest_func_addr < m_first_code_address) + return nullptr; + + ModuleSP module_sp(die.GetModule()); + func_range.GetBaseAddress().ResolveAddressUsingFileSections( + lowest_func_addr, module_sp->GetSectionList()); + if (!func_range.GetBaseAddress().IsValid()) + return nullptr; + + func_range.SetByteSize(highest_func_addr - lowest_func_addr); + if (!FixupAddress(func_range.GetBaseAddress())) + return nullptr; + + return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die, func_range); } lldb::addr_t SymbolFileDWARF::FixupAddress(lldb::addr_t file_addr) { @@ -2263,10 +2288,8 @@ addr = sc.function->GetAddressRange().GetBaseAddress(); } - if (addr.IsValid() && addr.GetFileAddress() >= m_first_code_address) { - sc_list.Append(sc); - return true; - } + sc_list.Append(sc); + return true; } return false; diff --git a/lldb/test/Shell/SymbolFile/DWARF/x86/dead-code-filtering.yaml b/lldb/test/Shell/SymbolFile/DWARF/x86/dead-code-filtering.yaml --- a/lldb/test/Shell/SymbolFile/DWARF/x86/dead-code-filtering.yaml +++ b/lldb/test/Shell/SymbolFile/DWARF/x86/dead-code-filtering.yaml @@ -1,6 +1,16 @@ # RUN: yaml2obj %s > %t +# RUN: lldb-test symbols %t | FileCheck %s --check-prefix=TEST # RUN: %lldb %t -o "image dump line-table a.c" -o "image lookup -n _start" -o "image lookup -n f" -o exit | FileCheck %s +# TEST: Compile units: +# TEST-NEXT: CompileUnit{0x00000000}, language = "c", file = 'a.c' +# TEST-NEXT: Function{0x00000043}, demangled = _start, type_uid = 0x00000043 +# TEST-NEXT: Block{0x00000043}, ranges = [0x00000080-0x00000086) +# TEST-EMPTY: +# TEST-EMPTY: +# TEST-NEXT: Symtab + + # CHECK-LABEL: image dump line-table a.c # CHECK-NEXT: Line table for a.c # CHECK-NEXT: 0x0000000000000080: a.c:1 @@ -59,6 +69,8 @@ Attributes: - Attribute: DW_AT_producer Form: DW_FORM_string + - Attribute: DW_AT_language + Form: DW_FORM_data1 - Attribute: DW_AT_name Form: DW_FORM_string - Attribute: DW_AT_stmt_list @@ -86,6 +98,7 @@ - AbbrCode: 0x00000001 Values: - CStr: Hand-written DWARF + - Value: 2 - CStr: a.c - Value: 0x0000000000000000 - Value: 0x0000000000000000