[Lldb-commits] [lldb] r361603 - DWARF: Implement DW_AT_signature lookup for type unit support

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Fri May 24 01:11:12 PDT 2019


Author: labath
Date: Fri May 24 01:11:12 2019
New Revision: 361603

URL: http://llvm.org/viewvc/llvm-project?rev=361603&view=rev
Log:
DWARF: Implement DW_AT_signature lookup for type unit support

Summary:
This patch implements the main feature of type units. When completing a
type, if we encounter a DW_AT_signature attribute, we use it's value to
lookup the complete definition of the type in the relevant type unit.

To enable this lookup, we build up a map of all type units in a symbol
file when parsing the units. Then we consult this map when resolving the
DW_AT_signature attribute.

I include add a couple of tests which exercise the type lookup feature,
including one that ensure we do something reasonable in case we fail to
lookup the type.

A lot of the ideas in this patch have been taken from D32167 and D61505.

Reviewers: clayborg, JDevlieghere, aprantl, alexshap

Subscribers: mgrang, lldb-commits

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

Added:
    lldb/trunk/lit/SymbolFile/DWARF/debug-types-missing-signature.test
    lldb/trunk/lit/SymbolFile/DWARF/debug-types-signature-loop.s
Modified:
    lldb/trunk/lit/SymbolFile/DWARF/Inputs/debug-types-basic.cpp
    lldb/trunk/lit/SymbolFile/DWARF/Inputs/debug-types-expressions.cpp
    lldb/trunk/lit/SymbolFile/DWARF/debug-types-basic.test
    lldb/trunk/lit/SymbolFile/DWARF/debug-types-expressions.test
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.h

Modified: lldb/trunk/lit/SymbolFile/DWARF/Inputs/debug-types-basic.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/DWARF/Inputs/debug-types-basic.cpp?rev=361603&r1=361602&r2=361603&view=diff
==============================================================================
--- lldb/trunk/lit/SymbolFile/DWARF/Inputs/debug-types-basic.cpp (original)
+++ lldb/trunk/lit/SymbolFile/DWARF/Inputs/debug-types-basic.cpp Fri May 24 01:11:12 2019
@@ -1,13 +1,15 @@
+enum E { e1, e2, e3 };
+enum class EC { e1, e2, e3 };
+
 struct A {
   int i;
   long l;
   float f;
   double d;
+  E e;
+  EC ec;
 };
 
-enum E { e1, e2, e3 };
-enum class EC { e1, e2, e3 };
-
-extern constexpr A a{42, 47l, 4.2f, 4.7};
+extern constexpr A a{42, 47l, 4.2f, 4.7, e1, EC::e3};
 extern constexpr E e(e2);
 extern constexpr EC ec(EC::e2);

Modified: lldb/trunk/lit/SymbolFile/DWARF/Inputs/debug-types-expressions.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/DWARF/Inputs/debug-types-expressions.cpp?rev=361603&r1=361602&r2=361603&view=diff
==============================================================================
--- lldb/trunk/lit/SymbolFile/DWARF/Inputs/debug-types-expressions.cpp (original)
+++ lldb/trunk/lit/SymbolFile/DWARF/Inputs/debug-types-expressions.cpp Fri May 24 01:11:12 2019
@@ -11,11 +11,19 @@ struct B: public A {
 namespace ns {
 struct A {
   int i = 147;
+  ::A getA();
   A();
 };
 A::A() = default;
+
+::A A::getA() {
+  ::A a;
+  a.i = i - 1;
+  return a;
 }
 
+} // namespace ns
+
 int foo(A *a) {
   return a->f();
 }

Modified: lldb/trunk/lit/SymbolFile/DWARF/debug-types-basic.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/DWARF/debug-types-basic.test?rev=361603&r1=361602&r2=361603&view=diff
==============================================================================
--- lldb/trunk/lit/SymbolFile/DWARF/debug-types-basic.test (original)
+++ lldb/trunk/lit/SymbolFile/DWARF/debug-types-basic.test Fri May 24 01:11:12 2019
@@ -19,6 +19,8 @@ type lookup A
 # CHECK-NEXT:   long l;
 # CHECK-NEXT:   float f;
 # CHECK-NEXT:   double d;
+# CHECK-NEXT:   E e;
+# CHECK-NEXT:   EC ec;
 # CHECK-NEXT: }
 
 type lookup E
@@ -44,3 +46,9 @@ print (E) 1
 print (EC) 1
 # CHECK-LABEL: print (EC) 1
 # CHECK: (EC) $1 = e2
+
+target variable a e ec
+# CHECK-LABEL: target variable a e ec
+# CHECK: (const A) a = (i = 42, l = 47, f = 4.{{[12].*}}, d = 4.{{[67].*}}, e = e1, ec = e3)
+# CHECK: (const E) e = e2
+# CHECK: (const EC) ec = e2

Modified: lldb/trunk/lit/SymbolFile/DWARF/debug-types-expressions.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/DWARF/debug-types-expressions.test?rev=361603&r1=361602&r2=361603&view=diff
==============================================================================
--- lldb/trunk/lit/SymbolFile/DWARF/debug-types-expressions.test (original)
+++ lldb/trunk/lit/SymbolFile/DWARF/debug-types-expressions.test Fri May 24 01:11:12 2019
@@ -19,6 +19,13 @@ frame variable a
 # CHECK-LABEL: frame variable a
 # CHECK: (B *) a =
 
+frame variable *a
+# CHECK-LABEL: frame variable *a
+# CHECK:      (B) *a = {
+# CHECK-NEXT:   A = (i = 47)
+# CHECK-NEXT:   j = 42
+# CHECK-NEXT: }
+
 print a->f()
 # CHECK-LABEL: print a->f()
 # CHECK: (int) $0 = 47
@@ -26,3 +33,11 @@ print a->f()
 print ns::A()
 # CHECK-LABEL: print ns::A()
 # CHECK: (ns::A) $1 = (i = 147)
+
+print ns::A().i + a->i
+# CHECK-LABEL: print ns::A().i + a->i
+# CHECK: (int) $2 = 194
+
+print ns::A().getA()
+# CHECK-LABEL: ns::A().getA()
+# CHECK: (A) $3 = (i = 146)

Added: lldb/trunk/lit/SymbolFile/DWARF/debug-types-missing-signature.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/DWARF/debug-types-missing-signature.test?rev=361603&view=auto
==============================================================================
--- lldb/trunk/lit/SymbolFile/DWARF/debug-types-missing-signature.test (added)
+++ lldb/trunk/lit/SymbolFile/DWARF/debug-types-missing-signature.test Fri May 24 01:11:12 2019
@@ -0,0 +1,26 @@
+Create a dangling DW_AT_signature reference by stripping the debug_types
+section, and make sure lldb does something reasonable.
+RUN: %clangxx -target x86_64-pc-linux %S/Inputs/debug-types-basic.cpp \
+RUN:   -g -gdwarf-4 -fdebug-types-section -c -o %t.o
+RUN: llvm-objcopy --remove-section=.debug_types %t.o %t
+
+
+RUN: %lldb %t -b -o "type lookup A" | FileCheck --check-prefix=LOOKUPA %s
+LOOKUPA: no type was found matching 'A'
+
+RUN: %lldb %t -b -o "type lookup E" | FileCheck --check-prefix=LOOKUPE %s
+LOOKUPE: no type was found matching 'E'
+
+RUN: %lldb %t -b -o "type lookup EC" | FileCheck --check-prefix=LOOKUPEC %s
+LOOKUPEC: no type was found matching 'EC'
+
+RUN: %lldb %t -b -o "print (E) 1" 2>&1 | FileCheck --check-prefix=PRINTE %s
+PRINTE: use of undeclared identifier 'E'
+
+RUN: %lldb %t -b -o "print (EC) 1" 2>&1 | FileCheck --check-prefix=PRINTEC %s
+PRINTEC: use of undeclared identifier 'EC'
+
+RUN: %lldb %t -b -o "target variable a e ec" | FileCheck --check-prefix=VARS %s
+VARS: (const (anonymous struct)) a = {}
+VARS: (const (anonymous enum)) e = 1
+VARS: (const (anonymous enum)) ec = 1

Added: lldb/trunk/lit/SymbolFile/DWARF/debug-types-signature-loop.s
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/DWARF/debug-types-signature-loop.s?rev=361603&view=auto
==============================================================================
--- lldb/trunk/lit/SymbolFile/DWARF/debug-types-signature-loop.s (added)
+++ lldb/trunk/lit/SymbolFile/DWARF/debug-types-signature-loop.s Fri May 24 01:11:12 2019
@@ -0,0 +1,115 @@
+# REQUIRES: lld
+
+# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux -o %t.o %s
+# RUN: ld.lld %t.o -o %t
+# RUN: %lldb %t -o "target variable e" -b | FileCheck %s
+
+# CHECK: e = <could not resolve type>
+
+        .type   e, at object               # @e
+        .section        .rodata,"a", at progbits
+        .globl  e
+        .p2align        2
+e:
+        .long   0                       # 0x0
+        .size   e, 4
+
+.Lstr_offsets_base0:
+        .section        .debug_str,"MS", at progbits,1
+.Linfo_string0:
+        .asciz  "Hand-written DWARF"
+.Linfo_string1:
+        .asciz  "a.cpp"            
+.Linfo_string3:
+        .asciz  "e"           
+.Linfo_string4:
+        .asciz  "unsigned int"
+.Linfo_string5:
+        .asciz  "e1"          
+.Linfo_string6:
+        .asciz  "E"           
+
+        .section        .debug_abbrev,"", at progbits
+        .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   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   5                       # Abbreviation Code
+        .byte   17                      # DW_TAG_compile_unit
+        .byte   1                       # DW_CHILDREN_yes
+        .byte   37                      # DW_AT_producer
+        .byte   14                      # DW_FORM_strp
+        .byte   19                      # DW_AT_language
+        .byte   5                       # DW_FORM_data2
+        .byte   3                       # DW_AT_name
+        .byte   14                      # DW_FORM_strp
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   6                       # Abbreviation Code
+        .byte   52                      # DW_TAG_variable
+        .byte   0                       # DW_CHILDREN_no
+        .byte   3                       # DW_AT_name
+        .byte   14                      # DW_FORM_strp
+        .byte   73                      # DW_AT_type
+        .byte   19                      # DW_FORM_ref4
+        .byte   2                       # DW_AT_location
+        .byte   24                      # DW_FORM_exprloc
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   8                       # Abbreviation Code
+        .byte   4                       # DW_TAG_enumeration_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)
+
+        .section        .debug_info,"", at progbits
+.Ltu_begin0:
+        .long   .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+        .short  5                       # DWARF version number
+        .byte   2                       # DWARF Unit Type
+        .byte   8                       # Address Size (in bytes)
+        .long   .debug_abbrev           # Offset Into Abbrev. Section
+        .quad   5390450678491038984     # Type Signature
+        .long   .LE-.Ltu_begin0         # Type DIE Offset
+        .byte   1                       # Abbrev [1] 0x18:0x1d DW_TAG_type_unit
+        .short  4                       # DW_AT_language
+.LE:
+        .byte   8                       # Abbrev [8] 0x23:0xd DW_TAG_enumeration_type
+                                        # DW_AT_declaration
+        .quad   5390450678491038984     # DW_AT_signature
+.Lbase:
+        .byte   0                       # End Of Children Mark
+.Ldebug_info_end0:
+
+.Lcu_begin0:
+        .long   .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit
+.Ldebug_info_start1:
+        .short  5                       # DWARF version number
+        .byte   1                       # DWARF Unit Type
+        .byte   8                       # Address Size (in bytes)
+        .long   .debug_abbrev           # Offset Into Abbrev. Section
+        .byte   5                       # Abbrev [5] 0xc:0x2c DW_TAG_compile_unit
+        .long   .Linfo_string0          # DW_AT_producer
+        .short  4                       # DW_AT_language
+        .long   .Linfo_string1          # DW_AT_name
+        .byte   6                       # Abbrev [6] 0x1e:0xb DW_TAG_variable
+        .long   .Linfo_string3          # DW_AT_name
+        .long   .LE_sig-.Lcu_begin0     # DW_AT_type
+        .byte   9                       # DW_AT_location
+        .byte   3
+        .quad   e
+.LE_sig:
+        .byte   8                       # Abbrev [8] 0x2e:0x9 DW_TAG_enumeration_type
+                                        # DW_AT_declaration
+        .quad   5390450678491038984     # DW_AT_signature
+        .byte   0                       # End Of Children Mark
+.Ldebug_info_end1:

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp?rev=361603&r1=361602&r2=361603&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp Fri May 24 01:11:12 2019
@@ -237,7 +237,6 @@ TypeSP DWARFASTParserClang::ParseTypeFro
   AccessType accessibility = eAccessNone;
   if (!die)
     return nullptr;
-
   SymbolFileDWARF *dwarf = die.GetDWARF();
   if (log) {
     DWARFDIE context_die;
@@ -252,11 +251,27 @@ TypeSP DWARFASTParserClang::ParseTypeFro
         die.GetTagAsCString(), die.GetName());
   }
 
+
   Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE());
   if (type_ptr == DIE_IS_BEING_PARSED)
     return nullptr;
   if (type_ptr)
     return type_ptr->shared_from_this();
+  // Set a bit that lets us know that we are currently parsing this
+  dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
+
+  if (DWARFDIE signature_die =
+          die.GetAttributeValueAsReferenceDIE(DW_AT_signature)) {
+    if (TypeSP type_sp =
+            ParseTypeFromDWARF(sc, signature_die, log, type_is_new_ptr)) {
+      dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+      if (clang::DeclContext *decl_ctx =
+              GetCachedClangDeclContextForDIE(signature_die))
+        LinkDeclContextToDIE(decl_ctx, die);
+      return type_sp;
+    }
+    return nullptr;
+  }
 
   TypeList *type_list = dwarf->GetTypeList();
   if (type_is_new_ptr)
@@ -289,9 +304,6 @@ TypeSP DWARFASTParserClang::ParseTypeFro
   case DW_TAG_restrict_type:
   case DW_TAG_volatile_type:
   case DW_TAG_unspecified_type: {
-    // Set a bit that lets us know that we are currently parsing this
-    dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
     const size_t num_attributes = die.GetAttributes(attributes);
     uint32_t encoding = 0;
     DWARFFormValue encoding_uid;
@@ -540,9 +552,6 @@ TypeSP DWARFASTParserClang::ParseTypeFro
   case DW_TAG_structure_type:
   case DW_TAG_union_type:
   case DW_TAG_class_type: {
-    // Set a bit that lets us know that we are currently parsing this
-    dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
     LanguageType class_language = eLanguageTypeUnknown;
     bool is_complete_objc_class = false;
     size_t calling_convention = llvm::dwarf::CallingConvention::DW_CC_normal;
@@ -974,9 +983,6 @@ TypeSP DWARFASTParserClang::ParseTypeFro
   } break;
 
   case DW_TAG_enumeration_type: {
-    // Set a bit that lets us know that we are currently parsing this
-    dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
     bool is_scoped = false;
     DWARFFormValue encoding_form;
 
@@ -1136,9 +1142,6 @@ TypeSP DWARFASTParserClang::ParseTypeFro
   case DW_TAG_inlined_subroutine:
   case DW_TAG_subprogram:
   case DW_TAG_subroutine_type: {
-    // Set a bit that lets us know that we are currently parsing this
-    dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
     DWARFFormValue type_die_form;
     bool is_variadic = false;
     bool is_inline = false;
@@ -1658,9 +1661,6 @@ TypeSP DWARFASTParserClang::ParseTypeFro
   } break;
 
   case DW_TAG_array_type: {
-    // Set a bit that lets us know that we are currently parsing this
-    dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
-
     DWARFFormValue type_die_form;
     uint32_t byte_stride = 0;
     uint32_t bit_stride = 0;

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp?rev=361603&r1=361602&r2=361603&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp Fri May 24 01:11:12 2019
@@ -15,6 +15,7 @@
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Utility/RegularExpression.h"
 #include "lldb/Utility/Stream.h"
+#include "llvm/Support/Casting.h"
 
 #include "DWARFCompileUnit.h"
 #include "DWARFContext.h"
@@ -74,12 +75,14 @@ llvm::Expected<DWARFDebugAranges &> DWAR
   return *m_cu_aranges_up;
 }
 
-void Parse(SymbolFileDWARF *dwarf, const DWARFDataExtractor &data,
-           DIERef::Section section, std::vector<DWARFUnitSP> &units) {
+void DWARFDebugInfo::ParseUnitsFor(DIERef::Section section) {
+  DWARFDataExtractor data = section == DIERef::Section::DebugTypes
+                                ? m_context.getOrLoadDebugTypesData()
+                                : m_context.getOrLoadDebugInfoData();
   lldb::offset_t offset = 0;
   while (data.ValidOffset(offset)) {
-    llvm::Expected<DWARFUnitSP> unit_sp =
-        DWARFUnit::extract(dwarf, units.size(), data, section, &offset);
+    llvm::Expected<DWARFUnitSP> unit_sp = DWARFUnit::extract(
+        m_dwarf2Data, m_units.size(), data, section, &offset);
 
     if (!unit_sp) {
       // FIXME: Propagate this error up.
@@ -89,10 +92,13 @@ void Parse(SymbolFileDWARF *dwarf, const
 
     // If it didn't return an error, then it should be returning a valid Unit.
     assert(*unit_sp);
-
-    units.push_back(*unit_sp);
-
+    m_units.push_back(*unit_sp);
     offset = (*unit_sp)->GetNextUnitOffset();
+
+    if (auto *type_unit = llvm::dyn_cast<DWARFTypeUnit>(unit_sp->get())) {
+      m_type_hash_to_unit_index.emplace_back(type_unit->GetTypeHash(),
+                                             unit_sp.get()->GetID());
+    }
   }
 }
 
@@ -102,10 +108,9 @@ void DWARFDebugInfo::ParseUnitHeadersIfN
   if (!m_dwarf2Data)
     return;
 
-  Parse(m_dwarf2Data, m_context.getOrLoadDebugInfoData(),
-        DIERef::Section::DebugInfo, m_units);
-  Parse(m_dwarf2Data, m_context.getOrLoadDebugTypesData(),
-        DIERef::Section::DebugTypes, m_units);
+  ParseUnitsFor(DIERef::Section::DebugInfo);
+  ParseUnitsFor(DIERef::Section::DebugTypes);
+  llvm::sort(m_type_hash_to_unit_index, llvm::less_first());
 }
 
 size_t DWARFDebugInfo::GetNumUnits() {
@@ -169,6 +174,14 @@ DWARFDebugInfo::GetUnitContainingDIEOffs
   return result;
 }
 
+DWARFTypeUnit *DWARFDebugInfo::GetTypeUnitForHash(uint64_t hash) {
+  auto pos = llvm::lower_bound(m_type_hash_to_unit_index,
+                               std::make_pair(hash, 0u), llvm::less_first());
+  if (pos == m_type_hash_to_unit_index.end() || pos->first != hash)
+    return nullptr;
+  return llvm::cast<DWARFTypeUnit>(GetUnitAtIndex(pos->second));
+}
+
 DWARFDIE
 DWARFDebugInfo::GetDIEForDIEOffset(DIERef::Section section,
                                    dw_offset_t die_offset) {

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h?rev=361603&r1=361602&r2=361603&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h Fri May 24 01:11:12 2019
@@ -13,6 +13,7 @@
 #include <vector>
 
 #include "DWARFDIE.h"
+#include "DWARFTypeUnit.h"
 #include "DWARFUnit.h"
 #include "SymbolFileDWARF.h"
 #include "lldb/Core/STLUtils.h"
@@ -46,6 +47,7 @@ public:
   DWARFUnit *GetUnitContainingDIEOffset(DIERef::Section section,
                                         dw_offset_t die_offset);
   DWARFUnit *GetUnit(const DIERef &die_ref);
+  DWARFTypeUnit *GetTypeUnitForHash(uint64_t hash);
   DWARFDIE GetDIEForDIEOffset(DIERef::Section section,
                               dw_offset_t die_offset);
   DWARFDIE GetDIE(const DIERef &die_ref);
@@ -69,11 +71,15 @@ protected:
   std::unique_ptr<DWARFDebugAranges>
       m_cu_aranges_up; // A quick address to compile unit table
 
+  std::vector<std::pair<uint64_t, uint32_t>> m_type_hash_to_unit_index;
+
 private:
   // All parsing needs to be done partially any managed by this class as
   // accessors are called.
   void ParseUnitHeadersIfNeeded();
 
+  void ParseUnitsFor(DIERef::Section section);
+
   uint32_t FindUnitIndex(DIERef::Section section, dw_offset_t offset);
 
   DISALLOW_COPY_AND_ASSIGN(DWARFDebugInfo);

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp?rev=361603&r1=361602&r2=361603&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp Fri May 24 01:11:12 2019
@@ -585,6 +585,14 @@ DWARFDIE DWARFFormValue::Reference() con
     return ref_cu->GetDIE(value);
   }
 
+  case DW_FORM_ref_sig8: {
+    DWARFTypeUnit *tu =
+        m_unit->GetSymbolFileDWARF()->DebugInfo()->GetTypeUnitForHash(value);
+    if (!tu)
+      return {};
+    return tu->GetDIE(tu->GetTypeOffset());
+  }
+
   default:
     return {};
   }

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp?rev=361603&r1=361602&r2=361603&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp Fri May 24 01:11:12 2019
@@ -14,7 +14,6 @@
 using namespace lldb;
 using namespace lldb_private;
 
-
 void DWARFTypeUnit::Dump(Stream *s) const {
   s->Printf("0x%8.8x: Type Unit: length = 0x%8.8x, version = 0x%4.4x, "
             "abbr_offset = 0x%8.8x, addr_size = 0x%2.2x (next CU at "

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h?rev=361603&r1=361602&r2=361603&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h Fri May 24 01:11:12 2019
@@ -18,6 +18,14 @@ public:
 
   void Dump(lldb_private::Stream *s) const override;
 
+  uint64_t GetTypeHash() { return m_header.GetTypeHash(); }
+
+  dw_offset_t GetTypeOffset() { return GetOffset() + m_header.GetTypeOffset(); }
+
+  static bool classof(const DWARFUnit *unit) {
+    return unit->GetUnitType() == DW_UT_type;
+  }
+
 private:
   DWARFTypeUnit(SymbolFileDWARF *dwarf, lldb::user_id_t uid,
                 const DWARFUnitHeader &header,

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp?rev=361603&r1=361602&r2=361603&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp Fri May 24 01:11:12 2019
@@ -715,9 +715,16 @@ DWARFUnitHeader::extract(const DWARFData
         section == DIERef::Section::DebugTypes ? DW_UT_type : DW_UT_compile;
   }
 
+  if (header.IsTypeUnit()) {
+    header.m_type_hash = data.GetU64(offset_ptr);
+    header.m_type_offset = data.GetDWARFOffset(offset_ptr);
+  }
+
   bool length_OK = data.ValidOffset(header.GetNextUnitOffset() - 1);
   bool version_OK = SymbolFileDWARF::SupportedVersion(header.m_version);
   bool addr_size_OK = (header.m_addr_size == 4) || (header.m_addr_size == 8);
+  bool type_offset_OK =
+      !header.IsTypeUnit() || (header.m_type_offset <= header.GetLength());
 
   if (!length_OK)
     return llvm::make_error<llvm::object::GenericBinaryError>(
@@ -728,6 +735,9 @@ DWARFUnitHeader::extract(const DWARFData
   if (!addr_size_OK)
     return llvm::make_error<llvm::object::GenericBinaryError>(
         "Invalid unit address size");
+  if (!type_offset_OK)
+    return llvm::make_error<llvm::object::GenericBinaryError>(
+        "Type offset out of range");
 
   return header;
 }

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.h?rev=361603&r1=361602&r2=361603&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFUnit.h Fri May 24 01:11:12 2019
@@ -41,6 +41,10 @@ class DWARFUnitHeader {
   dw_offset_t m_abbr_offset = 0;
   uint8_t m_unit_type = 0;
   uint8_t m_addr_size = 0;
+
+  uint64_t m_type_hash = 0;
+  uint32_t m_type_offset = 0;
+
   uint64_t m_dwo_id = 0;
 
   DWARFUnitHeader() = default;
@@ -52,6 +56,8 @@ public:
   dw_offset_t GetLength() const { return m_length; }
   dw_offset_t GetAbbrOffset() const { return m_abbr_offset; }
   uint8_t GetUnitType() const { return m_unit_type; }
+  uint64_t GetTypeHash() const { return m_type_hash; }
+  dw_offset_t GetTypeOffset() const { return m_type_offset; }
   bool IsTypeUnit() const {
     return m_unit_type == DW_UT_type || m_unit_type == DW_UT_split_type;
   }
@@ -205,6 +211,8 @@ public:
 
   DIERef::Section GetDebugSection() const { return m_section; }
 
+  uint8_t GetUnitType() const { return m_header.GetUnitType(); }
+
 protected:
   DWARFUnit(SymbolFileDWARF *dwarf, lldb::user_id_t uid,
             const DWARFUnitHeader &header,




More information about the lldb-commits mailing list