25 #ifdef _FORTIFY_SOURCE
26 #undef _FORTIFY_SOURCE
37 #if defined(__clang__) || defined(__GNUC__)
38 #if defined(__arm__) || defined(__aarch64__)
39 #define MKJMP_SET_SP(sp, size) \
40 __asm__("mov sp, %0" ::"r"((char *)(sp) + (size)))
41 #elif defined(__i386__)
42 #define MKJMP_SET_SP(sp, size) \
43 __asm__("movl %0, %%esp" ::"r"((char *)(sp) + (size)))
44 #elif defined(__x86_64__)
45 #define MKJMP_SET_SP(sp, size) \
46 __asm__("movq %0, %%rsp" ::"r"((char *)(sp) + (size)))
48 #elif defined(_MSC_VER)
50 #define MKJMP_SET_SP(sp, size) \
51 void *_sp = (char *)(sp) + (size); \
53 #elif defined(_M_IX86)
54 #define MKJMP_SET_SP(sp, size) \
55 void *_sp = (char *)(sp) + (size); \
61 #error Unsupported compiler or architecture for mkjmp()/sigmkjmp().
67 static thread_local
struct {
75 static _Noreturn void ctx_init(
void *sp,
size_t size);
78 #if _POSIX_C_SOURCE >= 200112L && (!defined(__NEWLIB__) || defined(__CYGWIN__))
81 static struct sigctx {
83 static thread_local
struct {
92 static _Noreturn void sigctx_init(
void *sp,
size_t size);
98 mkjmp(jmp_buf env,
void (*func)(
void *),
void *arg,
void *sp,
size_t size)
104 if (!setjmp(ctx.env))
110 #if _POSIX_C_SOURCE >= 200112L && (!defined(__NEWLIB__) || defined(__CYGWIN__))
113 sigmkjmp(sigjmp_buf env,
int savemask,
void (*func)(
void *),
void *arg,
114 void *sp,
size_t size)
117 sigctx.savemask = savemask;
121 if (!sigsetjmp(sigctx.env, 0))
122 sigctx_init(sp, size);
130 ctx_init(
void *sp,
size_t size)
135 MKJMP_SET_SP(sp, size);
146 void (*func)(
void *) = ctx.func;
150 if (!setjmp(ctx.penv))
168 #if _POSIX_C_SOURCE >= 200112L && (!defined(__NEWLIB__) || defined(__CYGWIN__))
171 sigctx_init(
void *sp,
size_t size)
176 MKJMP_SET_SP(sp, size);
187 void (*func)(
void *) = sigctx.func;
188 void *arg = sigctx.arg;
191 if (!sigsetjmp(sigctx.penv, sigctx.savemask))
192 siglongjmp(sigctx.env, 1);
#define _Noreturn
A function declared with a _Noreturn function specifier SHALL not return to its caller.
int mkjmp(jmp_buf env, void(*func)(void *), void *arg, void *sp, size_t size)
Creates and stores a calling environment with a user-provided stack suitable for use by longjmp().
int sigmkjmp(sigjmp_buf env, int savemask, void(*func)(void *), void *arg, void *sp, size_t size)
Creates and stores a calling environment with a user-provided stack suitable for use by siglongjmp().
This header file is part of the utilities library; it contains the mkjmp() and sigmkjmp() function de...
This is the internal header file of the utilities library.
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib....
This header file is part of the C11 and POSIX compatibility library; it includes <threads....
_Noreturn void thrd_exit(int res)
Terminates execution of the calling thread and sets its result code to res.