diff --git a/modules/rostests/apitests/crt/crtdll_crt_apitest.cmake b/modules/rostests/apitests/crt/crtdll_crt_apitest.cmake index cc9a32d004b..77a443e3e09 100644 --- a/modules/rostests/apitests/crt/crtdll_crt_apitest.cmake +++ b/modules/rostests/apitests/crt/crtdll_crt_apitest.cmake @@ -260,7 +260,7 @@ list(APPEND SOURCE_CRTDLL # _scalb.c # _searchenv.c # _seterrormode.c -# _setjmp.c + setjmp.c # _setmode.c # _setsystime.c # _sleep.c @@ -544,7 +544,7 @@ if(ARCH STREQUAL "i386") elseif(ARCH STREQUAL "amd64") list(APPEND SOURCE_CRTDLL # __C_specific_handler - # _setjmp.c + setjmp.c # _setjmpex.c # _local_unwind.c # longjmp.c diff --git a/modules/rostests/apitests/crt/msvcrt_crt_apitest.cmake b/modules/rostests/apitests/crt/msvcrt_crt_apitest.cmake index ad599eed3a3..4fdbe676158 100644 --- a/modules/rostests/apitests/crt/msvcrt_crt_apitest.cmake +++ b/modules/rostests/apitests/crt/msvcrt_crt_apitest.cmake @@ -1145,7 +1145,7 @@ list(APPEND SOURCE_MSVCRT # scanf.c # scanf_s.c # setbuf.c -# _setjmp.c + setjmp.c # setlocale.c # setvbuf.c # signal.c @@ -1352,7 +1352,7 @@ if(ARCH STREQUAL "i386") elseif(ARCH STREQUAL "amd64") list(APPEND SOURCE_MSVCRT # __C_specific_handler - # _setjmp.c + setjmp.c # _setjmpex.c # _local_unwind.c # longjmp.c diff --git a/modules/rostests/apitests/crt/ntdll_crt_apitest.cmake b/modules/rostests/apitests/crt/ntdll_crt_apitest.cmake index 7f923043068..6aee9d615f3 100644 --- a/modules/rostests/apitests/crt/ntdll_crt_apitest.cmake +++ b/modules/rostests/apitests/crt/ntdll_crt_apitest.cmake @@ -146,7 +146,7 @@ if(ARCH STREQUAL "i386") elseif(ARCH STREQUAL "amd64") list(APPEND SOURCE_NTDLL # __C_specific_handler - # _setjmp.c + setjmp.c # _setjmpex.c # _local_unwind.c # longjmp.c diff --git a/modules/rostests/apitests/crt/setjmp.c b/modules/rostests/apitests/crt/setjmp.c new file mode 100644 index 00000000000..fe5a79d6006 --- /dev/null +++ b/modules/rostests/apitests/crt/setjmp.c @@ -0,0 +1,67 @@ +/* + * PROJECT: ReactOS CRT + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Tests for setjmp/longjmp + * COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com) + */ + +#include +#include +# +static jmp_buf g_jmp_buf; + +static void Test_longjmp(void) +{ + longjmp(g_jmp_buf, 1); +} + +static void Test_setjmp_0(void) +{ + if (setjmp(g_jmp_buf) == 0) + { + ok_int(TRUE, TRUE); + } + else + { + ok_int(TRUE, FALSE); + } +} + +static void Test_setjmp_1(void) +{ + if (setjmp(g_jmp_buf) == 0) + { + Test_longjmp(); + ok_int(TRUE, FALSE); + } + else + { + ok_int(TRUE, TRUE); + } +} + +static void Test_setjmp_2(void) +{ + volatile int x = 2; + volatile int y = 3; + volatile int z = 4; + if (setjmp(g_jmp_buf) == 0) + { + Test_longjmp(); + ok_int(TRUE, FALSE); + } + else + { + ok_int(x, 2); + ok_int(y, 3); + ok_int(z, 4); + ok_int(TRUE, TRUE); + } +} + +START_TEST(setjmp) +{ + Test_setjmp_0(); + Test_setjmp_1(); + Test_setjmp_2(); +} diff --git a/modules/rostests/apitests/crt/static_crt_apitest.cmake b/modules/rostests/apitests/crt/static_crt_apitest.cmake index 78f4487ec2f..4edc08e388b 100644 --- a/modules/rostests/apitests/crt/static_crt_apitest.cmake +++ b/modules/rostests/apitests/crt/static_crt_apitest.cmake @@ -14,6 +14,7 @@ list(APPEND SOURCE_STATIC mbstowcs.c mbtowc.c rand_s.c + setjmp.c sprintf.c strcpy.c strlen.c diff --git a/modules/rostests/apitests/crt/testlist.c b/modules/rostests/apitests/crt/testlist.c index 331c368f114..b7041bae71e 100644 --- a/modules/rostests/apitests/crt/testlist.c +++ b/modules/rostests/apitests/crt/testlist.c @@ -32,6 +32,7 @@ extern void func__vsnprintf(void); extern void func__vsnwprintf(void); extern void func_mbstowcs(void); extern void func_mbtowc(void); +extern void func_setjmp(void); extern void func_rand_s(void); extern void func_sprintf(void); extern void func_strcpy(void); @@ -56,6 +57,7 @@ const struct test winetest_testlist[] = { "_vsnwprintf", func__vsnwprintf }, { "mbstowcs", func_mbstowcs }, { "mbtowc", func_mbtowc }, + { "setjmp", func_setjmp }, { "_snprintf", func__snprintf }, { "_snwprintf", func__snwprintf }, { "sprintf", func_sprintf }, diff --git a/sdk/lib/crt/setjmp/amd64/setjmp.s b/sdk/lib/crt/setjmp/amd64/setjmp.s index 6aee6dbe07a..deb481af0d0 100644 --- a/sdk/lib/crt/setjmp/amd64/setjmp.s +++ b/sdk/lib/crt/setjmp/amd64/setjmp.s @@ -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