jankratochvil updated this revision to Diff 170342.
jankratochvil added a comment.
Herald added a subscriber: arphaman.

Patch `concat` = original posting with `DWARFConcatenatingDataExtractor` used 
only for `.debug_info`(+`.debug_types`) section. download 
<https://people.redhat.com/jkratoch/concat.patch>
Patch `concat2` = used `DWARFDataExtractor` with integrated concatenation for 
all DWARF sections. download <https://people.redhat.com/jkratoch/concat2.patch>

  master  real=0.996s user=14.744s sys=1.050s
  concat  real=0.994s user=15.524s sys=1.117s
  concat2 real=1.001s user=15.580s sys=1.334s

`concat` vs. `concat2` benchmark difference was mostly a measurement error. It 
is now 5% slowdown compared to trunk - even for former `concat` which I do not 
understand now, I will investigate it more as my original measured slowdown was 
just 1% before.
`concat2` sometimes needs to cast `DWARFDataExtractor` to `DataExtractor` by 
`.AsDataExtractor()` as some functions expected a contiguous block of memory. 
That is a method applicable only for non-`.debug_info` sections (it would 
assert on `.debug_info`). It needs to be called as `DWARFDataExtractor` can no 
longer inherit `DataExtractor`. I did not use `operator DataExtractor &` as it 
could accidentally by applied to `.debug_info` which may be difficult to catch 
when not tested with `-fdebug-types-section`.
`DataExtractorConcat` is a separate class but it is never used separately 
without `DWARFDataExtractor` inheriting it.
Greg, do you mean it somehow way or do I miss something? Personally I may like 
a bit more `concat` but then the patch size is almost the same for both.


Repository:
  rLLDB LLDB

https://reviews.llvm.org/D51578

Files:
  source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
  source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
  source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
  source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
  source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp
  source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
  source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
  source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
  source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp
  source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
  source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
  source/Plugins/SymbolFile/DWARF/DWARFUnit.h
  source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
  source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp

Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
@@ -105,9 +105,11 @@
   auto *offsets =
       it->second->getOffset(lldbSectTypeToLlvmSectionKind(sect_type));
   if (offsets) {
-    data.SetData(section_data, offsets->Offset, offsets->Length);
+    data.AsDataExtractor().SetData(
+        section_data.AsDataExtractor(), offsets->Offset, offsets->Length);
   } else {
-    data.SetData(section_data, 0, section_data.GetByteSize());
+    data.AsDataExtractor().SetData(
+        section_data.AsDataExtractor(), 0, section_data.GetByteSize());
   }
   return true;
 }
@@ -131,12 +133,13 @@
     lldb::SectionSP section_sp(
         section_list->FindSectionByType(sect_type, true));
     if (section_sp) {
-      if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0) {
+      if (m_obj_file->ReadSectionData(
+          section_sp.get(), data.AsDataExtractor()) != 0) {
         m_sections[sect_type] = data;
         return true;
       }
     }
   }
-  m_sections[sect_type].Clear();
+  m_sections[sect_type].AsDataExtractor().Clear();
   return false;
 }
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -36,15 +36,17 @@
     if (section_sp) {
       // See if we memory mapped the DWARF segment?
       if (m_dwarf_data.GetByteSize()) {
-        data.SetData(m_dwarf_data, section_sp->GetOffset(),
-                     section_sp->GetFileSize());
+        data.AsDataExtractor().SetData(m_dwarf_data.AsDataExtractor(),
+                                       section_sp->GetOffset(),
+                                       section_sp->GetFileSize());
         return;
       }
 
-      if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0)
+      if (m_obj_file->ReadSectionData(
+          section_sp.get(), data.AsDataExtractor()) != 0)
         return;
 
-      data.Clear();
+      data.AsDataExtractor().Clear();
     }
   }
 
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -240,15 +240,16 @@
   const lldb_private::DWARFDataExtractor &get_debug_aranges_data();
   const lldb_private::DWARFDataExtractor &get_debug_frame_data();
   const lldb_private::DWARFDataExtractor &get_debug_info_data();
+  const lldb_private::DWARFDataExtractor &get_raw_debug_info_data();
   const lldb_private::DWARFDataExtractor &get_debug_line_data();
   const lldb_private::DWARFDataExtractor &get_debug_line_str_data();
   const lldb_private::DWARFDataExtractor &get_debug_macro_data();
   const lldb_private::DWARFDataExtractor &get_debug_loc_data();
   const lldb_private::DWARFDataExtractor &get_debug_ranges_data();
   const lldb_private::DWARFDataExtractor &get_debug_rnglists_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_raw_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();
@@ -486,6 +487,9 @@
   DWARFDataSegment m_data_apple_objc;
   DWARFDataSegment m_data_gnu_debugaltlink;
 
+  llvm::once_flag m_concatenated_data_once;
+  lldb_private::DWARFDataExtractor m_data_debug_info_concatenated;
+
   // The unique pointer items below are generated on demand if and when someone
   // accesses
   // them through a non const version of this class.
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -453,7 +453,7 @@
         section_list->FindSectionByName(GetDWARFMachOSegmentName()).get();
 
     if (section)
-      m_obj_file->ReadSectionData(section, m_dwarf_data);
+      m_obj_file->ReadSectionData(section, m_dwarf_data.AsDataExtractor());
   }
 
   if (!GetGlobalPluginProperties()->IgnoreFileIndexes()) {
@@ -577,24 +577,8 @@
 const DWARFDataExtractor &
 SymbolFileDWARF::GetCachedSectionData(lldb::SectionType sect_type,
                                       DWARFDataSegment &data_segment) {
-  llvm::call_once(data_segment.m_flag, [&] {
+  llvm::call_once(data_segment.m_flag, [this, sect_type, &data_segment] {
     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;
 }
@@ -608,11 +592,13 @@
     if (section_sp) {
       // See if we memory mapped the DWARF segment?
       if (m_dwarf_data.GetByteSize()) {
-        data.SetData(m_dwarf_data, section_sp->GetOffset(),
-                     section_sp->GetFileSize());
+        data.AsDataExtractor().SetData(
+            m_dwarf_data.AsDataExtractor(), section_sp->GetOffset(),
+            section_sp->GetFileSize());
       } else {
-        if (m_obj_file->ReadSectionData(section_sp.get(), data) == 0)
-          data.Clear();
+        if (m_obj_file->ReadSectionData(
+            section_sp.get(), data.AsDataExtractor()) == 0)
+          data.AsDataExtractor().Clear();
       }
     }
   }
@@ -636,7 +622,7 @@
   return GetCachedSectionData(eSectionTypeDWARFDebugFrame, m_data_debug_frame);
 }
 
-const DWARFDataExtractor &SymbolFileDWARF::get_debug_info_data() {
+const DWARFDataExtractor &SymbolFileDWARF::get_raw_debug_info_data() {
   return GetCachedSectionData(eSectionTypeDWARFDebugInfo, m_data_debug_info);
 }
 
@@ -675,7 +661,7 @@
                               m_data_debug_str_offsets);
 }
 
-const DWARFDataExtractor &SymbolFileDWARF::get_debug_types_data() {
+const DWARFDataExtractor &SymbolFileDWARF::get_raw_debug_types_data() {
   return GetCachedSectionData(eSectionTypeDWARFDebugTypes, m_data_debug_types);
 }
 
@@ -701,6 +687,18 @@
                               m_data_gnu_debugaltlink);
 }
 
+const DWARFDataExtractor &
+    SymbolFileDWARF::get_debug_info_data() {
+  llvm::call_once(m_concatenated_data_once, [&] {
+    m_data_debug_info_concatenated.SetDataExtractors(
+        const_cast<DWARFDataExtractor &>(get_raw_debug_info_data())
+        .AsDataExtractor(),
+        const_cast<DWARFDataExtractor &>(get_raw_debug_types_data())
+        .AsDataExtractor());
+  });
+  return m_data_debug_info_concatenated;
+}
+
 DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() {
   if (m_abbr.get() == NULL) {
     const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data();
@@ -3248,10 +3246,12 @@
               auto debug_info_data = die.GetData();
               if (DWARFFormValue::IsBlockForm(form_value.Form())) {
                 // Retrieve the value as a block expression.
+                const DataExtractor &block_extractor =
+                    debug_info_data.GetDataExtractor(form_value.BlockData());
                 uint32_t block_offset =
-                    form_value.BlockData() - debug_info_data.GetDataStart();
+                    form_value.BlockData() - block_extractor.GetDataStart();
                 uint32_t block_length = form_value.Unsigned();
-                location.CopyOpcodeData(module, debug_info_data, block_offset,
+                location.CopyOpcodeData(module, block_extractor, block_offset,
                                         block_length);
               } else if (DWARFFormValue::IsDataForm(form_value.Form())) {
                 // Retrieve the value as a data expression.
@@ -3271,9 +3271,15 @@
                     // create the variable
                     const_value = form_value;
                   }
-                } else
-                  location.CopyOpcodeData(module, debug_info_data, data_offset,
-                                          data_length);
+                } else {
+                  lldb::offset_t block_extractor_offset;
+                  const DataExtractor &block_extractor =
+                      debug_info_data.GetDataExtractor(
+                          data_offset, &block_extractor_offset);
+                  location.CopyOpcodeData(
+                      module, block_extractor,
+                      data_offset - block_extractor_offset, data_length);
+                }
               } else {
                 // Retrieve the value as a string expression.
                 if (form_value.Form() == DW_FORM_strp) {
@@ -3283,16 +3289,24 @@
                               ->GetAddressByteSize(),
                           attributes.CompileUnitAtIndex(i)->IsDWARF64());
                   uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
+                  lldb::offset_t block_extractor_offset;
+                  const DataExtractor &block_extractor =
+                      debug_info_data.GetDataExtractor(
+                          data_offset, &block_extractor_offset);
                   uint32_t data_length =
                       fixed_form_sizes.GetSize(form_value.Form());
-                  location.CopyOpcodeData(module, debug_info_data, data_offset,
-                                          data_length);
+                  location.CopyOpcodeData(
+                      module, block_extractor,
+                      data_offset - block_extractor_offset, data_length);
                 } else {
                   const char *str = form_value.AsCString();
+                  const DataExtractor &block_extractor =
+                      debug_info_data.GetDataExtractor(
+                          (const uint8_t *)str);
                   uint32_t string_offset =
-                      str - (const char *)debug_info_data.GetDataStart();
+                      str - (const char *)block_extractor.GetDataStart();
                   uint32_t string_length = strlen(str) + 1;
-                  location.CopyOpcodeData(module, debug_info_data,
+                  location.CopyOpcodeData(module, block_extractor,
                                           string_offset, string_length);
                 }
               }
@@ -3304,19 +3318,24 @@
             if (DWARFFormValue::IsBlockForm(form_value.Form())) {
               auto data = die.GetData();
 
+              const DataExtractor &block_extractor =
+                  data.GetDataExtractor(form_value.BlockData());
               uint32_t block_offset =
-                  form_value.BlockData() - data.GetDataStart();
+                  form_value.BlockData() - block_extractor.GetDataStart();
               uint32_t block_length = form_value.Unsigned();
-              location.CopyOpcodeData(module, data, block_offset, block_length);
+              location.CopyOpcodeData(
+                  module, block_extractor, block_offset, block_length);
             } else {
               const DWARFDataExtractor &debug_loc_data = get_debug_loc_data();
               const dw_offset_t debug_loc_offset = form_value.Unsigned();
 
               size_t loc_list_length = DWARFExpression::LocationListSize(
-                  die.GetCU(), debug_loc_data, debug_loc_offset);
+                  die.GetCU(), debug_loc_data.AsDataExtractor(),
+                  debug_loc_offset);
               if (loc_list_length > 0) {
-                location.CopyOpcodeData(module, debug_loc_data,
-                                        debug_loc_offset, loc_list_length);
+                location.CopyOpcodeData(
+                    module, debug_loc_data.AsDataExtractor(), debug_loc_offset,
+                    loc_list_length);
                 assert(func_low_pc != LLDB_INVALID_ADDRESS);
                 location.SetLocationListSlide(
                     func_low_pc -
Index: source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
+++ source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
@@ -348,7 +348,8 @@
 DWARFMappedHash::MemoryTable::MemoryTable(
     lldb_private::DWARFDataExtractor &table_data,
     const lldb_private::DWARFDataExtractor &string_table, const char *name)
-    : MappedHash::MemoryTable<uint32_t, Header, DIEInfoArray>(table_data),
+    : MappedHash::MemoryTable<uint32_t, Header, DIEInfoArray>(
+          table_data.AsDataExtractor()),
       m_data(table_data), m_string_table(string_table), m_name(name) {}
 
 const char *
Index: source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
+++ source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
@@ -17,7 +17,7 @@
 using namespace lldb_private;
 using namespace lldb;
 
-static llvm::DWARFDataExtractor ToLLVM(const DWARFDataExtractor &data) {
+static llvm::DWARFDataExtractor ToLLVM(const DataExtractor &data) {
   return llvm::DWARFDataExtractor(
       llvm::StringRef(reinterpret_cast<const char *>(data.GetDataStart()),
                       data.GetByteSize()),
@@ -32,8 +32,9 @@
     return llvm::make_error<llvm::StringError>("debug info null",
                                                llvm::inconvertibleErrorCode());
   }
-  auto index_up =
-      llvm::make_unique<DebugNames>(ToLLVM(debug_names), ToLLVM(debug_str));
+  auto index_up = llvm::make_unique<DebugNames>(
+      ToLLVM(debug_names.AsDataExtractor()),
+      ToLLVM(debug_str.AsDataExtractor()));
   if (llvm::Error E = index_up->extract())
     return std::move(E);
 
Index: source/Plugins/SymbolFile/DWARF/DWARFUnit.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -79,7 +79,7 @@
   /// @return
   ///   The correct data for the DIE information in this unit.
   //------------------------------------------------------------------
-  virtual const lldb_private::DWARFDataExtractor &GetData() const = 0;
+  const lldb_private::DWARFDataExtractor &GetData() const;
   //------------------------------------------------------------------
   /// Get the size in bytes of the compile unit header.
   ///
Index: source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -829,3 +829,6 @@
   return false;
 }
 
+const lldb_private::DWARFDataExtractor &DWARFUnit::GetData() const {
+  return m_dwarf->get_debug_info_data();
+}
Index: source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
+++ source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
@@ -24,17 +24,6 @@
 
   void Dump(lldb_private::Stream *s) const override;
 
-  //------------------------------------------------------------------
-  /// Get the data that contains the DIE information for this unit.
-  ///
-  /// @return
-  ///   The correct data (.debug_types for DWARF 4 and earlier, and
-  ///   .debug_info for DWARF 5 and later) for the DIE information in
-  ///   this unit.
-  //------------------------------------------------------------------
-  const lldb_private::DWARFDataExtractor &GetData() const override;
-  
-
   //------------------------------------------------------------------
   /// Get the size in bytes of the header.
   ///
Index: source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.cpp
@@ -51,13 +51,3 @@
   // unit offset to ensure we get the correct DIE.
   return GetDIE(GetTypeUnitDIEOffset());
 }
-
-const lldb_private::DWARFDataExtractor &DWARFTypeUnit::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 (GetVersion() < 5)
-    return m_dwarf->get_debug_types_data();
-  else
-    return m_dwarf->get_debug_info_data();
-}
-
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -524,20 +524,23 @@
         case DW_AT_frame_base:
           if (frame_base) {
             if (form_value.BlockData()) {
-              uint32_t block_offset =
-                  form_value.BlockData() - debug_info_data.GetDataStart();
+              const DataExtractor &block_extractor =
+                  debug_info_data.GetDataExtractor(form_value.BlockData());
+              uint32_t block_offset = form_value.BlockData()
+                  - block_extractor.GetDataStart();
               uint32_t block_length = form_value.Unsigned();
-              frame_base->SetOpcodeData(module, debug_info_data, block_offset,
+              frame_base->SetOpcodeData(module, block_extractor, block_offset,
                                         block_length);
             } else {
               const DWARFDataExtractor &debug_loc_data =
                   dwarf2Data->get_debug_loc_data();
               const dw_offset_t debug_loc_offset = form_value.Unsigned();
 
               size_t loc_list_length = DWARFExpression::LocationListSize(
-                  cu, debug_loc_data, debug_loc_offset);
+                  cu, debug_loc_data.AsDataExtractor(), debug_loc_offset);
               if (loc_list_length > 0) {
-                frame_base->SetOpcodeData(module, debug_loc_data,
+                frame_base->SetOpcodeData(module,
+                                          debug_loc_data.AsDataExtractor(),
                                           debug_loc_offset, loc_list_length);
                 if (lo_pc != LLDB_INVALID_ADDRESS) {
                   assert(lo_pc >= cu->GetBaseAddress());
@@ -621,8 +624,8 @@
           dw_attr_t attr;
           abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
 
-          DumpAttribute(dwarf2Data, cu, debug_info_data, &offset, s, attr,
-                        form_value);
+          DumpAttribute(dwarf2Data, cu, debug_info_data, &offset,
+                        s, attr, form_value);
         }
 
         const DWARFDebugInfoEntry *child = GetFirstChild();
@@ -714,19 +717,23 @@
   case DW_AT_data_member_location: {
     const uint8_t *blockData = form_value.BlockData();
     if (blockData) {
+      uint64_t form_data_offset;
+      const DataExtractor &form_data =
+          debug_info_data.GetDataExtractor(blockData, &form_data_offset);
       // Location description is inlined in data in the form value
-      DWARFDataExtractor locationData(debug_info_data,
-                                      (*offset_ptr) - form_value.Unsigned(),
-                                      form_value.Unsigned());
+      DataExtractor locationData(
+          form_data, (*offset_ptr) - form_value.Unsigned() - form_data_offset,
+          form_value.Unsigned());
       DWARFExpression::PrintDWARFExpression(
           s, locationData, DWARFUnit::GetAddressByteSize(cu), 4, false);
     } else {
       // We have a location list offset as the value that is the offset into
       // the .debug_loc section that describes the value over it's lifetime
       uint64_t debug_loc_offset = form_value.Unsigned();
       if (dwarf2Data) {
         DWARFExpression::PrintDWARFLocationList(
-            s, cu, dwarf2Data->get_debug_loc_data(), debug_loc_offset);
+            s, cu, dwarf2Data->get_debug_loc_data().AsDataExtractor(),
+            debug_loc_offset);
       }
     }
   } break;
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -104,8 +104,11 @@
   lldb::offset_t offset = 0;
   DWARFCompileUnitSP cu_sp;
   const auto &debug_info_data = m_dwarf2Data->get_debug_info_data();
-  while ((cu_sp = DWARFCompileUnit::Extract(m_dwarf2Data, debug_info_data,
-                                            &offset))) {
+  const uint64_t raw_debug_info_data_size =
+      m_dwarf2Data->get_raw_debug_info_data().GetByteSize();
+  while (offset < raw_debug_info_data_size
+      && (cu_sp = DWARFCompileUnit::Extract(
+          m_dwarf2Data, debug_info_data, &offset))) {
     m_compile_units.push_back(cu_sp);
     offset = cu_sp->GetNextCompileUnitOffset();
   }
@@ -119,15 +122,8 @@
   // types in the .debug_types to have a unique DIE offset that is:
   //    offset = sizeof(.debug_info) + debug_type_offset
   //
-  // So below we set "offset" to be the size of the .debug_info section. We have
-  // modified the debug_types_data to know that its first byte starts at this
-  // offset.
-  auto debug_types_data = m_dwarf2Data->get_debug_types_data();
-  if (debug_types_data.GetByteSize() == 0)
-    return;
-  offset = debug_info_data.GetByteSize();
   DWARFTypeUnitSP tu_sp;
-  while ((tu_sp = DWARFTypeUnit::Extract(m_dwarf2Data, debug_types_data,
+  while ((tu_sp = DWARFTypeUnit::Extract(m_dwarf2Data, debug_info_data,
                                          &offset))) {
     m_type_sig_to_cu_index[tu_sp->GetTypeSignature()] = m_compile_units.size();
     m_compile_units.push_back(tu_sp);
Index: source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
+++ source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h
@@ -10,55 +10,191 @@
 #ifndef liblldb_DWARFDataExtractor_h_
 #define liblldb_DWARFDataExtractor_h_
 
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/LLDBAssert.h"
+
 // Other libraries and framework includes.
 #include "lldb/Core/dwarf.h"
-#include "lldb/Utility/DataExtractor.h"
 
 namespace lldb_private {
 
-class DWARFDataExtractor : public DataExtractor {
+class DataExtractorConcat {
 public:
-  DWARFDataExtractor() : DataExtractor(), m_is_dwarf64(false) {}
+  DataExtractorConcat();
+  void SetDataExtractors(DataExtractor &extractor1, DataExtractor &extractor2);
+  inline const DataExtractor &GetDataExtractor(
+      const uint8_t *inner, uint64_t *extractor_offsetp = nullptr) const;
+  inline const DataExtractor &GetDataExtractor(
+      lldb::offset_t offset, lldb::offset_t *extractor_offsetp) const {
+    return offset_to_extractor(offset, extractor_offsetp);
+  }
+  inline DataExtractor &AsDataExtractor();
+  inline const DataExtractor &AsDataExtractor() const;
+  inline uint64_t GetByteSize() const;
+  inline uint32_t GetAddressByteSize() const;
+  inline lldb::ByteOrder GetByteOrder() const;
+  // forwarder-based implementation would assert on out of bound 'offset'.
+  bool ValidOffset(lldb::offset_t offset) const;
 
-  DWARFDataExtractor(const DWARFDataExtractor &data, lldb::offset_t offset,
-                     lldb::offset_t length)
-      : DataExtractor(data, offset, length), m_is_dwarf64(false) {}
+#define FORWARDER(FuncName, RetType, ParamListParen, ...) \
+    inline RetType FuncName ParamListParen const { \
+      return forwarder<RetType, DataExtractor>( \
+          &DataExtractor::FuncName, __VA_ARGS__); \
+    }
+  FORWARDER(GetFloat, float,
+      (lldb::offset_t *offset_ptr), offset_ptr)
+  FORWARDER(GetDouble, double,
+      (lldb::offset_t *offset_ptr), offset_ptr)
+  FORWARDER(GetLongDouble, long double,
+      (lldb::offset_t *offset_ptr), offset_ptr)
+  FORWARDER(GetMaxU32, uint32_t,
+      (lldb::offset_t *offset_ptr, size_t byte_size), offset_ptr, byte_size)
+  FORWARDER(GetMaxU64, uint64_t,
+      (lldb::offset_t *offset_ptr, size_t byte_size), offset_ptr, byte_size)
+  FORWARDER(GetMaxU64_unchecked, uint64_t,
+    (lldb::offset_t *offset_ptr, size_t byte_size), offset_ptr, byte_size)
+  FORWARDER(GetMaxS64, int64_t,
+      (lldb::offset_t *offset_ptr, size_t byte_size), offset_ptr, byte_size)
+  FORWARDER(GetMaxU64Bitfield, uint64_t,
+      (lldb::offset_t *offset_ptr, size_t size, uint32_t bitfield_bit_size,
+          uint32_t bitfield_bit_offset),
+      offset_ptr, size, bitfield_bit_size, bitfield_bit_offset)
+  FORWARDER(GetMaxS64Bitfield, int64_t,
+      (lldb::offset_t *offset_ptr, size_t size, uint32_t bitfield_bit_size,
+          uint32_t bitfield_bit_offset),
+      offset_ptr, size, bitfield_bit_size, bitfield_bit_offset)
+  FORWARDER(GetPointer, uint64_t, (lldb::offset_t *offset_ptr), offset_ptr)
+  FORWARDER(GetU8, uint8_t, (lldb::offset_t *offset_ptr), offset_ptr)
+  FORWARDER(GetU8_unchecked, uint8_t, (lldb::offset_t *offset_ptr), offset_ptr)
+  FORWARDER(GetU16_unchecked, uint16_t,
+      (lldb::offset_t *offset_ptr), offset_ptr)
+  FORWARDER(GetU32_unchecked, uint32_t,
+      (lldb::offset_t *offset_ptr), offset_ptr)
+  FORWARDER(GetU64_unchecked, uint64_t,
+      (lldb::offset_t *offset_ptr), offset_ptr)
+  FORWARDER(GetU8, void *,
+      (lldb::offset_t *offset_ptr, void *dst, uint32_t count),
+      offset_ptr, dst, count)
+  FORWARDER(GetU16, uint16_t, (lldb::offset_t *offset_ptr), offset_ptr)
+  FORWARDER(GetU16, void *,
+      (lldb::offset_t *offset_ptr, void *dst, uint32_t count),
+      offset_ptr, dst, count)
+  FORWARDER(GetU32, uint32_t, (lldb::offset_t *offset_ptr), offset_ptr)
+  FORWARDER(GetU32, void *,
+      (lldb::offset_t *offset_ptr, void *dst, uint32_t count),
+      offset_ptr, dst, count)
+  FORWARDER(GetU64, uint64_t, (lldb::offset_t *offset_ptr), offset_ptr)
+  FORWARDER(GetU64, void *,
+      (lldb::offset_t *offset_ptr, void *dst, uint32_t count),
+      offset_ptr, dst, count)
+  FORWARDER(GetSLEB128, int64_t, (lldb::offset_t *offset_ptr), offset_ptr)
+  FORWARDER(GetULEB128, uint64_t, (lldb::offset_t *offset_ptr), offset_ptr)
+  FORWARDER(PeekCStr, const char *, (lldb::offset_t offset), offset)
+  FORWARDER(PeekData, const uint8_t *,
+      (lldb::offset_t offset, lldb::offset_t length), offset, length)
+  FORWARDER(GetCStr, const char *, (lldb::offset_t *offset_ptr), offset_ptr)
+  FORWARDER(Skip_LEB128, uint32_t, (lldb::offset_t *offset_ptr), offset_ptr)
+  FORWARDER(ValidOffsetForDataOfSize, bool,
+      (lldb::offset_t offset, lldb::offset_t length), offset, length)
+#undef FORWARDER
 
-  uint64_t GetDWARFInitialLength(lldb::offset_t *offset_ptr) const;
+private:
+  const DataExtractor &offset_to_extractor_slow(lldb::offset_t offset,
+      lldb::offset_t *extractor_offsetp) const;
+  inline const DataExtractor &offset_to_extractor(lldb::offset_t offset,
+      lldb::offset_t *extractor_offsetp) const;
+  const DataExtractor &GetDataExtractor_slow(
+      const uint8_t *inner, uint64_t *extractor_offsetp) const;
+  uint64_t GetByteSize_slow() const;
+  uint32_t GetAddressByteSize_slow() const;
+  lldb::ByteOrder GetByteOrder_slow() const;
+  template<class RetType, class Extractor, class... Args>
+  inline RetType forwarder(
+      RetType (Extractor::*mptr)(lldb::offset_t *offset_ptr, Args...) const,
+      lldb::offset_t *offset_ptr, Args... args) const {
+    lldb::offset_t extractor_offset;
+    const Extractor &extractor =
+        offset_to_extractor(*offset_ptr, &extractor_offset);
+    *offset_ptr -= extractor_offset;
+    RetType retval = (extractor.*mptr)(offset_ptr, std::forward<Args>(args)...);
+    *offset_ptr += extractor_offset;
+    return retval;
+  }
+  template<class RetType, class Extractor, class... Args>
+  inline RetType forwarder(
+      RetType (Extractor::*mptr)(lldb::offset_t offset, Args...) const,
+      lldb::offset_t offset, Args... args) const {
+    lldb::offset_t extractor_offset;
+    const Extractor &extractor = offset_to_extractor(offset, &extractor_offset);
+    offset -= extractor_offset;
+    return (extractor.*mptr)(offset, std::forward<Args>(args)...);
+  }
 
-  dw_offset_t GetDWARFOffset(lldb::offset_t *offset_ptr) const;
+  llvm::SmallVector<DataExtractor *, 2> m_extractors;
+  DataExtractor m_extractor_local;
+};
+
+const DataExtractor &DataExtractorConcat::offset_to_extractor(
+    lldb::offset_t offset, lldb::offset_t *extractor_offsetp) const {
+  if (extractor_offsetp)
+    *extractor_offsetp = 0;
+  if (m_extractors.size() == 1)
+    return *m_extractors[0];
+  return offset_to_extractor_slow(offset, extractor_offsetp);
+}
+
+uint64_t DataExtractorConcat::GetByteSize() const {
+  if (m_extractors.size() == 1)
+    return m_extractors[0]->GetByteSize();
+  return GetByteSize_slow();
+}
+
+uint32_t DataExtractorConcat::GetAddressByteSize() const {
+  if (m_extractors.size() == 1)
+    return m_extractors[0]->GetAddressByteSize();
+  return GetAddressByteSize_slow();
+}
 
+lldb::ByteOrder DataExtractorConcat::GetByteOrder() const {
+  if (m_extractors.size() == 1)
+    return m_extractors[0]->GetByteOrder();
+  return GetByteOrder_slow();
+}
+
+const DataExtractor &DataExtractorConcat::GetDataExtractor(
+    const uint8_t *inner, uint64_t *extractor_offsetp) const {
+  if (m_extractors.size() == 1) {
+    if (extractor_offsetp)
+      *extractor_offsetp = 0;
+    return *m_extractors[0];
+  }
+  return GetDataExtractor_slow(inner, extractor_offsetp);
+}
+
+// Use only if you are sure it is not .debug_info section.
+DataExtractor &DataExtractorConcat::AsDataExtractor() {
+  lldbassert(m_extractors.size() == 1);
+  return *m_extractors[0];
+}
+const DataExtractor &DataExtractorConcat::AsDataExtractor() const {
+  lldbassert(m_extractors.size() == 1);
+  return *m_extractors[0];
+}
+
+class DWARFDataExtractor : public DataExtractorConcat {
+public:
+  using DataExtractorConcat::DataExtractorConcat;
+
+  uint64_t GetDWARFInitialLength(lldb::offset_t *offset_ptr) const;
+  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;
+private:
+  mutable bool m_is_dwarf64 = false;
 };
+
 }
 
 #endif // liblldb_DWARFDataExtractor_h_
Index: source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp
@@ -8,9 +8,80 @@
 //===----------------------------------------------------------------------===//
 
 #include "DWARFDataExtractor.h"
+#include "lldb/Utility/LLDBAssert.h"
 
 namespace lldb_private {
 
+DataExtractorConcat::DataExtractorConcat()
+    : m_extractors({&m_extractor_local}) {}
+
+void DataExtractorConcat::SetDataExtractors(
+    DataExtractor &extractor1, DataExtractor &extractor2) {
+  m_extractors.clear();
+  if (extractor1.GetByteSize()||!extractor2.GetByteSize())
+    m_extractors.push_back(&extractor1);
+  if (extractor2.GetByteSize())
+    m_extractors.push_back(&extractor2);
+}
+
+const DataExtractor &
+    DataExtractorConcat::offset_to_extractor_slow(
+    lldb::offset_t offset, lldb::offset_t *extractor_offsetp) const {
+  for (const DataExtractor *extractorp : m_extractors) {
+    if (offset < extractorp->GetByteSize())
+      return *extractorp;
+    offset -= extractorp->GetByteSize();
+    if (extractor_offsetp)
+      *extractor_offsetp += extractorp->GetByteSize();
+  }
+  llvm_unreachable("offset out of range");
+}
+
+const DataExtractor &DataExtractorConcat::GetDataExtractor_slow(
+    const uint8_t *inner, uint64_t *extractor_offsetp) const {
+  if (extractor_offsetp)
+    *extractor_offsetp = 0;
+  for (const DataExtractor *extractorp : m_extractors) {
+    if (inner >= extractorp->GetDataStart() && inner < extractorp->GetDataEnd())
+      return *extractorp;
+    if (extractor_offsetp)
+      *extractor_offsetp += extractorp->GetByteSize();
+  }
+  llvm_unreachable("pointer out of range");
+}
+
+uint64_t DataExtractorConcat::GetByteSize_slow() const {
+  uint64_t retval = 0;
+  for (const DataExtractor *extractorp : m_extractors)
+    retval += extractorp->GetByteSize();
+  return retval;
+}
+
+uint32_t DataExtractorConcat::GetAddressByteSize_slow() const {
+  lldbassert(!m_extractors.empty());
+  for (size_t ix = 0; ix < m_extractors.size(); ++ix)
+    lldbassert(m_extractors[0]->GetAddressByteSize()
+        == m_extractors[ix]->GetAddressByteSize());
+  return m_extractors[0]->GetAddressByteSize();
+}
+
+lldb::ByteOrder DataExtractorConcat::GetByteOrder_slow() const {
+  lldbassert(!m_extractors.empty());
+  for (size_t ix = 0; ix < m_extractors.size(); ++ix)
+    lldbassert(m_extractors[0]->GetByteOrder()
+        == m_extractors[ix]->GetByteOrder());
+  return m_extractors[0]->GetByteOrder();
+}
+
+bool DataExtractorConcat::ValidOffset(lldb::offset_t offset) const {
+  for (const DataExtractor *extractorp : m_extractors) {
+    if (offset < extractorp->GetByteSize())
+      return true;
+    offset -= extractorp->GetByteSize();
+  }
+  return false;
+}
+
 uint64_t
 DWARFDataExtractor::GetDWARFInitialLength(lldb::offset_t *offset_ptr) const {
   uint64_t length = GetU32(offset_ptr);
@@ -24,4 +95,5 @@
 DWARFDataExtractor::GetDWARFOffset(lldb::offset_t *offset_ptr) const {
   return GetMaxU64(offset_ptr, GetDWARFSizeOfOffset());
 }
+
 }
Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -19,16 +19,6 @@
       lldb::offset_t *offset_ptr);
   void Dump(lldb_private::Stream *s) const override;
 
-  //------------------------------------------------------------------
-  /// Get the data that contains the DIE information for this unit.
-  ///
-  /// @return
-  ///   The correct data (.debug_types for DWARF 4 and earlier, and
-  ///   .debug_info for DWARF 5 and later) for the DIE information in
-  ///   this unit.
-  //------------------------------------------------------------------
-  const lldb_private::DWARFDataExtractor &GetData() const override;
-
   //------------------------------------------------------------------
   /// Get the size in bytes of the header.
   ///
Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -53,7 +53,3 @@
   }
   llvm_unreachable("invalid UnitType.");
 }
-
-const lldb_private::DWARFDataExtractor &DWARFCompileUnit::GetData() const {
-  return m_dwarf->get_debug_info_data();
-}
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp
@@ -655,7 +655,8 @@
               if (form_value.BlockData()) {
                 Value initialValue(0);
                 Value memberOffset(0);
-                const DWARFDataExtractor &debug_info_data = die.GetData();
+                const DataExtractor &debug_info_data =
+                    die.GetData().GetDataExtractor(form_value.BlockData());
                 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
@@ -2778,7 +2778,8 @@
               if (form_value.BlockData()) {
                 Value initialValue(0);
                 Value memberOffset(0);
-                const DWARFDataExtractor &debug_info_data = die.GetData();
+                const DataExtractor &debug_info_data =
+                    die.GetData().GetDataExtractor(form_value.BlockData());
                 uint32_t block_length = form_value.Unsigned();
                 uint32_t block_offset =
                     form_value.BlockData() - debug_info_data.GetDataStart();
@@ -3230,7 +3231,8 @@
               if (form_value.BlockData()) {
                 Value initialValue(0);
                 Value memberOffset(0);
-                const DWARFDataExtractor &debug_info_data = die.GetData();
+                const DataExtractor &debug_info_data =
+                    die.GetData().GetDataExtractor(form_value.BlockData());
                 uint32_t block_length = form_value.Unsigned();
                 uint32_t block_offset =
                     form_value.BlockData() - debug_info_data.GetDataStart();
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to