[Lldb-commits] [lldb] c1055f0 - [lldb/DWARF] Don't create lldb_private::Functions for gc'ed DW_TAG_subprograms
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Mon Oct 25 01:32:42 PDT 2021
Author: Pavel Labath
Date: 2021-10-25T10:32:35+02:00
New Revision: c1055f09190856ae58c9a075b4103d77623228ee
URL: https://github.com/llvm/llvm-project/commit/c1055f09190856ae58c9a075b4103d77623228ee
DIFF: https://github.com/llvm/llvm-project/commit/c1055f09190856ae58c9a075b4103d77623228ee.diff
LOG: [lldb/DWARF] Don't create lldb_private::Functions for gc'ed DW_TAG_subprograms
Front-load the first_valid_code_address check, so that we avoid creating
the function object (instead of simply refusing to use it in queries).
Differential Revision: https://reviews.llvm.org/D112310
Added:
Modified:
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
lldb/test/Shell/SymbolFile/DWARF/x86/dead-code-filtering.yaml
Removed:
################################################################################
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
index ffe24836955fa..00123a4b92160 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
@@ -32,7 +32,8 @@ class DWARFASTParser {
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.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index ec560f3fdd69d..a240784c942b0 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -2342,8 +2342,11 @@ size_t DWARFASTParserClang::ParseChildEnumerators(
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 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
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<CompilerType> param_types;
+ std::vector<clang::ParmVarDecl *> 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<CompilerType> param_types;
- std::vector<clang::ParmVarDecl *> 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<Declaration> decl_up;
- if (decl_file != 0 || decl_line != 0 || decl_column != 0)
- decl_up = std::make_unique<Declaration>(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<Function>(&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<Declaration> decl_up;
+ if (decl_file != 0 || decl_line != 0 || decl_column != 0)
+ decl_up = std::make_unique<Declaration>(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<Function>(&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/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index 19b17936e201c..f97c0c470ab07 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -47,7 +47,8 @@ class DWARFASTParserClang : public DWARFASTParser {
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/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index d8a17755b2470..ad5b44365054a 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -856,7 +856,32 @@ Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit,
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 @@ bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die,
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
index cbdb91c4ef249..9ac922ef3159c 100644
--- 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 @@ DWARF:
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 @@ DWARF:
- AbbrCode: 0x00000001
Values:
- CStr: Hand-written DWARF
+ - Value: 2
- CStr: a.c
- Value: 0x0000000000000000
- Value: 0x0000000000000000
More information about the lldb-commits
mailing list