Use ranges in MemoryBlock*
This commit is contained in:
parent
d71b7af31c
commit
4a5ece2076
|
@ -185,20 +185,20 @@ namespace BizHawk.Common.BizInvoke
|
|||
|
||||
private void WriteThunk(byte[] data, int placeholderIndex, IntPtr p, int index)
|
||||
{
|
||||
_memory.Protect(_memory.Start, _memory.Size, MemoryBlockBase.Protection.RW);
|
||||
var ss = _memory.GetStream(_memory.Start + (ulong)index * BlockSize, BlockSize, true);
|
||||
_memory.Protect(_memory.AddressRange.Start, _memory.Size, MemoryBlockBase.Protection.RW);
|
||||
var ss = _memory.GetStream(_memory.AddressRange.Start + BlockSize * (ulong) index, BlockSize, true);
|
||||
ss.Write(data, 0, data.Length);
|
||||
for (int i = data.Length; i < BlockSize; i++)
|
||||
ss.WriteByte(Padding);
|
||||
ss.Position = placeholderIndex;
|
||||
var bw = new BinaryWriter(ss);
|
||||
bw.Write((long)p);
|
||||
_memory.Protect(_memory.Start, _memory.Size, MemoryBlockBase.Protection.RX);
|
||||
_memory.Protect(_memory.AddressRange.Start, _memory.Size, MemoryBlockBase.Protection.RX);
|
||||
}
|
||||
|
||||
private IntPtr GetThunkAddress(int index)
|
||||
{
|
||||
return Z.US(_memory.Start + (ulong)index * BlockSize);
|
||||
return Z.US(_memory.AddressRange.Start + BlockSize * (ulong) index);
|
||||
}
|
||||
|
||||
private void SetLifetime(int index, object lifetime)
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace BizHawk.Common.BizInvoke
|
|||
/// </summary>
|
||||
private IntPtr _handle;
|
||||
|
||||
/// <summary>allocate <paramref name="size"/> bytes starting at a particular address <paramref name="start"/></summary>
|
||||
/// <inheritdoc cref="MemoryBlockBase(ulong,ulong)"/>
|
||||
/// <exception cref="InvalidOperationException">failed to create file mapping</exception>
|
||||
public MemoryBlock(ulong start, ulong size) : base(start, size)
|
||||
{
|
||||
|
@ -31,8 +31,14 @@ namespace BizHawk.Common.BizInvoke
|
|||
{
|
||||
if (Active)
|
||||
throw new InvalidOperationException("Already active");
|
||||
if (Kernel32.MapViewOfFileEx(_handle, Kernel32.FileMapAccessType.Read | Kernel32.FileMapAccessType.Write | Kernel32.FileMapAccessType.Execute,
|
||||
0, 0, Z.UU(Size), Z.US(Start)) != Z.US(Start))
|
||||
if (Kernel32.MapViewOfFileEx(
|
||||
_handle,
|
||||
Kernel32.FileMapAccessType.Read | Kernel32.FileMapAccessType.Write | Kernel32.FileMapAccessType.Execute,
|
||||
0,
|
||||
0,
|
||||
Z.UU(Size),
|
||||
Z.US(AddressRange.Start)
|
||||
) != Z.US(AddressRange.Start))
|
||||
{
|
||||
throw new InvalidOperationException($"{nameof(Kernel32.MapViewOfFileEx)}() returned NULL");
|
||||
}
|
||||
|
@ -45,7 +51,7 @@ namespace BizHawk.Common.BizInvoke
|
|||
{
|
||||
if (!Active)
|
||||
throw new InvalidOperationException("Not active");
|
||||
if (!Kernel32.UnmapViewOfFile(Z.US(Start)))
|
||||
if (!Kernel32.UnmapViewOfFile(Z.US(AddressRange.Start)))
|
||||
throw new InvalidOperationException($"{nameof(Kernel32.UnmapViewOfFile)}() returned NULL");
|
||||
Active = false;
|
||||
}
|
||||
|
@ -61,12 +67,12 @@ namespace BizHawk.Common.BizInvoke
|
|||
// temporarily switch the entire block to `R`: in case some areas are unreadable, we don't want
|
||||
// that to complicate things
|
||||
Kernel32.MemoryProtection old;
|
||||
if (!Kernel32.VirtualProtect(Z.UU(Start), Z.UU(Size), Kernel32.MemoryProtection.READONLY, out old))
|
||||
if (!Kernel32.VirtualProtect(Z.UU(AddressRange.Start), Z.UU(Size), Kernel32.MemoryProtection.READONLY, out old))
|
||||
throw new InvalidOperationException($"{nameof(Kernel32.VirtualProtect)}() returned FALSE!");
|
||||
|
||||
_snapshot = new byte[Size];
|
||||
var ds = new MemoryStream(_snapshot, true);
|
||||
var ss = GetStream(Start, Size, false);
|
||||
var ss = GetStream(AddressRange.Start, Size, false);
|
||||
ss.CopyTo(ds);
|
||||
XorHash = WaterboxUtils.Hash(_snapshot);
|
||||
|
||||
|
@ -80,9 +86,9 @@ namespace BizHawk.Common.BizInvoke
|
|||
throw new InvalidOperationException("Not active");
|
||||
// temporarily switch the entire block to `R`
|
||||
Kernel32.MemoryProtection old;
|
||||
if (!Kernel32.VirtualProtect(Z.UU(Start), Z.UU(Size), Kernel32.MemoryProtection.READONLY, out old))
|
||||
if (!Kernel32.VirtualProtect(Z.UU(AddressRange.Start), Z.UU(Size), Kernel32.MemoryProtection.READONLY, out old))
|
||||
throw new InvalidOperationException($"{nameof(Kernel32.VirtualProtect)}() returned FALSE!");
|
||||
var ret = WaterboxUtils.Hash(GetStream(Start, Size, false));
|
||||
var ret = WaterboxUtils.Hash(GetStream(AddressRange.Start, Size, false));
|
||||
ProtectAll();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -6,28 +6,26 @@ namespace BizHawk.Common.BizInvoke
|
|||
{
|
||||
public abstract class MemoryBlockBase : IDisposable
|
||||
{
|
||||
/// <summary>allocate <paramref name="size"/> bytes starting at a particular address <paramref name="start"/></summary>
|
||||
/// <exception cref="ArgumentOutOfRangeException"><paramref name="start"/> is not aligned or <paramref name="size"/> is <c>0</c></exception>
|
||||
protected MemoryBlockBase(ulong start, ulong size)
|
||||
{
|
||||
if (!WaterboxUtils.Aligned(start)) throw new ArgumentOutOfRangeException();
|
||||
if (size == 0) throw new ArgumentOutOfRangeException();
|
||||
Start = start;
|
||||
if (!WaterboxUtils.Aligned(start)) throw new ArgumentOutOfRangeException(nameof(start), start, "start address must be aligned");
|
||||
if (size == 0) throw new ArgumentOutOfRangeException(nameof(size), size, "cannot create 0-length block");
|
||||
Size = WaterboxUtils.AlignUp(size);
|
||||
End = Start + Size;
|
||||
_pageData = new Protection[GetPage(End - 1) + 1];
|
||||
AddressRange = start.RangeToExclusive(start + Size);
|
||||
_pageData = new Protection[1 + GetPage(AddressRange.EndInclusive)];
|
||||
}
|
||||
|
||||
/// <summary>stores last set memory protection value for each page</summary>
|
||||
protected readonly Protection[] _pageData;
|
||||
|
||||
/// <summary>ending address of the memory block; equal to <see cref="Start"/> + <see cref="Size"/></summary>
|
||||
public readonly ulong End;
|
||||
/// <summary>valid address range of the memory block</summary>
|
||||
public readonly Range<ulong> AddressRange;
|
||||
|
||||
/// <summary>total size of the memory block</summary>
|
||||
public readonly ulong Size;
|
||||
|
||||
/// <summary>starting address of the memory block</summary>
|
||||
public readonly ulong Start;
|
||||
|
||||
/// <summary>snapshot for XOR buffer</summary>
|
||||
protected byte[] _snapshot;
|
||||
|
||||
|
@ -37,33 +35,31 @@ namespace BizHawk.Common.BizInvoke
|
|||
public byte[] XorHash { get; protected set; }
|
||||
|
||||
/// <summary>get a page index within the block</summary>
|
||||
protected int GetPage(ulong addr)
|
||||
{
|
||||
if (addr < Start || End <= addr) throw new ArgumentOutOfRangeException();
|
||||
return (int) ((addr - Start) >> WaterboxUtils.PageShift);
|
||||
}
|
||||
protected int GetPage(ulong addr) => AddressRange.Contains(addr)
|
||||
? (int) ((addr - AddressRange.Start) >> WaterboxUtils.PageShift)
|
||||
: throw new ArgumentOutOfRangeException(nameof(addr), addr, "invalid address");
|
||||
|
||||
/// <summary>get a start address for a page index within the block</summary>
|
||||
protected ulong GetStartAddr(int page) => ((ulong) page << WaterboxUtils.PageShift) + Start;
|
||||
protected ulong GetStartAddr(int page) => AddressRange.Start + ((ulong) page << WaterboxUtils.PageShift);
|
||||
|
||||
/// <summary>Get a stream that can be used to read or write from part of the block. Does not check for or change <see cref="Protect"/>!</summary>
|
||||
/// <exception cref="ArgumentOutOfRangeException"><paramref name="start"/> or end (= <paramref name="start"/> + <paramref name="length"/>) are outside bounds of memory block (<see cref="Start"/> and <see cref="End"/>)</exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException"><paramref name="start"/> or end (= <paramref name="start"/> + <paramref name="length"/>) are outside <see cref="AddressRange"/></exception>
|
||||
public Stream GetStream(ulong start, ulong length, bool writer)
|
||||
{
|
||||
if (start < Start) throw new ArgumentOutOfRangeException(nameof(start));
|
||||
if (End < start + length) throw new ArgumentOutOfRangeException(nameof(length));
|
||||
if (start < AddressRange.Start) throw new ArgumentOutOfRangeException(nameof(start), start, "invalid address");
|
||||
if (AddressRange.EndInclusive < start + length - 1) throw new ArgumentOutOfRangeException(nameof(length), length, "requested length implies invalid end address");
|
||||
return new MemoryViewStream(!writer, writer, (long) start, (long) length, this);
|
||||
}
|
||||
|
||||
/// <summary>get a stream that can be used to read or write from part of the block. both reads and writes will be XORed against an earlier recorded snapshot</summary>
|
||||
/// <exception cref="ArgumentOutOfRangeException"><paramref name="start"/> or end (= <paramref name="start"/> + <paramref name="length"/>) are outside bounds of memory block (<see cref="Start"/> and <see cref="End"/>)</exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException"><paramref name="start"/> or end (= <paramref name="start"/> + <paramref name="length"/>) are outside <see cref="AddressRange"/></exception>
|
||||
/// <exception cref="InvalidOperationException">no snapshot taken (haven't called <see cref="SaveXorSnapshot"/>)</exception>
|
||||
public Stream GetXorStream(ulong start, ulong length, bool writer)
|
||||
{
|
||||
if (start < Start) throw new ArgumentOutOfRangeException(nameof(start));
|
||||
if (End < start + length) throw new ArgumentOutOfRangeException(nameof(length));
|
||||
if (start < AddressRange.Start) throw new ArgumentOutOfRangeException(nameof(start), start, "invalid address");
|
||||
if (AddressRange.EndInclusive < start + length - 1) throw new ArgumentOutOfRangeException(nameof(length), length, "requested length implies invalid end address");
|
||||
if (_snapshot == null) throw new InvalidOperationException("No snapshot taken!");
|
||||
return new MemoryViewXorStream(!writer, writer, (long) start, (long) length, this, _snapshot, (long) (start - Start));
|
||||
return new MemoryViewXorStream(!writer, writer, (long) start, (long) length, this, _snapshot, (long) (start - AddressRange.Start));
|
||||
}
|
||||
|
||||
/// <summary>activate the memory block, swapping it in at the pre-specified address</summary>
|
||||
|
@ -144,10 +140,9 @@ namespace BizHawk.Common.BizInvoke
|
|||
|
||||
private void EnsureNotDisposed()
|
||||
{
|
||||
if (_owner.Start == 0) throw new ObjectDisposedException("MemoryBlockBase");
|
||||
if (_owner.AddressRange.Start == 0) throw new ObjectDisposedException(nameof(MemoryBlockBase)); //TODO bug?
|
||||
}
|
||||
|
||||
/// <remarks>TODO should this call base.Flush()? --yoshi</remarks>
|
||||
public override void Flush() {}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace BizHawk.Common.BizInvoke
|
|||
/// <summary>handle returned by <see cref="memfd_create"/></summary>
|
||||
private int _fd;
|
||||
|
||||
/// <summary>allocate <paramref name="size"/> bytes starting at a particular address <paramref name="start"/></summary>
|
||||
/// <inheritdoc cref="MemoryBlockBase(ulong,ulong)"/>
|
||||
/// <exception cref="InvalidOperationException">failed to get file descriptor (never thrown as <see cref="NotImplementedException"/> is thrown first)</exception>
|
||||
/// <exception cref="NotImplementedException">always</exception>
|
||||
public MemoryBlockUnix(ulong start, ulong size) : base(start, size)
|
||||
|
@ -25,8 +25,8 @@ namespace BizHawk.Common.BizInvoke
|
|||
{
|
||||
if (Active) throw new InvalidOperationException("Already active");
|
||||
|
||||
var ptr = mmap(Z.US(Start), Z.UU(Size), MemoryProtection.Read | MemoryProtection.Write | MemoryProtection.Execute, 16, _fd, IntPtr.Zero);
|
||||
if (ptr != Z.US(Start)) throw new InvalidOperationException($"{nameof(mmap)}() returned NULL or the wrong pointer");
|
||||
var ptr = mmap(Z.US(AddressRange.Start), Z.UU(Size), MemoryProtection.Read | MemoryProtection.Write | MemoryProtection.Execute, 16, _fd, IntPtr.Zero);
|
||||
if (ptr != Z.US(AddressRange.Start)) throw new InvalidOperationException($"{nameof(mmap)}() returned NULL or the wrong pointer");
|
||||
|
||||
ProtectAll();
|
||||
Active = true;
|
||||
|
@ -37,7 +37,7 @@ namespace BizHawk.Common.BizInvoke
|
|||
{
|
||||
if (!Active) throw new InvalidOperationException("Not active");
|
||||
|
||||
var exitCode = munmap(Z.US(Start), Z.UU(Size));
|
||||
var exitCode = munmap(Z.US(AddressRange.Start), Z.UU(Size));
|
||||
if (exitCode != 0) throw new InvalidOperationException($"{nameof(munmap)}() returned {exitCode}");
|
||||
|
||||
Active = false;
|
||||
|
@ -49,10 +49,10 @@ namespace BizHawk.Common.BizInvoke
|
|||
if (!Active) throw new InvalidOperationException("Not active");
|
||||
|
||||
// temporarily switch the entire block to `R`
|
||||
var exitCode = mprotect(Z.US(Start), Z.UU(Size), MemoryProtection.Read);
|
||||
var exitCode = mprotect(Z.US(AddressRange.Start), Z.UU(Size), MemoryProtection.Read);
|
||||
if (exitCode != 0) throw new InvalidOperationException($"{nameof(mprotect)}() returned {exitCode}!");
|
||||
|
||||
var ret = WaterboxUtils.Hash(GetStream(Start, Size, false));
|
||||
var ret = WaterboxUtils.Hash(GetStream(AddressRange.Start, Size, false));
|
||||
ProtectAll();
|
||||
return ret;
|
||||
}
|
||||
|
@ -105,11 +105,11 @@ namespace BizHawk.Common.BizInvoke
|
|||
if (!Active) throw new InvalidOperationException("Not active");
|
||||
|
||||
// temporarily switch the entire block to `R`: in case some areas are unreadable, we don't want that to complicate things
|
||||
var exitCode = mprotect(Z.US(Start), Z.UU(Size), MemoryProtection.Read);
|
||||
var exitCode = mprotect(Z.US(AddressRange.Start), Z.UU(Size), MemoryProtection.Read);
|
||||
if (exitCode != 0) throw new InvalidOperationException($"{nameof(mprotect)}() returned {exitCode}!");
|
||||
|
||||
_snapshot = new byte[Size];
|
||||
GetStream(Start, Size, false).CopyTo(new MemoryStream(_snapshot, true));
|
||||
GetStream(AddressRange.Start, Size, false).CopyTo(new MemoryStream(_snapshot, true));
|
||||
XorHash = WaterboxUtils.Hash(_snapshot);
|
||||
ProtectAll();
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
if (HasRelocations())
|
||||
{
|
||||
_base = MemoryBlockBase.CallPlatformCtor((ulong)(orig_end - orig_start));
|
||||
_loadoffset = (long)_base.Start - orig_start;
|
||||
_loadoffset = (long) _base.AddressRange.Start - orig_start;
|
||||
Initialize(0);
|
||||
}
|
||||
else
|
||||
|
@ -94,7 +94,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
_disposeList.Add(_base);
|
||||
AddMemoryBlock(_base, "elf");
|
||||
_base.Activate();
|
||||
_base.Protect(_base.Start, _base.Size, MemoryBlockBase.Protection.RW);
|
||||
_base.Protect(_base.AddressRange.Start, _base.Size, MemoryBlockBase.Protection.RW);
|
||||
|
||||
foreach (var seg in loadsegs)
|
||||
{
|
||||
|
@ -104,7 +104,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
RegisterSymbols();
|
||||
ProcessRelocations();
|
||||
|
||||
_base.Protect(_base.Start, _base.Size, MemoryBlockBase.Protection.R);
|
||||
_base.Protect(_base.AddressRange.Start, _base.Size, MemoryBlockBase.Protection.R);
|
||||
|
||||
foreach (var sec in _elf.Sections.Where(s => (s.Flags & SectionFlags.Allocatable) != 0))
|
||||
{
|
||||
|
@ -114,13 +114,13 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
_base.Protect((ulong)(sec.LoadAddress + _loadoffset), (ulong)sec.Size, MemoryBlockBase.Protection.RW);
|
||||
}
|
||||
|
||||
ulong end = _base.End;
|
||||
ulong end = _base.AddressRange.EndInclusive + 1;
|
||||
|
||||
if (heapsize > 0)
|
||||
{
|
||||
_heap = new Heap(GetHeapStart(end), (ulong)heapsize, "sbrk-heap");
|
||||
_heap.Memory.Activate();
|
||||
end = _heap.Memory.End;
|
||||
end = _heap.Memory.AddressRange.EndInclusive + 1;
|
||||
_disposeList.Add(_heap);
|
||||
AddMemoryBlock(_heap.Memory, "sbrk - heap");
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
{
|
||||
_sealedheap = new Heap(GetHeapStart(end), (ulong)sealedheapsize, "sealed-heap");
|
||||
_sealedheap.Memory.Activate();
|
||||
end = _sealedheap.Memory.End;
|
||||
end = _sealedheap.Memory.AddressRange.EndInclusive + 1;
|
||||
_disposeList.Add(_sealedheap);
|
||||
AddMemoryBlock(_sealedheap.Memory, "sealed-heap");
|
||||
}
|
||||
|
@ -138,13 +138,13 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
{
|
||||
_invisibleheap = new Heap(GetHeapStart(end), (ulong)invisibleheapsize, "invisible-heap");
|
||||
_invisibleheap.Memory.Activate();
|
||||
end = _invisibleheap.Memory.End;
|
||||
end = _invisibleheap.Memory.AddressRange.EndInclusive + 1;
|
||||
_disposeList.Add(_invisibleheap);
|
||||
AddMemoryBlock(_invisibleheap.Memory, "invisible-heap");
|
||||
}
|
||||
|
||||
ConnectAllClibPatches();
|
||||
Console.WriteLine("Loaded {0}@{1:X16}", filename, _base.Start);
|
||||
Console.WriteLine($"Loaded {filename}@{_base.AddressRange.Start:X16}");
|
||||
foreach (var sec in _elf.Sections.Where(s => s.LoadAddress != 0))
|
||||
{
|
||||
Console.WriteLine(" {0}@{1:X16}, size {2}", sec.Name.PadLeft(20), sec.LoadAddress + _loadoffset, sec.Size.ToString().PadLeft(12));
|
||||
|
|
|
@ -63,8 +63,8 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
{
|
||||
throw new InvalidOperationException($"Failed to allocate {size} bytes from heap {Name}");
|
||||
}
|
||||
ulong ret = Memory.Start + allocstart;
|
||||
Memory.Protect(Memory.Start + Used, newused - Used, MemoryBlockBase.Protection.RW);
|
||||
ulong ret = Memory.AddressRange.Start + allocstart;
|
||||
Memory.Protect(Memory.AddressRange.Start + Used, newused - Used, MemoryBlockBase.Protection.RW);
|
||||
Used = newused;
|
||||
Console.WriteLine($"Allocated {size} bytes on {Name}, utilization {Used}/{Memory.Size} ({100.0 * Used / Memory.Size:0.#}%)");
|
||||
return ret;
|
||||
|
@ -74,8 +74,8 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
{
|
||||
if (!Sealed)
|
||||
{
|
||||
Memory.Protect(Memory.Start, Used, MemoryBlockBase.Protection.R);
|
||||
_hash = WaterboxUtils.Hash(Memory.GetStream(Memory.Start, Used, false));
|
||||
Memory.Protect(Memory.AddressRange.Start, Used, MemoryBlockBase.Protection.R);
|
||||
_hash = WaterboxUtils.Hash(Memory.GetStream(Memory.AddressRange.Start, Used, false));
|
||||
Sealed = true;
|
||||
}
|
||||
else
|
||||
|
@ -91,7 +91,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
if (!Sealed)
|
||||
{
|
||||
bw.Write(Memory.XorHash);
|
||||
var ms = Memory.GetXorStream(Memory.Start, WaterboxUtils.AlignUp(Used), false);
|
||||
var ms = Memory.GetXorStream(Memory.AddressRange.Start, WaterboxUtils.AlignUp(Used), false);
|
||||
ms.CopyTo(bw.BaseStream);
|
||||
}
|
||||
else
|
||||
|
@ -118,9 +118,9 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
}
|
||||
var usedAligned = WaterboxUtils.AlignUp(used);
|
||||
|
||||
Memory.Protect(Memory.Start, Memory.Size, MemoryBlockBase.Protection.None);
|
||||
Memory.Protect(Memory.Start, used, MemoryBlockBase.Protection.RW);
|
||||
var ms = Memory.GetXorStream(Memory.Start, usedAligned, true);
|
||||
Memory.Protect(Memory.AddressRange.Start, Memory.Size, MemoryBlockBase.Protection.None);
|
||||
Memory.Protect(Memory.AddressRange.Start, used, MemoryBlockBase.Protection.RW);
|
||||
var ms = Memory.GetXorStream(Memory.AddressRange.Start, usedAligned, true);
|
||||
WaterboxUtils.CopySome(br.BaseStream, ms, (long)usedAligned);
|
||||
Used = used;
|
||||
}
|
||||
|
|
|
@ -29,18 +29,12 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
/// <summary>
|
||||
/// get a page index within the block
|
||||
/// </summary>
|
||||
private int GetPage(ulong addr)
|
||||
{
|
||||
return (int)((addr - Memory.Start) >> WaterboxUtils.PageShift);
|
||||
}
|
||||
private int GetPage(ulong addr) => (int) ((addr - Memory.AddressRange.Start) >> WaterboxUtils.PageShift);
|
||||
|
||||
/// <summary>
|
||||
/// get a start address for a page index within the block
|
||||
/// </summary>
|
||||
private ulong GetStartAddr(int page)
|
||||
{
|
||||
return ((ulong)page << WaterboxUtils.PageShift) + Memory.Start;
|
||||
}
|
||||
private ulong GetStartAddr(int page) => Memory.AddressRange.Start + ((ulong) page << WaterboxUtils.PageShift);
|
||||
|
||||
private const MemoryBlockBase.Protection FREE = (MemoryBlockBase.Protection)255;
|
||||
|
||||
|
@ -180,7 +174,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
{
|
||||
// TODO: what is the expected behavior when everything requested for remap is allocated,
|
||||
// but with different protections?
|
||||
if (start < Memory.Start || start + oldSize > Memory.End || oldSize == 0 || newSize == 0)
|
||||
if (oldSize == 0 || newSize == 0 || start < Memory.AddressRange.Start || Memory.AddressRange.EndInclusive < start + oldSize - 1)
|
||||
return 0;
|
||||
|
||||
var oldStartPage = GetPage(start);
|
||||
|
@ -245,7 +239,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
|
||||
public bool Protect(ulong start, ulong size, MemoryBlockBase.Protection prot)
|
||||
{
|
||||
if (start < Memory.Start || start + size > Memory.End || size == 0)
|
||||
if (size == 0 || start < Memory.AddressRange.Start || Memory.AddressRange.EndInclusive < start + size - 1)
|
||||
return false;
|
||||
|
||||
var startPage = GetPage(start);
|
||||
|
@ -276,8 +270,8 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
bw.Write(Memory.XorHash);
|
||||
bw.Write(_pagesAsBytes);
|
||||
|
||||
Memory.Protect(Memory.Start, Memory.Size, MemoryBlockBase.Protection.R);
|
||||
var srcs = Memory.GetXorStream(Memory.Start, Memory.Size, false);
|
||||
Memory.Protect(Memory.AddressRange.Start, Memory.Size, MemoryBlockBase.Protection.R);
|
||||
var srcs = Memory.GetXorStream(Memory.AddressRange.Start, Memory.Size, false);
|
||||
for (int i = 0, addr = 0; i < _pages.Length; i++, addr += WaterboxUtils.PageSize)
|
||||
{
|
||||
if (_pages[i] != FREE)
|
||||
|
@ -307,8 +301,8 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
throw new InvalidOperationException("Unexpected error reading!");
|
||||
|
||||
Used = 0;
|
||||
Memory.Protect(Memory.Start, Memory.Size, MemoryBlockBase.Protection.RW);
|
||||
var dsts = Memory.GetXorStream(Memory.Start, Memory.Size, true);
|
||||
Memory.Protect(Memory.AddressRange.Start, Memory.Size, MemoryBlockBase.Protection.RW);
|
||||
var dsts = Memory.GetXorStream(Memory.AddressRange.Start, Memory.Size, true);
|
||||
for (int i = 0, addr = 0; i < _pages.Length; i++, addr += WaterboxUtils.PageSize)
|
||||
{
|
||||
if (_pages[i] != FREE)
|
||||
|
|
|
@ -420,13 +420,13 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
{
|
||||
var heap = _parent._heap;
|
||||
|
||||
var start = heap.Memory.Start;
|
||||
var start = heap.Memory.AddressRange.Start;
|
||||
var end = start + heap.Used;
|
||||
var max = heap.Memory.End;
|
||||
var max = heap.Memory.AddressRange.EndInclusive;
|
||||
|
||||
var p = (ulong)_p;
|
||||
|
||||
if (p < start || p > max)
|
||||
if (p < start || max + 1 < p) //TODO bug?
|
||||
{
|
||||
// failure: return current break
|
||||
return Z.UU(end);
|
||||
|
|
|
@ -293,7 +293,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
/// </summary>
|
||||
private void ProtectMemory()
|
||||
{
|
||||
Memory.Protect(Memory.Start, Memory.Size, MemoryBlockBase.Protection.R);
|
||||
Memory.Protect(Memory.AddressRange.Start, Memory.Size, MemoryBlockBase.Protection.R);
|
||||
|
||||
foreach (var s in _sections)
|
||||
{
|
||||
|
@ -424,7 +424,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
// unlikely to get this far if the previous checks pssed
|
||||
throw new InvalidOperationException("Trickys elves moved on you!");
|
||||
|
||||
Memory.Protect(Memory.Start, Memory.Size, MemoryBlockBase.Protection.RW);
|
||||
Memory.Protect(Memory.AddressRange.Start, Memory.Size, MemoryBlockBase.Protection.RW);
|
||||
|
||||
foreach (var s in _sections)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue