This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rG7c603a41e20f: lldb/minidump: Refactor memory region 
computation code (authored by labath).
Herald added a project: LLDB.

Changed prior to commit:
  https://reviews.llvm.org/D69035?vs=225212&id=226511#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D69035

Files:
  lldb/include/lldb/Target/MemoryRegionInfo.h
  lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
  lldb/source/Plugins/Process/minidump/MinidumpParser.h
  lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
  lldb/source/Plugins/Process/minidump/ProcessMinidump.h
  lldb/source/Target/CMakeLists.txt
  lldb/source/Target/MemoryRegionInfo.cpp
  lldb/test/Shell/Minidump/memory-region.yaml
  lldb/unittests/Process/minidump/MinidumpParserTest.cpp

Index: lldb/unittests/Process/minidump/MinidumpParserTest.cpp
===================================================================
--- lldb/unittests/Process/minidump/MinidumpParserTest.cpp
+++ lldb/unittests/Process/minidump/MinidumpParserTest.cpp
@@ -332,34 +332,6 @@
   EXPECT_FALSE(parser->FindMemoryRange(0x7ffe0000 + 4096).hasValue());
 }
 
-void check_region(MinidumpParser &parser, lldb::addr_t addr, lldb::addr_t start,
-                  lldb::addr_t end, MemoryRegionInfo::OptionalBool read,
-                  MemoryRegionInfo::OptionalBool write,
-                  MemoryRegionInfo::OptionalBool exec,
-                  MemoryRegionInfo::OptionalBool mapped,
-                  ConstString name = ConstString()) {
-  SCOPED_TRACE(addr);
-  auto range_info = parser.GetMemoryRegionInfo(addr);
-  EXPECT_EQ(start, range_info.GetRange().GetRangeBase());
-  EXPECT_EQ(end, range_info.GetRange().GetRangeEnd());
-  EXPECT_EQ(read, range_info.GetReadable());
-  EXPECT_EQ(write, range_info.GetWritable());
-  EXPECT_EQ(exec, range_info.GetExecutable());
-  EXPECT_EQ(mapped, range_info.GetMapped());
-  EXPECT_EQ(name, range_info.GetName());
-}
-
-// Same as above function where addr == start
-void check_region(MinidumpParser &parser, lldb::addr_t start, lldb::addr_t end,
-                  MemoryRegionInfo::OptionalBool read,
-                  MemoryRegionInfo::OptionalBool write,
-                  MemoryRegionInfo::OptionalBool exec,
-                  MemoryRegionInfo::OptionalBool mapped,
-                  ConstString name = ConstString()) {
-  check_region(parser, start, start, end, read, write, exec, mapped, name);
-}
-
-
 constexpr auto yes = MemoryRegionInfo::eYes;
 constexpr auto no = MemoryRegionInfo::eNo;
 constexpr auto unknown = MemoryRegionInfo::eDontKnow;
@@ -378,17 +350,7 @@
         Type:            [  ]
       - Base Address:    0x0000000000010000
         Allocation Protect: [ PAGE_READ_WRITE ]
-        Region Size:     0x0000000000010000
-        State:           [ MEM_COMMIT ]
-        Type:            [ MEM_MAPPED ]
-      - Base Address:    0x0000000000020000
-        Allocation Protect: [ PAGE_READ_WRITE ]
-        Region Size:     0x0000000000010000
-        State:           [ MEM_COMMIT ]
-        Type:            [ MEM_MAPPED ]
-      - Base Address:    0x0000000000030000
-        Allocation Protect: [ PAGE_READ_WRITE ]
-        Region Size:     0x0000000000001000
+        Region Size:     0x0000000000021000
         State:           [ MEM_COMMIT ]
         Type:            [ MEM_MAPPED ]
       - Base Address:    0x0000000000040000
@@ -413,21 +375,20 @@
 )"),
                     llvm::Succeeded());
 
-  check_region(*parser, 0x00000000, 0x00010000, no, no, no, no);
-  check_region(*parser, 0x00010000, 0x00020000, yes, yes, no, yes);
-  check_region(*parser, 0x00020000, 0x00030000, yes, yes, no, yes);
-  check_region(*parser, 0x00030000, 0x00031000, yes, yes, no, yes);
-  check_region(*parser, 0x00031000, 0x00040000, no, no, no, no);
-  check_region(*parser, 0x00040000, 0x00041000, yes, no, no, yes);
-
-  // Check addresses contained inside ranges
-  check_region(*parser, 0x00000001, 0x00000000, 0x00010000, no, no, no, no);
-  check_region(*parser, 0x0000ffff, 0x00000000, 0x00010000, no, no, no, no);
-  check_region(*parser, 0x00010001, 0x00010000, 0x00020000, yes, yes, no, yes);
-  check_region(*parser, 0x0001ffff, 0x00010000, 0x00020000, yes, yes, no, yes);
-
-  // Test that an address after the last entry maps to rest of the memory space
-  check_region(*parser, 0x7fff0000, 0x7fff0000, UINT64_MAX, no, no, no, no);
+  EXPECT_THAT(
+      parser->BuildMemoryRegions(),
+      testing::Pair(testing::ElementsAre(
+                        MemoryRegionInfo({0x0, 0x10000}, no, no, no, no,
+                                         ConstString(), unknown, 0),
+                        MemoryRegionInfo({0x10000, 0x21000}, yes, yes, no, yes,
+                                         ConstString(), unknown, 0),
+                        MemoryRegionInfo({0x40000, 0x1000}, yes, no, no, yes,
+                                         ConstString(), unknown, 0),
+                        MemoryRegionInfo({0x7ffe0000, 0x1000}, yes, no, no, yes,
+                                         ConstString(), unknown, 0),
+                        MemoryRegionInfo({0x7ffe1000, 0xf000}, no, no, no, yes,
+                                         ConstString(), unknown, 0)),
+                    true));
 }
 
 TEST_F(MinidumpParserTest, GetMemoryRegionInfoFromMemoryList) {
@@ -443,30 +404,33 @@
 ...
 )"),
                     llvm::Succeeded());
+
   // Test we can get memory regions from the MINIDUMP_MEMORY_LIST stream when
   // we don't have a MemoryInfoListStream.
 
