Author: Jorge Gorbe Moya
Date: 2021-02-23T13:26:11-08:00
New Revision: 979ca1c05f83114483caec3e6d1b75daae86da79

URL: 
https://github.com/llvm/llvm-project/commit/979ca1c05f83114483caec3e6d1b75daae86da79
DIFF: 
https://github.com/llvm/llvm-project/commit/979ca1c05f83114483caec3e6d1b75daae86da79.diff

LOG: Defer the decision whether to use the CU or TU index until after reading 
the unit header.

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.

Differential Revision: https://reviews.llvm.org/D96194

Added: 
    lldb/test/Shell/SymbolFile/DWARF/dwarf5_tu_index_abbrev_offset.s

Modified: 
    lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
    lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
    lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
index 8d393b295443..5f0af57da9e4 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -72,16 +72,10 @@ void DWARFDebugInfo::ParseUnitsFor(DIERef::Section section) 
{
   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);
   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);
 
     if (!unit_sp) {
       // FIXME: Propagate this error up.

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index a761dd3daac4..bb60ab9878c8 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -784,12 +784,11 @@ const DWARFDebugAranges &DWARFUnit::GetFunctionAranges() {
 
 llvm::Expected<DWARFUnitHeader>
 DWARFUnitHeader::extract(const DWARFDataExtractor &data,
-                         DIERef::Section section, lldb::offset_t *offset_ptr,
-                         const llvm::DWARFUnitIndex *index) {
+                         DIERef::Section section,
+                         lldb_private::DWARFContext &context,
+                         lldb::offset_t *offset_ptr) {
   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,16 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data,
         section == DIERef::Section::DebugTypes ? DW_UT_type : DW_UT_compile;
   }
 
+  if (context.isDwo()) {
+    if (header.IsTypeUnit()) {
+      header.m_index_entry =
+          context.GetAsLLVM().getTUIndex().getFromOffset(header.m_offset);
+    } else {
+      header.m_index_entry =
+          context.GetAsLLVM().getCUIndex().getFromOffset(header.m_offset);
+    }
+  }
+
   if (header.m_index_entry) {
     if (header.m_abbr_offset) {
       return llvm::createStringError(
@@ -856,12 +865,11 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data,
 llvm::Expected<DWARFUnitSP>
 DWARFUnit::extract(SymbolFileDWARF &dwarf, user_id_t uid,
                    const DWARFDataExtractor &debug_info,
-                   DIERef::Section section, lldb::offset_t *offset_ptr,
-                   const llvm::DWARFUnitIndex *index) {
+                   DIERef::Section section, lldb::offset_t *offset_ptr) {
   assert(debug_info.ValidOffset(*offset_ptr));
 
-  auto expected_header =
-      DWARFUnitHeader::extract(debug_info, section, offset_ptr, index);
+  auto expected_header = DWARFUnitHeader::extract(
+      debug_info, section, dwarf.GetDWARFContext(), offset_ptr);
   if (!expected_header)
     return expected_header.takeError();
 

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h 
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
index 5739c36bbacb..0fc8ceae81d2 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -73,7 +73,8 @@ class DWARFUnitHeader {
 
   static llvm::Expected<DWARFUnitHeader>
   extract(const lldb_private::DWARFDataExtractor &data, DIERef::Section 
section,
-          lldb::offset_t *offset_ptr, const llvm::DWARFUnitIndex *index);
+          lldb_private::DWARFContext &dwarf_context,
+          lldb::offset_t *offset_ptr);
 };
 
 class DWARFUnit : public lldb_private::UserID {
@@ -84,8 +85,7 @@ class DWARFUnit : public lldb_private::UserID {
   static llvm::Expected<DWARFUnitSP>
   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);
+          DIERef::Section section, lldb::offset_t *offset_ptr);
   virtual ~DWARFUnit();
 
   bool IsDWOUnit() { return m_is_dwo; }

diff  --git a/lldb/test/Shell/SymbolFile/DWARF/dwarf5_tu_index_abbrev_offset.s 
b/lldb/test/Shell/SymbolFile/DWARF/dwarf5_tu_index_abbrev_offset.s
new file mode 100644
index 000000000000..4dae81b48a68
--- /dev/null
+++ b/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


        
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to