jankratochvil updated this revision to Diff 333692.
jankratochvil added a comment.

testcase: DWZ is unsupported on OSX.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D98826/new/

https://reviews.llvm.org/D98826

Files:
  lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
  lldb/test/Shell/SymbolFile/DWARF/dwz-namespace-inline.s

Index: lldb/test/Shell/SymbolFile/DWARF/dwz-namespace-inline.s
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/DWARF/dwz-namespace-inline.s
@@ -0,0 +1,198 @@
+# Workaround for DWZ tool bug producing corrupted DWARF:
+# Multifile drops DW_TAG_namespace::DW_AT_export_symbols
+# https://sourceware.org/bugzilla/show_bug.cgi?id=27572
+
+# REQUIRES: target-x86_64, system-linux, native
+
+# RUN: %clang_host -o %t %s
+# RUN: %lldb %t -o 'b main' -o r -o 'p N::A::m' -o 'p N::m' \
+# RUN:   -o exit | FileCheck %s
+
+# CHECK-LABEL: (lldb) p N::A::m
+# CHECK-NEXT: (int (*)()) $0 = 0x{{.*}}`N::A::m())
+# CHECK-LABEL: (lldb) p N::m
+# Failing case was:
+# error: <user expression 1>:1:4: no member named 'm' in namespace 'N'
+# CHECK-NEXT: (int (*)()) $1 = 0x{{.*}}`N::A::m())
+
+	.text
+	.globl	main                            # -- Begin function main
+	.type	main,@function
+main:                                   # @main
+.Lfunc_begin0:
+	pushq	%rbp
+	movq	%rsp, %rbp
+	popq	%rbp
+	retq
+.Lfunc_end0:
+	.size	main, .Lfunc_end0-main
+                                        # -- End function
+	.type	_ZN1N1AL1mEv,@function
+_ZN1N1AL1mEv:                           # @_ZN1N1AL1mEv
+.Lfunc_begin1:
+	pushq	%rbp
+	movq	%rsp, %rbp
+	movl	$42, %eax
+	popq	%rbp
+	retq
+.Lfunc_end1:
+	.size	_ZN1N1AL1mEv, .Lfunc_end1-_ZN1N1AL1mEv
+                                        # -- End function
+	.section	.debug_abbrev,"",@progbits
+.Labbrev0:
+	.byte	1                               # Abbreviation Code
+	.byte	17                              # DW_TAG_compile_unit
+	.byte	1                               # DW_CHILDREN_yes
+	.byte	37                              # DW_AT_producer
+	.byte	8                               # DW_FORM_string
+	.byte	19                              # DW_AT_language
+	.byte	5                               # DW_FORM_data2
+	.byte	3                               # DW_AT_name
+	.byte	8                               # DW_FORM_string
+	.byte	17                              # DW_AT_low_pc
+	.byte	1                               # DW_FORM_addr
+	.byte	18                              # DW_AT_high_pc
+	.byte	6                               # DW_FORM_data4
+	.byte	0                               # EOM(1)
+	.byte	0                               # EOM(2)
+	.byte	3                               # Abbreviation Code
+	.byte	57                              # DW_TAG_namespace
+	.byte	1                               # DW_CHILDREN_yes
+	.byte	3                               # DW_AT_name
+	.byte	8                               # DW_FORM_string
+	.byte	0                               # EOM(1)
+	.byte	0                               # EOM(2)
+	.byte	4                               # Abbreviation Code
+	.byte	57                              # DW_TAG_namespace
+	.byte	1                               # DW_CHILDREN_yes
+	.byte	3                               # DW_AT_name
+	.byte	8                               # DW_FORM_string
+	.ascii	"\211\001"                      # DW_AT_export_symbols
+	.byte	25                              # DW_FORM_flag_present
+	.byte	0                               # EOM(1)
+	.byte	0                               # EOM(2)
+	.byte	5                               # Abbreviation Code
+	.byte	46                              # DW_TAG_subprogram
+	.byte	0                               # DW_CHILDREN_no
+	.byte	17                              # DW_AT_low_pc
+	.byte	1                               # DW_FORM_addr
+	.byte	18                              # DW_AT_high_pc
+	.byte	6                               # DW_FORM_data4
+	.byte	64                              # DW_AT_frame_base
+	.byte	24                              # DW_FORM_exprloc
+	.byte	0x47                            # DW_AT_specification
+	.byte	0x10                            # DW_FORM_ref_addr
+	.byte	0                               # EOM(1)
+	.byte	0                               # EOM(2)
+	.byte	6                               # Abbreviation Code
+	.byte	36                              # DW_TAG_base_type
+	.byte	0                               # DW_CHILDREN_no
+	.byte	3                               # DW_AT_name
+	.byte	8                               # DW_FORM_string
+	.byte	62                              # DW_AT_encoding
+	.byte	11                              # DW_FORM_data1
+	.byte	11                              # DW_AT_byte_size
+	.byte	11                              # DW_FORM_data1
+	.byte	0                               # EOM(1)
+	.byte	0                               # EOM(2)
+	.byte	7                               # Abbreviation Code
+	.byte	0x3c                              # DW_TAG_partial_unit
+	.byte	1                               # DW_CHILDREN_yes
+	.byte	0                               # EOM(1)
+	.byte	0                               # EOM(2)
+	.byte	8                               # Abbreviation Code
+	.byte	46                              # DW_TAG_subprogram
+	.byte	0                               # DW_CHILDREN_no
+	.byte	110                             # DW_AT_linkage_name
+	.byte	8                               # DW_FORM_string
+	.byte	3                               # DW_AT_name
+	.byte	8                               # DW_FORM_string
+	.byte	58                              # DW_AT_decl_file
+	.byte	11                              # DW_FORM_data1
+	.byte	59                              # DW_AT_decl_line
+	.byte	11                              # DW_FORM_data1
+	.byte	73                              # DW_AT_type
+	.byte	0x10                            # DW_FORM_ref_addr
+	.byte	0                               # EOM(1)
+	.byte	0                               # EOM(2)
+	.byte	9                               # Abbreviation Code
+	.byte	0x3d                            # DW_TAG_imported_unit
+	.byte	0                               # DW_CHILDREN_no
+	.byte	0x18                            # DW_AT_import
+	.byte	0x10                            # DW_FORM_ref_addr
+	.byte	0                               # EOM(1)
+	.byte	0                               # EOM(2)
+	.byte	0                               # EOM(3)
+	.section	.debug_info,"",@progbits
+.Lcu_begin0:
+	.long	.Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+	.short	4                               # DWARF version number
+	.long	.Labbrev0                       # Offset Into Abbrev. Section
+	.byte	8                               # Address Size (in bytes)
+	.byte	1                               # Abbrev [1] DW_TAG_compile_unit
+	                                        # DW_AT_producer
+	.asciz	"clang version 11.0.0 (Fedora 11.0.0-2.fc33)"
+	.short	33                              # DW_AT_language
+	                                        # DW_AT_name
+	.asciz	"-"
+	.quad	.Lfunc_begin0                   # DW_AT_low_pc
+	.long	.Lfunc_end1-.Lfunc_begin0       # DW_AT_high_pc
+
+	.byte	9                               # Abbrev [0] DW_TAG_imported_unit
+	.long	.Lpartial_unit                  # DW_AT_import
+
+	.byte	3                               # Abbrev [3] DW_TAG_namespace
+	                                        # DW_AT_name
+	.asciz	"N"
+	.byte	4                               # Abbrev [4] DW_TAG_namespace
+	                                        # DW_AT_name
+	.asciz	"A"
+                                        # DW_AT_export_symbols
+	.byte	0                               # End Of Children Mark
+	.byte	0                               # End Of Children Mark
+	.byte	5                               # Abbrev [5] DW_TAG_subprogram
+	.quad	.Lfunc_begin1                   # DW_AT_low_pc
+	.long	.Lfunc_end1-.Lfunc_begin1       # DW_AT_high_pc
+	.byte	1                               # DW_AT_frame_base
+	.byte	86
+	.long	.Lmethod_decl			# DW_AT_specification
+.Ltype_int:
+	.byte	6                               # Abbrev [6] DW_TAG_base_type
+	                                        # DW_AT_name
+	.asciz	"int"
+	.byte	5                               # DW_AT_encoding
+	.byte	4                               # DW_AT_byte_size
+	.byte	0                               # End Of Children Mark
+.Ldebug_info_end0:
+
+.Lcu_begin1:
+	.long	.Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit
+.Ldebug_info_start1:
+	.short	4                               # DWARF version number
+	.long	.Labbrev0                       # Offset Into Abbrev. Section
+	.byte	8                               # Address Size (in bytes)
+.Lpartial_unit:
+	.byte	7                               # Abbrev [7] DW_TAG_partial_unit
+	.byte	3                               # Abbrev [3] DW_TAG_namespace
+	                                        # DW_AT_name
+	.asciz	"N"
+	.byte	3                               # Abbrev [3] DW_TAG_namespace
+	                                        # DW_AT_name
+	.asciz	"A"
+                                                # The Bug - missing DW_AT_export_symbols
+.Lmethod_decl:
+	.byte	8                               # Abbrev [8] DW_TAG_subprogram
+	                                        # DW_AT_linkage_name
+	.asciz	"_ZN1N1AL1mEv"
+	                                        # DW_AT_name
+	.asciz	"m"
+	.byte	1                               # DW_AT_decl_file
+	.byte	1                               # DW_AT_decl_line
+	.long	.Ltype_int                      # DW_AT_type (DW_FORM_ref_addr)
+	.byte	0                               # End Of Children Mark
+	.byte	0                               # End Of Children Mark
+	.byte	0                               # End Of Children Mark
+.Ldebug_info_end1:
+
+	.section	".note.GNU-stack","",@progbits
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -240,6 +240,7 @@
   lldb::TypeSP ParsePointerToMemberType(const lldb_private::SymbolContext &sc,
                                         const DWARFDIE &die,
                                         const ParsedDWARFTypeAttributes &attrs);
