コード例 #1
0
ファイル: MemoryBlock.cs プロジェクト: xHailFirex/BizHawk
        /// <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();
        }
コード例 #2
0
ファイル: MemoryBlock.cs プロジェクト: red031000/tpp-BizHawk2
        /// <exception cref="InvalidOperationException">failed to protect memory</exception>
        public override void Protect(ulong start, ulong length, Protection prot)
        {
            if (length == 0)
            {
                return;
            }
            int pstart = GetPage(start);
            int pend   = GetPage(start + length - 1);

            var p = GetKernelMemoryProtectionValue(prot);

            for (int i = pstart; i <= pend; i++)
            {
                _pageData[i] = prot; // also store the value for later use
            }
            if (Active)              // it's legal to Protect() if we're not active; the information is just saved for the next activation
            {
                var computedStart  = WaterboxUtils.AlignDown(start);
                var computedEnd    = WaterboxUtils.AlignUp(start + length);
                var computedLength = computedEnd - computedStart;

                Kernel32.MemoryProtection old;
                if (!Kernel32.VirtualProtect(Z.UU(computedStart),
                                             Z.UU(computedLength), p, out old))
                {
                    throw new InvalidOperationException($"{nameof(Kernel32.VirtualProtect)}() returned FALSE!");
                }
            }
        }
コード例 #3
0
        /// <exception cref="InvalidOperationException">failed to protect memory</exception>
        public override void Protect(ulong start, ulong length, Protection prot)
        {
            if (length == 0)
            {
                return;
            }

            var pstart = GetPage(start);
            var pend   = GetPage(start + length - 1);

            for (var i = pstart; i <= pend; i++)
            {
                _pageData[i] = prot;                                              // also store the value for later use
            }
            if (!Active)
            {
                return;                      // it's legal to call this method if we're not active; the information is just saved for the next activation
            }
            var computedStart = WaterboxUtils.AlignDown(start);
            var protEnum      = prot.ToMemoryProtection();
            var exitCode      = mprotect(
                Z.US(computedStart),
                Z.UU(WaterboxUtils.AlignUp(start + length) - computedStart),
                protEnum
                );

            if (exitCode != 0)
            {
                throw new InvalidOperationException($"{nameof(mprotect)}() returned {exitCode}!");
            }
        }
コード例 #4
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);
            }
        }
コード例 #5
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)
        {
            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;

            _pal.Protect(computedStart, computedLength, prot);
        }
コード例 #6
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>
        /// <exception cref="ObjectDisposedException">disposed</exception>
        public void Protect(ulong start, ulong length, Protection prot)
        {
            if (_pal == null)
            {
                throw new ObjectDisposedException(nameof(MemoryBlock));
            }
            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;

            _pal.Protect(computedStart, computedLength, prot);
        }
コード例 #7
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)
        {
            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;

            int pstart = GetPage(start);
            int pend   = GetPage(start + length - 1);

            for (int i = pstart; i <= pend; i++)
            {
                _pageData[i] = prot;                 // also store the value for later use
            }
            // potentially commit more memory
            var minNewCommittedSize = computedEnd - Start;

            if (minNewCommittedSize > CommittedSize)
            {
                CommittedSize = minNewCommittedSize;
            }

            if (Active)             // it's legal to Protect() if we're not active; the information is just saved for the next activation
            {
                if (CommittedSize > LastActiveCommittedSize)
                {
                    _pal.Commit(CommittedSize);
                    LastActiveCommittedSize = CommittedSize;
                    ProtectAll();
                }
                else
                {
                    _pal.Protect(computedStart, computedLength, prot);
                }
            }
        }