2020#include  < algorithm> 
2121#include  < map> 
2222#include  < optional> 
23- #include  < vector> 
2423#include  < utility> 
24+ #include  < vector> 
2525
2626using  namespace  lldb_private ; 
2727using  namespace  minidump ; 
@@ -75,8 +75,7 @@ UUID MinidumpParser::GetModuleUUID(const minidump::Module *module) {
7575    if  (GetArchitecture ().GetTriple ().isOSBinFormatELF ()) {
7676      if  (pdb70_uuid->Age  != 0 )
7777        return  UUID (pdb70_uuid, sizeof (*pdb70_uuid));
78-       return  UUID (&pdb70_uuid->Uuid ,
79-                                     sizeof (pdb70_uuid->Uuid ));
78+       return  UUID (&pdb70_uuid->Uuid , sizeof (pdb70_uuid->Uuid ));
8079    }
8180    return  UUID (*pdb70_uuid);
8281  } else  if  (cv_signature == CvSignature::ElfBuildId)
@@ -429,62 +428,65 @@ MinidumpParser::GetExceptionStreams() {
429428
430429std::optional<minidump::Range>
431430MinidumpParser::FindMemoryRange (lldb::addr_t  addr) {
432-   Log *log = GetLog (LLDBLog::Modules);
431+   if  (m_memory_ranges.IsEmpty ())
432+     PopulateMemoryRanges ();
433+ 
434+   const  MemoryRangeVector::Entry *entry =
435+       m_memory_ranges.FindEntryThatContains (addr);
436+   if  (!entry)
437+     return  std::nullopt ;
433438
439+   return  entry->data ;
440+ }
441+ 
442+ void  MinidumpParser::PopulateMemoryRanges () {
443+   Log *log = GetLog (LLDBLog::Modules);
434444  auto  ExpectedMemory = GetMinidumpFile ().getMemoryList ();
435-   if  (!ExpectedMemory) {
436-     LLDB_LOG_ERROR (log, ExpectedMemory.takeError (),
437-                    " Failed to read memory list: {0}"  );
438-   } else  {
445+   if  (ExpectedMemory) {
439446    for  (const  auto  &memory_desc : *ExpectedMemory) {
440447      const  LocationDescriptor &loc_desc = memory_desc.Memory ;
441448      const  lldb::addr_t  range_start = memory_desc.StartOfMemoryRange ;
442449      const  size_t  range_size = loc_desc.DataSize ;
443- 
444-       if  (loc_desc.RVA  + loc_desc.DataSize  > GetData ().size ())
445-         return  std::nullopt ;
446- 
447-       if  (range_start <= addr && addr < range_start + range_size) {
448-         auto  ExpectedSlice = GetMinidumpFile ().getRawData (loc_desc);
449-         if  (!ExpectedSlice) {
450-           LLDB_LOG_ERROR (log, ExpectedSlice.takeError (),
451-                          " Failed to get memory slice: {0}"  );
452-           return  std::nullopt ;
453-         }
454-         return  minidump::Range (range_start, *ExpectedSlice);
450+       auto  ExpectedSlice = GetMinidumpFile ().getRawData (loc_desc);
451+       if  (!ExpectedSlice) {
452+         LLDB_LOG_ERROR (log, ExpectedSlice.takeError (),
453+                        " Failed to get memory slice: {0}"  );
454+         continue ;
455455      }
456+       m_memory_ranges.Append (MemoryRangeVector::Entry (
457+           range_start, range_size,
458+           minidump::Range (range_start, *ExpectedSlice)));
456459    }
460+   } else  {
461+     LLDB_LOG_ERROR (log, ExpectedMemory.takeError (),
462+                    " Failed to read memory list: {0}"  );
457463  }
458464
459465  if  (!GetStream (StreamType::Memory64List).empty ()) {
460466    llvm::Error err = llvm::Error::success ();
461-     for  (const  auto  &memory_desc :   GetMinidumpFile ().getMemory64List (err)) {
462-       if  (memory_desc. first . StartOfMemoryRange  <= addr  
463-           && addr <  memory_desc.first .StartOfMemoryRange  +  memory_desc.first .DataSize ) { 
464-         return   minidump::Range (memory_desc.first .StartOfMemoryRange , memory_desc. second ); 
465-       } 
467+     for  (const  auto  &memory_desc : GetMinidumpFile ().getMemory64List (err)) {
468+       m_memory_ranges. Append ( MemoryRangeVector::Entry ( 
469+           memory_desc.first .StartOfMemoryRange ,  memory_desc.first .DataSize , 
470+            minidump::Range (memory_desc.first .StartOfMemoryRange ,
471+                           memory_desc. second ))); 
466472    }
467473
468474    if  (err)
469475      LLDB_LOG_ERROR (log, std::move (err), " Failed to read memory64 list: {0}"  );
470476  }
471477
472-   return  std:: nullopt ;
478+   m_memory_ranges. Sort () ;
473479}
474480
475481llvm::ArrayRef<uint8_t > MinidumpParser::GetMemory (lldb::addr_t  addr,
476482                                                  size_t  size) {
477-   //  I don't have a sense of how frequently this is called or how many memory
478-   //  ranges a Minidump typically has, so I'm not sure if searching for the
479-   //  appropriate range linearly each time is stupid.  Perhaps we should build
480-   //  an index for faster lookups.
481483  std::optional<minidump::Range> range = FindMemoryRange (addr);
482484  if  (!range)
483485    return  {};
484486
485487  //  There's at least some overlap between the beginning of the desired range
486-   //  (addr) and the current range.  Figure out where the overlap begins and how 
487-   //  much overlap there is.
488+   //  (addr) and the current range.  Figure out where the overlap begins and
489+   //  how  much overlap there is.
488490
489491  const  size_t  offset = addr - range->start ;
490492
@@ -495,7 +497,8 @@ llvm::ArrayRef<uint8_t> MinidumpParser::GetMemory(lldb::addr_t addr,
495497  return  range->range_ref .slice (offset, overlap);
496498}
497499
498- llvm::iterator_range<FallibleMemory64Iterator> MinidumpParser::GetMemory64Iterator (llvm::Error &err) {
500+ llvm::iterator_range<FallibleMemory64Iterator>
501+ MinidumpParser::GetMemory64Iterator (llvm::Error &err) {
499502  llvm::ErrorAsOutParameter ErrAsOutParam (&err);
500503  return  m_file->getMemory64List (err);
501504}
@@ -607,8 +610,7 @@ std::pair<MemoryRegionInfos, bool> MinidumpParser::BuildMemoryRegions() {
607610  case  StreamType::ST:                                                         \
608611    return  #ST
609612
610- llvm::StringRef
611- MinidumpParser::GetStreamTypeAsString (StreamType stream_type) {
613+ llvm::StringRef MinidumpParser::GetStreamTypeAsString (StreamType stream_type) {
612614  switch  (stream_type) {
613615    ENUM_TO_CSTR (Unused);
614616    ENUM_TO_CSTR (ThreadList);
0 commit comments