reactos/modules/rostests/apitests/rtl/amd64/RtlCaptureContext-asm.s
Timo Kreuzer bdf52a9868 [RTL_APITEST] Add rtl_unittest
First test is RtlCaptureContext
2023-11-10 19:00:41 +02:00

183 lines
4.1 KiB
ArmAsm

/*
* PROJECT: ReactOS api tests
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
* PURPOSE: Test helper for x64 RtlCaptureContext
* COPYRIGHT: Copyright 2022 Timo Kreuzer <timo.kreuzer@reactos.org>
*/
#include <asm.inc>
#include <ksamd64.inc>
.code64
EXTERN RtlCaptureContext:PROC
FUNC ZeroContext
pushfq
.ALLOCSTACK 8
push rax
.PUSHREG rax
push rcx
.PUSHREG rcx
push rdi
.PUSHREG rdi
.ENDPROLOG
mov rdi, rcx
mov rcx, CONTEXT_FRAME_LENGTH
xor eax, eax
cld
rep stosb
pop rdi
pop rcx
pop rax
popfq
ret
ENDFUNC
//
// VOID
// RtlCaptureContextWrapper (
// _Inout_ PCONTEXT InOutContext,
// _Out_ PCONTEXT CapturedContext);
//
PUBLIC RtlCaptureContextWrapper
FUNC RtlCaptureContextWrapper
// Generate a KEXCEPTION_FRAME on the stack
GENERATE_EXCEPTION_FRAME
// Save parameters
mov [rsp + ExP1Home], rcx
mov [rsp + ExP2Home], rdx
// Save current EFlags
pushfq
pop qword ptr [rsp + ExP3Home]
// Load integer registers from InOutContext
mov rax, [rcx + CxRax]
mov rdx, [rcx + CxRdx]
mov rbx, [rcx + CxRbx]
mov rbp, [rcx + CxRbp]
mov rsi, [rcx + CxRsi]
mov rdi, [rcx + CxRdi]
mov r8, [rcx + CxR8]
mov r9, [rcx + CxR9]
mov r10, [rcx + CxR10]
mov r11, [rcx + CxR11]
mov r12, [rcx + CxR12]
mov r13, [rcx + CxR13]
mov r14, [rcx + CxR14]
mov r15, [rcx + CxR15]
// Load floating point registers from InOutContext
fxrstor [rcx + CxFltSave]
// Load MxCsr (this overwrites the value from FltSave)
ldmxcsr [rcx + CxMxCsr]
// Load 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]
// Load EFlags
push qword ptr [rcx + CxEFlags]
popfq
// Capture the context
mov rcx, [rsp + ExP2Home]
call RtlCaptureContext
ReturnAddress:
// Save the returned rcx
mov [rsp + ExP4Home], rcx
// Restore original rcx
mov rcx, [rsp + ExP1Home]
// Zero out the context (this does not clobber any registers/flags)
call ZeroContext
// Save returned Eflags
pushfq
pop qword ptr [rcx + CxEFlags]
// Restore original EFLags
push qword ptr [rsp + ExP3Home]
popfq
// Save returned integer registers to InOutContext
mov [rcx + CxRax], rax
mov [rcx + CxRdx], rdx
mov [rcx + CxRbx], rbx
mov [rcx + CxRbp], rbp
mov [rcx + CxRsi], rsi
mov [rcx + CxRdi], rdi
mov [rcx + CxR8], r8
mov [rcx + CxR9], r9
mov [rcx + CxR10], r10
mov [rcx + CxR11], r11
mov [rcx + CxR12], r12
mov [rcx + CxR13], r13
mov [rcx + CxR14], r14
mov [rcx + CxR15], r15
// Save the returned rcx in the context
mov rax, [rsp + ExP4Home]
mov [rcx + CxRcx], rax
// Save returned floating point registers to InOutContext
stmxcsr [rcx + CxMxCsr]
fxsave [rcx + CxFltSave]
movaps [rcx + CxXmm0], xmm0
movaps [rcx + CxXmm1], xmm1
movaps [rcx + CxXmm2], xmm2
movaps [rcx + CxXmm3], xmm3
movaps [rcx + CxXmm4], xmm4
movaps [rcx + CxXmm5], xmm5
movaps [rcx + CxXmm6], xmm6
movaps [rcx + CxXmm7], xmm7
movaps [rcx + CxXmm8], xmm8
movaps [rcx + CxXmm9], xmm9
movaps [rcx + CxXmm10], xmm10
movaps [rcx + CxXmm11], xmm11
movaps [rcx + CxXmm12], xmm12
movaps [rcx + CxXmm13], xmm13
movaps [rcx + CxXmm14], xmm14
movaps [rcx + CxXmm15], xmm15
// Save the expected return address
lea rax, ReturnAddress[rip]
mov [rcx + CxRip], rax
// Save the expected stored rsp
mov [rcx + CxRsp], rsp
// Restore the registers from the KEXCEPTION_FRAME
RESTORE_EXCEPTION_STATE
ret
ENDFUNC
END