Beispiel #1
0
        /// <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);
            }
        }
Beispiel #2
0
 /// <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;
 }
Beispiel #3
0
        /// <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();
        }