-  // Test addres before the first entry comes back with nothing mapped up
-  // to first valid region info
-  check_region(*parser, 0x00000000, 0x00001000, no, no, no, no);
-  check_region(*parser, 0x00001000, 0x00001010, yes, unknown, unknown, yes);
-  check_region(*parser, 0x00001010, 0x00002000, no, no, no, no);
-  check_region(*parser, 0x00002000, 0x00002020, yes, unknown, unknown, yes);
-  check_region(*parser, 0x00002020, UINT64_MAX, no, no, no, no);
+  EXPECT_THAT(
+      parser->BuildMemoryRegions(),
+      testing::Pair(testing::ElementsAre(
+                        MemoryRegionInfo({0x1000, 0x10}, yes, unknown, unknown,
+                                         yes, ConstString(), unknown, 0),
+                        MemoryRegionInfo({0x2000, 0x20}, yes, unknown, unknown,
+                                         yes, ConstString(), unknown, 0)),
+                    false));
 }
 
 TEST_F(MinidumpParserTest, GetMemoryRegionInfoFromMemory64List) {
   SetUpData("regions-memlist64.dmp");
+
   // Test we can get memory regions from the MINIDUMP_MEMORY64_LIST stream when
   // we don't have a MemoryInfoListStream.
-
-  // Test addres before the first entry comes back with nothing mapped up
-  // to first valid region info
-  check_region(*parser, 0x00000000, 0x00001000, no, no, no, no);
-  check_region(*parser, 0x00001000, 0x00001010, yes, unknown, unknown, yes);
-  check_region(*parser, 0x00001010, 0x00002000, no, no, no, no);
-  check_region(*parser, 0x00002000, 0x00002020, yes, unknown, unknown, yes);
-  check_region(*parser, 0x00002020, UINT64_MAX, no, no, no, no);
+  EXPECT_THAT(
+      parser->BuildMemoryRegions(),
+      testing::Pair(testing::ElementsAre(
+                        MemoryRegionInfo({0x1000, 0x10}, yes, unknown, unknown,
+                                         yes, ConstString(), unknown, 0),
+                        MemoryRegionInfo({0x2000, 0x20}, yes, unknown, unknown,
+                                         yes, ConstString(), unknown, 0)),
+                    false));
 }
 
 TEST_F(MinidumpParserTest, GetMemoryRegionInfoLinuxMaps) {
@@ -478,57 +442,34 @@
       400d9000-400db000 r-xp 00000000 b3:04 227        /system/bin/app_process
       400db000-400dc000 r--p 00001000 b3:04 227        /system/bin/app_process
       400dc000-400dd000 rw-p 00000000 00:00 0
-      400dd000-400ec000 r-xp 00000000 b3:04 300        /system/bin/linker
       400ec000-400ed000 r--p 00000000 00:00 0
-      400ed000-400ee000 r--p 0000f000 b3:04 300        /system/bin/linker
       400ee000-400ef000 rw-p 00010000 b3:04 300        /system/bin/linker
-      400ef000-400fb000 rw-p 00000000 00:00 0
-      400fb000-400fc000 r-xp 00000000 b3:04 1096       /system/lib/liblog.so
       400fc000-400fd000 rwxp 00001000 b3:04 1096       /system/lib/liblog.so
-      400fd000-400ff000 r-xp 00002000 b3:04 1096       /system/lib/liblog.so
-      400ff000-40100000 r--p 00003000 b3:04 1096       /system/lib/liblog.so
-      40100000-40101000 rw-p 00004000 b3:04 1096       /system/lib/liblog.so
-      40101000-40122000 r-xp 00000000 b3:04 955        /system/lib/libc.so
-      40122000-40123000 rwxp 00021000 b3:04 955        /system/lib/libc.so
-      40123000-40167000 r-xp 00022000 b3:04 955        /system/lib/libc.so
-      40167000-40169000 r--p 00065000 b3:04 955        /system/lib/libc.so
-      40169000-4016b000 rw-p 00067000 b3:04 955        /system/lib/libc.so
-      4016b000-40176000 rw-p 00000000 00:00 0
 
 ...
 )"),
                     llvm::Succeeded());
   // Test we can get memory regions from the linux /proc/<pid>/maps stream when
   // we don't have a MemoryInfoListStream.
