clayborg updated this revision to Diff 135913.
clayborg added a comment.
Herald added subscribers: JDevlieghere, eraman, arichardson, emaste.

Updated to top of tree sources and verified it passes all tests on linux.


https://reviews.llvm.org/D32167

Files:
  include/lldb/lldb-enumerations.h
  include/lldb/lldb-forward.h
  packages/Python/lldbsuite/test/lldbinline.py
  packages/Python/lldbsuite/test/lldbtest.py
  packages/Python/lldbsuite/test/make/Makefile.rules
  packages/Python/lldbsuite/test/plugins/builder_base.py
  packages/Python/lldbsuite/test/test_categories.py
  source/Core/Section.cpp
  source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
  source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
  source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
  source/Plugins/SymbolFile/DWARF/DIERef.cpp
  source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
  source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
  source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
  source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
  source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
  source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
  source/Plugins/SymbolFile/DWARF/DWARFDIE.h
  source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp
  source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
  source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
  source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
  source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
  source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
  source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
  source/Symbol/ObjectFile.cpp

Index: source/Symbol/ObjectFile.cpp
===================================================================
--- source/Symbol/ObjectFile.cpp
+++ source/Symbol/ObjectFile.cpp
@@ -360,6 +360,7 @@
           case eSectionTypeDWARFDebugRanges:
           case eSectionTypeDWARFDebugStr:
           case eSectionTypeDWARFDebugStrOffsets:
+          case eSectionTypeDWARFDebugTypes:
           case eSectionTypeDWARFAppleNames:
           case eSectionTypeDWARFAppleTypes:
           case eSectionTypeDWARFAppleNamespaces:
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -246,6 +246,7 @@
   const lldb_private::DWARFDataExtractor &get_debug_ranges_data();
   const lldb_private::DWARFDataExtractor &get_debug_str_data();
   const lldb_private::DWARFDataExtractor &get_debug_str_offsets_data();
+  const lldb_private::DWARFDataExtractor &get_debug_types_data();
   const lldb_private::DWARFDataExtractor &get_apple_names_data();
   const lldb_private::DWARFDataExtractor &get_apple_types_data();
   const lldb_private::DWARFDataExtractor &get_apple_namespaces_data();
@@ -491,6 +492,7 @@
   DWARFDataSegment m_data_debug_ranges;
   DWARFDataSegment m_data_debug_str;
   DWARFDataSegment m_data_debug_str_offsets;
+  DWARFDataSegment m_data_debug_types;
   DWARFDataSegment m_data_apple_names;
   DWARFDataSegment m_data_apple_types;
   DWARFDataSegment m_data_apple_namespaces;
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -501,21 +501,6 @@
     if (section_list == NULL)
       return 0;
 
-    // On non Apple platforms we might have .debug_types debug info that
-    // is created by using "-fdebug-types-section". LLDB currently will try
-    // to load this debug info, but it causes crashes during debugging when
-    // types are missing since it doesn't know how to parse the info in
-    // the .debug_types type units. This causes all complex debug info
-    // types to be unresolved. Because this causes LLDB to crash and since
-    // it really doesn't provide a solid debuggiung experience, we should
-    // disable trying to debug this kind of DWARF until support gets
-    // added or deprecated.
-    if (section_list->FindSectionByName(ConstString(".debug_types"))) {
-      m_obj_file->GetModule()->ReportWarning(
-        "lldb doesn’t support .debug_types debug info");
-      return 0;
-    }
-
     uint64_t debug_abbrev_file_size = 0;
     uint64_t debug_info_file_size = 0;
     uint64_t debug_line_file_size = 0;
@@ -591,8 +576,24 @@
 const DWARFDataExtractor &
 SymbolFileDWARF::GetCachedSectionData(lldb::SectionType sect_type,
                                       DWARFDataSegment &data_segment) {
-  llvm::call_once(data_segment.m_flag, [this, sect_type, &data_segment] {
+  llvm::call_once(data_segment.m_flag, [&] {
     this->LoadSectionData(sect_type, std::ref(data_segment.m_data));
+    if (sect_type == eSectionTypeDWARFDebugTypes) {
+      // To add .debug_types support in DWARF 4 and earlier with minimally
+      // invasive changes to the current DWARF parsing code, we pretend that
+      // any DIEs in .debug_types start at the end of the .debug_info section.
+      // All info in .debug_types is relative and has no external DIE
+      // references unless thay are DW_AT_signature references, so the DIE
+      // offset for things in the .debug_types. If we do this, then we can
+      // just add the type units to the compile units collection and treat all
+      // information just as we do for all other information in the DWARF and
+      // everything just works. If we were to try to split this out, we would
+      // end up having to change a TON of code. Also DWARF 5 will have compile
+      // and type units in the .debug_info, so coding it this way will prepare
+      // use for an easy transition to DWARF 5.
+      uint64_t debug_info_size = get_debug_info_data().GetByteSize();
+      data_segment.m_data.OffsetData(debug_info_size);
+    }
   });
   return data_segment.m_data;
 }
@@ -664,6 +665,10 @@
                               m_data_debug_str_offsets);
 }
 
+const DWARFDataExtractor &SymbolFileDWARF::get_debug_types_data() {
+  return GetCachedSectionData(eSectionTypeDWARFDebugTypes, m_data_debug_types);
+}
+
 const DWARFDataExtractor &SymbolFileDWARF::get_apple_names_data() {
   return GetCachedSectionData(eSectionTypeDWARFAppleNames, m_data_apple_names);
 }
@@ -3794,7 +3799,7 @@
               location_is_const_value_data = true;
               // The constant value will be either a block, a data value or a
               // string.
-              const DWARFDataExtractor &debug_info_data = get_debug_info_data();
+              auto debug_info_data = die.GetData();
               if (DWARFFormValue::IsBlockForm(form_value.Form())) {
                 // Retrieve the value as a block expression.
                 uint32_t block_offset =
@@ -3851,7 +3856,7 @@
             location_is_const_value_data = false;
             has_explicit_location = true;
             if (DWARFFormValue::IsBlockForm(form_value.Form())) {
-              const DWARFDataExtractor &debug_info_data = get_debug_info_data();
+              auto debug_info_data = die.GetData();
 
               uint32_t block_offset =
                   form_value.BlockData() - debug_info_data.GetDataStart();
Index: source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
+++ source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
@@ -11,6 +11,7 @@
 #define SymbolFileDWARF_DWARFFormValue_h_
 
 #include "DWARFDataExtractor.h"
+#include "DWARFDIE.h"
 #include <stddef.h> // for NULL
 
 class DWARFCompileUnit;
@@ -67,6 +68,7 @@
   const uint8_t *BlockData() const;
   uint64_t Reference() const;
   uint64_t Reference(dw_offset_t offset) const;
+  DWARFDIE GetTypeSignatureDIE() const;
   bool Boolean() const { return m_value.value.uval != 0; }
   uint64_t Unsigned() const { return m_value.value.uval; }
   void SetUnsigned(uint64_t uval) { m_value.value.uval = uval; }
Index: source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -580,6 +580,13 @@
     die_offset += m_cu->GetOffset();
     break;
 
+  case DW_FORM_ref_sig8:
+    // CU must be valid since we will need to back up into the debug info and
+    // find the DIE offset of the type in the type unit.
+    assert(m_cu);
+    die_offset = m_cu->FindTypeSignatureDIEOffset(m_value.value.uval);
+    break;
+
   default:
     break;
   }
@@ -598,13 +605,32 @@
     die_offset += base_offset;
     break;
 
+  case DW_FORM_ref_sig8:
+    // CU must be valid since we will need to back up into the debug info and
+    // find the DIE offset of the type in the type unit.
+    assert(m_cu);
+    die_offset = m_cu->FindTypeSignatureDIEOffset(m_value.value.uval) +
+        base_offset;
+    break;
+
   default:
     break;
   }
 
   return die_offset;
 }
 
+DWARFDIE DWARFFormValue::GetTypeSignatureDIE() const {
+  if (m_form == DW_FORM_ref_sig8) {
+    // CU must be valid since we will need to back up into the debug info and
+    // find the DIE offset of the type in the type unit.
+    assert(m_cu);
+    return m_cu->FindTypeSignatureDIE(m_value.value.uval);
+  }
+  
+  return DWARFDIE();
+}
+
 const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; }
 
 bool DWARFFormValue::IsBlockForm(const dw_form_t form) {
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -196,7 +196,7 @@
 bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data,
                                   const DWARFCompileUnit *cu,
                                   lldb::offset_t *offset_ptr) {
-  const DWARFDataExtractor &debug_info_data = dwarf2Data->get_debug_info_data();
+  const DWARFDataExtractor &debug_info_data = cu->GetData();
   //    const DWARFDataExtractor& debug_str_data =
   //    dwarf2Data->get_debug_str_data();
   const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset();
@@ -404,8 +404,7 @@
   lldb::ModuleSP module = dwarf2Data->GetObjectFile()->GetModule();
 
   if (abbrevDecl) {
-    const DWARFDataExtractor &debug_info_data =
-        dwarf2Data->get_debug_info_data();
+    const DWARFDataExtractor &debug_info_data = cu->GetData();
 
     if (!debug_info_data.ValidOffset(offset))
       return false;
@@ -588,7 +587,7 @@
 void DWARFDebugInfoEntry::Dump(SymbolFileDWARF *dwarf2Data,
                                const DWARFCompileUnit *cu, Stream &s,
                                uint32_t recurse_depth) const {
-  const DWARFDataExtractor &debug_info_data = dwarf2Data->get_debug_info_data();
+  const DWARFDataExtractor &debug_info_data = cu->GetData();
   lldb::offset_t offset = m_offset;
 
   if (debug_info_data.ValidOffset(offset)) {
@@ -782,8 +781,7 @@
   }
 
   if (abbrevDecl) {
-    const DWARFDataExtractor &debug_info_data =
-        dwarf2Data->get_debug_info_data();
+    const DWARFDataExtractor &debug_info_data = cu->GetData();
 
     if (fixed_form_sizes.Empty())
       fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(
@@ -864,9 +862,8 @@
     uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr);
 
     if (attr_idx != DW_INVALID_INDEX) {
-      const DWARFDataExtractor &debug_info_data =
-          dwarf2Data->get_debug_info_data();
-
+      const DWARFDataExtractor &debug_info_data = cu->GetData();
+	
       uint32_t idx = 0;
       while (idx < attr_idx)
         DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++),
@@ -1785,8 +1782,7 @@
         // Make sure the abbreviation code still matches. If it doesn't and
         // the DWARF data was mmap'ed, the backing file might have been modified
         // which is bad news.
-        const uint64_t abbrev_code =
-            dwarf2Data->get_debug_info_data().GetULEB128(&offset);
+        const uint64_t abbrev_code = cu->GetData().GetULEB128(&offset);
 
         if (abbrev_decl->Code() == abbrev_code)
           return abbrev_decl;
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
@@ -12,6 +12,7 @@
 
 #include <map>
 #include <vector>
+#include <unordered_map>
 
 #include "DWARFCompileUnit.h"
 #include "DWARFDIE.h"
@@ -38,20 +39,14 @@
   size_t GetNumCompileUnits();
   bool ContainsCompileUnit(const DWARFCompileUnit *cu) const;
   DWARFCompileUnit *GetCompileUnitAtIndex(uint32_t idx);
+  DWARFCompileUnit *GetTypeUnitForSignature(uint64_t type_sig);
   DWARFCompileUnit *GetCompileUnit(dw_offset_t cu_offset,
                                    uint32_t *idx_ptr = NULL);
   DWARFCompileUnit *GetCompileUnitContainingDIEOffset(dw_offset_t die_offset);
   DWARFCompileUnit *GetCompileUnit(const DIERef &die_ref);
   DWARFDIE GetDIEForDIEOffset(dw_offset_t die_offset);
   DWARFDIE GetDIE(const DIERef &die_ref);
 
-  void Dump(lldb_private::Stream *s, const uint32_t die_offset,
-            const uint32_t recurse_depth);
-  static void Parse(SymbolFileDWARF *parser, Callback callback, void *userData);
-  static void Verify(lldb_private::Stream *s, SymbolFileDWARF *dwarf2Data);
-  static void Dump(lldb_private::Stream *s, SymbolFileDWARF *dwarf2Data,
-                   const uint32_t die_offset, const uint32_t recurse_depth);
-
   enum {
     eDumpFlag_Verbose = (1 << 0),  // Verbose dumping
     eDumpFlag_ShowForm = (1 << 1), // Show the DW_form type
@@ -66,12 +61,13 @@
                                               const DWARFCompileUnitSP &cu_sp);
 
   typedef std::vector<DWARFCompileUnitSP> CompileUnitColl;
-
+  typedef std::unordered_map<uint64_t, uint32_t> TypeSignatureMap;
   //----------------------------------------------------------------------
   // Member variables
   //----------------------------------------------------------------------
   SymbolFileDWARF *m_dwarf2Data;
   CompileUnitColl m_compile_units;
+  TypeSignatureMap m_type_sig_to_cu_index;
   std::unique_ptr<DWARFDebugAranges>
       m_cu_aranges_ap; // A quick address to compile unit table
 
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -98,11 +98,28 @@
     if (m_dwarf2Data != NULL) {
       lldb::offset_t offset = 0;
       DWARFCompileUnitSP cu_sp;
-      while ((cu_sp = DWARFCompileUnit::Extract(m_dwarf2Data, &offset))) {
+      auto debug_info_data = m_dwarf2Data->get_debug_info_data();
+      while ((cu_sp = DWARFCompileUnit::Extract(m_dwarf2Data, debug_info_data,
+                                                &offset, false))) {
         m_compile_units.push_back(cu_sp);
-
         offset = cu_sp->GetNextCompileUnitOffset();
       }
+      
+      auto debug_types_data = m_dwarf2Data->get_debug_types_data();
+      if (debug_types_data.GetByteSize() == 0)
+        return;
+      offset = debug_info_data.GetByteSize();
+      while (debug_types_data.ValidOffset(offset)) {
+        if ((cu_sp = DWARFCompileUnit::Extract(m_dwarf2Data, debug_types_data,
+                                               &offset, true))) {
+          m_type_sig_to_cu_index[cu_sp->GetTypeSignature()] =
+              m_compile_units.size();
+          m_compile_units.push_back(cu_sp);
+          offset = cu_sp->GetNextCompileUnitOffset();
+        } else {
+          break;
+        }
+      }
     }
   }
 }
@@ -224,269 +241,9 @@
   return DWARFDIE(); // Not found
 }
 
-//----------------------------------------------------------------------
-// Parse
-//
-// Parses the .debug_info section and uses the .debug_abbrev section
-// and various other sections in the SymbolFileDWARF class and calls the
-// supplied callback function each time a compile unit header, or debug
-// information entry is successfully parsed. This function can be used
-// for different tasks such as parsing the file contents into a
-// structured data, dumping, verifying and much more.
-//----------------------------------------------------------------------
-void DWARFDebugInfo::Parse(SymbolFileDWARF *dwarf2Data, Callback callback,
-                           void *userData) {
-  if (dwarf2Data) {
-    lldb::offset_t offset = 0;
-    uint32_t depth = 0;
-    DWARFDebugInfoEntry die;
-
-    DWARFCompileUnitSP cu;
-    while ((cu = DWARFCompileUnit::Extract(dwarf2Data, &offset))) {
-      const dw_offset_t next_cu_offset = cu->GetNextCompileUnitOffset();
-
-      depth = 0;
-      // Call the callback function with no DIE pointer for the compile unit
-      // and get the offset that we are to continue to parse from
-      offset = callback(dwarf2Data, cu.get(), NULL, offset, depth, userData);
-
-      // Make sure we are within our compile unit
-      if (offset < next_cu_offset) {
-        // We are in our compile unit, parse starting at the offset
-        // we were told to parse
-        bool done = false;
-        while (!done && die.Extract(dwarf2Data, cu.get(), &offset)) {
-          // Call the callback function with DIE pointer that falls within the
-          // compile unit
-          offset =
-              callback(dwarf2Data, cu.get(), &die, offset, depth, userData);
-
-          if (die.IsNULL()) {
-            if (depth)
-              --depth;
-            else
-              done = true; // We are done with this compile unit!
-          } else if (die.HasChildren())
-            ++depth;
-        }
-      }
-
-      // Make sure the offset returned is valid, and if not stop parsing.
-      // Returning DW_INVALID_OFFSET from this callback is a good way to end
-      // all parsing
-      if (!dwarf2Data->get_debug_info_data().ValidOffset(offset))
-        break;
-
-      // Make sure we start on a proper
-      offset = next_cu_offset;
-    }
-  }
-}
-
-typedef struct DumpInfo {
-  DumpInfo(Stream *init_strm, uint32_t off, uint32_t depth)
-      : strm(init_strm), die_offset(off), recurse_depth(depth),
-        found_depth(UINT32_MAX), found_die(false), ancestors() {}
-  Stream *strm;
-  const uint32_t die_offset;
-  const uint32_t recurse_depth;
-  uint32_t found_depth;
-  bool found_die;
-  std::vector<DWARFDebugInfoEntry> ancestors;
-
-  DISALLOW_COPY_AND_ASSIGN(DumpInfo);
-} DumpInfo;
-
-//----------------------------------------------------------------------
-// DumpCallback
-//
-// A callback function for the static DWARFDebugInfo::Parse() function
-// that gets called each time a compile unit header or debug information
-// entry is successfully parsed.
-//
-// This function dump DWARF information and obey recurse depth and
-// whether a single DIE is to be dumped (or all of the data).
-//----------------------------------------------------------------------
-static dw_offset_t DumpCallback(SymbolFileDWARF *dwarf2Data,
-                                DWARFCompileUnit *cu, DWARFDebugInfoEntry *die,
-                                const dw_offset_t next_offset,
-                                const uint32_t curr_depth, void *userData) {
-  DumpInfo *dumpInfo = (DumpInfo *)userData;
-  Stream *s = dumpInfo->strm;
-  bool show_parents =
-      s->GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowAncestors);
-
-  if (die) {
-    // Are we dumping everything?
-    if (dumpInfo->die_offset == DW_INVALID_OFFSET) {
-      // Yes we are dumping everything. Obey our recurse level though
-      if (curr_depth < dumpInfo->recurse_depth)
-        die->Dump(dwarf2Data, cu, *s, 0);
-    } else {
-      // We are dumping a specific DIE entry by offset
-      if (dumpInfo->die_offset == die->GetOffset()) {
-        // We found the DIE we were looking for, dump it!
-        if (show_parents) {
-          s->SetIndentLevel(0);
-          const uint32_t num_ancestors = dumpInfo->ancestors.size();
-          if (num_ancestors > 0) {
-            for (uint32_t i = 0; i < num_ancestors - 1; ++i) {
-              dumpInfo->ancestors[i].Dump(dwarf2Data, cu, *s, 0);
-              s->IndentMore();
-            }
-          }
-        }
-
-        dumpInfo->found_depth = curr_depth;
-
-        die->Dump(dwarf2Data, cu, *s, 0);
-
-        // Note that we found the DIE we were looking for
-        dumpInfo->found_die = true;
-
-        // Since we are dumping a single DIE, if there are no children we are
-        // done!
-        if (!die->HasChildren() || dumpInfo->recurse_depth == 0)
-          return DW_INVALID_OFFSET; // Return an invalid address to end parsing
-      } else if (dumpInfo->found_die) {
-        // Are we done with all the children?
-        if (curr_depth <= dumpInfo->found_depth)
-          return DW_INVALID_OFFSET;
-
-        // We have already found our DIE and are printing it's children. Obey
-        // our recurse depth and return an invalid offset if we get done
-        // dumping all of the children
-        if (dumpInfo->recurse_depth == UINT32_MAX ||
-            curr_depth <= dumpInfo->found_depth + dumpInfo->recurse_depth)
-          die->Dump(dwarf2Data, cu, *s, 0);
-      } else if (dumpInfo->die_offset > die->GetOffset()) {
-        if (show_parents)
-          dumpInfo->ancestors.back() = *die;
-      }
-    }
-
-    // Keep up with our indent level
-    if (die->IsNULL()) {
-      if (show_parents)
-        dumpInfo->ancestors.pop_back();
-
-      if (curr_depth <= 1)
-        return cu->GetNextCompileUnitOffset();
-      else
-        s->IndentLess();
-    } else if (die->HasChildren()) {
-      if (show_parents) {
-        DWARFDebugInfoEntry null_die;
-        dumpInfo->ancestors.push_back(null_die);
-      }
-      s->IndentMore();
-    }
-  } else {
-    if (cu == NULL)
-      s->PutCString("NULL - cu");
-    // We have a compile unit, reset our indent level to zero just in case
-    s->SetIndentLevel(0);
-
-    // See if we are dumping everything?
-    if (dumpInfo->die_offset == DW_INVALID_OFFSET) {
-      // We are dumping everything
-      if (cu) {
-        cu->Dump(s);
-        return cu->GetFirstDIEOffset(); // Return true to parse all DIEs in this
-                                        // Compile Unit
-      } else {
-        return DW_INVALID_OFFSET;
-      }
-    } else {
-      if (show_parents) {
-        dumpInfo->ancestors.clear();
-        dumpInfo->ancestors.resize(1);
-      }
-
-      // We are dumping only a single DIE possibly with it's children and
-      // we must find it's compile unit before we can dump it properly
-      if (cu && dumpInfo->die_offset < cu->GetFirstDIEOffset()) {
-        // Not found, maybe the DIE offset provided wasn't correct?
-        //  *ostrm_ptr << "DIE at offset " << HEX32 << dumpInfo->die_offset << "
-        //  was not found." << endl;
-        return DW_INVALID_OFFSET;
-      } else {
-        // See if the DIE is in this compile unit?
-        if (cu && dumpInfo->die_offset < cu->GetNextCompileUnitOffset()) {
-          return next_offset;
-          //  // We found our compile unit that contains our DIE, just skip to
-          //  dumping the requested DIE...
-          //  return dumpInfo->die_offset;
-        } else {
-          // Skip to the next compile unit as the DIE isn't in the current one!
-          if (cu) {
-            return cu->GetNextCompileUnitOffset();
-          } else {
-            return DW_INVALID_OFFSET;
-          }
-        }
-      }
-    }
-  }
-
-  // Just return the current offset to parse the next CU or DIE entry
-  return next_offset;
-}
-
-//----------------------------------------------------------------------
-// Dump
-//
-// Dump the information in the .debug_info section to the specified
-// ostream. If die_offset is valid, a single DIE will be dumped. If the
-// die_offset is invalid, all the DWARF information will be dumped. Both
-// cases will obey a "recurse_depth" or how deep to traverse into the
-// children of each DIE entry. A recurse_depth of zero will dump all
-// compile unit headers. A recurse_depth of 1 will dump all compile unit
-// headers and the DW_TAG_compile unit tags. A depth of 2 will also
-// dump all types and functions.
-//----------------------------------------------------------------------
-void DWARFDebugInfo::Dump(Stream *s, SymbolFileDWARF *dwarf2Data,
-                          const uint32_t die_offset,
-                          const uint32_t recurse_depth) {
-  DumpInfo dumpInfo(s, die_offset, recurse_depth);
-  s->PutCString(".debug_info contents");
-  if (dwarf2Data->get_debug_info_data().GetByteSize() > 0) {
-    if (die_offset == DW_INVALID_OFFSET)
-      s->PutCString(":\n");
-    else {
-      s->Printf(" for DIE entry at .debug_info[0x%8.8x]", die_offset);
-      if (recurse_depth != UINT32_MAX)
-        s->Printf(" recursing %u levels deep.", recurse_depth);
-      s->EOL();
-    }
-  } else {
-    s->PutCString(": < EMPTY >\n");
-    return;
-  }
-  DWARFDebugInfo::Parse(dwarf2Data, DumpCallback, &dumpInfo);
-}
-
-//----------------------------------------------------------------------
-// Dump
-//
-// Dump the contents of this DWARFDebugInfo object as has been parsed
-// and/or modified after it has been parsed.
-//----------------------------------------------------------------------
-void DWARFDebugInfo::Dump(Stream *s, const uint32_t die_offset,
-                          const uint32_t recurse_depth) {
-  DumpInfo dumpInfo(s, die_offset, recurse_depth);
-
-  s->PutCString("Dumping .debug_info section from internal representation\n");
-
-  CompileUnitColl::const_iterator pos;
-  uint32_t curr_depth = 0;
-  ParseCompileUnitHeadersIfNeeded();
-  for (pos = m_compile_units.begin(); pos != m_compile_units.end(); ++pos) {
-    DWARFCompileUnit *cu = pos->get();
-    DumpCallback(m_dwarf2Data, cu, NULL, 0, curr_depth, &dumpInfo);
-
-    const DWARFDIE die = cu->DIE();
-    if (die)
-      die.Dump(s, recurse_depth);
-  }
+DWARFCompileUnit *DWARFDebugInfo::GetTypeUnitForSignature(uint64_t type_sig) {
+  auto pos = m_type_sig_to_cu_index.find(type_sig);
+  if (pos != m_type_sig_to_cu_index.end())
+    return GetCompileUnitAtIndex(pos->second);
+  return nullptr;
 }
Index: source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
+++ source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
@@ -29,9 +29,34 @@
   dw_offset_t GetDWARFOffset(lldb::offset_t *offset_ptr) const;
 
   size_t GetDWARFSizeofInitialLength() const { return m_is_dwarf64 ? 12 : 4; }
-
+  size_t GetDWARFSizeOfOffset() const { return m_is_dwarf64 ? 8 : 4; }
   bool IsDWARF64() const { return m_is_dwarf64; }
 
+  //------------------------------------------------------------------
+  /// Slide the data in the buffer so that access to the data will
+  /// start at offset \a offset.
+  ///
+  /// This is currently used to provide access to the .debug_types
+  /// section and pretend it starts at at offset of the size of the
+  /// .debug_info section. This allows a minimally invasive change to
+  /// add support for .debug_types by allowing all DIEs to have unique
+  /// offsets and thus allowing no code to change in the DWARF parser.
+  /// Modifying the offsets in the .debug_types doesn't affect
+  /// anything because since all info in the .debug_types is type unit
+  /// relative and no types within a type unit can refer to any DIEs
+  /// outside of the type unit without using DW_AT_signature. It also
+  /// sets us up to move to DWARF5 where there is no .debug_types
+  /// section as compile units and type units are in the .debug_info.
+  ///
+  /// @param[in] offset
+  ///   The amount to slide the data contents by.
+  //------------------------------------------------------------------
+  void OffsetData(lldb::offset_t offset)
+  {
+    if (GetByteSize())
+      m_start -= offset;
+  }
+  
 protected:
   mutable bool m_is_dwarf64;
 };
Index: source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp
@@ -22,6 +22,6 @@
 
 dw_offset_t
 DWARFDataExtractor::GetDWARFOffset(lldb::offset_t *offset_ptr) const {
-  return GetMaxU64(offset_ptr, m_is_dwarf64 ? 8 : 4);
+  return GetMaxU64(offset_ptr, GetDWARFSizeOfOffset());
 }
 }
