54 lines
2.4 KiB
C#
54 lines
2.4 KiB
C#
// Copyright (C) 2026 SharpEmu Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
using SharpEmu.HLE;
|
|
using Xunit;
|
|
|
|
namespace SharpEmu.Libs.Tests.Memory;
|
|
|
|
// A POSIX query reports the run of pages sharing the queried page's protection, ending at the
|
|
// next protection change, as Win32 VirtualQuery does.
|
|
public sealed unsafe class HostMemoryQueryRunTests
|
|
{
|
|
[Fact]
|
|
public void QueryRunsEndAtTheNextProtectionChange()
|
|
{
|
|
if (OperatingSystem.IsWindows()) return;
|
|
var page = (ulong)Environment.SystemPageSize;
|
|
var memory = (byte*)HostMemory.Alloc(null, (nuint)(page * 16), HostMemory.MEM_RESERVE | HostMemory.MEM_COMMIT, HostMemory.PAGE_READWRITE);
|
|
Assert.True(memory != null);
|
|
var start = (ulong)memory;
|
|
try
|
|
{
|
|
Assert.True(HostMemory.Protect((void*)(start + 3 * page), (nuint)(3 * page), HostMemory.PAGE_READONLY, out _));
|
|
Assert.True(HostMemory.Protect((void*)(start + 9 * page), (nuint)page, HostMemory.PAGE_NOACCESS, out _));
|
|
Assert.True(HostMemory.Protect((void*)(start + 15 * page), (nuint)page, HostMemory.PAGE_READONLY, out _));
|
|
|
|
AssertRun(start, 0, 3, HostMemory.PAGE_READWRITE);
|
|
AssertRun(start, 3, 3, HostMemory.PAGE_READONLY);
|
|
AssertRun(start, 4, 2, HostMemory.PAGE_READONLY);
|
|
AssertRun(start, 6, 3, HostMemory.PAGE_READWRITE);
|
|
AssertRun(start, 9, 1, HostMemory.PAGE_NOACCESS);
|
|
AssertRun(start, 10, 5, HostMemory.PAGE_READWRITE);
|
|
// A run at the last page of the mapping.
|
|
AssertRun(start, 15, 1, HostMemory.PAGE_READONLY);
|
|
|
|
// Restoring the default protection removes the overrides from the run.
|
|
Assert.True(HostMemory.Protect((void*)(start + 3 * page), (nuint)(7 * page), HostMemory.PAGE_READWRITE, out _));
|
|
AssertRun(start, 0, 15, HostMemory.PAGE_READWRITE);
|
|
}
|
|
finally
|
|
{
|
|
Assert.True(HostMemory.Free(memory, 0, HostMemory.MEM_RELEASE));
|
|
}
|
|
|
|
void AssertRun(ulong baseAddress, ulong firstPage, ulong pages, uint protect)
|
|
{
|
|
Assert.NotEqual(0u, (uint)HostMemory.Query((void*)(baseAddress + firstPage * page + 8), out var info));
|
|
Assert.Equal(baseAddress + firstPage * page, info.BaseAddress);
|
|
Assert.Equal(pages * page, info.RegionSize);
|
|
Assert.Equal(protect, info.Protect);
|
|
}
|
|
}
|
|
}
|