-
-  // Test addres before the first entry comes back with nothing mapped up
-  // to first valid region info
-  ConstString a("/system/bin/app_process");
-  ConstString b("/system/bin/linker");
-  ConstString c("/system/lib/liblog.so");
-  ConstString d("/system/lib/libc.so");
-  ConstString n;
-  check_region(*parser, 0x00000000, 0x400d9000, no, no, no, no, n);
-  check_region(*parser, 0x400d9000, 0x400db000, yes, no, yes, yes, a);
-  check_region(*parser, 0x400db000, 0x400dc000, yes, no, no, yes, a);
-  check_region(*parser, 0x400dc000, 0x400dd000, yes, yes, no, yes, n);
-  check_region(*parser, 0x400dd000, 0x400ec000, yes, no, yes, yes, b);
-  check_region(*parser, 0x400ec000, 0x400ed000, yes, no, no, yes, n);
-  check_region(*parser, 0x400ed000, 0x400ee000, yes, no, no, yes, b);
-  check_region(*parser, 0x400ee000, 0x400ef000, yes, yes, no, yes, b);
-  check_region(*parser, 0x400ef000, 0x400fb000, yes, yes, no, yes, n);
-  check_region(*parser, 0x400fb000, 0x400fc000, yes, no, yes, yes, c);
-  check_region(*parser, 0x400fc000, 0x400fd000, yes, yes, yes, yes, c);
-  check_region(*parser, 0x400fd000, 0x400ff000, yes, no, yes, yes, c);
-  check_region(*parser, 0x400ff000, 0x40100000, yes, no, no, yes, c);
-  check_region(*parser, 0x40100000, 0x40101000, yes, yes, no, yes, c);
-  check_region(*parser, 0x40101000, 0x40122000, yes, no, yes, yes, d);
-  check_region(*parser, 0x40122000, 0x40123000, yes, yes, yes, yes, d);
-  check_region(*parser, 0x40123000, 0x40167000, yes, no, yes, yes, d);
-  check_region(*parser, 0x40167000, 0x40169000, yes, no, no, yes, d);
-  check_region(*parser, 0x40169000, 0x4016b000, yes, yes, no, yes, d);
-  check_region(*parser, 0x4016b000, 0x40176000, yes, yes, no, yes, n);
-  check_region(*parser, 0x40176000, UINT64_MAX, no, no, no, no, n);
+  ConstString app_process("/system/bin/app_process");
+  ConstString linker("/system/bin/linker");
+  ConstString liblog("/system/lib/liblog.so");
+  EXPECT_THAT(
+      parser->BuildMemoryRegions(),
+      testing::Pair(testing::ElementsAre(
+                        MemoryRegionInfo({0x400d9000, 0x2000}, yes, no, yes,
+                                         yes, app_process, unknown, 0),
+                        MemoryRegionInfo({0x400db000, 0x1000}, yes, no, no, yes,
+                                         app_process, unknown, 0),
+                        MemoryRegionInfo({0x400dc000, 0x1000}, yes, yes, no,
+                                         yes, ConstString(), unknown, 0),
+                        MemoryRegionInfo({0x400ec000, 0x1000}, yes, no, no, yes,
+                                         ConstString(), unknown, 0),
+                        MemoryRegionInfo({0x400ee000, 0x1000}, yes, yes, no,
+                                         yes, linker, unknown, 0),
+                        MemoryRegionInfo({0x400fc000, 0x1000}, yes, yes, yes,
+                                         yes, liblog, unknown, 0)),
+                    true));
 }
 
 // Windows Minidump tests
Index: lldb/test/Shell/Minidump/memory-region.yaml
===================================================================
--- /dev/null
+++ lldb/test/Shell/Minidump/memory-region.yaml
@@ -0,0 +1,49 @@
+# Check that memory region parsing works correctly, with a particular emphasis
+# on the boundary conditions.
+
+# RUN: yaml2obj %s > %t
+# RUN: %lldb -b -c %t \
+# RUN:   -o "memory region 0" -o "memory region 0xd9000" \
+# RUN:   -o "memory region 0xd9001" -o "memory region 0xdafff" \
+# RUN:   -o "memory region 0xdb000" -o "memory region 0xdd000" | FileCheck %s
+
+# CHECK-LABEL: (lldb) memory region 0
+# CHECK: [0x0000000000000000-0x00000000000d9000) ---
+# CHECK-LABEL: (lldb) memory region 0xd9000
+# CHECK: [0x00000000000d9000-0x00000000000db000) r-x /system/bin/app_process
+# CHECK-LABEL: (lldb) memory region 0xd9001
+# CHECK: [0x00000000000d9000-0x00000000000db000) r-x /system/bin/app_process
+# CHECK-LABEL: (lldb) memory region 0xdafff
+# CHECK: [0x00000000000d9000-0x00000000000db000) r-x /system/bin/app_process
+# CHECK-LABEL: (lldb) memory region 0xdb000
+# CHECK: [0x00000000000db000-0x00000000000dc000) ---
+# CHECK-LABEL: (lldb) memory region 0xdd000
+# CHECK: [0x00000000000dd000-0xffffffffffffffff) ---
+
+--- !minidump
+Streams:         
+  - Type:            SystemInfo
+    Processor Arch:  AMD64
+    Platform ID:     Linux
+    CPU:             
+      Vendor ID:       GenuineIntel
+      Version Info:    0x00000000
+      Feature Info:    0x00000000
+  - Type:            LinuxProcStatus
+    Text:             |
+      Name:	nonexisting-module
+      State:	t (tracing stop)
+      Tgid:	29939
+      Ngid:	0
+      Pid:	29939
+      PPid:	29370
+      TracerPid:	29940
+      Uid:	1001	1001	1001	1001
+      Gid:	1001	1001	1001	1001
+
+  - Type:            LinuxMaps
+    Text:             |
+      000d9000-000db000 r-xp 00000000 b3:04 227        /system/bin/app_process
+      000dc000-000dd000 rw-p 00000000 00:00 0
+
+...
Index: lldb/source/Target/MemoryRegionInfo.cpp
===================================================================
--- /dev/null
+++ lldb/source/Target/MemoryRegionInfo.cpp
@@ -0,0 +1,20 @@
+//===-- MemoryRegionInfo.cpp ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/MemoryRegionInfo.h"
+
+llvm::raw_ostream &lldb_private::operator<<(llvm::raw_ostream &OS,
+                                            const MemoryRegionInfo &Info) {
+  return OS << llvm::formatv("MemoryRegionInfo([{0}, {1}), {2}, {3}, {4}, {5}, "
+                             "`{6}`, {7}, {8})",
+                             Info.GetRange().GetRangeBase(),
+                             Info.GetRange().GetRangeEnd(), Info.GetReadable(),
+                             Info.GetWritable(), Info.GetExecutable(),
+                             Info.GetMapped(), Info.GetName(), Info.GetFlash(),
+                             Info.GetBlocksize());
+}
Index: lldb/source/Target/CMakeLists.txt
===================================================================
--- lldb/source/Target/CMakeLists.txt
+++ lldb/source/Target/CMakeLists.txt
@@ -17,6 +17,7 @@
   LanguageRuntime.cpp
   Memory.cpp
   MemoryHistory.cpp
