jgorbe created this revision.
jgorbe added reviewers: dblaikie, labath.
Herald added a subscriber: arphaman.
jgorbe requested review of this revision.
Herald added a project: LLDB.

In DWARF v4 compile units go in .debug_info and type units go in
.debug_types. However, in v5 both kinds of units are in .debug_info.
Therefore we can't decide whether to use the CU or TU index just by
looking at which section we're reading from. We have to wait until we
have read the unit type from the header.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D96194

Files:
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
  lldb/test/Shell/SymbolFile/DWARF/dwarf5_tu_index_abbrev_offset.s

Index: lldb/test/Shell/SymbolFile/DWARF/dwarf5_tu_index_abbrev_offset.s
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/DWARF/dwarf5_tu_index_abbrev_offset.s
@@ -0,0 +1,323 @@
+## This test checks that lldb uses the abbrev_offset from .debug_tu_index when
+## reading TUs in the .debug_info section of a DWARF v5 DWP.
+##
+## The assembly here is, essentially, slightly hand-reduced output from
+## `clang -gsplit-dwarf -gdwarf-5 -fdebug-types-section`, with a manually-added
+## .debug_cu_index and a .debug_tu_index to create a DWP, and a twist: abbrevs
+## from the TU are listed *AFTER* abbrevs from the CU so that they don't begin
+## at offset 0.
+
+# RUN: llvm-mc --filetype=obj --triple x86_64 %s -o %t --defsym MAIN=1
+# RUN: llvm-mc --filetype=obj --triple x86_64 %s -o %t.dwp
+# RUN: %lldb %t -o "image lookup -t t1" -b | FileCheck %s
+# CHECK: struct t1
+
+.ifdef MAIN
+## Main file
+	.text
+	.globl	main                            # -- Begin function main
+main:                                   # @main
+.Lfunc_begin0:
+	pushq	%rbp
+	movq	%rsp, %rbp
+	xorl	%eax, %eax
+	popq	%rbp
+	retq
+.Lfunc_end0:
+                                        # -- End function
+	.section	.debug_abbrev,"",@progbits
+	.byte	1                               # Abbreviation Code
+	.byte	74                              # DW_TAG_skeleton_unit
+	.byte	0                               # DW_CHILDREN_no
+	.byte	118                             # DW_AT_dwo_name
+	.byte	8                               # DW_FORM_string
+	.byte	17                              # DW_AT_low_pc
+	.byte	27                              # DW_FORM_addrx
+	.byte	18                              # DW_AT_high_pc
+	.byte	6                               # DW_FORM_data4
+	.byte	115                             # DW_AT_addr_base
+	.byte	23                              # DW_FORM_sec_offset
+	.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	5                             # DWARF version number
+	.byte	4                               # DWARF Unit Type
+	.byte	8                               # Address Size (in bytes)
+	.long	.debug_abbrev                   # Offset Into Abbrev. Section
+	.quad	-8218585293556409984            # dwo_id
+	.byte	1                               # Abbrev [1] 0x14:0x14 DW_TAG_skeleton_unit
+	.asciz "hello.dwo"                    # DW_AT_dwo_name
+	.byte	0                               # DW_AT_low_pc
+	.long	.Lfunc_end0-.Lfunc_begin0       # DW_AT_high_pc
+	.long	.Laddr_table_base0              # DW_AT_addr_base
+.Ldebug_info_end0:
+
+
+	.section	.debug_addr,"",@progbits
+	.long	.Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
+.Ldebug_addr_start0:
+	.short	5                               # DWARF version number
+	.byte	8                               # Address size
+	.byte	0                               # Segment selector size
+.Laddr_table_base0:
+	.quad	.Lfunc_begin0
+.Ldebug_addr_end0:
+
+
+.else
+## DWP file
+	.section	.debug_info.dwo,"e",@progbits
+	.long	.Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
+.Ldebug_info_dwo_start0:
+	.short	5                               # DWARF version number
+	.byte	6                               # DWARF Unit Type
+	.byte	8                               # Address Size (in bytes)
+	.long	0                               # Offset Into Abbrev. Section
+	.quad	-4149699470930386446            # Type Signature
+	.long	31                              # Type DIE Offset
+	.byte	1                               # Abbrev [1] 0x18:0xe DW_TAG_type_unit
+	.short	33                              # DW_AT_language
+	.long	0                               # DW_AT_stmt_list
+	.byte	2                               # Abbrev [2] 0x1f:0x6 DW_TAG_structure_type
+	.byte	5                               # DW_AT_calling_convention
+	.byte	3                               # DW_AT_name
+	.byte	1                               # DW_AT_byte_size
+	.byte	0                               # DW_AT_decl_file
+	.byte	1                               # DW_AT_decl_line
+	.byte	0                               # End Of Children Mark
+.Ldebug_info_dwo_end0:
+	.long	.Ldebug_info_dwo_end1-.Ldebug_info_dwo_start1 # Length of Unit
+.Ldebug_info_dwo_start1:
+	.short	5                               # DWARF version number
+	.byte	5                               # DWARF Unit Type
+	.byte	8                               # Address Size (in bytes)
+	.long	0                               # Offset Into Abbrev. Section
+	.quad	-8218585293556409984
+	.byte	3                               # Abbrev [3] 0x14:0x2f DW_TAG_compile_unit
+	.byte	4                               # DW_AT_producer
+	.short	33                              # DW_AT_language
+	.byte	5                               # DW_AT_name
+	.byte	6                               # DW_AT_dwo_name
+	.byte	4                               # Abbrev [4] 0x1a:0x1b DW_TAG_subprogram
+	.byte	0                               # DW_AT_low_pc
+	.long	8                               # DW_AT_high_pc
+	.byte	1                               # DW_AT_frame_base
+	.byte	86
+	.byte	0                               # DW_AT_name
+	.byte	0                               # DW_AT_decl_file
+	.byte	2                               # DW_AT_decl_line
+	.long	53                              # DW_AT_type
+                                        # DW_AT_external
+	.byte	5                               # Abbrev [5] 0x29:0xb DW_TAG_variable
+	.byte	2                               # DW_AT_location
+	.byte	145
+	.byte	120
+	.byte	2                               # DW_AT_name
+	.byte	0                               # DW_AT_decl_file
+	.byte	3                               # DW_AT_decl_line
+	.long	57                              # DW_AT_type
+	.byte	0                               # End Of Children Mark
+	.byte	6                               # Abbrev [6] 0x35:0x4 DW_TAG_base_type
+	.byte	1                               # DW_AT_name
+	.byte	5                               # DW_AT_encoding
+	.byte	4                               # DW_AT_byte_size
+	.byte	7                               # Abbrev [7] 0x39:0x9 DW_TAG_structure_type
+                                        # DW_AT_declaration
+	.quad	-4149699470930386446            # DW_AT_signature
+	.byte	0                               # End Of Children Mark
+.Ldebug_info_dwo_end1:
+
+
+
+	.section	.debug_str.dwo,"eMS",@progbits,1
+.Linfo_string0:
+	.asciz	"main"
+.Linfo_string1:
+	.asciz	"int"
+.Linfo_string2:
+	.asciz	"v1"
+.Linfo_string3:
+	.asciz	"t1"
+.Linfo_string4:
+	.asciz	"hand-tuned clang output"
+.Linfo_string5:
+	.asciz	"test.cc"
+.Linfo_string6:
+	.asciz	"test.dwo"
+
+
+	.section	.debug_str_offsets.dwo,"e",@progbits
+	.long	32                              # Length of String Offsets Set
+	.short	5
+	.short	0
+
+	.long	.Linfo_string0-.debug_str.dwo
+	.long	.Linfo_string1-.debug_str.dwo
+	.long	.Linfo_string2-.debug_str.dwo
+	.long	.Linfo_string3-.debug_str.dwo
+	.long	.Linfo_string4-.debug_str.dwo
+	.long	.Linfo_string5-.debug_str.dwo
+	.long	.Linfo_string6-.debug_str.dwo
+.Lstr_offsets_end:
+
+	.section	.debug_abbrev.dwo,"e",@progbits
+.Ldebug_cu_abbrev_begin:
+	.byte	3                               # Abbreviation Code
+	.byte	17                              # DW_TAG_compile_unit
+	.byte	1                               # DW_CHILDREN_yes
+	.byte	37                              # DW_AT_producer
+	.byte	37                              # DW_FORM_strx1
+	.byte	19                              # DW_AT_language
+	.byte	5                               # DW_FORM_data2
+	.byte	3                               # DW_AT_name
+	.byte	37                              # DW_FORM_strx1
+	.byte	118                             # DW_AT_dwo_name
+	.byte	37                              # DW_FORM_strx1
+	.byte	0                               # EOM(1)
+	.byte	0                               # EOM(2)
+	.byte	4                               # Abbreviation Code
+	.byte	46                              # DW_TAG_subprogram
+	.byte	1                               # DW_CHILDREN_yes
+	.byte	17                              # DW_AT_low_pc
+	.byte	27                              # DW_FORM_addrx
+	.byte	18                              # DW_AT_high_pc
+	.byte	6                               # DW_FORM_data4
+	.byte	64                              # DW_AT_frame_base
+	.byte	24                              # DW_FORM_exprloc
+	.byte	3                               # DW_AT_name
+	.byte	37                              # DW_FORM_strx1
+	.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	19                              # DW_FORM_ref4
+	.byte	63                              # DW_AT_external
+	.byte	25                              # DW_FORM_flag_present
+	.byte	0                               # EOM(1)
+	.byte	0                               # EOM(2)
+	.byte	5                               # Abbreviation Code
+	.byte	52                              # DW_TAG_variable
+	.byte	0                               # DW_CHILDREN_no
+	.byte	2                               # DW_AT_location
+	.byte	24                              # DW_FORM_exprloc
+	.byte	3                               # DW_AT_name
+	.byte	37                              # DW_FORM_strx1
+	.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	19                              # DW_FORM_ref4
+	.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	37                              # DW_FORM_strx1
+	.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	19                              # DW_TAG_structure_type
+	.byte	0                               # DW_CHILDREN_no
+	.byte	60                              # DW_AT_declaration
+	.byte	25                              # DW_FORM_flag_present
+	.byte	105                             # DW_AT_signature
+	.byte	32                              # DW_FORM_ref_sig8
+	.byte	0                               # EOM(1)
+	.byte	0                               # EOM(2)
+	.byte	0                               # EOM(3)
+.Ldebug_cu_abbrev_end:
+.Ldebug_tu_abbrev_begin:
+  .byte	1                               # Abbreviation Code
+	.byte	65                              # DW_TAG_type_unit
+	.byte	1                               # DW_CHILDREN_yes
+	.byte	19                              # DW_AT_language
+	.byte	5                               # DW_FORM_data2
+	.byte	16                              # DW_AT_stmt_list
+	.byte	23                              # DW_FORM_sec_offset
+	.byte	0                               # EOM(1)
+	.byte	0                               # EOM(2)
+	.byte	2                               # Abbreviation Code
+	.byte	19                              # DW_TAG_structure_type
+	.byte	0                               # DW_CHILDREN_no
+	.byte	54                              # DW_AT_calling_convention
+	.byte	11                              # DW_FORM_data1
+	.byte	3                               # DW_AT_name
+	.byte	37                              # DW_FORM_strx1
+	.byte	11                              # DW_AT_byte_size
+	.byte	11                              # DW_FORM_data1
+	.byte	58                              # DW_AT_decl_file
+	.byte	11                              # DW_FORM_data1
+	.byte	59                              # DW_AT_decl_line
+	.byte	11                              # DW_FORM_data1
+	.byte	0                               # EOM(1)
+	.byte	0                               # EOM(2)
+	.byte	0                               # EOM(3)
+.Ldebug_tu_abbrev_end:
+.Ldebug_abbrev_dwo_end:
+
+.section .debug_tu_index,"",@progbits
+.short 5  # DWARF version number
+.short 0  # Reserved
+.long  3  # Section count
+.long  1  # Unit count
+.long  2 # Slot count
+
+.quad  -4149699470930386446, 0 # Hash table
+.long  1, 0 # Index table
+
+## Table header
+.long 1   # DW_SECT_INFO
+.long 3   # DW_SECT_ABBREV
+.long 6   # DW_SECT_STR_OFFSETS
+
+## Offsets
+.long 0   # offset into .debug_info.dwo
+.long .Ldebug_tu_abbrev_begin - .debug_abbrev.dwo   # offset into .debug_abbrev.dwo
+.long 0   # offset into .debug_str_offsets.dwo
+
+## Sizes
+.long .Ldebug_info_dwo_end0 - .debug_info.dwo
+.long .Ldebug_tu_abbrev_end - .Ldebug_tu_abbrev_begin
+.long .Lstr_offsets_end - .debug_str_offsets.dwo
+
+
+.section .debug_cu_index,"",@progbits
+.short 5  # DWARF version number
+.short 0  # Reserved
+.long  3  # Section count
+.long  1  # Unit count
+.long  2 # Slot count
+
+.quad  -8218585293556409984, 0 # Hash table
+.long  1, 0 # Index table
+
+## Table header
+.long 1   # DW_SECT_INFO
+.long 3   # DW_SECT_ABBREV
+.long 6   # DW_SECT_STR_OFFSETS
+
+## Offsets
+.long .Ldebug_info_dwo_end0 - .debug_info.dwo   # offset into .debug_info.dwo
+.long .Ldebug_cu_abbrev_begin - .debug_abbrev.dwo  # offset into .debug_abbrev.dwo
+.long 0   # offset into .debug_str_offsets.dwo
+
+## Sizes
+.long .Ldebug_info_dwo_end1 - .Ldebug_info_dwo_end0
+.long .Ldebug_cu_abbrev_end - .Ldebug_cu_abbrev_begin
+.long .Lstr_offsets_end - .debug_str_offsets.dwo
+
+
+.endif
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -73,7 +73,8 @@
 
   static llvm::Expected<DWARFUnitHeader>
   extract(const lldb_private::DWARFDataExtractor &data, DIERef::Section section,
-          lldb::offset_t *offset_ptr, const llvm::DWARFUnitIndex *index);
+          lldb::offset_t *offset_ptr, const llvm::DWARFUnitIndex *cu_index,
+          const llvm::DWARFUnitIndex *tu_index);
 };
 
 class DWARFUnit : public lldb_private::UserID {
@@ -85,7 +86,8 @@
   extract(SymbolFileDWARF &dwarf2Data, lldb::user_id_t uid,
           const lldb_private::DWARFDataExtractor &debug_info,
           DIERef::Section section, lldb::offset_t *offset_ptr,
-          const llvm::DWARFUnitIndex *index);
+          const llvm::DWARFUnitIndex *cu_index,
+          const llvm::DWARFUnitIndex *tu_index);
   virtual ~DWARFUnit();
 
   bool IsDWOUnit() { return m_is_dwo; }
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -785,11 +785,10 @@
 llvm::Expected<DWARFUnitHeader>
 DWARFUnitHeader::extract(const DWARFDataExtractor &data,
                          DIERef::Section section, lldb::offset_t *offset_ptr,
-                         const llvm::DWARFUnitIndex *index) {
+                         const llvm::DWARFUnitIndex *cu_index,
+                         const llvm::DWARFUnitIndex *tu_index) {
   DWARFUnitHeader header;
   header.m_offset = *offset_ptr;
-  if (index)
-    header.m_index_entry = index->getFromOffset(*offset_ptr);
   header.m_length = data.GetDWARFInitialLength(offset_ptr);
   header.m_version = data.GetU16(offset_ptr);
   if (header.m_version == 5) {
@@ -806,6 +805,15 @@
         section == DIERef::Section::DebugTypes ? DW_UT_type : DW_UT_compile;
   }
 
+  if (cu_index && (header.m_unit_type == llvm::dwarf::DW_UT_compile ||
+                   header.m_unit_type == llvm::dwarf::DW_UT_split_compile)) {
+    header.m_index_entry = cu_index->getFromOffset(header.m_offset);
+  }
+  if (tu_index && (header.m_unit_type == llvm::dwarf::DW_UT_type ||
+                   header.m_unit_type == llvm::dwarf::DW_UT_split_type)) {
+    header.m_index_entry = tu_index->getFromOffset(header.m_offset);
+  }
+
   if (header.m_index_entry) {
     if (header.m_abbr_offset) {
       return llvm::createStringError(
@@ -857,11 +865,13 @@
 DWARFUnit::extract(SymbolFileDWARF &dwarf, user_id_t uid,
                    const DWARFDataExtractor &debug_info,
                    DIERef::Section section, lldb::offset_t *offset_ptr,
-                   const llvm::DWARFUnitIndex *index) {
+                   const llvm::DWARFUnitIndex *cu_index,
+                   const llvm::DWARFUnitIndex *tu_index) {
   assert(debug_info.ValidOffset(*offset_ptr));
 
   auto expected_header =
-      DWARFUnitHeader::extract(debug_info, section, offset_ptr, index);
+      DWARFUnitHeader::extract(debug_info, section, offset_ptr, cu_index,
+                               tu_index);
   if (!expected_header)
     return expected_header.takeError();
 
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -72,16 +72,16 @@
   DWARFDataExtractor data = section == DIERef::Section::DebugTypes
                                 ? m_context.getOrLoadDebugTypesData()
                                 : m_context.getOrLoadDebugInfoData();
-  const llvm::DWARFUnitIndex *index = nullptr;
-  if (m_context.isDwo())
-    index = &llvm::getDWARFUnitIndex(m_context.GetAsLLVM(),
-                                     section == DIERef::Section::DebugTypes
-                                         ? llvm::DW_SECT_EXT_TYPES
-                                         : llvm::DW_SECT_INFO);
+  const llvm::DWARFUnitIndex *cu_index = nullptr;
+  const llvm::DWARFUnitIndex *tu_index = nullptr;
+  if (m_context.isDwo()) {
+    cu_index = &m_context.GetAsLLVM().getCUIndex();
+    tu_index = &m_context.GetAsLLVM().getTUIndex();
+  }
   lldb::offset_t offset = 0;
   while (data.ValidOffset(offset)) {
     llvm::Expected<DWARFUnitSP> unit_sp = DWARFUnit::extract(
-        m_dwarf, m_units.size(), data, section, &offset, index);
+        m_dwarf, m_units.size(), data, section, &offset, cu_index, tu_index);
 
     if (!unit_sp) {
       // FIXME: Propagate this error up.
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to