[SDK][CRT] Improve x64 setjmp/longjmp and add testcase

This commit is contained in:
Katayama Hirofumi MZ 2025-03-29 19:28:44 +09:00
parent 467dec4d16
commit 2a2c8318bf
7 changed files with 135 additions and 87 deletions

View file

@ -4,6 +4,7 @@
* PURPOSE: Implementation of _setjmp/longjmp
* FILE: lib/sdk/crt/setjmp/amd64/setjmp.s
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
* Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
*/
/* INCLUDES ******************************************************************/
@ -50,33 +51,8 @@ FUNC _setjmp
.endprolog
/* Load rsp as it was before the call into rax */
lea rax, [rsp + 8]
/* Load return address into r8 */
mov r8, [rsp]
mov qword ptr [rcx + JUMP_BUFFER_Frame], 0
mov [rcx + JUMP_BUFFER_Rbx], rbx
mov [rcx + JUMP_BUFFER_Rbp], rbp
mov [rcx + JUMP_BUFFER_Rsi], rsi
mov [rcx + JUMP_BUFFER_Rdi], rdi
mov [rcx + JUMP_BUFFER_R12], r12
mov [rcx + JUMP_BUFFER_R13], r13
mov [rcx + JUMP_BUFFER_R14], r14
mov [rcx + JUMP_BUFFER_R15], r15
mov [rcx + JUMP_BUFFER_Rsp], rax
mov [rcx + JUMP_BUFFER_Rip], r8
movdqa [rcx + JUMP_BUFFER_Xmm6], xmm6
movdqa [rcx + JUMP_BUFFER_Xmm7], xmm7
movdqa [rcx + JUMP_BUFFER_Xmm8], xmm8
movdqa [rcx + JUMP_BUFFER_Xmm9], xmm9
movdqa [rcx + JUMP_BUFFER_Xmm10], xmm10
movdqa [rcx + JUMP_BUFFER_Xmm11], xmm11
movdqa [rcx + JUMP_BUFFER_Xmm12], xmm12
movdqa [rcx + JUMP_BUFFER_Xmm13], xmm13
movdqa [rcx + JUMP_BUFFER_Xmm14], xmm14
movdqa [rcx + JUMP_BUFFER_Xmm15], xmm15
xor rax, rax
ret
xor rdx, rdx
jmp _setjmpex
ENDFUNC
/*!
@ -92,32 +68,35 @@ FUNC _setjmpex
.endprolog
/* Load rsp as it was before the call into rax */
lea rax, [rsp + 8]
/* Load return address into r8 */
mov r8, [rsp]
mov [rcx + JUMP_BUFFER_Frame], rdx
mov [rcx + JUMP_BUFFER_Rbx], rbx
mov [rcx + JUMP_BUFFER_Rbp], rbp
mov [rcx + JUMP_BUFFER_Rsi], rsi
mov [rcx + JUMP_BUFFER_Rdi], rdi
mov [rcx + JUMP_BUFFER_R12], r12
mov [rcx + JUMP_BUFFER_R13], r13
mov [rcx + JUMP_BUFFER_R14], r14
mov [rcx + JUMP_BUFFER_R15], r15
mov [rcx + JUMP_BUFFER_Rsp], rax
mov [rcx + JUMP_BUFFER_Rip], r8
movdqa [rcx + JUMP_BUFFER_Xmm6], xmm6
movdqa [rcx + JUMP_BUFFER_Xmm7], xmm7
movdqa [rcx + JUMP_BUFFER_Xmm8], xmm8
movdqa [rcx + JUMP_BUFFER_Xmm9], xmm9
movdqa [rcx + JUMP_BUFFER_Xmm10], xmm10
movdqa [rcx + JUMP_BUFFER_Xmm11], xmm11
movdqa [rcx + JUMP_BUFFER_Xmm12], xmm12
movdqa [rcx + JUMP_BUFFER_Xmm13], xmm13
movdqa [rcx + JUMP_BUFFER_Xmm14], xmm14
movdqa [rcx + JUMP_BUFFER_Xmm15], xmm15
xor rax, rax
push rbp /* Save rbp */
mov rbp, rsp /* rbp = rsp */
and rsp, -16 /* Align rsp to 16-byte boundary */
mov [rcx + JUMP_BUFFER_Rbx], rbx /* Store rbx */
mov [rcx + JUMP_BUFFER_Rsp], rsp /* Store rsp */
mov [rcx + JUMP_BUFFER_Rbp], rbp /* Store rbp */
mov [rcx + JUMP_BUFFER_Rsi], rsi /* Store rsi (non-volatile on windows) */
mov [rcx + JUMP_BUFFER_Rdi], rdi /* Store rdi (non-volatile on windows) */
mov [rcx + JUMP_BUFFER_R12], r12 /* Store r12 */
mov [rcx + JUMP_BUFFER_R13], r13 /* Store r13 */
mov [rcx + JUMP_BUFFER_R14], r14 /* Store r14 */
mov [rcx + JUMP_BUFFER_R15], r15 /* Store r15 */
lea rax, [rip + LABEL2] /* Get the return address (LABEL2) */
mov [rcx + JUMP_BUFFER_Rip], rax /* Store rip (return address) */
mov [rcx + JUMP_BUFFER_Frame], rdx /* Store frame */
movdqu [rcx + JUMP_BUFFER_Xmm6], xmm6 /* Store xmm6 */
movdqu [rcx + JUMP_BUFFER_Xmm7], xmm7 /* Store xmm7 */
movdqu [rcx + JUMP_BUFFER_Xmm8], xmm8 /* Store xmm8 */
movdqu [rcx + JUMP_BUFFER_Xmm9], xmm9 /* Store xmm9 */
movdqu [rcx + JUMP_BUFFER_Xmm10], xmm10 /* Store xmm10 */
movdqu [rcx + JUMP_BUFFER_Xmm11], xmm11 /* Store xmm11 */
movdqu [rcx + JUMP_BUFFER_Xmm12], xmm12 /* Store xmm12 */
movdqu [rcx + JUMP_BUFFER_Xmm13], xmm13 /* Store xmm13 */
movdqu [rcx + JUMP_BUFFER_Xmm14], xmm14 /* Store xmm14 */
movdqu [rcx + JUMP_BUFFER_Xmm15], xmm15 /* Store xmm15 */
mov rsp, rbp /* Restore original rsp */
pop rbp /* Restore original rbp */
xor eax, eax /* Return 0 */
LABEL2:
ret
ENDFUNC
@ -135,35 +114,34 @@ FUNC longjmp
.endprolog
// FIXME: handle frame
mov rbx, [rcx + JUMP_BUFFER_Rbx]
mov rbp, [rcx + JUMP_BUFFER_Rbp]
mov rsi, [rcx + JUMP_BUFFER_Rsi]
mov rdi, [rcx + JUMP_BUFFER_Rdi]
mov r12, [rcx + JUMP_BUFFER_R12]
mov r13, [rcx + JUMP_BUFFER_R13]
mov r14, [rcx + JUMP_BUFFER_R14]
mov r15, [rcx + JUMP_BUFFER_R15]
mov rsp, [rcx + JUMP_BUFFER_Rsp]
mov r8, [rcx + JUMP_BUFFER_Rip]
movdqa xmm6, [rcx + JUMP_BUFFER_Xmm6]
movdqa xmm7, [rcx + JUMP_BUFFER_Xmm7]
movdqa xmm8, [rcx + JUMP_BUFFER_Xmm8]
movdqa xmm9, [rcx + JUMP_BUFFER_Xmm9]
movdqa xmm10, [rcx + JUMP_BUFFER_Xmm10]
movdqa xmm11, [rcx + JUMP_BUFFER_Xmm11]
movdqa xmm12, [rcx + JUMP_BUFFER_Xmm12]
movdqa xmm13, [rcx + JUMP_BUFFER_Xmm13]
movdqa xmm14, [rcx + JUMP_BUFFER_Xmm14]
movdqa xmm15, [rcx + JUMP_BUFFER_Xmm15]
/* return param2 or 1 if it was 0 */
mov rax, rdx
test rax, rax
jnz l2
inc rax
l2: jmp r8
mov rbx, [rcx + JUMP_BUFFER_Rbx] /* Restore rbx */
mov rsp, [rcx + JUMP_BUFFER_Rsp] /* Restore rsp */
mov rbp, [rcx + JUMP_BUFFER_Rbp] /* Restore rbp */
mov rsi, [rcx + JUMP_BUFFER_Rsi] /* Restore rsi */
mov rdi, [rcx + JUMP_BUFFER_Rdi] /* Restore rdi */
mov r12, [rcx + JUMP_BUFFER_R12] /* Restore r12 */
mov r13, [rcx + JUMP_BUFFER_R13] /* Restore r13 */
mov r14, [rcx + JUMP_BUFFER_R14] /* Restore r14 */
mov r15, [rcx + JUMP_BUFFER_R15] /* Restore r15 */
mov rax, [rcx + JUMP_BUFFER_Frame] /* Restore frame pointer */
mov [rsp + 8], rax /* Restore frame pointer */
movdqu xmm6, [rcx + JUMP_BUFFER_Xmm6] /* Restore xmm6 */
movdqu xmm7, [rcx + JUMP_BUFFER_Xmm7] /* Restore xmm7 */
movdqu xmm8, [rcx + JUMP_BUFFER_Xmm8] /* Restore xmm8 */
movdqu xmm9, [rcx + JUMP_BUFFER_Xmm9] /* Restore xmm9 */
movdqu xmm10, [rcx + JUMP_BUFFER_Xmm10] /* Restore xmm10 */
movdqu xmm11, [rcx + JUMP_BUFFER_Xmm11] /* Restore xmm11 */
movdqu xmm12, [rcx + JUMP_BUFFER_Xmm12] /* Restore xmm12 */
movdqu xmm13, [rcx + JUMP_BUFFER_Xmm13] /* Restore xmm13 */
movdqu xmm14, [rcx + JUMP_BUFFER_Xmm14] /* Restore xmm14 */
movdqu xmm15, [rcx + JUMP_BUFFER_Xmm15] /* Restore xmm15 */
mov rax, rdx /* Move val into rax (return value) */
test rax, rax /* Check if val is 0 */
jz LABEL3 /* If val is 0, jump to LABEL3 */
jmp qword ptr [rcx + JUMP_BUFFER_Rip] /* Jump to the stored return address (rip) */
LABEL3:
mov rax, 1 /* If val was 0, return 1 */
jmp qword ptr [rcx + JUMP_BUFFER_Rip] /* Jump to the stored return address (rip) */
ENDFUNC
END