+  MemoryRegionInfo.cpp
   ModuleCache.cpp
   OperatingSystem.cpp
   PathMappingList.cpp
Index: lldb/source/Plugins/Process/minidump/ProcessMinidump.h
===================================================================
--- lldb/source/Plugins/Process/minidump/ProcessMinidump.h
+++ lldb/source/Plugins/Process/minidump/ProcessMinidump.h
@@ -111,6 +111,9 @@
   const minidump::ExceptionStream *m_active_exception;
   lldb::CommandObjectSP m_command_sp;
   bool m_is_wow64;
+  llvm::Optional<MemoryRegionInfos> m_memory_regions;
+
+  void BuildMemoryRegions();
 };
 
 } // namespace minidump
Index: lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
===================================================================
--- lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -334,15 +334,46 @@
   return ArchSpec(triple);
 }
 
+void ProcessMinidump::BuildMemoryRegions() {
+  if (m_memory_regions)
+    return;
+  m_memory_regions.emplace();
+  bool is_complete;
+  std::tie(*m_memory_regions, is_complete) =
+      m_minidump_parser->BuildMemoryRegions();
+  // TODO: Use loaded modules to complete the region list.
+}
+
 Status ProcessMinidump::GetMemoryRegionInfo(lldb::addr_t load_addr,
-                                            MemoryRegionInfo &range_info) {
-  range_info = m_minidump_parser->GetMemoryRegionInfo(load_addr);
+                                            MemoryRegionInfo &region) {
+  BuildMemoryRegions();
+  auto pos = llvm::upper_bound(*m_memory_regions, load_addr);
+  if (pos != m_memory_regions->begin() &&
+      std::prev(pos)->GetRange().Contains(load_addr)) {
+    region = *std::prev(pos);
+    return Status();
+  }
+
+  if (pos == m_memory_regions->begin())
+    region.GetRange().SetRangeBase(0);
+  else
+    region.GetRange().SetRangeBase(std::prev(pos)->GetRange().GetRangeEnd());
+
+  if (pos == m_memory_regions->end())
+    region.GetRange().SetRangeEnd(UINT64_MAX);
+  else
+    region.GetRange().SetRangeEnd(pos->GetRange().GetRangeBase());
+
+  region.SetReadable(MemoryRegionInfo::eNo);
+  region.SetWritable(MemoryRegionInfo::eNo);
+  region.SetExecutable(MemoryRegionInfo::eNo);
+  region.SetMapped(MemoryRegionInfo::eNo);
   return Status();
 }
 
