This revision was not accepted when it landed; it landed in state "Needs 
Revision".
This revision was automatically updated to reflect the committed changes.
Closed by commit rL356278: Return Error and Expected from more DWARF 
interfaces. (authored by zturner, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D59381?vs=190700&id=190851#toc

Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D59381/new/

https://reviews.llvm.org/D59381

Files:
  lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
  lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
  lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
  lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
  lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
  lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
  lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
  lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
  lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -10,12 +10,14 @@
 #define SymbolFileDWARF_DWARFCompileUnit_h_
 
 #include "DWARFUnit.h"
+#include "llvm/Support/Error.h"
 
 class DWARFCompileUnit : public DWARFUnit {
 public:
-  static DWARFUnitSP Extract(SymbolFileDWARF *dwarf2Data,
-                             const lldb_private::DWARFDataExtractor &debug_info,
-                             lldb::offset_t *offset_ptr);
+  static llvm::Expected<DWARFUnitSP>
+  extract(SymbolFileDWARF *dwarf2Data,
+          const lldb_private::DWARFDataExtractor &debug_info,
+          lldb::offset_t *offset_ptr);
   void Dump(lldb_private::Stream *s) const override;
 
   //------------------------------------------------------------------
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -10,6 +10,7 @@
 
 #include "SymbolFileDWARF.h"
 #include "lldb/Utility/Stream.h"
+#include "llvm/Object/Error.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -17,50 +18,64 @@
 DWARFCompileUnit::DWARFCompileUnit(SymbolFileDWARF *dwarf2Data)
     : DWARFUnit(dwarf2Data) {}
 
-DWARFUnitSP DWARFCompileUnit::Extract(SymbolFileDWARF *dwarf2Data,
-                                      const DWARFDataExtractor &debug_info,
-                                      lldb::offset_t *offset_ptr) {
+llvm::Expected<DWARFUnitSP>
+DWARFCompileUnit::extract(SymbolFileDWARF *dwarf2Data,
+                          const DWARFDataExtractor &debug_info,
+                          lldb::offset_t *offset_ptr) {
+  assert(debug_info.ValidOffset(*offset_ptr));
+
   // std::make_shared would require the ctor to be public.
   std::shared_ptr<DWARFCompileUnit> cu_sp(new DWARFCompileUnit(dwarf2Data));
 
   cu_sp->m_offset = *offset_ptr;
 
-  if (debug_info.ValidOffset(*offset_ptr)) {
-    dw_offset_t abbr_offset;
-    const DWARFDebugAbbrev *abbr = dwarf2Data->DebugAbbrev();
-    cu_sp->m_length = debug_info.GetDWARFInitialLength(offset_ptr);
-    cu_sp->m_version = debug_info.GetU16(offset_ptr);
-
-    if (cu_sp->m_version == 5) {
-      cu_sp->m_unit_type = debug_info.GetU8(offset_ptr);
-      cu_sp->m_addr_size = debug_info.GetU8(offset_ptr);
-      abbr_offset = debug_info.GetDWARFOffset(offset_ptr);
-
-      if (cu_sp->m_unit_type == llvm::dwarf::DW_UT_skeleton)
-        cu_sp->m_dwo_id = debug_info.GetU64(offset_ptr);
-    } else {
-      abbr_offset = debug_info.GetDWARFOffset(offset_ptr);
-      cu_sp->m_addr_size = debug_info.GetU8(offset_ptr);
-    }
-
-    bool length_OK =
-        debug_info.ValidOffset(cu_sp->GetNextCompileUnitOffset() - 1);
-    bool version_OK = SymbolFileDWARF::SupportedVersion(cu_sp->m_version);
-    bool abbr_offset_OK =
-        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 (length_OK && version_OK && addr_size_OK && abbr_offset_OK &&
-        abbr != NULL) {
-      cu_sp->m_abbrevs = abbr->GetAbbreviationDeclarationSet(abbr_offset);
-      return cu_sp;
-    }
-
-    // reset the offset to where we tried to parse from if anything went wrong
-    *offset_ptr = cu_sp->m_offset;
+  dw_offset_t abbr_offset;
+  const DWARFDebugAbbrev *abbr = dwarf2Data->DebugAbbrev();
+  if (!abbr)
+    return llvm::make_error<llvm::object::GenericBinaryError>(
+        "No debug_abbrev data");
+
+  cu_sp->m_length = debug_info.GetDWARFInitialLength(offset_ptr);
+  cu_sp->m_version = debug_info.GetU16(offset_ptr);
+
+  if (cu_sp->m_version == 5) {
+    cu_sp->m_unit_type = debug_info.GetU8(offset_ptr);
+    cu_sp->m_addr_size = debug_info.GetU8(offset_ptr);
+    abbr_offset = debug_info.GetDWARFOffset(offset_ptr);
+
+    if (cu_sp->m_unit_type == llvm::dwarf::DW_UT_skeleton)
+      cu_sp->m_dwo_id = debug_info.GetU64(offset_ptr);
+  } else {
+    abbr_offset = debug_info.GetDWARFOffset(offset_ptr);
+    cu_sp->m_addr_size = debug_info.GetU8(offset_ptr);
   }
 
-  return nullptr;
+  bool length_OK =
+      debug_info.ValidOffset(cu_sp->GetNextCompileUnitOffset() - 1);
+  bool version_OK = SymbolFileDWARF::SupportedVersion(cu_sp->m_version);
+  bool abbr_offset_OK =
+      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 (!length_OK)
+    return llvm::make_error<llvm::object::GenericBinaryError>(
+        "Invalid compile unit length");
+  if (!version_OK)
+    return llvm::make_error<llvm::object::GenericBinaryError>(
+        "Unsupported compile unit version");
+  if (!abbr_offset_OK)
+    return llvm::make_error<llvm::object::GenericBinaryError>(
+        "Abbreviation offset for compile unit is not valid");
+  if (!addr_size_OK)
+    return llvm::make_error<llvm::object::GenericBinaryError>(
+        "Invalid compile unit address size");
+
+  cu_sp->m_abbrevs = abbr->GetAbbreviationDeclarationSet(abbr_offset);
+  if (!cu_sp->m_abbrevs)
+    return llvm::make_error<llvm::object::GenericBinaryError>(
+        "No abbrev exists at the specified offset.");
+
+  return cu_sp;
 }
 
 void DWARFCompileUnit::Dump(Stream *s) const {
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
@@ -12,11 +12,12 @@
 #include <map>
 #include <vector>
 
-#include "DWARFUnit.h"
 #include "DWARFDIE.h"
+#include "DWARFUnit.h"
 #include "SymbolFileDWARF.h"
 #include "lldb/Core/STLUtils.h"
 #include "lldb/lldb-private.h"
+#include "llvm/Support/Error.h"
 
 typedef std::multimap<const char *, dw_offset_t, CStringCompareFunctionObject>
     CStringToDIEMap;
@@ -50,7 +51,7 @@
         (1 << 2) // Show all parent DIEs when dumping single DIEs
   };
 
-  DWARFDebugAranges &GetCompileUnitAranges();
+  llvm::Expected<DWARFDebugAranges &> GetCompileUnitAranges();
 
 protected:
   static bool OffsetLessThanCompileUnitOffset(dw_offset_t offset,
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp
@@ -47,28 +47,33 @@
 //----------------------------------------------------------------------
 // Extract
 //----------------------------------------------------------------------
-bool DWARFDebugAranges::Extract(const DWARFDataExtractor &debug_aranges_data) {
-  if (debug_aranges_data.ValidOffset(0)) {
-    lldb::offset_t offset = 0;
-
-    DWARFDebugArangeSet set;
-    Range range;
-    while (set.Extract(debug_aranges_data, &offset)) {
-      const uint32_t num_descriptors = set.NumDescriptors();
-      if (num_descriptors > 0) {
-        const dw_offset_t cu_offset = set.GetCompileUnitDIEOffset();
-
-        for (uint32_t i = 0; i < num_descriptors; ++i) {
-          const DWARFDebugArangeSet::Descriptor &descriptor =
-              set.GetDescriptorRef(i);
-          m_aranges.Append(RangeToDIE::Entry(descriptor.address,
-                                             descriptor.length, cu_offset));
-        }
+llvm::Error
+DWARFDebugAranges::extract(const DWARFDataExtractor &debug_aranges_data) {
+  assert(debug_aranges_data.ValidOffset(0));
+
+  lldb::offset_t offset = 0;
+
+  DWARFDebugArangeSet set;
+  Range range;
+  while (debug_aranges_data.ValidOffset(offset)) {
+    llvm::Error error = set.extract(debug_aranges_data, &offset);
+    if (!error)
+      return error;
+
+    const uint32_t num_descriptors = set.NumDescriptors();
+    if (num_descriptors > 0) {
+      const dw_offset_t cu_offset = set.GetCompileUnitDIEOffset();
+
+      for (uint32_t i = 0; i < num_descriptors; ++i) {
+        const DWARFDebugArangeSet::Descriptor &descriptor =
+            set.GetDescriptorRef(i);
+        m_aranges.Append(RangeToDIE::Entry(descriptor.address,
+                                           descriptor.length, cu_offset));
       }
-      set.Clear();
     }
+    set.Clear();
   }
-  return false;
+  return llvm::ErrorSuccess();
 }
 
 //----------------------------------------------------------------------
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.h
@@ -44,8 +44,8 @@
                  uint8_t seg_size);
   void AddDescriptor(const DWARFDebugArangeSet::Descriptor &range);
   void Compact();
-  bool Extract(const lldb_private::DWARFDataExtractor &data,
-               lldb::offset_t *offset_ptr);
+  llvm::Error extract(const lldb_private::DWARFDataExtractor &data,
+                      lldb::offset_t *offset_ptr);
   void Dump(lldb_private::Stream *s) const;
   dw_offset_t GetCompileUnitDIEOffset() const { return m_header.cu_offset; }
   dw_offset_t GetOffsetOfNextEntry() const;
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1758,8 +1758,18 @@
 
     DWARFDebugInfo *debug_info = DebugInfo();
     if (debug_info) {
-      const dw_offset_t cu_offset =
-          debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
+      llvm::Expected<DWARFDebugAranges &> aranges =
+          debug_info->GetCompileUnitAranges();
+      if (!aranges) {
+        Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO |
+                                                DWARF_LOG_DEBUG_ARANGES);
+        LLDB_LOG_ERROR(log, aranges.takeError(),
+                       "SymbolFileDWARF::ResolveSymbolContext failed to get cu "
+                       "aranges.  {0}");
+        return 0;
+      }
+
+      const dw_offset_t cu_offset = aranges->FindAddress(file_vm_addr);
       if (cu_offset == DW_INVALID_OFFSET) {
         // Global variables are not in the compile unit address ranges. The
         // only way to currently find global variables is to iterate over the
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -42,69 +42,87 @@
   m_compile_units.clear();
 }
 
-DWARFDebugAranges &DWARFDebugInfo::GetCompileUnitAranges() {
-  if (m_cu_aranges_up == NULL && m_dwarf2Data) {
-    Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES));
-
-    m_cu_aranges_up.reset(new DWARFDebugAranges());
-    const DWARFDataExtractor &debug_aranges_data =
-        m_dwarf2Data->get_debug_aranges_data();
-    if (debug_aranges_data.GetByteSize() > 0) {
-      if (log)
-        log->Printf(
-            "DWARFDebugInfo::GetCompileUnitAranges() for \"%s\" from "
-            ".debug_aranges",
-            m_dwarf2Data->GetObjectFile()->GetFileSpec().GetPath().c_str());
-      m_cu_aranges_up->Extract(debug_aranges_data);
-    }
+llvm::Expected<DWARFDebugAranges &> DWARFDebugInfo::GetCompileUnitAranges() {
+  if (m_cu_aranges_up)
+    return *m_cu_aranges_up;
+
+  assert(m_dwarf2Data);
+
+  Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES));
+
+  m_cu_aranges_up = llvm::make_unique<DWARFDebugAranges>();
+  const DWARFDataExtractor &debug_aranges_data =
+      m_dwarf2Data->get_debug_aranges_data();
+  if (debug_aranges_data.GetByteSize() > 0) {
+    if (log)
+      log->Printf(
+          "DWARFDebugInfo::GetCompileUnitAranges() for \"%s\" from "
+          ".debug_aranges",
+          m_dwarf2Data->GetObjectFile()->GetFileSpec().GetPath().c_str());
+    llvm::Error error = m_cu_aranges_up->extract(debug_aranges_data);
+    if (error)
+      return std::move(error);
+  }
 
-    // Make a list of all CUs represented by the arange data in the file.
-    std::set<dw_offset_t> cus_with_data;
-    for (size_t n = 0; n < m_cu_aranges_up->GetNumRanges(); n++) {
-      dw_offset_t offset = m_cu_aranges_up->OffsetAtIndex(n);
-      if (offset != DW_INVALID_OFFSET)
-        cus_with_data.insert(offset);
-    }
+  // Make a list of all CUs represented by the arange data in the file.
+  std::set<dw_offset_t> cus_with_data;
+  for (size_t n = 0; n < m_cu_aranges_up->GetNumRanges(); n++) {
+    dw_offset_t offset = m_cu_aranges_up->OffsetAtIndex(n);
+    if (offset != DW_INVALID_OFFSET)
+      cus_with_data.insert(offset);
+  }
 
-    // Manually build arange data for everything that wasn't in the
-    // .debug_aranges table.
-    bool printed = false;
-    const size_t num_compile_units = GetNumCompileUnits();
-    for (size_t idx = 0; idx < num_compile_units; ++idx) {
-      DWARFUnit *cu = GetCompileUnitAtIndex(idx);
-
-      dw_offset_t offset = cu->GetOffset();
-      if (cus_with_data.find(offset) == cus_with_data.end()) {
-        if (log) {
-          if (!printed)
-            log->Printf(
-                "DWARFDebugInfo::GetCompileUnitAranges() for \"%s\" by parsing",
-                m_dwarf2Data->GetObjectFile()->GetFileSpec().GetPath().c_str());
-          printed = true;
-        }
-        cu->BuildAddressRangeTable(m_dwarf2Data, m_cu_aranges_up.get());
+  // Manually build arange data for everything that wasn't in the
+  // .debug_aranges table.
+  bool printed = false;
+  const size_t num_compile_units = GetNumCompileUnits();
+  for (size_t idx = 0; idx < num_compile_units; ++idx) {
+    DWARFUnit *cu = GetCompileUnitAtIndex(idx);
+
+    dw_offset_t offset = cu->GetOffset();
+    if (cus_with_data.find(offset) == cus_with_data.end()) {
+      if (log) {
+        if (!printed)
+          log->Printf(
+              "DWARFDebugInfo::GetCompileUnitAranges() for \"%s\" by parsing",
+              m_dwarf2Data->GetObjectFile()->GetFileSpec().GetPath().c_str());
+        printed = true;
       }
+      cu->BuildAddressRangeTable(m_dwarf2Data, m_cu_aranges_up.get());
     }
-
-    const bool minimize = true;
-    m_cu_aranges_up->Sort(minimize);
   }
+
+  const bool minimize = true;
+  m_cu_aranges_up->Sort(minimize);
   return *m_cu_aranges_up;
 }
 
 void DWARFDebugInfo::ParseCompileUnitHeadersIfNeeded() {
-  if (m_compile_units.empty()) {
-    if (m_dwarf2Data != NULL) {
-      lldb::offset_t offset = 0;
-      DWARFUnitSP cu_sp;
-      const auto &debug_info_data = m_dwarf2Data->get_debug_info_data();
-      while ((cu_sp = DWARFCompileUnit::Extract(m_dwarf2Data, debug_info_data,
-                                                &offset))) {
-        m_compile_units.push_back(cu_sp);
+  if (!m_compile_units.empty())
+    return;
+  if (!m_dwarf2Data)
+    return;
 
-        offset = cu_sp->GetNextCompileUnitOffset();
-      }
+  lldb::offset_t offset = 0;
+  const auto &debug_info_data = m_dwarf2Data->get_debug_info_data();
+
+  while (debug_info_data.ValidOffset(offset)) {
+    llvm::Expected<DWARFUnitSP> cu_sp =
+        DWARFCompileUnit::extract(m_dwarf2Data, debug_info_data, &offset);
+
+    if (!cu_sp) {
+      // FIXME: Propagate this error up.
+      llvm::consumeError(cu_sp.takeError());
+      return;
     }
+
+    // If it didn't return an error, then it should be returning a valid
+    // CompileUnit.
+    assert(*cu_sp);
+
+    m_compile_units.push_back(*cu_sp);
+
+    offset = (*cu_sp)->GetNextCompileUnitOffset();
   }
 }
 
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h
@@ -11,6 +11,7 @@
 
 #include "DWARFDebugArangeSet.h"
 #include "lldb/Utility/RangeMap.h"
+#include "llvm/Support/Error.h"
 #include <list>
 
 class SymbolFileDWARF;
@@ -28,7 +29,8 @@
 
   void Clear() { m_aranges.Clear(); }
 
-  bool Extract(const lldb_private::DWARFDataExtractor &debug_aranges_data);
+  llvm::Error
+  extract(const lldb_private::DWARFDataExtractor &debug_aranges_data);
 
   bool Generate(SymbolFileDWARF *dwarf2Data);
 
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugArangeSet.cpp
@@ -10,6 +10,7 @@
 
 #include "SymbolFileDWARF.h"
 #include "lldb/Utility/Stream.h"
+#include "llvm/Object/Error.h"
 #include <assert.h>
 
 using namespace lldb_private;
@@ -130,98 +131,88 @@
   }
 }
 
-bool DWARFDebugArangeSet::Extract(const DWARFDataExtractor &data,
-                                  lldb::offset_t *offset_ptr) {
-  if (data.ValidOffset(*offset_ptr)) {
-    m_arange_descriptors.clear();
-    m_offset = *offset_ptr;
-
-    // 7.20 Address Range Table
-    //
-    // Each set of entries in the table of address ranges contained in the
-    // .debug_aranges section begins with a header consisting of: a 4-byte
-    // length containing the length of the set of entries for this compilation
-    // unit, not including the length field itself; a 2-byte version identifier
-    // containing the value 2 for DWARF Version 2; a 4-byte offset into
-    // the.debug_infosection; a 1-byte unsigned integer containing the size in
-    // bytes of an address (or the offset portion of an address for segmented
-    // addressing) on the target system; and a 1-byte unsigned integer
-    // containing the size in bytes of a segment descriptor on the target
-    // system. This header is followed by a series of tuples. Each tuple
-    // consists of an address and a length, each in the size appropriate for an
-    // address on the target architecture.
-    m_header.length = data.GetDWARFInitialLength(offset_ptr);
-    m_header.version = data.GetU16(offset_ptr);
-    m_header.cu_offset = data.GetDWARFOffset(offset_ptr);
-    m_header.addr_size = data.GetU8(offset_ptr);
-    m_header.seg_size = data.GetU8(offset_ptr);
-
-    // Try to avoid reading invalid arange sets by making sure:
-    // 1 - the version looks good
-    // 2 - the address byte size looks plausible
-    // 3 - the length seems to make sense
-    // size looks plausible
-    if ((m_header.version >= 2 && m_header.version <= 5) &&
-        (m_header.addr_size == 4 || m_header.addr_size == 8) &&
-        (m_header.length > 0)) {
-      if (data.ValidOffset(m_offset + sizeof(m_header.length) +
-                           m_header.length - 1)) {
-        // The first tuple following the header in each set begins at an offset
-        // that is a multiple of the size of a single tuple (that is, twice the
-        // size of an address). The header is padded, if necessary, to the
-        // appropriate boundary.
-        const uint32_t header_size = *offset_ptr - m_offset;
-        const uint32_t tuple_size = m_header.addr_size << 1;
-        uint32_t first_tuple_offset = 0;
-        while (first_tuple_offset < header_size)
-          first_tuple_offset += tuple_size;
-
-        *offset_ptr = m_offset + first_tuple_offset;
-
-        Descriptor arangeDescriptor;
-
-        static_assert(
-            sizeof(arangeDescriptor.address) == sizeof(arangeDescriptor.length),
-            "DWARFDebugArangeSet::Descriptor.address and "
-            "DWARFDebugArangeSet::Descriptor.length must have same size");
-
-        while (data.ValidOffset(*offset_ptr)) {
-          arangeDescriptor.address =
-              data.GetMaxU64(offset_ptr, m_header.addr_size);
-          arangeDescriptor.length =
-              data.GetMaxU64(offset_ptr, m_header.addr_size);
-
-          // Each set of tuples is terminated by a 0 for the address and 0 for
-          // the length.
-          if (arangeDescriptor.address || arangeDescriptor.length)
-            m_arange_descriptors.push_back(arangeDescriptor);
-          else
-            break; // We are done if we get a zero address and length
-        }
-      }
-#if defined(LLDB_CONFIGURATION_DEBUG)
-      else {
-        printf("warning: .debug_arange set length is too large arange data at "
-               "0x%8.8x: length=0x%8.8x, version=0x%4.4x, cu_offset=0x%8.8x, "
-               "addr_size=%u, seg_size=%u\n",
-               m_offset, m_header.length, m_header.version, m_header.cu_offset,
-               m_header.addr_size, m_header.seg_size);
-      }
-#endif
-    }
-#if defined(LLDB_CONFIGURATION_DEBUG)
-    else {
-      printf("warning: .debug_arange set has bad header at 0x%8.8x: "
-             "length=0x%8.8x, version=0x%4.4x, cu_offset=0x%8.8x, "
-             "addr_size=%u, seg_size=%u\n",
-             m_offset, m_header.length, m_header.version, m_header.cu_offset,
-             m_header.addr_size, m_header.seg_size);
-    }
-#endif
+llvm::Error DWARFDebugArangeSet::extract(const DWARFDataExtractor &data,
+                                         lldb::offset_t *offset_ptr) {
+  assert(data.ValidOffset(*offset_ptr));
 
-    return !m_arange_descriptors.empty();
+  m_arange_descriptors.clear();
+  m_offset = *offset_ptr;
+
+  // 7.20 Address Range Table
+  //
+  // Each set of entries in the table of address ranges contained in the
+  // .debug_aranges section begins with a header consisting of: a 4-byte
+  // length containing the length of the set of entries for this compilation
+  // unit, not including the length field itself; a 2-byte version identifier
+  // containing the value 2 for DWARF Version 2; a 4-byte offset into
+  // the.debug_infosection; a 1-byte unsigned integer containing the size in
+  // bytes of an address (or the offset portion of an address for segmented
+  // addressing) on the target system; and a 1-byte unsigned integer
+  // containing the size in bytes of a segment descriptor on the target
+  // system. This header is followed by a series of tuples. Each tuple
+  // consists of an address and a length, each in the size appropriate for an
+  // address on the target architecture.
+  m_header.length = data.GetDWARFInitialLength(offset_ptr);
+  m_header.version = data.GetU16(offset_ptr);
+  m_header.cu_offset = data.GetDWARFOffset(offset_ptr);
+  m_header.addr_size = data.GetU8(offset_ptr);
+  m_header.seg_size = data.GetU8(offset_ptr);
+
+  // Try to avoid reading invalid arange sets by making sure:
+  // 1 - the version looks good
+  // 2 - the address byte size looks plausible
+  // 3 - the length seems to make sense
+  // size looks plausible
+  if (m_header.version < 2 || m_header.version > 5)
+    return llvm::make_error<llvm::object::GenericBinaryError>(
+        "Invalid arange header version");
+
+  if (m_header.addr_size != 4 && m_header.addr_size != 8)
+    return llvm::make_error<llvm::object::GenericBinaryError>(
+        "Invalid arange header address size");
+
+  if (m_header.length == 0)
+    return llvm::make_error<llvm::object::GenericBinaryError>(
+        "Invalid arange header length");
+
+  if (!data.ValidOffset(m_offset + sizeof(m_header.length) + m_header.length -
+                        1))
+    return llvm::make_error<llvm::object::GenericBinaryError>(
+        "Invalid arange header length");
+
+  // The first tuple following the header in each set begins at an offset
+  // that is a multiple of the size of a single tuple (that is, twice the
+  // size of an address). The header is padded, if necessary, to the
+  // appropriate boundary.
+  const uint32_t header_size = *offset_ptr - m_offset;
+  const uint32_t tuple_size = m_header.addr_size << 1;
+  uint32_t first_tuple_offset = 0;
+  while (first_tuple_offset < header_size)
+    first_tuple_offset += tuple_size;
+
+  *offset_ptr = m_offset + first_tuple_offset;
+
+  Descriptor arangeDescriptor;
+
+  static_assert(sizeof(arangeDescriptor.address) ==
+                    sizeof(arangeDescriptor.length),
+                "DWARFDebugArangeSet::Descriptor.address and "
+                "DWARFDebugArangeSet::Descriptor.length must have same size");
+
+  while (data.ValidOffset(*offset_ptr)) {
+    arangeDescriptor.address = data.GetMaxU64(offset_ptr, m_header.addr_size);
+    arangeDescriptor.length = data.GetMaxU64(offset_ptr, m_header.addr_size);
+
+    // Each set of tuples is terminated by a 0 for the address and 0 for
+    // the length.
+    if (!arangeDescriptor.address && !arangeDescriptor.length)
+      return llvm::ErrorSuccess();
+
+    m_arange_descriptors.push_back(arangeDescriptor);
   }
-  return false;
+
+  return llvm::make_error<llvm::object::GenericBinaryError>(
+      "arange descriptors not terminated by null entry");
 }
 
 dw_offset_t DWARFDebugArangeSet::GetOffsetOfNextEntry() const {
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to