[CPU] Host RBX is restored from the saved host frame below
This commit is contained in:
parent
6d6a5a1a0d
commit
a036bc1a48
|
|
@ -2610,6 +2610,7 @@ public sealed unsafe partial class DirectExecutionBackend : INativeCpuBackend, I
|
|||
|
||||
byte* code = (byte*)ptr;
|
||||
int offset = 0;
|
||||
EmitByte(code, ref offset, 0x48); EmitByte(code, ref offset, 0x89); EmitByte(code, ref offset, 0xC3); // mov rbx,rax
|
||||
EmitByte(code, ref offset, 0x48); // sub rsp, 0x20
|
||||
EmitByte(code, ref offset, 0x83);
|
||||
EmitByte(code, ref offset, 0xEC);
|
||||
|
|
@ -2639,6 +2640,7 @@ public sealed unsafe partial class DirectExecutionBackend : INativeCpuBackend, I
|
|||
EmitByte(code, ref offset, 0x5E);
|
||||
EmitByte(code, ref offset, 0x5F);
|
||||
EmitByte(code, ref offset, 0x5D);
|
||||
EmitByte(code, ref offset, 0x48); EmitByte(code, ref offset, 0x89); EmitByte(code, ref offset, 0xD8); // mov rax,rbx
|
||||
EmitByte(code, ref offset, 0x5B);
|
||||
EmitByte(code, ref offset, 0xC3);
|
||||
|
||||
|
|
|
|||
|
|
@ -82,7 +82,24 @@ public sealed class Gen5NativeReturnSmokeTests
|
|||
]);
|
||||
}
|
||||
|
||||
private static void ExecuteSyntheticGuest(byte[]? callbackInstructions = null)
|
||||
[Fact]
|
||||
public async Task SyntheticGen5Continuation_PreservesFullReturnValue()
|
||||
{
|
||||
if (!IsSupportedHost)
|
||||
return;
|
||||
|
||||
if (Environment.GetEnvironmentVariable(WorkerEnvironmentVariable) != "1")
|
||||
{
|
||||
var result = await RunIsolatedWorker(nameof(SyntheticGen5Continuation_PreservesFullReturnValue));
|
||||
Assert.True(result.Completed, result.Output);
|
||||
Assert.True(result.ExitCode == 0, result.Output);
|
||||
return;
|
||||
}
|
||||
|
||||
ExecuteSyntheticGuest(continuation: true);
|
||||
}
|
||||
|
||||
private static void ExecuteSyntheticGuest(byte[]? callbackInstructions = null, bool continuation = false)
|
||||
{
|
||||
using var memory = new PhysicalVirtualMemory();
|
||||
var image = new SelfLoader().Load(BuildSyntheticElf(callbackInstructions), memory);
|
||||
|
|
@ -119,6 +136,21 @@ public sealed class Gen5NativeReturnSmokeTests
|
|||
Assert.Null(dispatcher.LastNotImplementedInfo);
|
||||
|
||||
var callerContext = new CpuContext(new TrackedCpuMemory(memory), Generation.Gen5);
|
||||
if (continuation)
|
||||
{
|
||||
Assert.True(memory.TryAllocateAtOrAbove(0x1_0000_0000, 0x4000, false, 0x4000, out var stack));
|
||||
callerContext[CpuRegister.Rsp] = stack + 0x4000 - sizeof(ulong);
|
||||
// Resume directly into mov rax, imm64; ret through the shared guest return stub.
|
||||
var execute = typeof(DirectExecutionBackend).GetMethod(
|
||||
"ExecuteGuestContinuationEntry", BindingFlags.Instance | BindingFlags.NonPublic)!;
|
||||
object?[] arguments = [callerContext, image.EntryPoint + 3, callerContext[CpuRegister.Rsp],
|
||||
"synthetic-native-continuation-return", null];
|
||||
var exitReason = execute.Invoke(backend, arguments);
|
||||
Assert.True(exitReason?.ToString() == "Returned", arguments[4]?.ToString());
|
||||
Assert.Equal(CallbackReturnValue, callerContext[CpuRegister.Rax]);
|
||||
return;
|
||||
}
|
||||
|
||||
ulong dataAddress = 0;
|
||||
var recoveryCounter = typeof(DirectExecutionBackend).GetField(
|
||||
"_sse4aInstructionsEmulated", BindingFlags.Static | BindingFlags.NonPublic)!;
|
||||
|
|
|
|||
Loading…
Reference in New Issue