-Status ProcessMinidump::GetMemoryRegions(
-    lldb_private::MemoryRegionInfos &region_list) {
-  region_list = m_minidump_parser->GetMemoryRegions();
+Status ProcessMinidump::GetMemoryRegions(MemoryRegionInfos &region_list) {
+  BuildMemoryRegions();
+  region_list = *m_memory_regions;
   return Status();
 }
 
Index: lldb/source/Plugins/Process/minidump/MinidumpParser.h
===================================================================
--- lldb/source/Plugins/Process/minidump/MinidumpParser.h
+++ lldb/source/Plugins/Process/minidump/MinidumpParser.h
@@ -88,9 +88,9 @@
 
   llvm::ArrayRef<uint8_t> GetMemory(lldb::addr_t addr, size_t size);
 
-  MemoryRegionInfo GetMemoryRegionInfo(lldb::addr_t load_addr);
-
-  const MemoryRegionInfos &GetMemoryRegions();
+  /// Returns a list of memory regions and a flag indicating whether the list is
+  /// complete (includes all regions mapped into the process memory).
+  std::pair<MemoryRegionInfos, bool> BuildMemoryRegions();
 
   static llvm::StringRef GetStreamTypeAsString(StreamType stream_type);
 
@@ -100,14 +100,10 @@
   MinidumpParser(lldb::DataBufferSP data_sp,
                  std::unique_ptr<llvm::object::MinidumpFile> file);
 
-  MemoryRegionInfo FindMemoryRegion(lldb::addr_t load_addr) const;
-
 private:
   lldb::DataBufferSP m_data_sp;
   std::unique_ptr<llvm::object::MinidumpFile> m_file;
   ArchSpec m_arch;
-  MemoryRegionInfos m_regions;
-  bool m_parsed_regions = false;
 };
 
 } // end namespace minidump
Index: lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
===================================================================
--- lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
+++ lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
@@ -518,58 +518,26 @@
   return !regions.empty();
 }
 
