public int GetChunkContainingAddress(ulong address) { MinidumpMemoryChunk targetChunk = new MinidumpMemoryChunk { TargetStartAddress = address }; int index = Array.BinarySearch(_chunks, targetChunk); if (index >= 0) { Debug.Assert(_chunks[index].TargetStartAddress == address); return(index); // exact match will contain the address } if (~index != 0) { int possibleIndex = Math.Min(_chunks.Length, ~index) - 1; if (_chunks[possibleIndex].TargetStartAddress <= address && _chunks[possibleIndex].TargetEndAddress > address) { return(possibleIndex); } } return(-1); }
public void InitFromMemoryList() { _memoryList = new MinidumpMemoryList(_dumpStream); uint count = _memoryList.Count; MINIDUMP_MEMORY_DESCRIPTOR tempMD; List <MinidumpMemoryChunk> chunks = new List <MinidumpMemoryChunk>(); for (ulong i = 0; i < count; i++) { MinidumpMemoryChunk chunk = new MinidumpMemoryChunk(); tempMD = _memoryList.GetElement((uint)i); if (tempMD.Memory.DataSize > 0) { chunk.Size = tempMD.Memory.DataSize; chunk.TargetStartAddress = tempMD.StartOfMemoryRange; chunk.TargetEndAddress = tempMD.StartOfMemoryRange + tempMD.Memory.DataSize; chunk.RVA = tempMD.Memory.Rva.Value; chunks.Add(chunk); } } chunks.Sort(); SplitAndMergeChunks(chunks); _chunks = chunks.ToArray(); Count = (ulong)chunks.Count; ValidateChunks(); }
private void InitFromMemory64List() { _memory64List = new MinidumpMemory64List(_dumpStream); RVA64 currentRVA = _memory64List.BaseRva; ulong count = _memory64List.Count; // Initialize all chunks. MINIDUMP_MEMORY_DESCRIPTOR64 tempMD; List <MinidumpMemoryChunk> chunks = new List <MinidumpMemoryChunk>(); for (ulong i = 0; i < count; i++) { tempMD = _memory64List.GetElement((uint)i); MinidumpMemoryChunk chunk = new MinidumpMemoryChunk { Size = tempMD.DataSize, TargetStartAddress = tempMD.StartOfMemoryRange, TargetEndAddress = tempMD.StartOfMemoryRange + tempMD.DataSize, RVA = currentRVA.Value }; currentRVA.Value += tempMD.DataSize; chunks.Add(chunk); } chunks.Sort(); SplitAndMergeChunks(chunks); _chunks = chunks.ToArray(); Count = (ulong)chunks.Count; ValidateChunks(); }
private void SplitAndMergeChunks(List <MinidumpMemoryChunk> chunks) { for (int i = 1; i < chunks.Count; i++) { MinidumpMemoryChunk prevChunk = chunks[i - 1]; MinidumpMemoryChunk curChunk = chunks[i]; // we already sorted Debug.Assert(prevChunk.TargetStartAddress <= curChunk.TargetStartAddress); // there is some overlap if (prevChunk.TargetEndAddress > curChunk.TargetStartAddress) { // the previous chunk completely covers this chunk rendering it useless if (prevChunk.TargetEndAddress >= curChunk.TargetEndAddress) { chunks.RemoveAt(i); i--; } // previous chunk partially covers this one so we will remove the front // of this chunk and resort it if needed else { ulong overlap = prevChunk.TargetEndAddress - curChunk.TargetStartAddress; curChunk.TargetStartAddress += overlap; curChunk.RVA += overlap; curChunk.Size -= overlap; // now that we changes the start address it might not be sorted anymore // find the correct index int newIndex = i; for (; newIndex < chunks.Count - 1; newIndex++) { if (curChunk.TargetStartAddress <= chunks[newIndex + 1].TargetStartAddress) { break; } } if (newIndex != i) { chunks.RemoveAt(i); chunks.Insert(newIndex - 1, curChunk); i--; } } } } }