示例#1
0
        /// <summary>
        /// Creates a new multi-range with multiple physical regions.
        /// </summary>
        /// <param name="ranges">Array of physical regions</param>
        /// <exception cref="ArgumentNullException"><paramref name="ranges"/> is null</exception>
        public MultiRange(MemoryRange[] ranges)
        {
            _singleRange = MemoryRange.Empty;
            _ranges      = ranges ?? throw new ArgumentNullException(nameof(ranges));

            if (ranges.Length != 0)
            {
                MinAddress = ulong.MaxValue;
                MaxAddress = 0UL;

                foreach (MemoryRange range in ranges)
                {
                    if (MinAddress > range.Address)
                    {
                        MinAddress = range.Address;
                    }

                    if (MaxAddress < range.EndAddress)
                    {
                        MaxAddress = range.EndAddress;
                    }
                }
            }
            else
            {
                MinAddress = 0UL;
                MaxAddress = 0UL;
            }
        }
示例#2
0
 /// <summary>
 /// Creates a new multi-range with a single physical region.
 /// </summary>
 /// <param name="address">Start address of the region</param>
 /// <param name="size">Size of the region in bytes</param>
 public MultiRange(ulong address, ulong size)
 {
     _singleRange = new MemoryRange(address, size);
     _ranges      = null;
     MinAddress   = address;
     MaxAddress   = address + size;
 }
示例#3
0
        /// <summary>
        /// Check if two multi-ranges overlap with each other.
        /// </summary>
        /// <param name="other">Other multi-range to check for overlap</param>
        /// <returns>True if any sub-range overlaps, false otherwise</returns>
        public bool OverlapsWith(MultiRange other)
        {
            if (HasSingleRange && other.HasSingleRange)
            {
                return(_singleRange.OverlapsWith(other._singleRange));
            }
            else
            {
                for (int i = 0; i < Count; i++)
                {
                    MemoryRange currentRange = GetSubRangeUnchecked(i);

                    for (int j = 0; j < other.Count; j++)
                    {
                        if (currentRange.OverlapsWith(other.GetSubRangeUnchecked(j)))
                        {
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
示例#4
0
        /// <summary>
        /// Calculates the offset of a given multi-range inside another, when the multi-range is fully contained
        /// inside the other multi-range, otherwise returns -1.
        /// </summary>
        /// <param name="other">Multi-range that should be fully contained inside this one</param>
        /// <returns>Offset in bytes if fully contained, otherwise -1</returns>
        public int FindOffset(MultiRange other)
        {
            int thisCount  = Count;
            int otherCount = other.Count;

            if (thisCount == 1 && otherCount == 1)
            {
                MemoryRange otherFirstRange   = other.GetSubRangeUnchecked(0);
                MemoryRange currentFirstRange = GetSubRangeUnchecked(0);

                if (otherFirstRange.Address >= currentFirstRange.Address &&
                    otherFirstRange.EndAddress <= currentFirstRange.EndAddress)
                {
                    return((int)(otherFirstRange.Address - currentFirstRange.Address));
                }
            }
            else if (thisCount >= otherCount)
            {
                ulong baseOffset = 0;

                MemoryRange otherFirstRange = other.GetSubRangeUnchecked(0);
                MemoryRange otherLastRange  = other.GetSubRangeUnchecked(otherCount - 1);

                for (int i = 0; i < (thisCount - otherCount) + 1; baseOffset += GetSubRangeUnchecked(i).Size, i++)
                {
                    MemoryRange currentFirstRange = GetSubRangeUnchecked(i);
                    MemoryRange currentLastRange  = GetSubRangeUnchecked(i + otherCount - 1);

                    if (otherCount > 1)
                    {
                        if (otherFirstRange.Address < currentFirstRange.Address ||
                            otherFirstRange.EndAddress != currentFirstRange.EndAddress)
                        {
                            continue;
                        }

                        if (otherLastRange.Address != currentLastRange.Address ||
                            otherLastRange.EndAddress > currentLastRange.EndAddress)
                        {
                            continue;
                        }

                        bool fullMatch = true;

                        for (int j = 1; j < otherCount - 1; j++)
                        {
                            if (!GetSubRangeUnchecked(i + j).Equals(other.GetSubRangeUnchecked(j)))
                            {
                                fullMatch = false;
                                break;
                            }
                        }

                        if (!fullMatch)
                        {
                            continue;
                        }
                    }
                    else if (currentFirstRange.Address > otherFirstRange.Address ||
                             currentFirstRange.EndAddress < otherFirstRange.EndAddress)
                    {
                        continue;
                    }

                    return((int)(baseOffset + (otherFirstRange.Address - currentFirstRange.Address)));
                }
            }

            return(-1);
        }
示例#5
0
 /// <summary>
 /// Checks if a given sub-range of memory is invalid.
 /// Those are used to represent unmapped memory regions (holes in the region mapping).
 /// </summary>
 /// <param name="subRange">Memory range to checl</param>
 /// <returns>True if the memory range is considered invalid, false otherwise</returns>
 private static bool IsInvalid(ref MemoryRange subRange)
 {
     return(subRange.Address == ulong.MaxValue);
 }