[Tests] Cover backward red-zone spans, direct memory no-space results and the mount info size
This commit is contained in:
parent
ee9660d81d
commit
0666071f79
|
|
@ -436,6 +436,50 @@ public sealed class KernelMemoryCompatExportsTests
|
|||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AvailableDirectMemorySize_FullRangeClearsOutputsAndReportsNoSpace()
|
||||
{
|
||||
const ulong allocationStart = 0;
|
||||
const ulong allocationLength = 0x0040_0000;
|
||||
var context = new CpuContext(new FakeCpuMemory(GuestMemoryBase, 0x1000), Generation.Gen5);
|
||||
|
||||
try
|
||||
{
|
||||
AllocateDirectMemory(context, allocationStart, allocationLength);
|
||||
Assert.True(context.TryWriteUInt64(SpanStartOutAddress, 0xDEAD_BEEF));
|
||||
Assert.True(context.TryWriteUInt64(SpanSizeOutAddress, 0xDEAD_BEEF));
|
||||
|
||||
context[CpuRegister.Rdi] = allocationStart;
|
||||
context[CpuRegister.Rsi] = allocationStart + allocationLength;
|
||||
context[CpuRegister.Rdx] = 0;
|
||||
context[CpuRegister.Rcx] = SpanStartOutAddress;
|
||||
context[CpuRegister.R8] = SpanSizeOutAddress;
|
||||
|
||||
Assert.Equal(unchecked((int)0x8002000C), KernelMemoryCompatExports.KernelAvailableDirectMemorySize(context));
|
||||
Assert.True(context.TryReadUInt64(SpanStartOutAddress, out var spanStart));
|
||||
Assert.True(context.TryReadUInt64(SpanSizeOutAddress, out var spanSize));
|
||||
Assert.Equal(0UL, spanStart);
|
||||
Assert.Equal(0UL, spanSize);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ReleaseDirectMemory(context, allocationStart, allocationLength);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AvailableDirectMemorySize_EmptySearchRangeReportsNoSpace()
|
||||
{
|
||||
var context = new CpuContext(new FakeCpuMemory(GuestMemoryBase, 0x1000), Generation.Gen5);
|
||||
context[CpuRegister.Rdi] = 0x0010_0000;
|
||||
context[CpuRegister.Rsi] = 0x0010_0000;
|
||||
context[CpuRegister.Rdx] = 0;
|
||||
context[CpuRegister.Rcx] = SpanStartOutAddress;
|
||||
context[CpuRegister.R8] = SpanSizeOutAddress;
|
||||
|
||||
Assert.Equal(unchecked((int)0x8002000C), KernelMemoryCompatExports.KernelAvailableDirectMemorySize(context));
|
||||
}
|
||||
|
||||
private static void AllocateDirectMemory(CpuContext context, ulong start, ulong length, ulong outputAddress = AllocationOutAddress)
|
||||
{
|
||||
context[CpuRegister.Rdi] = start;
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ public sealed class GuestRedZonePatcherTests
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public unsafe void LeavesShortAccessUnchangedWhenNextInstructionIsBranchTarget()
|
||||
public unsafe void PatchesShortAccessBeforeBranchTargetFromThePreviousInstruction()
|
||||
{
|
||||
if (RuntimeInformation.ProcessArchitecture != Architecture.X64)
|
||||
return;
|
||||
|
|
@ -199,14 +199,45 @@ public sealed class GuestRedZonePatcherTests
|
|||
var argument = OperatingSystem.IsWindows() ? (byte)0x91 : (byte)0x97;
|
||||
byte[] function =
|
||||
[
|
||||
0x48, 0xB8, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, // mov rax, value
|
||||
0x48, 0x89, 0x44, 0x24, 0xF8, // mov [rsp-8], rax
|
||||
0x48, 0x8D, argument, 0x00, 0x20, 0x00, 0x00, // lea rdx, [arg+0x2000]
|
||||
0xB8, 0xFE, 0xFF, 0xFF, 0xFF, // mov eax, 0xFFFFFFFE
|
||||
0x21, 0x02, // and [rdx], eax
|
||||
0x48, 0x8B, 0x44, 0x24, 0xF8, // target: mov rax, [rsp-8]
|
||||
0xC3, // ret
|
||||
0xEB, 0xF8, // jmp target
|
||||
0x48, 0xB8, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11,
|
||||
0x48, 0x89, 0x44, 0x24, 0xF8,
|
||||
0x48, 0x8D, argument, 0x00, 0x20, 0x00, 0x00,
|
||||
0xB8, 0xFE, 0xFF, 0xFF, 0xFF,
|
||||
0x21, 0x02,
|
||||
0x48, 0x8B, 0x44, 0x24, 0xF8,
|
||||
0xC3,
|
||||
0xEB, 0xF8,
|
||||
];
|
||||
|
||||
using var image = PatchedImage.Create(function, [(0x2000, 7u)]);
|
||||
if (OperatingSystem.IsWindows() || OperatingSystem.IsMacOS())
|
||||
{
|
||||
Assert.Equal(1, image.Result.PatchedSites);
|
||||
Assert.Equal(0xE9, image.ReadByte(22));
|
||||
}
|
||||
|
||||
Assert.Equal(0x1122_3344_5566_7788UL, ((delegate* unmanaged<ulong, ulong>)image.Base)(image.Base));
|
||||
Assert.Equal(6u, image.ReadUInt32(0x2000));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public unsafe void LeavesShortAccessBeforeBranchTargetUnchangedWhenAnIndirectBranchIsUnresolved()
|
||||
{
|
||||
if (RuntimeInformation.ProcessArchitecture != Architecture.X64)
|
||||
return;
|
||||
|
||||
var argument = OperatingSystem.IsWindows() ? (byte)0x91 : (byte)0x97;
|
||||
byte[] function =
|
||||
[
|
||||
0x48, 0xB8, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11,
|
||||
0x48, 0x89, 0x44, 0x24, 0xF8,
|
||||
0x48, 0x8D, argument, 0x00, 0x20, 0x00, 0x00,
|
||||
0xB8, 0xFE, 0xFF, 0xFF, 0xFF,
|
||||
0x21, 0x02,
|
||||
0x48, 0x8B, 0x44, 0x24, 0xF8,
|
||||
0xC3,
|
||||
0xEB, 0xF8,
|
||||
0xFF, 0xE0,
|
||||
];
|
||||
|
||||
using var image = PatchedImage.Create(function, [(0x2000, 7u)]);
|
||||
|
|
@ -215,7 +246,7 @@ public sealed class GuestRedZonePatcherTests
|
|||
{
|
||||
Assert.Equal(1, image.Result.RedZoneFunctions);
|
||||
Assert.Equal(1, image.Result.UnrelocatableSites);
|
||||
Assert.Equal(1, image.Result.BranchTargetRefusals);
|
||||
Assert.Equal(1, image.Result.IndirectBranchRefusals);
|
||||
}
|
||||
|
||||
for (var index = 0; index < function.Length; index++)
|
||||
|
|
|
|||
|
|
@ -247,6 +247,25 @@ public sealed class SaveDataExportsTests : IDisposable
|
|||
Assert.Equal(16382UL, freeBlocks);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetMountInfo_WritesOnlyTheGuestStructure()
|
||||
{
|
||||
Assert.Equal(0, Mount());
|
||||
WriteAscii(MountPointStr, MountPoint);
|
||||
Span<byte> sentinel = stackalloc byte[0x10];
|
||||
sentinel.Fill(0xCD);
|
||||
Assert.True(_memory.TryWrite(MountInfo + 0x30, sentinel));
|
||||
|
||||
Assert.Equal(
|
||||
0,
|
||||
SaveDataExports.SaveDataGetMountInfo(
|
||||
Reg(rdi: MountPointStr, rsi: MountInfo)));
|
||||
|
||||
Span<byte> after = stackalloc byte[0x10];
|
||||
Assert.True(_memory.TryRead(MountInfo + 0x30, after));
|
||||
Assert.True(after.SequenceEqual(sentinel));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DirNameSearch_ReportsBlockCapacityAndRemainingBlocks()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue