Index: lit/SymbolFile/DWARF/debug_ranges_and_rnglists.test
===================================================================
--- lit/SymbolFile/DWARF/debug_ranges_and_rnglists.test
+++ lit/SymbolFile/DWARF/debug_ranges_and_rnglists.test
@@ -1,5 +1,4 @@
 # REQUIRES: lld
-# XFAIL: *
 
 # RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj %S/debug_ranges.s > %t-ranges.o
 # RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj %S/debug_rnglists.s > %t-rnglists.o
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -361,13 +361,6 @@
   return false;
 }
 
-static dw_offset_t GetRangesOffset(const DWARFDebugRangesBase *debug_ranges,
-                                   DWARFFormValue &form_value) {
-  if (form_value.Form() == DW_FORM_rnglistx)
-    return debug_ranges->GetOffset(form_value.Unsigned());
-  return form_value.Unsigned();
-}
-
 // GetDIENamesAndRanges
 //
 // Gets the valid address ranges for a given DIE by looking for a
@@ -439,15 +432,20 @@
           break;
 
         case DW_AT_ranges: {
-          const DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges();
-          if (debug_ranges)
-            debug_ranges->FindRanges(cu, GetRangesOffset(debug_ranges, form_value), ranges);
+          llvm::Expected<DWARFRangeList> expected_ranges =
+              (form_value.Form() == DW_FORM_rnglistx)
+                  ? cu->FindRnglistFromIndex(form_value.Unsigned())
+                  : cu->FindRnglistFromOffset(form_value.Unsigned());
+          if (expected_ranges)
+            ranges = *expected_ranges;
           else
             cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError(
-                "{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64
-                ") attribute yet DWARF has no .debug_ranges, please file a bug "
+                "{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64 ") attribute, but "
+                "range extraction failed (%s), please file a bug "
                 "and attach the file at the start of this error message",
-                m_offset, form_value.Unsigned());
+                m_offset, form_value.Unsigned(),
+                toString(expected_ranges.takeError()).c_str());
+
         } break;
 
         case DW_AT_name:
@@ -703,14 +701,6 @@
     s.PutCString(" )");
   } break;
 
-  case DW_AT_ranges: {
-    lldb::offset_t ranges_offset =
-        GetRangesOffset(dwarf2Data->DebugRanges(), form_value);
-    dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0;
-    DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(),
-                           &ranges_offset, base_addr);
-  } break;
-
   default:
     break;
   }
@@ -966,13 +956,22 @@
     bool check_specification_or_abstract_origin) const {
   ranges.Clear();
 
-  SymbolFileDWARF *dwarf2Data = cu->GetSymbolFileDWARF();
-
   DWARFFormValue form_value;
   if (GetAttributeValue(cu, DW_AT_ranges, form_value)) {
-    if (DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges())
-      debug_ranges->FindRanges(cu, GetRangesOffset(debug_ranges, form_value),
-                               ranges);
+    llvm::Expected<DWARFRangeList> expected_ranges =
+        (form_value.Form() == DW_FORM_rnglistx)
+            ? cu->FindRnglistFromIndex(form_value.Unsigned())
+            : cu->FindRnglistFromOffset(form_value.Unsigned());
+    if (expected_ranges)
+      ranges = *expected_ranges;
+    else
+      cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError(
+          "{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64 ") attribute, but "
+          "range extraction failed (%s), please file a bug "
+          "and attach the file at the start of this error message",
+          m_offset, form_value.Unsigned(),
+          toString(expected_ranges.takeError()).c_str());
+
   } else if (check_hi_lo_pc) {
     dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
     dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
@@ -1417,45 +1416,38 @@
               ((function_die != nullptr) || (block_die != nullptr));
         }
       } else {
-        DWARFFormValue form_value;
-        if (GetAttributeValue(cu, DW_AT_ranges, form_value)) {
-          DWARFRangeList ranges;
-          SymbolFileDWARF *dwarf2Data = cu->GetSymbolFileDWARF();
-          DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges();
-          debug_ranges->FindRanges(
-              cu, GetRangesOffset(debug_ranges, form_value), ranges);
-
-          if (ranges.FindEntryThatContains(address)) {
-            found_address = true;
-            //  puts("***MATCH***");
-            switch (m_tag) {
-            case DW_TAG_compile_unit: // File
-            case DW_TAG_partial_unit: // File
+        DWARFRangeList ranges;
+        if (GetAttributeAddressRanges(cu, ranges, /*check_hi_lo_pc*/ false) &&
+            ranges.FindEntryThatContains(address)) {
+          found_address = true;
+          //  puts("***MATCH***");
+          switch (m_tag) {
+          case DW_TAG_compile_unit: // File
+          case DW_TAG_partial_unit: // File
               check_children =
                   ((function_die != nullptr) || (block_die != nullptr));
               break;
 
-            case DW_TAG_subprogram: // Function
-              if (function_die)
-                *function_die = this;
-              check_children = (block_die != nullptr);
-              break;
-
-            case DW_TAG_inlined_subroutine: // Inlined Function
-            case DW_TAG_lexical_block:      // Block { } in code
-              if (block_die) {
-                *block_die = this;
-                check_children = true;
-              }
-              break;
+          case DW_TAG_subprogram: // Function
+            if (function_die)
+              *function_die = this;
+            check_children = (block_die != nullptr);
+            break;
 
-            default:
+          case DW_TAG_inlined_subroutine: // Inlined Function
+          case DW_TAG_lexical_block:      // Block { } in code
+            if (block_die) {
+              *block_die = this;
               check_children = true;
-              break;
             }
-          } else {
-            check_children = false;
+            break;
+
+          default:
+            check_children = true;
+            break;
           }
+        } else {
+          check_children = false;
         }
       }
     }
Index: source/Plugins/SymbolFile/DWARF/DWARFUnit.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -205,6 +205,15 @@
 
   DIERef::Section GetDebugSection() const { return m_section; }
 
+  /// Return a list of address ranges resulting from a (possibly encoded)
+  /// range list starting at a given offset in the appropriate ranges section.
+  llvm::Expected<DWARFRangeList> FindRnglistFromOffset(dw_offset_t offset) const;
+
+  /// Return a list of address ranges retrieved from an encoded range
+  /// list whose offset is found via a table lookup given an index (DWARF v5
+  /// and later).
+  llvm::Expected<DWARFRangeList> FindRnglistFromIndex(uint32_t index) const;
+
 protected:
   DWARFUnit(SymbolFileDWARF *dwarf, lldb::user_id_t uid,
             const DWARFUnitHeader &header,
Index: source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -788,3 +788,32 @@
   }
   llvm_unreachable("invalid UnitType.");
 }
+
+llvm::Expected<DWARFRangeList>
+DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) const {
+  const DWARFDebugRangesBase *debug_ranges;
+  llvm::StringRef section;
+  if (GetVersion() <= 4) {
+    debug_ranges = m_dwarf->GetDebugRanges();
+    section = "debug_ranges";
+  } else {
+    debug_ranges = m_dwarf->GetDebugRngLists();
+    section = "debug_rnglists";
+  }
+  if (!debug_ranges)
+    return llvm::make_error<llvm::object::GenericBinaryError>("No " + section +
+                                                              " section");
+
+  DWARFRangeList ranges;
+  debug_ranges->FindRanges(this, offset, ranges);
+  return ranges;
+}
+
+llvm::Expected<DWARFRangeList>
+DWARFUnit::FindRnglistFromIndex(uint32_t index) const {
+  const DWARFDebugRangesBase *debug_rnglists = m_dwarf->GetDebugRngLists();
+  if (!debug_rnglists)
+    return llvm::make_error<llvm::object::GenericBinaryError>(
+        "No debug_rnglists section");
+  return FindRnglistFromOffset(debug_rnglists->GetOffset(index));
+}
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -225,9 +225,8 @@
 
   const DWARFDebugInfo *DebugInfo() const;
 
