/// <summary> /// Indicate that a virtual region has been mapped, and which physical region it has been mapped to. /// Should be called after the mapping is complete. /// </summary> /// <param name="va">Virtual memory address</param> /// <param name="size">Size to be mapped</param> public void Map(ulong va, ulong size) { // A mapping may mean we need to re-evaluate each VirtualRegion's affected area. // Find all handles that overlap with the range, we need to recalculate their physical regions lock (TrackingLock) { var results = _virtualResults; int count = _virtualRegions.FindOverlapsNonOverlapping(va, size, ref results); for (int i = 0; i < count; i++) { VirtualRegion region = results[i]; // If the region has been fully remapped, signal that it has been mapped again. bool remapped = _memoryManager.IsRangeMapped(region.Address, region.Size); if (remapped) { region.SignalMappingChanged(true); } region.UpdateProtection(); } } }
/// <summary> /// Signal that a virtual memory event happened at the given location. /// </summary> /// <param name="address">Virtual address accessed</param> /// <param name="size">Size of the region affected in bytes</param> /// <param name="write">Whether the region was written to or read</param> /// <returns>True if the event triggered any tracking regions, false otherwise</returns> public bool VirtualMemoryEvent(ulong address, ulong size, bool write) { // Look up the virtual region using the region list. // Signal up the chain to relevant handles. lock (TrackingLock) { var results = _virtualResults; int count = _virtualRegions.FindOverlapsNonOverlapping(address, size, ref results); if (count == 0) { if (!_memoryManager.IsMapped(address)) { throw new InvalidMemoryRegionException(); } _memoryManager.TrackingReprotect(address & ~(ulong)(_pageSize - 1), (ulong)_pageSize, MemoryPermission.ReadAndWrite); return(false); // We can't handle this - it's probably a real invalid access. } for (int i = 0; i < count; i++) { VirtualRegion region = results[i]; region.Signal(address, size, write); } } return(true); }
/// <summary> /// Remove a parent virtual region from this physical region. Assumes that the tracking lock has been obtained. /// </summary> /// <param name="region">Region to remove</param> /// <returns>True if there are no more parents and we should be removed, false otherwise.</returns> public bool RemoveParent(VirtualRegion region) { VirtualParents.Remove(region); UpdateProtection(); if (VirtualParents.Count == 0) { return(true); } return(false); }
public override INonOverlappingRange Split(ulong splitAddress) { VirtualRegion newRegion = new VirtualRegion(_tracking, splitAddress, EndAddress - splitAddress, _lastPermission); Size = splitAddress - Address; // The new region inherits all of our parents. newRegion.Handles = new List <RegionHandle>(Handles); foreach (var parent in Handles) { parent.AddChild(newRegion); } return(newRegion); }
/// <summary> /// Indicate that a virtual region has been unmapped. /// Should be called after the unmapping is complete. /// </summary> /// <param name="va">Virtual memory address</param> /// <param name="size">Size to be unmapped</param> public void Unmap(ulong va, ulong size) { // An unmapping may mean we need to re-evaluate each VirtualRegion's affected area. // Find all handles that overlap with the range, we need to recalculate their physical regions lock (TrackingLock) { var results = _virtualResults; int count = _virtualRegions.FindOverlapsNonOverlapping(va, size, ref results); for (int i = 0; i < count; i++) { VirtualRegion region = results[i]; region.RecalculatePhysicalChildren(); } } }
/// <summary> /// Indicate that a virtual region has been unmapped. /// Should be called before the unmapping is complete. /// </summary> /// <param name="va">Virtual memory address</param> /// <param name="size">Size to be unmapped</param> public void Unmap(ulong va, ulong size) { // An unmapping may mean we need to re-evaluate each VirtualRegion's affected area. // Find all handles that overlap with the range, we need to notify them that the region was unmapped. lock (TrackingLock) { var results = _virtualResults; int count = _virtualRegions.FindOverlapsNonOverlapping(va, size, ref results); for (int i = 0; i < count; i++) { VirtualRegion region = results[i]; region.SignalMappingChanged(false); } } }
/// <summary> /// Add a child virtual region to this handle. /// </summary> /// <param name="region">Virtual region to add as a child</param> internal void AddChild(VirtualRegion region) { _regions.Add(region); }
/// <summary> /// Reprotect a given virtual region. The virtual memory manager will handle this. /// </summary> /// <param name="region">Region to reprotect</param> /// <param name="permission">Memory permission to protect with</param> internal void ProtectVirtualRegion(VirtualRegion region, MemoryPermission permission) { _memoryManager.TrackingReprotect(region.Address, region.Size, permission); }
/// <summary> /// Remove a virtual region from the range list. This assumes that the lock has been acquired. /// </summary> /// <param name="region">Region to remove</param> internal void RemoveVirtual(VirtualRegion region) { _virtualRegions.Remove(region); }