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