mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-15 05:16:30 +00:00
Polyfill SA_RESETHAND on MacOS ARM64
This change solves the XNU crash loop mystery. Apple's documentation claims to support this feature, but they only define the constant in their header files. The kernel acknowledges thi SA_RESETHAND bit, by clearing it from the sa_flags state, returns zero, and does nothing.
This commit is contained in:
parent
952b9009e8
commit
793393a341
3 changed files with 23 additions and 2 deletions
|
@ -252,6 +252,12 @@ static int __sigaction(int sig, const struct sigaction *act,
|
|||
rc = sys_sigaction(sig, ap, oldact, arg4, arg5);
|
||||
} else {
|
||||
rc = _sysret(__syslib->__sigaction(sig, ap, oldact));
|
||||
// xnu silicon claims to support sa_resethand but it does nothing
|
||||
// this can be tested, since it clears the bit from flags as well
|
||||
if (!rc && oldact &&
|
||||
(((struct sigaction_silicon *)ap)->sa_flags & SA_RESETHAND)) {
|
||||
((struct sigaction_silicon *)oldact)->sa_flags |= SA_RESETHAND;
|
||||
}
|
||||
}
|
||||
if (rc != -1) {
|
||||
sigaction_native2cosmo((union metasigaction *)oldact);
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/stack.h"
|
||||
#include "libc/runtime/syslib.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/sa.h"
|
||||
|
||||
|
@ -494,6 +495,8 @@ privileged void __sigenter_xnu(void *fn, int infostyle, int sig,
|
|||
privileged void __sigenter_xnu(int sig, struct siginfo_xnu *xnuinfo,
|
||||
struct __darwin_ucontext *xnuctx) {
|
||||
#endif
|
||||
|
||||
// allocate signal frame on stack
|
||||
#pragma GCC push_options
|
||||
#pragma GCC diagnostic ignored "-Wframe-larger-than="
|
||||
struct Goodies {
|
||||
|
@ -502,10 +505,24 @@ privileged void __sigenter_xnu(int sig, struct siginfo_xnu *xnuinfo,
|
|||
} g;
|
||||
CheckLargeStackAllocation(&g, sizeof(g));
|
||||
#pragma GCC pop_options
|
||||
|
||||
// handle signal
|
||||
int rva, flags;
|
||||
rva = __sighandrvas[sig];
|
||||
if (rva >= kSigactionMinRva) {
|
||||
flags = __sighandflags[sig];
|
||||
|
||||
#ifdef __aarch64__
|
||||
// xnu silicon claims to support sa_resethand but it does nothing
|
||||
// this can be tested, since it clears the bit from flags as well
|
||||
if (flags & SA_RESETHAND) {
|
||||
struct sigaction sa = {0};
|
||||
__syslib->__sigaction(sig, &sa, 0);
|
||||
__sighandflags[sig] = 0;
|
||||
__sighandrvas[sig] = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (~flags & SA_SIGINFO) {
|
||||
((sigaction_f)(__executable_start + rva))(sig, 0, 0);
|
||||
} else {
|
||||
|
|
|
@ -394,8 +394,6 @@ relegated void __oncrash(int sig, struct siginfo *si, void *arg) {
|
|||
BLOCK_CANCELATION;
|
||||
SpinLock(&lock);
|
||||
__oncrash_impl(sig, si, arg);
|
||||
if (sig != SIGQUIT && sig != SIGTRAP)
|
||||
_exit(1);
|
||||
SpinUnlock(&lock);
|
||||
ALLOW_CANCELATION;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue