https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0c3812eb7e58b1a7ced66a68999794c9a34eb564

commit 0c3812eb7e58b1a7ced66a68999794c9a34eb564
Author:     Timo Kreuzer <[email protected]>
AuthorDate: Sat Mar 3 00:13:37 2018 +0100
Commit:     Timo Kreuzer <[email protected]>
CommitDate: Sat May 29 21:20:48 2021 +0200

    [RTL/x64] Implement RtlRestoreContext
---
 sdk/include/asm/asm.inc        |   4 ++
 sdk/lib/rtl/amd64/except_asm.S | 130 +++++++++++++++++++++++++++++++++++++++++
 sdk/lib/rtl/amd64/stubs.c      |   9 ---
 3 files changed, 134 insertions(+), 9 deletions(-)

diff --git a/sdk/include/asm/asm.inc b/sdk/include/asm/asm.inc
index d879b44ca7f..de46fb5c963 100644
--- a/sdk/include/asm/asm.inc
+++ b/sdk/include/asm/asm.inc
@@ -313,6 +313,10 @@ ENDM
     jmp far ptr \segment:\offset
 .endm
 
+.macro retf
+    lret
+.endm
+
 /* MASM compatible EXTERN */
 .macro EXTERN name
 .endm
diff --git a/sdk/lib/rtl/amd64/except_asm.S b/sdk/lib/rtl/amd64/except_asm.S
index ea2eb7f88c8..e3fd67b852f 100644
--- a/sdk/lib/rtl/amd64/except_asm.S
+++ b/sdk/lib/rtl/amd64/except_asm.S
@@ -106,6 +106,136 @@ PUBLIC RtlCaptureContext
     ret
 .ENDP
 
+/*
+ * VOID NTAPI
+ * RtlRestoreContext(
+ *     _In_ PCONTEXT ContextRecord@<rcx>,
+ *     PEXCEPTION_RECORD *ExceptionRecord@<rdx>);
+ */
+PUBLIC RtlRestoreContext
+.PROC RtlRestoreContext
+
+    /* Allocate space */
+    sub rsp, HEX(8)
+    .ALLOCSTACK 8
+    .ENDPROLOG
+
+    // TODO: Handle ExceptionRecord
+
+    /* Restore legacy floating point registers (It's slow, so do it first) */
+    ldmxcsr [rcx + CxMxCsr]
+    fxrstor [rcx + CxFltSave]
+
+    /* Load the target stack pointer into rdx */
+    mov rdx, [rcx + CxRsp]
+
+    /* Load EFlags into rax (zero extended) */
+    mov eax, [rcx + CxEFlags]
+
+    /* Load the return address into r8 */
+    mov r8, [rcx + CxRip]
+
+    /* Load rdx restore value into r9 */
+    mov r9, [rcx + CxRdx]
+
+    /* Restore xmm registers */
+    movaps xmm0, [rcx + CxXmm0]
+    movaps xmm1, [rcx + CxXmm1]
+    movaps xmm2, [rcx + CxXmm2]
+    movaps xmm3, [rcx + CxXmm3]
+    movaps xmm4, [rcx + CxXmm4]
+    movaps xmm5, [rcx + CxXmm5]
+    movaps xmm6, [rcx + CxXmm6]
+    movaps xmm7, [rcx + CxXmm7]
+    movaps xmm8, [rcx + CxXmm8]
+    movaps xmm9, [rcx + CxXmm9]
+    movaps xmm10, [rcx + CxXmm10]
+    movaps xmm11, [rcx + CxXmm11]
+    movaps xmm12, [rcx + CxXmm12]
+    movaps xmm13, [rcx + CxXmm13]
+    movaps xmm14, [rcx + CxXmm14]
+    movaps xmm15, [rcx + CxXmm15]
+
+    /* Copy Return address (now in r8) to the target stack */
+    mov [rdx - 2 * 8], r8
+
+    /* Copy Eflags (now in rax) to the target stack */
+    mov [rdx - 3 * 8], rax
+
+    /* Copy the value for rdx (now in r9) to the target stack */
+    mov [rdx - 4 * 8], r9
+
+    /* Restore the integer registers */
+    mov rbx, [rcx + CxRbx]
+    mov rsi, [rcx + CxRsi]
+    mov rdi, [rcx + CxRdi]
+    mov rbp, [rcx + CxRbp]
+    mov r10, [rcx + CxR10]
+    mov r11, [rcx + CxR11]
+    mov r12, [rcx + CxR12]
+    mov r13, [rcx + CxR13]
+    mov r14, [rcx + CxR14]
+    mov r15, [rcx + CxR15]
+
+    /* Restore segment selectors */
+    mov ds, [rcx + CxSegDs] // FIXME: WOW64 context?
+    mov es, [rcx + CxSegEs]
+    mov fs, [rcx + CxSegFs]
+    //mov gs, [rcx + CxSegGs]
+    //mov ss, [rcx + CxSegSs]
+
+    /* Restore the registers we used */
+    mov r8,  [rcx + CxR8]
+    mov r9,  [rcx + CxR9]
+
+    /* Check if we go to a different cs */
+    mov ax, cs
+    cmp [rcx + CxSegCs], ax
+    jne ReturnFar
+
+    /* Restore rax and rcx */
+    mov rax, [rcx + CxRax]
+    mov rcx, [rcx + CxRcx]
+
+    /* Switch to the target stack */
+    lea rsp, [rdx - 4 * 8]
+
+    /* Pop rdx from the stack */
+    pop rdx
+
+    /* Pop Eflags from the stack */
+    popfq
+
+    /* Return and fix up the stack */
+    ret 8
+
+ReturnFar:
+
+    /* Put cs on the stack for the far return */
+    mov ax, [rcx + CxSegCs]
+    mov [rdx - 1 * 8], ax
+
+    /* Load ss */
+    mov ss, [rcx + CxSegSs]
+
+    /* Restore rax and rcx */
+    mov rax, [rcx + CxRax]
+    mov rcx, [rcx + CxRcx]
+
+    /* Switch to the target stack */
+    lea rsp, [rdx - 4 * 8]
+
+    /* Pop rdx from the stack */
+    pop rdx
+
+    /* Pop Eflags from the stack */
+    popfq
+
+    /* Return far */
+    retf
+
+.ENDP
+
 END
 
 
diff --git a/sdk/lib/rtl/amd64/stubs.c b/sdk/lib/rtl/amd64/stubs.c
index 52288c44f84..7eb61416c36 100644
--- a/sdk/lib/rtl/amd64/stubs.c
+++ b/sdk/lib/rtl/amd64/stubs.c
@@ -97,15 +97,6 @@ RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
     return FALSE;
 }
 
-NTSYSAPI
-VOID
-RtlRestoreContext(
-    PCONTEXT ContextRecord,
-    PEXCEPTION_RECORD ExceptionRecord)
-{
-    UNIMPLEMENTED;
-}
-
 NTSTATUS
 NTAPI
 RtlQueueApcWow64Thread(

Reply via email to