mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 17:52:56 +00:00
[SDK][CRT] Improve x64 setjmp/longjmp and add testcase
This commit is contained in:
parent
467dec4d16
commit
2a2c8318bf
7 changed files with 135 additions and 87 deletions
|
@ -260,7 +260,7 @@ list(APPEND SOURCE_CRTDLL
|
||||||
# _scalb.c
|
# _scalb.c
|
||||||
# _searchenv.c
|
# _searchenv.c
|
||||||
# _seterrormode.c
|
# _seterrormode.c
|
||||||
# _setjmp.c
|
setjmp.c
|
||||||
# _setmode.c
|
# _setmode.c
|
||||||
# _setsystime.c
|
# _setsystime.c
|
||||||
# _sleep.c
|
# _sleep.c
|
||||||
|
@ -544,7 +544,7 @@ if(ARCH STREQUAL "i386")
|
||||||
elseif(ARCH STREQUAL "amd64")
|
elseif(ARCH STREQUAL "amd64")
|
||||||
list(APPEND SOURCE_CRTDLL
|
list(APPEND SOURCE_CRTDLL
|
||||||
# __C_specific_handler
|
# __C_specific_handler
|
||||||
# _setjmp.c
|
setjmp.c
|
||||||
# _setjmpex.c
|
# _setjmpex.c
|
||||||
# _local_unwind.c
|
# _local_unwind.c
|
||||||
# longjmp.c
|
# longjmp.c
|
||||||
|
|
|
@ -1145,7 +1145,7 @@ list(APPEND SOURCE_MSVCRT
|
||||||
# scanf.c
|
# scanf.c
|
||||||
# scanf_s.c
|
# scanf_s.c
|
||||||
# setbuf.c
|
# setbuf.c
|
||||||
# _setjmp.c
|
setjmp.c
|
||||||
# setlocale.c
|
# setlocale.c
|
||||||
# setvbuf.c
|
# setvbuf.c
|
||||||
# signal.c
|
# signal.c
|
||||||
|
@ -1352,7 +1352,7 @@ if(ARCH STREQUAL "i386")
|
||||||
elseif(ARCH STREQUAL "amd64")
|
elseif(ARCH STREQUAL "amd64")
|
||||||
list(APPEND SOURCE_MSVCRT
|
list(APPEND SOURCE_MSVCRT
|
||||||
# __C_specific_handler
|
# __C_specific_handler
|
||||||
# _setjmp.c
|
setjmp.c
|
||||||
# _setjmpex.c
|
# _setjmpex.c
|
||||||
# _local_unwind.c
|
# _local_unwind.c
|
||||||
# longjmp.c
|
# longjmp.c
|
||||||
|
|
|
@ -146,7 +146,7 @@ if(ARCH STREQUAL "i386")
|
||||||
elseif(ARCH STREQUAL "amd64")
|
elseif(ARCH STREQUAL "amd64")
|
||||||
list(APPEND SOURCE_NTDLL
|
list(APPEND SOURCE_NTDLL
|
||||||
# __C_specific_handler
|
# __C_specific_handler
|
||||||
# _setjmp.c
|
setjmp.c
|
||||||
# _setjmpex.c
|
# _setjmpex.c
|
||||||
# _local_unwind.c
|
# _local_unwind.c
|
||||||
# longjmp.c
|
# longjmp.c
|
||||||
|
|
67
modules/rostests/apitests/crt/setjmp.c
Normal file
67
modules/rostests/apitests/crt/setjmp.c
Normal file
|
@ -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 <apitest.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
#
|
||||||
|
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();
|
||||||
|
}
|
|
@ -14,6 +14,7 @@ list(APPEND SOURCE_STATIC
|
||||||
mbstowcs.c
|
mbstowcs.c
|
||||||
mbtowc.c
|
mbtowc.c
|
||||||
rand_s.c
|
rand_s.c
|
||||||
|
setjmp.c
|
||||||
sprintf.c
|
sprintf.c
|
||||||
strcpy.c
|
strcpy.c
|
||||||
strlen.c
|
strlen.c
|
||||||
|
|
|
@ -32,6 +32,7 @@ extern void func__vsnprintf(void);
|
||||||
extern void func__vsnwprintf(void);
|
extern void func__vsnwprintf(void);
|
||||||
extern void func_mbstowcs(void);
|
extern void func_mbstowcs(void);
|
||||||
extern void func_mbtowc(void);
|
extern void func_mbtowc(void);
|
||||||
|
extern void func_setjmp(void);
|
||||||
extern void func_rand_s(void);
|
extern void func_rand_s(void);
|
||||||
extern void func_sprintf(void);
|
extern void func_sprintf(void);
|
||||||
extern void func_strcpy(void);
|
extern void func_strcpy(void);
|
||||||
|
@ -56,6 +57,7 @@ const struct test winetest_testlist[] =
|
||||||
{ "_vsnwprintf", func__vsnwprintf },
|
{ "_vsnwprintf", func__vsnwprintf },
|
||||||
{ "mbstowcs", func_mbstowcs },
|
{ "mbstowcs", func_mbstowcs },
|
||||||
{ "mbtowc", func_mbtowc },
|
{ "mbtowc", func_mbtowc },
|
||||||
|
{ "setjmp", func_setjmp },
|
||||||
{ "_snprintf", func__snprintf },
|
{ "_snprintf", func__snprintf },
|
||||||
{ "_snwprintf", func__snwprintf },
|
{ "_snwprintf", func__snwprintf },
|
||||||
{ "sprintf", func_sprintf },
|
{ "sprintf", func_sprintf },
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* PURPOSE: Implementation of _setjmp/longjmp
|
* PURPOSE: Implementation of _setjmp/longjmp
|
||||||
* FILE: lib/sdk/crt/setjmp/amd64/setjmp.s
|
* FILE: lib/sdk/crt/setjmp/amd64/setjmp.s
|
||||||
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
|
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||||
|
* Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
@ -50,33 +51,8 @@ FUNC _setjmp
|
||||||
|
|
||||||
.endprolog
|
.endprolog
|
||||||
|
|
||||||
/* Load rsp as it was before the call into rax */
|
xor rdx, rdx
|
||||||
lea rax, [rsp + 8]
|
jmp _setjmpex
|
||||||
/* 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
|
|
||||||
ENDFUNC
|
ENDFUNC
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -92,32 +68,35 @@ FUNC _setjmpex
|
||||||
|
|
||||||
.endprolog
|
.endprolog
|
||||||
|
|
||||||
/* Load rsp as it was before the call into rax */
|
push rbp /* Save rbp */
|
||||||
lea rax, [rsp + 8]
|
mov rbp, rsp /* rbp = rsp */
|
||||||
/* Load return address into r8 */
|
and rsp, -16 /* Align rsp to 16-byte boundary */
|
||||||
mov r8, [rsp]
|
mov [rcx + JUMP_BUFFER_Rbx], rbx /* Store rbx */
|
||||||
mov [rcx + JUMP_BUFFER_Frame], rdx
|
mov [rcx + JUMP_BUFFER_Rsp], rsp /* Store rsp */
|
||||||
mov [rcx + JUMP_BUFFER_Rbx], rbx
|
mov [rcx + JUMP_BUFFER_Rbp], rbp /* Store rbp */
|
||||||
mov [rcx + JUMP_BUFFER_Rbp], rbp
|
mov [rcx + JUMP_BUFFER_Rsi], rsi /* Store rsi (non-volatile on windows) */
|
||||||
mov [rcx + JUMP_BUFFER_Rsi], rsi
|
mov [rcx + JUMP_BUFFER_Rdi], rdi /* Store rdi (non-volatile on windows) */
|
||||||
mov [rcx + JUMP_BUFFER_Rdi], rdi
|
mov [rcx + JUMP_BUFFER_R12], r12 /* Store r12 */
|
||||||
mov [rcx + JUMP_BUFFER_R12], r12
|
mov [rcx + JUMP_BUFFER_R13], r13 /* Store r13 */
|
||||||
mov [rcx + JUMP_BUFFER_R13], r13
|
mov [rcx + JUMP_BUFFER_R14], r14 /* Store r14 */
|
||||||
mov [rcx + JUMP_BUFFER_R14], r14
|
mov [rcx + JUMP_BUFFER_R15], r15 /* Store r15 */
|
||||||
mov [rcx + JUMP_BUFFER_R15], r15
|
lea rax, [rip + LABEL2] /* Get the return address (LABEL2) */
|
||||||
mov [rcx + JUMP_BUFFER_Rsp], rax
|
mov [rcx + JUMP_BUFFER_Rip], rax /* Store rip (return address) */
|
||||||
mov [rcx + JUMP_BUFFER_Rip], r8
|
mov [rcx + JUMP_BUFFER_Frame], rdx /* Store frame */
|
||||||
movdqa [rcx + JUMP_BUFFER_Xmm6], xmm6
|
movdqu [rcx + JUMP_BUFFER_Xmm6], xmm6 /* Store xmm6 */
|
||||||
movdqa [rcx + JUMP_BUFFER_Xmm7], xmm7
|
movdqu [rcx + JUMP_BUFFER_Xmm7], xmm7 /* Store xmm7 */
|
||||||
movdqa [rcx + JUMP_BUFFER_Xmm8], xmm8
|
movdqu [rcx + JUMP_BUFFER_Xmm8], xmm8 /* Store xmm8 */
|
||||||
movdqa [rcx + JUMP_BUFFER_Xmm9], xmm9
|
movdqu [rcx + JUMP_BUFFER_Xmm9], xmm9 /* Store xmm9 */
|
||||||
movdqa [rcx + JUMP_BUFFER_Xmm10], xmm10
|
movdqu [rcx + JUMP_BUFFER_Xmm10], xmm10 /* Store xmm10 */
|
||||||
movdqa [rcx + JUMP_BUFFER_Xmm11], xmm11
|
movdqu [rcx + JUMP_BUFFER_Xmm11], xmm11 /* Store xmm11 */
|
||||||
movdqa [rcx + JUMP_BUFFER_Xmm12], xmm12
|
movdqu [rcx + JUMP_BUFFER_Xmm12], xmm12 /* Store xmm12 */
|
||||||
movdqa [rcx + JUMP_BUFFER_Xmm13], xmm13
|
movdqu [rcx + JUMP_BUFFER_Xmm13], xmm13 /* Store xmm13 */
|
||||||
movdqa [rcx + JUMP_BUFFER_Xmm14], xmm14
|
movdqu [rcx + JUMP_BUFFER_Xmm14], xmm14 /* Store xmm14 */
|
||||||
movdqa [rcx + JUMP_BUFFER_Xmm15], xmm15
|
movdqu [rcx + JUMP_BUFFER_Xmm15], xmm15 /* Store xmm15 */
|
||||||
xor rax, rax
|
mov rsp, rbp /* Restore original rsp */
|
||||||
|
pop rbp /* Restore original rbp */
|
||||||
|
xor eax, eax /* Return 0 */
|
||||||
|
LABEL2:
|
||||||
ret
|
ret
|
||||||
ENDFUNC
|
ENDFUNC
|
||||||
|
|
||||||
|
@ -135,35 +114,34 @@ FUNC longjmp
|
||||||
|
|
||||||
.endprolog
|
.endprolog
|
||||||
|
|
||||||
// FIXME: handle frame
|
mov rbx, [rcx + JUMP_BUFFER_Rbx] /* Restore rbx */
|
||||||
|
mov rsp, [rcx + JUMP_BUFFER_Rsp] /* Restore rsp */
|
||||||
mov rbx, [rcx + JUMP_BUFFER_Rbx]
|
mov rbp, [rcx + JUMP_BUFFER_Rbp] /* Restore rbp */
|
||||||
mov rbp, [rcx + JUMP_BUFFER_Rbp]
|
mov rsi, [rcx + JUMP_BUFFER_Rsi] /* Restore rsi */
|
||||||
mov rsi, [rcx + JUMP_BUFFER_Rsi]
|
mov rdi, [rcx + JUMP_BUFFER_Rdi] /* Restore rdi */
|
||||||
mov rdi, [rcx + JUMP_BUFFER_Rdi]
|
mov r12, [rcx + JUMP_BUFFER_R12] /* Restore r12 */
|
||||||
mov r12, [rcx + JUMP_BUFFER_R12]
|
mov r13, [rcx + JUMP_BUFFER_R13] /* Restore r13 */
|
||||||
mov r13, [rcx + JUMP_BUFFER_R13]
|
mov r14, [rcx + JUMP_BUFFER_R14] /* Restore r14 */
|
||||||
mov r14, [rcx + JUMP_BUFFER_R14]
|
mov r15, [rcx + JUMP_BUFFER_R15] /* Restore r15 */
|
||||||
mov r15, [rcx + JUMP_BUFFER_R15]
|
mov rax, [rcx + JUMP_BUFFER_Frame] /* Restore frame pointer */
|
||||||
mov rsp, [rcx + JUMP_BUFFER_Rsp]
|
mov [rsp + 8], rax /* Restore frame pointer */
|
||||||
mov r8, [rcx + JUMP_BUFFER_Rip]
|
movdqu xmm6, [rcx + JUMP_BUFFER_Xmm6] /* Restore xmm6 */
|
||||||
movdqa xmm6, [rcx + JUMP_BUFFER_Xmm6]
|
movdqu xmm7, [rcx + JUMP_BUFFER_Xmm7] /* Restore xmm7 */
|
||||||
movdqa xmm7, [rcx + JUMP_BUFFER_Xmm7]
|
movdqu xmm8, [rcx + JUMP_BUFFER_Xmm8] /* Restore xmm8 */
|
||||||
movdqa xmm8, [rcx + JUMP_BUFFER_Xmm8]
|
movdqu xmm9, [rcx + JUMP_BUFFER_Xmm9] /* Restore xmm9 */
|
||||||
movdqa xmm9, [rcx + JUMP_BUFFER_Xmm9]
|
movdqu xmm10, [rcx + JUMP_BUFFER_Xmm10] /* Restore xmm10 */
|
||||||
movdqa xmm10, [rcx + JUMP_BUFFER_Xmm10]
|
movdqu xmm11, [rcx + JUMP_BUFFER_Xmm11] /* Restore xmm11 */
|
||||||
movdqa xmm11, [rcx + JUMP_BUFFER_Xmm11]
|
movdqu xmm12, [rcx + JUMP_BUFFER_Xmm12] /* Restore xmm12 */
|
||||||
movdqa xmm12, [rcx + JUMP_BUFFER_Xmm12]
|
movdqu xmm13, [rcx + JUMP_BUFFER_Xmm13] /* Restore xmm13 */
|
||||||
movdqa xmm13, [rcx + JUMP_BUFFER_Xmm13]
|
movdqu xmm14, [rcx + JUMP_BUFFER_Xmm14] /* Restore xmm14 */
|
||||||
movdqa xmm14, [rcx + JUMP_BUFFER_Xmm14]
|
movdqu xmm15, [rcx + JUMP_BUFFER_Xmm15] /* Restore xmm15 */
|
||||||
movdqa xmm15, [rcx + JUMP_BUFFER_Xmm15]
|
mov rax, rdx /* Move val into rax (return value) */
|
||||||
|
test rax, rax /* Check if val is 0 */
|
||||||
/* return param2 or 1 if it was 0 */
|
jz LABEL3 /* If val is 0, jump to LABEL3 */
|
||||||
mov rax, rdx
|
jmp qword ptr [rcx + JUMP_BUFFER_Rip] /* Jump to the stored return address (rip) */
|
||||||
test rax, rax
|
LABEL3:
|
||||||
jnz l2
|
mov rax, 1 /* If val was 0, return 1 */
|
||||||
inc rax
|
jmp qword ptr [rcx + JUMP_BUFFER_Rip] /* Jump to the stored return address (rip) */
|
||||||
l2: jmp r8
|
|
||||||
ENDFUNC
|
ENDFUNC
|
||||||
|
|
||||||
END
|
END
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue