From 22cf6e11ebc8704519d084bf738ecf19d2811951 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Thu, 21 Sep 2023 10:10:20 -0700 Subject: [PATCH] Add siglongjmp() for aarch64 --- examples/ttyinfo.c | 2 +- libc/calls/read-nt.c | 10 ++++++---- libc/calls/setpgid.c | 4 ++-- libc/calls/struct/fd.internal.h | 2 +- libc/calls/tcgetattr-nt.c | 2 +- libc/calls/tcsetattr-nt.c | 4 ++-- libc/nexgen32e/longjmp.S | 1 + libc/nexgen32e/siglongjmp.S | 29 ----------------------------- libc/runtime/__sigsetjmp_tail.c | 5 +---- libc/runtime/runtime.h | 4 ++-- libc/runtime/runtime.mk | 2 ++ libc/runtime/sigsetjmp.S | 15 +++++++++++++++ test/libc/runtime/sigsetjmp_test.c | 3 --- 13 files changed, 34 insertions(+), 49 deletions(-) delete mode 100644 libc/nexgen32e/siglongjmp.S diff --git a/examples/ttyinfo.c b/examples/ttyinfo.c index 8672aecdb..dda2c7be0 100644 --- a/examples/ttyinfo.c +++ b/examples/ttyinfo.c @@ -82,7 +82,7 @@ int EnableRawMode(void) { t.c_iflag &= ~(INPCK | ISTRIP | PARMRK | INLCR | IGNCR | ICRNL | IXON | IGNBRK | BRKINT); - t.c_lflag &= ~(IEXTEN | ICANON | ECHO | ECHONL /* | ISIG */); + t.c_lflag &= ~(IEXTEN | ICANON | ECHO | ECHONL); t.c_cflag &= ~(CSIZE | PARENB); t.c_oflag |= OPOST | ONLCR; t.c_cflag |= CS8; diff --git a/libc/calls/read-nt.c b/libc/calls/read-nt.c index 2efc7fb00..7a1d8b03d 100644 --- a/libc/calls/read-nt.c +++ b/libc/calls/read-nt.c @@ -214,10 +214,12 @@ static textwindows int ProcessKeyEvent(const struct NtInputRecord *r, char *p) { } // handle ctrl-d the end of file keystroke - if (c == __veof && __veof != _POSIX_VDISABLE) { - STRACE("encountered CTRL(%#c) c_cc[VEOF] closing console input", CTRL(c)); - __keystroke.end_of_file = true; - return 0; + if (!(__ttymagic & kFdTtyUncanon)) { + if (c == __veof && __veof != _POSIX_VDISABLE) { + STRACE("encountered CTRL(%#c) c_cc[VEOF] closing console input", CTRL(c)); + __keystroke.end_of_file = true; + return 0; + } } // insert esc prefix when alt is held diff --git a/libc/calls/setpgid.c b/libc/calls/setpgid.c index 5a5c6b271..f389feec4 100644 --- a/libc/calls/setpgid.c +++ b/libc/calls/setpgid.c @@ -53,8 +53,8 @@ int setpgid(int pid, int pgid) { rc = __winerr(); } } else { - // irregular use cases not supported on windows - rc = einval(); + // avoid bash printing scary warnings for now + rc = 0; } } STRACE("setpgid(%d, %d) → %d% m", pid, pgid, rc); diff --git a/libc/calls/struct/fd.internal.h b/libc/calls/struct/fd.internal.h index c1a0b3d50..9677150c6 100644 --- a/libc/calls/struct/fd.internal.h +++ b/libc/calls/struct/fd.internal.h @@ -21,7 +21,7 @@ COSMOPOLITAN_C_START_ #define kFdTtyEchoing 1 /* read()→write() (ECHO && !ICANON) */ #define kFdTtyEchoRaw 2 /* don't ^X visualize control codes */ -#define kFdTtyMunging 4 /* enable input / output remappings */ +#define kFdTtyUncanon 4 /* enables non-canonical (raw) mode */ #define kFdTtyNoCr2Nl 8 /* don't map \r → \n (a.k.a !ICRNL) */ #define kFdTtyNoIsigs 16 #define kFdTtyNoBlock 32 diff --git a/libc/calls/tcgetattr-nt.c b/libc/calls/tcgetattr-nt.c index fe815e563..154d5b608 100644 --- a/libc/calls/tcgetattr-nt.c +++ b/libc/calls/tcgetattr-nt.c @@ -95,7 +95,7 @@ textwindows int tcgetattr_nt(int fd, struct termios *tio) { if (!(__ttymagic & kFdTtyNoIsigs)) { tio->c_lflag |= ISIG; } - if ((inmode & kNtEnableProcessedInput) || (__ttymagic & kFdTtyMunging)) { + if (inmode & kNtEnableProcessedInput) { tio->c_lflag |= IEXTEN; } diff --git a/libc/calls/tcsetattr-nt.c b/libc/calls/tcsetattr-nt.c index 9b1590daf..acba74e9e 100644 --- a/libc/calls/tcsetattr-nt.c +++ b/libc/calls/tcsetattr-nt.c @@ -67,7 +67,7 @@ textwindows int tcsetattr_nt(int fd, int opt, const struct termios *tio) { } if (opt == TCSAFLUSH) { - tcflush(fd, TCIFLUSH); + FlushConsoleInputBytes(hInput); } inmode &= ~(kNtEnableLineInput | kNtEnableEchoInput | kNtEnableProcessedInput | kNtEnableVirtualTerminalInput); @@ -78,7 +78,7 @@ textwindows int tcsetattr_nt(int fd, int opt, const struct termios *tio) { kNtEnableLineInput | kNtEnableProcessedInput | kNtEnableQuickEditMode; } else { inmode &= ~kNtEnableQuickEditMode; - __ttymagic |= kFdTtyMunging; + __ttymagic |= kFdTtyUncanon; if (!tio->c_cc[VMIN]) { __ttymagic |= kFdTtyNoBlock; } diff --git a/libc/nexgen32e/longjmp.S b/libc/nexgen32e/longjmp.S index 23f344f2f..5b3aee4fb 100644 --- a/libc/nexgen32e/longjmp.S +++ b/libc/nexgen32e/longjmp.S @@ -62,3 +62,4 @@ longjmp: #endif .endfn longjmp,globl .alias longjmp,_longjmp + .alias longjmp,siglongjmp diff --git a/libc/nexgen32e/siglongjmp.S b/libc/nexgen32e/siglongjmp.S deleted file mode 100644 index b1b9e8dff..000000000 --- a/libc/nexgen32e/siglongjmp.S +++ /dev/null @@ -1,29 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2022 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/macros.internal.h" - -// Loads previously saved processor state. -// -// @param rdi points to the jmp_buf -// @param esi is returned by setjmp() invocation (coerced nonzero) -// @noreturn -// @asyncsignalsafe -siglongjmp: - jmp longjmp - .endfn siglongjmp,globl diff --git a/libc/runtime/__sigsetjmp_tail.c b/libc/runtime/__sigsetjmp_tail.c index 3eb4f87cc..0b97cee27 100644 --- a/libc/runtime/__sigsetjmp_tail.c +++ b/libc/runtime/__sigsetjmp_tail.c @@ -20,7 +20,6 @@ #include "libc/calls/struct/sigset.h" #include "libc/runtime/runtime.h" #include "libc/sysv/consts/sig.h" -#ifdef __x86_64__ // kudos rich felker for the brilliant design int __sigsetjmp_tail(sigjmp_buf jb, int rc) { @@ -28,8 +27,6 @@ int __sigsetjmp_tail(sigjmp_buf jb, int rc) { sizeof(sigjmp_buf) == sizeof(jmp_buf) + 8 + 8 + sizeof(sigset_t), "please recompute sigjmp_buf w.r.t. sigset_t"); void *p = (char *)jb + sizeof(jmp_buf) + 8 + 8; - npassert(!sigprocmask(SIG_SETMASK, rc ? p : 0, rc ? 0 : p)); + sigprocmask(SIG_SETMASK, rc ? p : 0, rc ? 0 : p); return rc; } - -#endif /* __x86_64__ */ diff --git a/libc/runtime/runtime.h b/libc/runtime/runtime.h index 963b2a89b..327612989 100644 --- a/libc/runtime/runtime.h +++ b/libc/runtime/runtime.h @@ -8,8 +8,10 @@ COSMOPOLITAN_C_START_ #ifdef __x86_64__ typedef long jmp_buf[8]; +typedef long sigjmp_buf[12]; #elif defined(__aarch64__) typedef long jmp_buf[22]; +typedef long sigjmp_buf[26]; #elif defined(__powerpc64__) typedef unsigned __int128 jmp_buf[32]; #elif defined(__s390x__) @@ -18,8 +20,6 @@ typedef unsigned long jmp_buf[18]; typedef unsigned long jmp_buf[26]; #endif -typedef long sigjmp_buf[12]; - void mcount(void); int daemon(int, int); unsigned long getauxval(unsigned long); diff --git a/libc/runtime/runtime.mk b/libc/runtime/runtime.mk index 451ebba90..79652e598 100644 --- a/libc/runtime/runtime.mk +++ b/libc/runtime/runtime.mk @@ -112,6 +112,8 @@ o/$(MODE)/libc/runtime/zipos.o: libc/runtime/zipos.S @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $< o/$(MODE)/libc/runtime/switchstacks.o: libc/runtime/switchstacks.S @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $< +o/$(MODE)/libc/runtime/sigsetjmp.o: libc/runtime/sigsetjmp.S + @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $< LIBC_RUNTIME_LIBS = $(foreach x,$(LIBC_RUNTIME_ARTIFACTS),$($(x))) LIBC_RUNTIME_SRCS = $(foreach x,$(LIBC_RUNTIME_ARTIFACTS),$($(x)_SRCS)) diff --git a/libc/runtime/sigsetjmp.S b/libc/runtime/sigsetjmp.S index 4873843fd..559ccf001 100644 --- a/libc/runtime/sigsetjmp.S +++ b/libc/runtime/sigsetjmp.S @@ -34,6 +34,7 @@ // @return eax 0 when set and !0 when longjmp'd // @returnstwice sigsetjmp: +#ifdef __x86_64__ test %esi,%esi jz setjmp popq 64(%rdi) @@ -45,5 +46,19 @@ sigsetjmp: mov %eax,%esi mov 72(%rdi),%rbx jmp __sigsetjmp_tail +#elif defined(__aarch64__) + cbz x1,setjmp + str x30,[x0,#176] + str x19,[x0,#176+8+8] + mov x19,x0 + bl setjmp + mov w1,w0 + mov x0,x19 + ldr x30,[x0,#176] + ldr x19,[x0,#176+8+8] + b __sigsetjmp_tail +#else +#error "unsupported architecture" +#endif .hidden __sigsetjmp_tail .endfn sigsetjmp,globl diff --git a/test/libc/runtime/sigsetjmp_test.c b/test/libc/runtime/sigsetjmp_test.c index f5f9eed72..1f9531e70 100644 --- a/test/libc/runtime/sigsetjmp_test.c +++ b/test/libc/runtime/sigsetjmp_test.c @@ -25,7 +25,6 @@ #include "libc/sysv/consts/sa.h" #include "libc/sysv/consts/sig.h" #include "libc/testlib/testlib.h" -#ifdef __x86_64__ sigjmp_buf jb; volatile int sigs; @@ -54,5 +53,3 @@ TEST(sigsetjmp, test) { ASSERT_EQ(1000, jumps); ASSERT_EQ(1000, sigs); } - -#endif /* __x86_64__ */