-MemoryRegionInfo
-MinidumpParser::FindMemoryRegion(lldb::addr_t load_addr) const {
-  auto begin = m_regions.begin();
-  auto end = m_regions.end();
-  auto pos = std::lower_bound(begin, end, load_addr);
-  if (pos != end && pos->GetRange().Contains(load_addr))
-    return *pos;
-  
-  MemoryRegionInfo region;
-  if (pos == begin)
-    region.GetRange().SetRangeBase(0);
-  else {
-    auto prev = pos - 1;
-    if (prev->GetRange().Contains(load_addr))
-      return *prev;
-    region.GetRange().SetRangeBase(prev->GetRange().GetRangeEnd());
-  }
-  if (pos == end)
-    region.GetRange().SetRangeEnd(UINT64_MAX);
-  else
-    region.GetRange().SetRangeEnd(pos->GetRange().GetRangeBase());
-  region.SetReadable(MemoryRegionInfo::eNo);
-  region.SetWritable(MemoryRegionInfo::eNo);
-  region.SetExecutable(MemoryRegionInfo::eNo);
-  region.SetMapped(MemoryRegionInfo::eNo);
-  return region;
-}
-
-MemoryRegionInfo
-MinidumpParser::GetMemoryRegionInfo(lldb::addr_t load_addr) {
-  if (!m_parsed_regions)
-    GetMemoryRegions();
-  return FindMemoryRegion(load_addr);
-}
-
-const MemoryRegionInfos &MinidumpParser::GetMemoryRegions() {
-  if (!m_parsed_regions) {
-    m_parsed_regions = true;
-    // We haven't cached our memory regions yet we will create the region cache
-    // once. We create the region cache using the best source. We start with
-    // the linux maps since they are the most complete and have names for the
-    // regions. Next we try the MemoryInfoList since it has
-    // read/write/execute/map data, and then fall back to the MemoryList and
-    // Memory64List to just get a list of the memory that is mapped in this
-    // core file
-    if (!CreateRegionsCacheFromLinuxMaps(*this, m_regions))
-      if (!CreateRegionsCacheFromMemoryInfoList(*this, m_regions))
-        if (!CreateRegionsCacheFromMemoryList(*this, m_regions))
-          CreateRegionsCacheFromMemory64List(*this, m_regions);
-    llvm::sort(m_regions.begin(), m_regions.end());
-  }
-  return m_regions;
+std::pair<MemoryRegionInfos, bool> MinidumpParser::BuildMemoryRegions() {
+  // We create the region cache using the best source. We start with
+  // the linux maps since they are the most complete and have names for the
+  // regions. Next we try the MemoryInfoList since it has
+  // read/write/execute/map data, and then fall back to the MemoryList and
+  // Memory64List to just get a list of the memory that is mapped in this
+  // core file
+  MemoryRegionInfos result;
+  const auto &return_sorted = [&](bool is_complete) {
+    llvm::sort(result);
+    return std::make_pair(std::move(result), is_complete);
+  };
+  if (CreateRegionsCacheFromLinuxMaps(*this, result))
+    return return_sorted(true);
+  if (CreateRegionsCacheFromMemoryInfoList(*this, result))
+    return return_sorted(true);
+  if (CreateRegionsCacheFromMemoryList(*this, result))
+    return return_sorted(false);
+  CreateRegionsCacheFromMemory64List(*this, result);
+  return return_sorted(false);
 }
 
 #define ENUM_TO_CSTR(ST)                                                       \
Index: lldb/include/lldb/Target/MemoryRegionInfo.h
===================================================================
--- lldb/include/lldb/Target/MemoryRegionInfo.h
+++ lldb/include/lldb/Target/MemoryRegionInfo.h
@@ -21,11 +21,13 @@
 
   enum OptionalBool { eDontKnow = -1, eNo = 0, eYes = 1 };
 
-  MemoryRegionInfo()
-      : m_range(), m_read(eDontKnow), m_write(eDontKnow), m_execute(eDontKnow),
-        m_mapped(eDontKnow), m_flash(eDontKnow), m_blocksize(0) {}
-
-  ~MemoryRegionInfo() {}
+  MemoryRegionInfo() = default;
+  MemoryRegionInfo(RangeType range, OptionalBool read, OptionalBool write,
+                   OptionalBool execute, OptionalBool mapped, ConstString name,
+                   OptionalBool flash, lldb::offset_t blocksize)
+      : m_range(range), m_read(read), m_write(write), m_execute(execute),
+        m_mapped(mapped), m_name(name), m_flash(flash), m_blocksize(blocksize) {
+  }
 
   RangeType &GetRange() { return m_range; }
 
@@ -88,20 +90,21 @@
   bool operator==(const MemoryRegionInfo &rhs) const {
     return m_range == rhs.m_range && m_read == rhs.m_read &&
            m_write == rhs.m_write && m_execute == rhs.m_execute &&
-           m_mapped == rhs.m_mapped;
+           m_mapped == rhs.m_mapped && m_name == rhs.m_name &&
+           m_flash == rhs.m_flash && m_blocksize == rhs.m_blocksize;
   }
 
   bool operator!=(const MemoryRegionInfo &rhs) const { return !(*this == rhs); }
 
 protected:
   RangeType m_range;
-  OptionalBool m_read;
-  OptionalBool m_write;
-  OptionalBool m_execute;
-  OptionalBool m_mapped;
+  OptionalBool m_read = eDontKnow;
+  OptionalBool m_write = eDontKnow;
+  OptionalBool m_execute = eDontKnow;
+  OptionalBool m_mapped = eDontKnow;
   ConstString m_name;
-  OptionalBool m_flash;
-  lldb::offset_t m_blocksize;
+  OptionalBool m_flash = eDontKnow;
+  lldb::offset_t m_blocksize = 0;
 };
   
 inline bool operator<(const MemoryRegionInfo &lhs,
@@ -117,6 +120,9 @@
   return lhs < rhs.GetRange().GetRangeBase();
 }
 
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+                              const MemoryRegionInfo &Info);
+
 // Forward-declarable wrapper.
 class MemoryRegionInfos : public std::vector<lldb_private::MemoryRegionInfo> {
 public:
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to