-  DWARFDebugRangesBase *DebugRanges();
-
-  const DWARFDebugRangesBase *DebugRanges() const;
+  DWARFDebugRangesBase *GetDebugRanges();
+  DWARFDebugRangesBase *GetDebugRngLists();
 
   const lldb_private::DWARFDataExtractor &DebugLocData();
 
@@ -476,6 +475,7 @@
   typedef std::unordered_map<std::string, DIERefSetSP> NameToOffsetMap;
   NameToOffsetMap m_function_scope_qualified_name_map;
   std::unique_ptr<DWARFDebugRangesBase> m_ranges;
+  std::unique_ptr<DWARFDebugRangesBase> m_rnglists;
   UniqueDWARFASTTypeMap m_unique_ast_type_map;
   DIEToTypePtr m_die_to_type;
   DIEToVariableSP m_die_to_variable_sp;
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -359,7 +359,7 @@
       m_context(objfile->GetModule()->GetSectionList(), dwo_section_list),
       m_data_debug_loc(), m_data_debug_ranges(), m_data_debug_rnglists(),
       m_abbr(), m_info(), m_line(), m_fetched_external_modules(false),
-      m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate), m_ranges(),
+      m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate),
       m_unique_ast_type_map() {}
 
 SymbolFileDWARF::~SymbolFileDWARF() {}
@@ -619,16 +619,14 @@
   return nullptr;
 }
 
-DWARFDebugRangesBase *SymbolFileDWARF::DebugRanges() {
-  if (m_ranges == nullptr) {
+DWARFDebugRangesBase *SymbolFileDWARF::GetDebugRanges() {
+  if (!m_ranges) {
     static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
     Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION,
                        static_cast<void *>(this));
 
     if (get_debug_ranges_data().GetByteSize() > 0)
       m_ranges.reset(new DWARFDebugRanges());
-    else if (get_debug_rnglists_data().GetByteSize() > 0)
-      m_ranges.reset(new DWARFDebugRngLists());
 
     if (m_ranges)
       m_ranges->Extract(this);
@@ -636,8 +634,19 @@
   return m_ranges.get();
 }
 
-const DWARFDebugRangesBase *SymbolFileDWARF::DebugRanges() const {
-  return m_ranges.get();
+DWARFDebugRangesBase *SymbolFileDWARF::GetDebugRngLists() {
+  if (!m_rnglists) {
+    static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
+    Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION,
+                       static_cast<void *>(this));
+
+    if (get_debug_rnglists_data().GetByteSize() > 0)
+      m_rnglists.reset(new DWARFDebugRngLists());
+
+    if (m_rnglists)
+      m_rnglists->Extract(this);
+  }
+  return m_rnglists.get();
 }
 
 lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFUnit *dwarf_cu,
@@ -3236,29 +3245,9 @@
           case DW_AT_specification:
             spec_die = form_value.Reference();
             break;
-          case DW_AT_start_scope: {
-            if (form_value.Form() == DW_FORM_sec_offset) {
-              DWARFRangeList dwarf_scope_ranges;
-              const DWARFDebugRangesBase *debug_ranges = DebugRanges();
-              debug_ranges->FindRanges(die.GetCU(),
-                                       form_value.Unsigned(),
-                                       dwarf_scope_ranges);
-            } else {
-              // TODO: Handle the case when DW_AT_start_scope have form
-              // constant. The
-              // dwarf spec is a bit ambiguous about what is the expected
-              // behavior in case the enclosing block have a non coninious
-              // address range and the DW_AT_start_scope entry have a form
-              // constant.
-              GetObjectFile()->GetModule()->ReportWarning(
-                  "0x%8.8" PRIx64
-                  ": DW_AT_start_scope has unsupported form type (0x%x)\n",
-                  die.GetID(), form_value.Form());
-            }
-
-            scope_ranges.Sort();
-            scope_ranges.CombineConsecutiveRanges();
-          } break;
+          case DW_AT_start_scope:
+            // TODO: Implement this.
+            break;
           case DW_AT_artificial:
             is_artificial = form_value.Boolean();
             break;