/// <summary>set r/w/x protection on a portion of memory. rounded to encompassing pages</summary /// <exception cref="InvalidOperationException">failed to protect memory</exception> public void Protect(ulong start, ulong length, Protection prot) { EnsureActive(); if (length == 0) { return; } if (_sealed) { _pal.GetWriteStatus(_dirtydata, _pageData); } // Note: asking for prot.none on memory that was not previously committed, commits it var computedStart = WaterboxUtils.AlignDown(start); var computedEnd = WaterboxUtils.AlignUp(start + length); var computedLength = computedEnd - computedStart; // potentially commit more memory var minNewCommittedSize = computedEnd - Start; if (minNewCommittedSize > CommittedSize) { CommittedSize = minNewCommittedSize; // Since Commit() was called, we have to do a full ProtectAll -- remember that when refactoring _pal.Commit(CommittedSize); } int pstart = GetPage(start); int pend = GetPage(start + length - 1); for (int i = pstart; i <= pend; i++) { _pageData[i] = prot; // inform the low level code what addresses might fault on it if (prot == Protection.RW || prot == Protection.RW_Stack) { _dirtydata[i] |= WriteDetectionStatus.CanChange; } else { _dirtydata[i] &= ~WriteDetectionStatus.CanChange; } } // TODO: restore the previous behavior where we would only reprotect a partial range ProtectAll(); if (_sealed) { _pal.SetWriteStatus(_dirtydata); } }
/// <summary>activate the memory block, swapping it in at the pre-specified address</summary> /// <exception cref="InvalidOperationException"><see cref="MemoryBlock.Active"/> is <see langword="true"/> or failed to map file view</exception> public void Activate() { if (Active) { throw new InvalidOperationException("Already active"); } _pal.Activate(); if (CommittedSize > LastActiveCommittedSize) { _pal.Commit(CommittedSize); LastActiveCommittedSize = CommittedSize; } ProtectAll(); Active = true; }
/// <summary>set r/w/x protection on a portion of memory. rounded to encompassing pages</summary> /// <exception cref="InvalidOperationException">failed to protect memory</exception> public void Protect(ulong start, ulong length, Protection prot) { EnsureActive(); if (length == 0) { return; } // Note: asking for prot.none on memory that was not previously committed, commits it var computedStart = WaterboxUtils.AlignDown(start); var computedEnd = WaterboxUtils.AlignUp(start + length); var computedLength = computedEnd - computedStart; // potentially commit more memory var minNewCommittedSize = computedEnd - Start; if (minNewCommittedSize > CommittedSize) { CommittedSize = minNewCommittedSize; // Since Commit() was called, we have to do a full ProtectAll -- remember that when refactoring _pal.Commit(CommittedSize); } int pstart = GetPage(start); int pend = GetPage(start + length - 1); for (int i = pstart; i <= pend; i++) { _pageData[i] = prot; } // TODO: restore the previous behavior where we would only reprotect a partial range ProtectAll(); }