mirror of
https://git.musl-libc.org/git/musl
synced 2025-01-23 22:52:23 +03:00
jmp_buf overhaul fixing several issues
on arm, the location of the saved-signal-mask flag and mask were off by one between sigsetjmp and siglongjmp, causing incorrect behavior restoring the signal mask. this is because the siglongjmp code assumed an extra slot was in the non-sig jmp_buf for the flag, but arm did not have this. now, the extra slot is removed for all archs since it was useless. also, arm eabi requires jmp_buf to have 8-byte alignment. we achieve that using long long as the type rather than with non-portable gcc attribute tags.
This commit is contained in:
parent
e6129e6d83
commit
d6c0efe106
@ -1 +1 @@
|
||||
typedef unsigned long jmp_buf [64];
|
||||
typedef unsigned long long jmp_buf[32];
|
||||
|
@ -1 +1 @@
|
||||
typedef unsigned long jmp_buf [7];
|
||||
typedef unsigned long jmp_buf[6];
|
||||
|
@ -1 +1 @@
|
||||
typedef unsigned long jmp_buf [9];
|
||||
typedef unsigned long jmp_buf[8];
|
||||
|
@ -11,7 +11,11 @@ extern "C" {
|
||||
#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
|
||||
|| defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
|
||||
|| defined(_BSD_SOURCE)
|
||||
typedef unsigned long sigjmp_buf[(128+sizeof(jmp_buf))/sizeof(long)];
|
||||
typedef struct {
|
||||
jmp_buf __jb;
|
||||
unsigned long __fl;
|
||||
unsigned long __ss[128];
|
||||
} sigjmp_buf[1];
|
||||
int sigsetjmp (sigjmp_buf, int);
|
||||
void siglongjmp (sigjmp_buf, int);
|
||||
#endif
|
||||
|
@ -1,12 +1,11 @@
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include "syscall.h"
|
||||
|
||||
void siglongjmp(sigjmp_buf buf, int ret)
|
||||
{
|
||||
unsigned long *flag = buf + sizeof(jmp_buf)/sizeof(long) - 1;
|
||||
sigset_t *mask = (void *)(flag + 1);
|
||||
if (*flag)
|
||||
sigprocmask (SIG_SETMASK, mask, NULL);
|
||||
longjmp((void *)buf, ret);
|
||||
if (buf->__fl)
|
||||
__syscall(SYS_rt_sigprocmask, SIG_SETMASK, buf->__ss, 0, 8);
|
||||
longjmp(buf->__jb, ret);
|
||||
}
|
||||
|
@ -9,9 +9,7 @@
|
||||
|
||||
int sigsetjmp(sigjmp_buf buf, int save)
|
||||
{
|
||||
unsigned long *flag = buf + sizeof(jmp_buf)/sizeof(long);
|
||||
sigset_t *mask = (void *)(flag + 1);
|
||||
if ((*flag = save))
|
||||
sigprocmask (SIG_SETMASK, NULL, mask);
|
||||
return setjmp((void *)buf);
|
||||
if ((buf->__fl = save))
|
||||
pthread_sigmask(SIG_SETMASK, 0, (sigset_t *)buf->__ss);
|
||||
return setjmp(buf->__jb);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user