1/* 2 * PROJECT: ReactOS api tests 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: Test helper for x64 RtlCaptureContext 5 * COPYRIGHT: Copyright 2022 Timo Kreuzer <timo.kreuzer@reactos.org> 6 */ 7 8#include <asm.inc> 9#include <ksamd64.inc> 10 11.code64 12 13EXTERN RtlCaptureContext:PROC 14 15FUNC ZeroContext 16 17 pushfq 18 .ALLOCSTACK 8 19 push rax 20 .PUSHREG rax 21 push rcx 22 .PUSHREG rcx 23 push rdi 24 .PUSHREG rdi 25 .ENDPROLOG 26 27 mov rdi, rcx 28 mov rcx, CONTEXT_FRAME_LENGTH 29 xor eax, eax 30 cld 31 rep stosb 32 33 pop rdi 34 pop rcx 35 pop rax 36 popfq 37 ret 38 39ENDFUNC 40 41// 42// VOID 43// RtlCaptureContextWrapper ( 44// _Inout_ PCONTEXT InOutContext, 45// _Out_ PCONTEXT CapturedContext); 46// 47PUBLIC RtlCaptureContextWrapper 48FUNC RtlCaptureContextWrapper 49 50 // Generate a KEXCEPTION_FRAME on the stack 51 GENERATE_EXCEPTION_FRAME 52 53 // Save parameters 54 mov [rsp + ExP1Home], rcx 55 mov [rsp + ExP2Home], rdx 56 57 // Save current EFlags 58 pushfq 59 pop qword ptr [rsp + ExP3Home] 60 61 // Load integer registers from InOutContext 62 mov rax, [rcx + CxRax] 63 mov rdx, [rcx + CxRdx] 64 mov rbx, [rcx + CxRbx] 65 mov rbp, [rcx + CxRbp] 66 mov rsi, [rcx + CxRsi] 67 mov rdi, [rcx + CxRdi] 68 mov r8, [rcx + CxR8] 69 mov r9, [rcx + CxR9] 70 mov r10, [rcx + CxR10] 71 mov r11, [rcx + CxR11] 72 mov r12, [rcx + CxR12] 73 mov r13, [rcx + CxR13] 74 mov r14, [rcx + CxR14] 75 mov r15, [rcx + CxR15] 76 77 // Load floating point registers from InOutContext 78 fxrstor [rcx + CxFltSave] 79 80 // Load MxCsr (this overwrites the value from FltSave) 81 ldmxcsr [rcx + CxMxCsr] 82 83 // Load XMM registers 84 movaps xmm0, [rcx + CxXmm0] 85 movaps xmm1, [rcx + CxXmm1] 86 movaps xmm2, [rcx + CxXmm2] 87 movaps xmm3, [rcx + CxXmm3] 88 movaps xmm4, [rcx + CxXmm4] 89 movaps xmm5, [rcx + CxXmm5] 90 movaps xmm6, [rcx + CxXmm6] 91 movaps xmm7, [rcx + CxXmm7] 92 movaps xmm8, [rcx + CxXmm8] 93 movaps xmm9, [rcx + CxXmm9] 94 movaps xmm10, [rcx + CxXmm10] 95 movaps xmm11, [rcx + CxXmm11] 96 movaps xmm12, [rcx + CxXmm12] 97 movaps xmm13, [rcx + CxXmm13] 98 movaps xmm14, [rcx + CxXmm14] 99 movaps xmm15, [rcx + CxXmm15] 100 101 // Load EFlags 102 push qword ptr [rcx + CxEFlags] 103 popfq 104 105 // Capture the context 106 mov rcx, [rsp + ExP2Home] 107 call RtlCaptureContext 108ReturnAddress: 109 110 // Save the returned rcx 111 mov [rsp + ExP4Home], rcx 112 113 // Restore original rcx 114 mov rcx, [rsp + ExP1Home] 115 116 // Zero out the context (this does not clobber any registers/flags) 117 call ZeroContext 118 119 // Save returned Eflags 120 pushfq 121 pop qword ptr [rcx + CxEFlags] 122 123 // Restore original EFLags 124 push qword ptr [rsp + ExP3Home] 125 popfq 126 127 // Save returned integer registers to InOutContext 128 mov [rcx + CxRax], rax 129 mov [rcx + CxRdx], rdx 130 mov [rcx + CxRbx], rbx 131 mov [rcx + CxRbp], rbp 132 mov [rcx + CxRsi], rsi 133 mov [rcx + CxRdi], rdi 134 mov [rcx + CxR8], r8 135 mov [rcx + CxR9], r9 136 mov [rcx + CxR10], r10 137 mov [rcx + CxR11], r11 138 mov [rcx + CxR12], r12 139 mov [rcx + CxR13], r13 140 mov [rcx + CxR14], r14 141 mov [rcx + CxR15], r15 142 143 // Save the returned rcx in the context 144 mov rax, [rsp + ExP4Home] 145 mov [rcx + CxRcx], rax 146 147 // Save returned floating point registers to InOutContext 148 stmxcsr [rcx + CxMxCsr] 149 fxsave [rcx + CxFltSave] 150 movaps [rcx + CxXmm0], xmm0 151 movaps [rcx + CxXmm1], xmm1 152 movaps [rcx + CxXmm2], xmm2 153 movaps [rcx + CxXmm3], xmm3 154 movaps [rcx + CxXmm4], xmm4 155 movaps [rcx + CxXmm5], xmm5 156 movaps [rcx + CxXmm6], xmm6 157 movaps [rcx + CxXmm7], xmm7 158 movaps [rcx + CxXmm8], xmm8 159 movaps [rcx + CxXmm9], xmm9 160 movaps [rcx + CxXmm10], xmm10 161 movaps [rcx + CxXmm11], xmm11 162 movaps [rcx + CxXmm12], xmm12 163 movaps [rcx + CxXmm13], xmm13 164 movaps [rcx + CxXmm14], xmm14 165 movaps [rcx + CxXmm15], xmm15 166 167 // Save the expected return address 168 lea rax, ReturnAddress[rip] 169 mov [rcx + CxRip], rax 170 171 // Save the expected stored rsp 172 mov [rcx + CxRsp], rsp 173 174 // Restore the registers from the KEXCEPTION_FRAME 175 RESTORE_EXCEPTION_STATE 176 177 ret 178 179ENDFUNC 180 181 182END 183