Index: source/Plugins/SymbolFile/DWARF/DWARFDIE.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -86,6 +86,15 @@
   DWARFDIE
   GetContainingDWOModuleDIE() const;
 
+  // Get the data that contains the attribute values for this DIE. Support
+  // for .debug_types means that any DIE can have its data either in the
+  // .debug_info or the .debug_types section so anyone extracting data from
+  // a DIE must use the correct data.
+  //
+  // Clients must validate that this object is valid before calling this.
+  const lldb_private::DWARFDataExtractor &GetData() const;
+
+
   //----------------------------------------------------------------------
   // Accessing information about a DIE
   //----------------------------------------------------------------------
Index: source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -460,3 +460,9 @@
 bool operator!=(const DWARFDIE &lhs, const DWARFDIE &rhs) {
   return !(lhs == rhs);
 }
+
+const DWARFDataExtractor &DWARFDIE::GetData() const {
+  // Clients must check if this DIE is valid before calling this function.
+  assert(IsValid());
+  return m_cu->GetData();
+}
Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -30,33 +30,60 @@
 
 class DWARFCompileUnit {
 public:
-  static DWARFCompileUnitSP Extract(SymbolFileDWARF *dwarf2Data,
-      lldb::offset_t *offset_ptr);
   ~DWARFCompileUnit();
-
+  static DWARFCompileUnitSP Extract(SymbolFileDWARF *dwarf2Data,
+      const lldb_private::DWARFDataExtractor &debug_info,
+      lldb::offset_t *offset_ptr, bool is_type_unit);
+  const lldb_private::DWARFDataExtractor &GetData() const;
   size_t ExtractDIEsIfNeeded(bool cu_die_only);
   DWARFDIE LookupAddress(const dw_addr_t address);
   size_t AppendDIEsWithTag(const dw_tag_t tag,
                            DWARFDIECollection &matching_dies,
                            uint32_t depth = UINT32_MAX) const;
-  bool Verify(lldb_private::Stream *s) const;
   void Dump(lldb_private::Stream *s) const;
   // Offset of the initial length field.
   dw_offset_t GetOffset() const { return m_offset; }
   lldb::user_id_t GetID() const;
-  // Size in bytes of the initial length + compile unit header.
-  uint32_t Size() const { return m_is_dwarf64 ? 23 : 11; }
+  //------------------------------------------------------------------
+  /// Get the size in bytes of the length field in the header.
+  ///
+  /// In DWARF32 this is just 4 bytes, and DWARF64 it is 12 where 4
+  /// are 0xFFFFFFFF followed by the actual 64 bit length.
+  ///
+  /// @return
+  ///     Byte size of the compile unit header length field
+  //------------------------------------------------------------------
+  size_t GetLengthByteSize() const { return m_is_dwarf64 ? 12 : 4; }
+  
+  //------------------------------------------------------------------
+  /// Get the size in bytes of the compile unit header.
+  ///
+  /// @return
+  ///     Byte size of the compile unit header
+  //------------------------------------------------------------------
+  uint32_t GetHeaderByteSize() const {
+    // Size in bytes of the compile or type unit header
+    // Start with the common size between compile and type units
+    uint32_t header_size = m_is_dwarf64 ? 23 : 11;
+    // Add the extra type unit size if needed
+    if (IsTypeUnit())
+      header_size += m_is_dwarf64 ? 16 : 12;
+    return header_size;
+  }
+  
   bool ContainsDIEOffset(dw_offset_t die_offset) const {
     return die_offset >= GetFirstDIEOffset() &&
            die_offset < GetNextCompileUnitOffset();
   }
-  dw_offset_t GetFirstDIEOffset() const { return m_offset + Size(); }
+  dw_offset_t GetFirstDIEOffset() const {
+    return m_offset + GetHeaderByteSize();
+  }
   dw_offset_t GetNextCompileUnitOffset() const {
     return m_offset + (m_is_dwarf64 ? 12 : 4) + m_length;
   }
   // Size of the CU data (without initial length and without header).
   size_t GetDebugInfoSize() const {
-    return (m_is_dwarf64 ? 12 : 4) + m_length - Size();
+    return m_offset + m_length + GetLengthByteSize();
   }
   // Size of the CU data incl. header but without initial length.
   uint32_t GetLength() const { return m_length; }
@@ -159,6 +186,88 @@
 
   dw_offset_t GetBaseObjOffset() const { return m_base_obj_offset; }
 
+  //------------------------------------------------------------------
+  /// Return true if this compile unit is a type unit.
+  ///
+  /// @return
+  //------------------------------------------------------------------
+  bool IsTypeUnit() const { return m_type_offset != DW_INVALID_OFFSET; }
+  //------------------------------------------------------------------
+  /// Get the type signature for the type contained in this unit.
+  ///
+  /// @return
+  ///   The 64 bit type signature for the type contained in this type
+  ///   unit. This value will not be valid if this compile unit is not
+  ///   a type unit.
+  //------------------------------------------------------------------
+  uint64_t GetTypeSignature() const { return m_type_signature; }
+
+  //------------------------------------------------------------------
+  /// Get the type DIE if this is a type unit.
+  ///
+  /// If this unit is a type unit, return type contained within it as
+  /// a DWARFDIE object.
+  ///
+  /// @return
+  ///   The DIE representing the type if this is a type unit, or an
+  ///   invalid DWARFDIE if this is not a type unit.
+  //------------------------------------------------------------------
+  DWARFDIE GetTypeUnitDIE();
+  //------------------------------------------------------------------
+  /// Get the type DIE offset if this is a type unit.
+  ///
+  /// If this unit is a type unit, return type DIE offset for the type
+  /// in this unit.
+  ///
+  /// @return
+  ///   The DIE offset that points to the type unit type if this is
+  ///   a type unit, otherwise return DW_INVALID_OFFSET.
+  //------------------------------------------------------------------
+  dw_offset_t GetTypeUnitDIEOffset() {
+    if (IsTypeUnit())
+      return m_offset + m_type_offset;
+    return DW_INVALID_OFFSET;
+  }
+
+  //------------------------------------------------------------------
+  /// Find the DIE for any given type signature.
+  ///
+  /// This is a convenience function that allows anyone to use the
+  /// current compile unit to access the DWARF and use its debug info
+  /// to retrieve a DIE that represents a type given a type signature.
+  ///
+  /// This function will cause all DIEs in the type unit to be parsed,
+  /// only call if you need the actual DIE object.
+  ///
+  /// @param[in] type_sig
+  ///   The 64 bit type signature extracted as a DW_FORM_ref_sig8.
+  ///
+  /// @return
+  ///   The DWARFDIE object that represents the type DIE for
+  ///   \a type_sig, or an invalid DWARFDIE object if not found.
+  //------------------------------------------------------------------
+  DWARFDIE FindTypeSignatureDIE(uint64_t type_sig) const;
+
+  //------------------------------------------------------------------
+  /// Find the DIE offset for any given type signature.
+  ///
+  /// This is a convenience function that allows anyone to use the
+  /// current compile unit to access the DWARF and use its debug info
+  /// to retrieve a DIE offset that represents a type given a type
+  /// signature. This function doesn't cause any debug information
+  /// to be parsed, so if clients only need the DIE offset of a type
+  /// signature, this function is more efficient than
+  /// DWARFDIE FindTypeSignatureDIE(...) above.
+  ///
+  /// @param[in] type_sig
+  ///   The 64 bit type signature extracted as a DW_FORM_ref_sig8.
+  ///
+  /// @return
+  ///   The DIE offset that represents the type DIE for \a type_sig,
+  ///   or DW_INVALID_OFFSET if not found.
+  //------------------------------------------------------------------
+  dw_offset_t FindTypeSignatureDIEOffset(uint64_t type_sig) const;
+
 protected:
   SymbolFileDWARF *m_dwarf2Data;
   std::unique_ptr<SymbolFileDWARFDwo> m_dwo_symbol_file;
@@ -190,6 +299,11 @@
   // If this is a dwo compile unit this is the offset of the base compile unit
   // in the main object file
   dw_offset_t m_base_obj_offset = DW_INVALID_OFFSET;
+  // Type signature contained in a type unit which will be valid (non-zero)
+  // for type units only.
+  uint64_t m_type_signature = 0;
+  // Compile unit relative type offset for type units only.
+  dw_offset_t m_type_offset = DW_INVALID_OFFSET;
 
   void ParseProducerInfo();
 
Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -44,14 +44,13 @@
 DWARFCompileUnit::~DWARFCompileUnit() {}
 
 DWARFCompileUnitSP DWARFCompileUnit::Extract(SymbolFileDWARF *dwarf2Data,
-    lldb::offset_t *offset_ptr) {
+    const DWARFDataExtractor &debug_info, lldb::offset_t *offset_ptr,
+    bool is_type_unit) {
   DWARFCompileUnitSP cu_sp(new DWARFCompileUnit(dwarf2Data));
   // Out of memory?
   if (cu_sp.get() == NULL)
     return nullptr;
 
-  const DWARFDataExtractor &debug_info = dwarf2Data->get_debug_info_data();
-
   cu_sp->m_offset = *offset_ptr;
 
   if (debug_info.ValidOffset(*offset_ptr)) {
@@ -70,8 +69,13 @@
         dwarf2Data->get_debug_abbrev_data().ValidOffset(abbr_offset);
     bool addr_size_OK = (cu_sp->m_addr_size == 4) || (cu_sp->m_addr_size == 8);
 
+    if (is_type_unit) {
+      cu_sp->m_type_signature = debug_info.GetU64(offset_ptr);
+      cu_sp->m_type_offset = debug_info.GetDWARFOffset(offset_ptr);
+    }
     if (length_OK && version_OK && addr_size_OK && abbr_offset_OK &&
-        abbr != NULL) {
+        abbr != NULL && (!is_type_unit ||
+                         cu_sp->m_type_offset != DW_INVALID_OFFSET)) {
       cu_sp->m_abbrevs = abbr->GetAbbreviationDeclarationSet(abbr_offset);
       return cu_sp;
     }
@@ -142,8 +146,7 @@
   uint32_t depth = 0;
   // We are in our compile unit, parse starting at the offset
   // we were told to parse
-  const DWARFDataExtractor &debug_info_data =
-      m_dwarf2Data->get_debug_info_data();
+  const DWARFDataExtractor &debug_info_data = GetData();
   std::vector<uint32_t> die_index_stack;
   die_index_stack.reserve(32);
   die_index_stack.push_back(0);
@@ -297,45 +300,6 @@
   return m_abbrevs ? m_abbrevs->GetOffset() : DW_INVALID_OFFSET;
 }
 
-bool DWARFCompileUnit::Verify(Stream *s) const {
-  const DWARFDataExtractor &debug_info = m_dwarf2Data->get_debug_info_data();
-  bool valid_offset = debug_info.ValidOffset(m_offset);
-  bool length_OK = debug_info.ValidOffset(GetNextCompileUnitOffset() - 1);
-  bool version_OK = SymbolFileDWARF::SupportedVersion(m_version);
-  bool abbr_offset_OK =
-      m_dwarf2Data->get_debug_abbrev_data().ValidOffset(GetAbbrevOffset());
-  bool addr_size_OK = ((m_addr_size == 4) || (m_addr_size == 8));
-  if (valid_offset && length_OK && version_OK && addr_size_OK &&
-      abbr_offset_OK) {
-    return true;
-  } else {
-    s->Printf("    0x%8.8x: ", m_offset);
-    DumpDataExtractor(m_dwarf2Data->get_debug_info_data(), s, m_offset,
-                      lldb::eFormatHex, 1, Size(), 32, LLDB_INVALID_ADDRESS, 0,
-                      0);
-    s->EOL();
-    if (valid_offset) {
-      if (!length_OK)
-        s->Printf("        The length (0x%8.8x) for this compile unit is too "
-                  "large for the .debug_info provided.\n",
-                  m_length);
-      if (!version_OK)
-        s->Printf("        The 16 bit compile unit header version is not "
-                  "supported.\n");
-      if (!abbr_offset_OK)
-        s->Printf("        The offset into the .debug_abbrev section (0x%8.8x) "
-                  "is not valid.\n",
-                  GetAbbrevOffset());
-      if (!addr_size_OK)
-        s->Printf("        The address size is unsupported: 0x%2.2x\n",
-                  m_addr_size);
-    } else
-      s->Printf("        The start offset of the compile unit header in the "
-                ".debug_info is invalid.\n");
-  }
-  return false;
-}
-
 void DWARFCompileUnit::Dump(Stream *s) const {
   s->Printf("0x%8.8x: Compile Unit: length = 0x%8.8x, version = 0x%4.4x, "
             "abbr_offset = 0x%8.8x, addr_size = 0x%2.2x (next CU at "
@@ -381,6 +345,10 @@
   // in order to produce a compile unit level set of address ranges that
   // is accurate.
 
+  // No addresses are found in a type unit.
+  if (IsTypeUnit())
+    return;
+  
   size_t num_debug_aranges = debug_aranges->GetNumRanges();
 
   // First get the compile unit DIE only and check if it has a DW_AT_ranges
@@ -1109,3 +1077,35 @@
 lldb::ByteOrder DWARFCompileUnit::GetByteOrder() const {
   return m_dwarf2Data->GetObjectFile()->GetByteOrder();
 }
+
+
+DWARFDIE DWARFCompileUnit::GetTypeUnitDIE() {
+  if (IsTypeUnit()) {
+    // The type offset is compile unit relative, so we need to add the compile
+    // unit offset to ensure we get the correct DIE.
+    return GetDIE(GetTypeUnitDIEOffset());
+  }
+  return DWARFDIE();
+}
+
+DWARFDIE DWARFCompileUnit::FindTypeSignatureDIE(uint64_t type_sig) const {
+  if (auto cu = m_dwarf2Data->DebugInfo()->GetTypeUnitForSignature(type_sig))
+    return cu->GetTypeUnitDIE();
+  return DWARFDIE();
+}
+
+dw_offset_t DWARFCompileUnit::FindTypeSignatureDIEOffset(uint64_t type_sig) const {
+  if (auto cu = m_dwarf2Data->DebugInfo()->GetTypeUnitForSignature(type_sig))
+    return cu->GetTypeUnitDIEOffset();
+  return DW_INVALID_OFFSET;
+}
+
+const lldb_private::DWARFDataExtractor &DWARFCompileUnit::GetData() const {
+  // In DWARF 5, type units are in the .debug_info section. Prior to DWARF 5
+  // type units are in the .debug_types section.
+  if (IsTypeUnit() && GetVersion() < 5)
+    return m_dwarf2Data->get_debug_types_data();
+  else
+    return m_dwarf2Data->get_debug_info_data();
+}
+
Index: source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
@@ -52,8 +52,7 @@
   form_value.SetCompileUnit(cu);
   form_value.SetForm(FormAtIndex(i));
   lldb::offset_t offset = DIEOffsetAtIndex(i);
-  return form_value.ExtractValue(
-      cu->GetSymbolFileDWARF()->get_debug_info_data(), &offset);
+  return form_value.ExtractValue(cu->GetData(), &offset);
 }
 
 uint64_t DWARFAttributes::FormValueAsUnsigned(dw_attr_t attr,
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
@@ -654,8 +654,7 @@
               if (form_value.BlockData()) {
                 Value initialValue(0);
                 Value memberOffset(0);
-                const DWARFDataExtractor &debug_info_data =
-                    die.GetDWARF()->get_debug_info_data();
+                const DWARFDataExtractor &debug_info_data = die.GetData();
                 uint32_t block_length = form_value.Unsigned();
                 uint32_t block_offset =
                     form_value.BlockData() - debug_info_data.GetDataStart();
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -239,8 +239,21 @@
     //        }
 
     Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE());
-    TypeList *type_list = dwarf->GetTypeList();
     if (type_ptr == NULL) {
+
+      // If we have .debug_types defer to the complete version in the
+      // .debug_types section, not the broken incomplete definition in real
+      // compile units that are only there so addresses can be assigned to
+      // static values.
+      auto signature_die = die.GetAttributeValueAsReferenceDIE(DW_AT_signature);
+      if (signature_die) {
+        type_sp = ParseTypeFromDWARF(sc, signature_die, log, type_is_new_ptr);
+        if (type_sp) {
+          dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
+          return type_sp;
+        }
+      }
+
       if (type_is_new_ptr)
         *type_is_new_ptr = true;
 
@@ -1907,7 +1920,7 @@
 
         // We are ready to put this type into the uniqued list up at the module
         // level
-        type_list->Insert(type_sp);
+        dwarf->GetTypeList()->Insert(type_sp);
 
         dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
       }
@@ -2861,8 +2874,7 @@
               if (form_value.BlockData()) {
                 Value initialValue(0);
                 Value memberOffset(0);
-                const DWARFDataExtractor &debug_info_data =
-                    die.GetDWARF()->get_debug_info_data();
+                const DWARFDataExtractor &debug_info_data = die.GetData();
                 uint32_t block_length = form_value.Unsigned();
                 uint32_t block_offset =
                     form_value.BlockData() - debug_info_data.GetDataStart();
@@ -3333,8 +3345,7 @@
               if (form_value.BlockData()) {
                 Value initialValue(0);
                 Value memberOffset(0);
-                const DWARFDataExtractor &debug_info_data =
-                    die.GetDWARF()->get_debug_info_data();
+                const DWARFDataExtractor &debug_info_data = die.GetData();
                 uint32_t block_length = form_value.Unsigned();
                 uint32_t block_offset =
                     form_value.BlockData() - debug_info_data.GetDataStart();
Index: source/Plugins/SymbolFile/DWARF/DIERef.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DIERef.cpp
+++ source/Plugins/SymbolFile/DWARF/DIERef.cpp
@@ -47,10 +47,22 @@
   if (form_value.IsValid()) {
     const DWARFCompileUnit *dwarf_cu = form_value.GetCompileUnit();
     if (dwarf_cu) {
-      if (dwarf_cu->GetBaseObjOffset() != DW_INVALID_OFFSET)
-        cu_offset = dwarf_cu->GetBaseObjOffset();
-      else
-        cu_offset = dwarf_cu->GetOffset();
+      // Replace the compile unit with the type signature compile unit for
+      // type signature attributes.
+      if (form_value.Form() == DW_FORM_ref_sig8) {
+        uint64_t type_sig = form_value.Unsigned();
+        auto debug_info = dwarf_cu->GetSymbolFileDWARF()->DebugInfo();
+        auto type_cu = debug_info->GetTypeUnitForSignature(type_sig);
+        if (type_cu) {
+          cu_offset = type_cu->GetOffset();
+          die_offset = type_cu->GetTypeUnitDIEOffset();
+        }
+      } else {
+        if (dwarf_cu->GetBaseObjOffset() != DW_INVALID_OFFSET)
+          cu_offset = dwarf_cu->GetBaseObjOffset();
+        else
+          cu_offset = dwarf_cu->GetOffset();
+      }
     }
     die_offset = form_value.Reference();
   }
Index: source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
===================================================================
--- source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
@@ -696,6 +696,7 @@
         static ConstString g_sect_name_dwarf_debug_pubtypes(".debug_pubtypes");
         static ConstString g_sect_name_dwarf_debug_ranges(".debug_ranges");
         static ConstString g_sect_name_dwarf_debug_str(".debug_str");
+        static ConstString g_sect_name_dwarf_debug_types(".debug_types");
         static ConstString g_sect_name_eh_frame(".eh_frame");
         static ConstString g_sect_name_go_symtab(".gosymtab");
         SectionType section_type = eSectionTypeOther;
@@ -744,6 +745,8 @@
           section_type = eSectionTypeDWARFDebugRanges;
         else if (const_sect_name == g_sect_name_dwarf_debug_str)
           section_type = eSectionTypeDWARFDebugStr;
+        else if (const_sect_name == g_sect_name_dwarf_debug_types)
+          section_type = eSectionTypeDWARFDebugTypes;
         else if (const_sect_name == g_sect_name_eh_frame)
           section_type = eSectionTypeEHFrame;
         else if (const_sect_name == g_sect_name_go_symtab)
Index: source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
===================================================================
--- source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -1208,6 +1208,7 @@
           case eSectionTypeDWARFDebugRanges:
           case eSectionTypeDWARFDebugStr:
           case eSectionTypeDWARFDebugStrOffsets:
+          case eSectionTypeDWARFDebugTypes:
           case eSectionTypeDWARFAppleNames:
           case eSectionTypeDWARFAppleTypes:
           case eSectionTypeDWARFAppleNamespaces:
@@ -1719,6 +1720,8 @@
                   static ConstString g_sect_name_dwarf_debug_ranges(
                       "__debug_ranges");
                   static ConstString g_sect_name_dwarf_debug_str("__debug_str");
+                  static ConstString g_sect_name_dwarf_debug_types(
+                      "__debug_types");
                   static ConstString g_sect_name_dwarf_apple_names(
                       "__apple_names");
                   static ConstString g_sect_name_dwarf_apple_types(
@@ -1756,6 +1759,8 @@
                     sect_type = eSectionTypeDWARFDebugRanges;
                   else if (section_name == g_sect_name_dwarf_debug_str)
                     sect_type = eSectionTypeDWARFDebugStr;
+                  else if (section_name == g_sect_name_dwarf_debug_types)
+                    sect_type = eSectionTypeDWARFDebugTypes;
                   else if (section_name == g_sect_name_dwarf_apple_names)
                     sect_type = eSectionTypeDWARFAppleNames;
                   else if (section_name == g_sect_name_dwarf_apple_types)
Index: source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
===================================================================
--- source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -1819,6 +1819,7 @@
       static ConstString g_sect_name_dwarf_debug_str_dwo(".debug_str.dwo");
       static ConstString g_sect_name_dwarf_debug_str_offsets_dwo(
           ".debug_str_offsets.dwo");
+      static ConstString g_sect_name_dwarf_debug_types(".debug_types");
       static ConstString g_sect_name_eh_frame(".eh_frame");
       static ConstString g_sect_name_arm_exidx(".ARM.exidx");
       static ConstString g_sect_name_arm_extab(".ARM.extab");
@@ -1889,6 +1890,8 @@
         sect_type = eSectionTypeDWARFDebugRanges;
       else if (name == g_sect_name_dwarf_debug_str)
         sect_type = eSectionTypeDWARFDebugStr;
+      else if (name == g_sect_name_dwarf_debug_types)
+        sect_type = eSectionTypeDWARFDebugTypes;
       else if (name == g_sect_name_dwarf_debug_str_offsets)
         sect_type = eSectionTypeDWARFDebugStrOffsets;
       else if (name == g_sect_name_dwarf_debug_abbrev_dwo)
Index: source/Core/Section.cpp
===================================================================
--- source/Core/Section.cpp
+++ source/Core/Section.cpp
@@ -89,6 +89,8 @@
     return "dwarf-str";
   case eSectionTypeDWARFDebugStrOffsets:
     return "dwarf-str-offsets";
+  case eSectionTypeDWARFDebugTypes:
+    return "dwarf-types";
   case eSectionTypeELFSymbolTable:
     return "elf-symbol-table";
   case eSectionTypeELFDynamicSymbols:
Index: packages/Python/lldbsuite/test/test_categories.py
===================================================================
--- packages/Python/lldbsuite/test/test_categories.py
+++ packages/Python/lldbsuite/test/test_categories.py
@@ -15,15 +15,16 @@
 
 
 debug_info_categories = [
-    'dwarf', 'dwo', 'dsym', 'gmodules'
+    'dwarf', 'dwo', 'dsym', 'gmodules', 'dwarf_type_units'
 ]
 
 all_categories = {
     'dataformatters': 'Tests related to the type command and the data formatters subsystem',
     'dwarf': 'Tests that can be run with DWARF debug information',
     'dwo': 'Tests that can be run with DWO debug information',
     'dsym': 'Tests that can be run with DSYM debug information',
     'gmodules': 'Tests that can be run with -gmodules debug information',
+    'dwarf_type_units' : 'Tests that can be run with -fdebug-types-section',
     'expression': 'Tests related to the expression parser',
     'libc++': 'Test for libc++ data formatters',
     'objc': 'Tests related to the Objective-C programming language support',
@@ -61,6 +62,8 @@
         if platform not in ["linux", "freebsd", "darwin", "macosx", "ios", "watchos", "tvos", "bridgeos"]:
             return False
         return gmodules.is_compiler_clang_with_gmodules(compiler_path)
+    elif category == "dwarf_type_units":
+        return platform in ["linux"]
     return True
 
 
Index: packages/Python/lldbsuite/test/plugins/builder_base.py
===================================================================
--- packages/Python/lldbsuite/test/plugins/builder_base.py
+++ packages/Python/lldbsuite/test/plugins/builder_base.py
@@ -227,6 +227,31 @@
     return True
 
 
+def buildDwarfTypeUnits(
+        sender=None,
+        architecture=None,
+        compiler=None,
+        dictionary=None,
+        clean=True,
+        testdir=None,
+        testname=None):
+    """Build the binaries with type units (type in  a .debug_types section)."""
+    commands = []
+    if clean:
+        commands.append(getMake(testdir, testname) +
+                        ["clean", getCmdLine(dictionary)])
+    commands.append(getMake(testdir, testname) +
+                    ["MAKE_DSYM=NO",
+                     "DWARF_TYPE_UNITS=YES",
+                     getArchSpec(architecture),
+                     getCCSpec(compiler),
+                     getCmdLine(dictionary)])
+
+    lldbtest.system(commands, sender=sender)
+    # True signifies that we can handle building with type units.
+    return True
+
+
 def cleanup(sender=None, dictionary=None):
     """Perform a platform-specific cleanup after the test."""
     return True
Index: packages/Python/lldbsuite/test/make/Makefile.rules
===================================================================
--- packages/Python/lldbsuite/test/make/Makefile.rules
+++ packages/Python/lldbsuite/test/make/Makefile.rules
@@ -247,6 +247,12 @@
 	CFLAGS += $(MANDATORY_MODULE_BUILD_CFLAGS)
 endif
 
+MANDATORY_DWARF_TYPE_UNITS_CFLAGS := -fdebug-types-section
+
+ifeq "$(DWARF_TYPE_UNITS)" "YES"
+	CFLAGS += $(MANDATORY_DWARF_TYPE_UNITS_CFLAGS)
+endif
+
 CXXFLAGS += -std=c++11 $(CFLAGS)
 LD = $(CC)
 LDFLAGS ?= $(CFLAGS)
@@ -668,7 +674,7 @@
 
 #----------------------------------------------------------------------
 # From http://blog.melski.net/tag/debugging-makefiles/
-# 
+#
 # Usage: make print-CC print-CXX print-LD
 #----------------------------------------------------------------------
 print-%:
Index: packages/Python/lldbsuite/test/lldbtest.py
===================================================================
--- packages/Python/lldbsuite/test/lldbtest.py
+++ packages/Python/lldbsuite/test/lldbtest.py
@@ -715,17 +715,17 @@
             variant = 'default'
         return os.path.join(os.environ["LLDB_BUILD"], self.mydir,
                             self.getBuildDirBasename())
-    
-     
+
+
     def makeBuildDir(self):
         """Create the test-specific working directory."""
         # See also dotest.py which sets up ${LLDB_BUILD}.
         lldbutil.mkdir_p(self.getBuildDir())
- 
+
     def getBuildArtifact(self, name="a.out"):
         """Return absolute path to an artifact in the test's build directory."""
         return os.path.join(self.getBuildDir(), name)
- 
+
     def getSourcePath(self, name):
         """Return absolute path to a file in the test's source directory."""
         return os.path.join(self.getSourceDir(), name)
@@ -1589,6 +1589,24 @@
                                     dictionary, clean, testdir, testname):
             raise Exception("Don't know how to build binary with gmodules")
 
+    def buildDwarfTypeUnits(
+            self,
+            architecture=None,
+            compiler=None,
+            dictionary=None,
+            clean=True):
+        """Platform specific way to build binaries with DWARF type units."""
+        testdir = self.mydir
+        testname = self.getBuildDirBasename()
+        if self.getDebugInfo() != "dwarf_type_units":
+            raise Exception("NO_DEBUG_INFO_TESTCASE must build with buildDefault")
+
+        module = builder_module()
+        dictionary = lldbplatformutil.finalize_build_dictionary(dictionary)
+        if not module.buildDwarfTypeUnits(self, architecture, compiler,
+                                          dictionary, clean, testdir, testname):
+            raise Exception("Don't know how to build binary with DWARF type units")
+
     def buildGo(self):
         """Build the default go binary.
         """
@@ -1761,7 +1779,7 @@
                 supported_categories = [
                     x for x in categories if test_categories.is_supported_on_platform(
                         x, target_platform, configuration.compiler)]
-                
+
                 if "dsym" in supported_categories:
                     @decorators.add_test_categories(["dsym"])
                     @wraps(attrvalue)
@@ -1802,6 +1820,16 @@
                     gmodules_test_method.debug_info = "gmodules"
                     newattrs[gmodules_method_name] = gmodules_test_method
 
+                if "dwarf_type_units" in supported_categories:
+                    @decorators.add_test_categories(["dwarf_type_units"])
+                    @wraps(attrvalue)
+                    def dwarf_type_units_test_method(self, attrvalue=attrvalue):
+                        return attrvalue(self)
+                    dwarf_type_units_method_name = attrname + "_dwarf_type_units"
+                    dwarf_type_units_test_method.__name__ = dwarf_type_units_method_name
+                    dwarf_type_units_test_method.debug_info = "dwarf_type_units"
+                    newattrs[dwarf_type_units_method_name] = dwarf_type_units_test_method
+
             else:
                 newattrs[attrname] = attrvalue
         return super(
@@ -1887,7 +1915,7 @@
         temp = os.path.join(self.getSourceDir(), template)
         with open(temp, 'r') as f:
             content = f.read()
-            
+
         public_api_dir = os.path.join(
             os.environ["LLDB_SRC"], "include", "lldb", "API")
 
@@ -2325,6 +2353,9 @@
         elif self.getDebugInfo() == "gmodules":
             return self.buildGModules(architecture, compiler, dictionary,
                                       clean)
+        elif self.getDebugInfo() == "dwarf_type_units":
+            return self.buildDwarfTypeUnits(architecture, compiler, dictionary,
+                                            clean)
         else:
             self.fail("Can't build for debug info: %s" % self.getDebugInfo())
 
Index: packages/Python/lldbsuite/test/lldbinline.py
===================================================================
--- packages/Python/lldbsuite/test/lldbinline.py
+++ packages/Python/lldbsuite/test/lldbinline.py
@@ -168,6 +168,14 @@
         self.do_test()
     __test_with_gmodules.debug_info = "gmodules"
 
+    @add_test_categories(["dwarf_type_units"])
+    def __test_with_dwarf_type_units(self):
+        self.using_dsym = False
+        self.BuildMakefile()
+        self.build()
+        self.do_test()
+    __test_with_dwarf_type_units.debug_info = "dwarf_type_units"
+
     def execute_user_command(self, __command):
         exec(__command, globals(), locals())
 
@@ -250,6 +258,10 @@
             "gmodules", target_platform, configuration.compiler):
         test.test_with_gmodules = ApplyDecoratorsToFunction(
             test._InlineTest__test_with_gmodules, decorators)
+    if test_categories.is_supported_on_platform(
+            "dwarf_type_units", target_platform, configuration.compiler):
+        test.test_with_dwarf_type_units = ApplyDecoratorsToFunction(
+            test._InlineTest__test_with_dwarf_type_units, decorators)
 
     # Add the test case to the globals, and hide InlineTest
     __globals.update({test_name: test})
Index: include/lldb/lldb-forward.h
===================================================================
--- include/lldb/lldb-forward.h
+++ include/lldb/lldb-forward.h
@@ -85,6 +85,7 @@
 class DiagnosticManager;
 class Disassembler;
 class DumpValueObjectOptions;
+class DWARFDataExtractor;
 class DynamicCheckerFunctions;
 class DynamicLoader;
 class Editline;
Index: include/lldb/lldb-enumerations.h
===================================================================
--- include/lldb/lldb-enumerations.h
+++ include/lldb/lldb-enumerations.h
@@ -656,6 +656,7 @@
   eSectionTypeGoSymtab,
   eSectionTypeAbsoluteAddress, // Dummy section for symbols with absolute
                                // address
+  eSectionTypeDWARFDebugTypes,
   eSectionTypeOther
 };
 
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to