[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