+  bool NamespaceDIEIsInline(DWARFUnit *main_unit, const DWARFDIE &nsdie) const;
 };
 
 /// Parsed form of all attributes that are relevant for type reconstruction.
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -3488,6 +3488,35 @@
   return nullptr;
 }
 
+// Workaround for DWZ tool bug producing corrupted DWARF:
+// Multifile drops DW_TAG_namespace::DW_AT_export_symbols
+// https://sourceware.org/bugzilla/show_bug.cgi?id=27572
+bool DWARFASTParserClang::NamespaceDIEIsInline(DWARFUnit *main_unit,
+                                               const DWARFDIE &nsdie) const {
+  if (nsdie.GetAttributeValueAsUnsigned(DW_AT_export_symbols, 0) != 0)
+    return true;
+  if (nsdie.GetCU()->GetUnitDIEOnly().Tag() != DW_TAG_partial_unit)
+    return false;
+  llvm::SmallVector<const char *, 4> namevec;
+  for (DWARFDIE myname = nsdie; myname.IsValid(); myname = myname.GetParent())
+    if (myname.Tag() == DW_TAG_namespace)
+      namevec.push_back(myname.GetName());
+  lldbassert(!namevec.empty());
+  DWARFDIE finddie = main_unit->DIE();
+  while (!namevec.empty()) {
+    llvm::StringRef findname = namevec.back();
+    namevec.pop_back();
+    for (finddie = finddie.GetFirstChild();; finddie = finddie.GetSibling()) {
+      if (!finddie.IsValid())
+        return false;
+      if (finddie.Tag() == DW_TAG_namespace &&
+          findname == llvm::StringRef(finddie.GetName()))
+        break;
+    }
+  }
+  return finddie.GetAttributeValueAsUnsigned(DW_AT_export_symbols, 0) != 0;
+}
+
 clang::NamespaceDecl *
 DWARFASTParserClang::ResolveNamespaceDIE(DWARFUnit *main_unit,
                                          const DWARFDIE &die) {
@@ -3502,8 +3531,7 @@
       const char *namespace_name = die.GetName();
       clang::DeclContext *containing_decl_ctx =
           GetClangDeclContextContainingDIE(main_unit, die, nullptr);
-      bool is_inline =
-          die.GetAttributeValueAsUnsigned(DW_AT_export_symbols, 0) != 0;
+      bool is_inline = NamespaceDIEIsInline(main_unit, die);
 
       namespace_decl = m_ast.GetUniqueNamespaceDeclaration(
           namespace_name, containing_decl_ctx,
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
  • [Lldb-commits] [PATCH] D98... Jan Kratochvil via Phabricator via lldb-commits
    • [Lldb-commits] [PATCH... Jan Kratochvil via Phabricator via lldb-commits

Reply via email to