diff --git a/libc/calls/kill.c b/libc/calls/kill.c index 3fd6cd0d2..a77ff7564 100644 --- a/libc/calls/kill.c +++ b/libc/calls/kill.c @@ -46,6 +46,6 @@ int kill(int pid, int sig) { } else { rc = sys_kill_nt(pid, sig); } - STRACE("kill(%d, %s) → %d% m", pid, strsignal(sig), rc); + STRACE("kill(%d, %G) → %d% m", pid, sig, rc); return rc; } diff --git a/libc/calls/raise.c b/libc/calls/raise.c index e4aa00b88..08a5a6009 100644 --- a/libc/calls/raise.c +++ b/libc/calls/raise.c @@ -45,7 +45,7 @@ static textwindows inline bool HasWorkingConsole(void) { */ int raise(int sig) { int rc, event; - STRACE("raise(%s) → [...]", strsignal(sig)); + STRACE("raise(%G) → [...]", sig); if (sig == SIGTRAP) { DebugBreak(); rc = 0; @@ -75,6 +75,6 @@ int raise(int sig) { rc = __sig_raise(sig, SI_USER); } } - STRACE("[...] raise(%s) → %d% m", strsignal(sig), rc); + STRACE("[...] raise(%G) → %d% m", sig, rc); return rc; } diff --git a/libc/calls/sig.c b/libc/calls/sig.c index 3836f8568..fc4ca7d1c 100644 --- a/libc/calls/sig.c +++ b/libc/calls/sig.c @@ -16,266 +16,20 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/calls/sig.internal.h" -#include "libc/calls/sigbits.h" -#include "libc/calls/strace.internal.h" -#include "libc/calls/struct/sigset.h" -#include "libc/calls/typedef/sigaction_f.h" -#include "libc/intrin/cmpxchg.h" -#include "libc/intrin/lockcmpxchg.h" #include "libc/intrin/spinlock.h" #include "libc/macros.internal.h" -#include "libc/runtime/internal.h" -#include "libc/runtime/runtime.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/sa.h" #include "libc/sysv/consts/sig.h" #include "libc/sysv/errfuns.h" /** - * @fileoverview UNIX signals for the New Technology. + * @fileoverview UNIX signals for the New Technology, Part 1. * @threadsafe */ -struct Signal { - struct Signal *next; - bool used; - int sig; - int si_code; -}; - -struct Signals { - sigset_t mask; - struct Signal *queue; - struct Signal mem[__SIG_QUEUE_LENGTH]; -}; - struct Signals __sig; // TODO(jart): Need TLS -/** - * Allocates piece of memory for storing pending signal. - * @assume lock is held - */ -static textwindows struct Signal *__sig_alloc(void) { - int i; - struct Signal *res = 0; - for (i = 0; i < ARRAYLEN(__sig.mem); ++i) { - if (!__sig.mem[i].used) { - __sig.mem[i].used = true; - res = __sig.mem + i; - break; - } - } - return res; -} - -/** - * Returns signal memory to static pool. - */ -static textwindows void __sig_free(struct Signal *mem) { - mem->used = false; -} - -/** - * Dequeues signal that isn't masked. - * @return signal or null if empty or none unmasked - */ -static textwindows struct Signal *__sig_remove(void) { - struct Signal *prev, *res; - if (__sig.queue) { - cthread_spinlock(&__sig_lock); - for (prev = 0, res = __sig.queue; res; prev = res, res = res->next) { - if (!sigismember(&__sig.mask, res->sig)) { - if (res == __sig.queue) { - __sig.queue = res->next; - } else if (prev) { - prev->next = res->next; - } - res->next = 0; - break; - } else { - STRACE("%s is masked", strsignal(res->sig)); - } - } - cthread_spunlock(&__sig_lock); - } else { - res = 0; - } - return res; -} - -/** - * Delivers signal to callback. - * @note called from main thread - * @return true if EINTR should be returned by caller - */ -static textwindows bool __sig_deliver(bool restartable, int sig, int si_code, - ucontext_t *ctx) { - unsigned rva, flags; - siginfo_t info, *infop; - STRACE("delivering %s", strsignal(sig)); - - // enter the signal - cthread_spinlock(&__sig_lock); - rva = __sighandrvas[sig]; - flags = __sighandflags[sig]; - if (~flags & SA_NODEFER) { - // by default we try to avoid reentering a signal handler. for - // example, if a sigsegv handler segfaults, then we'd want the - // second signal to just kill the process. doing this means we - // track state. that's bad if you want to longjmp() out of the - // signal handler. in that case you must use SA_NODEFER. - __sighandrvas[sig] = (int32_t)(intptr_t)SIG_DFL; - } - cthread_spunlock(&__sig_lock); - - // setup the somewhat expensive information args - // only if they're requested by the user in sigaction() - if (flags & SA_SIGINFO) { - bzero(&info, sizeof(info)); - info.si_signo = sig; - info.si_code = si_code; - infop = &info; - } else { - infop = 0; - ctx = 0; - } - - // handover control to user - ((sigaction_f)(_base + rva))(sig, infop, ctx); - - // leave the signal - cthread_spinlock(&__sig_lock); - if (~flags & SA_NODEFER) { - _cmpxchg(__sighandrvas + sig, (int32_t)(intptr_t)SIG_DFL, rva); - } - if (flags & SA_RESETHAND) { - STRACE("resetting oneshot signal handler"); - __sighandrvas[sig] = (int32_t)(intptr_t)SIG_DFL; - } - cthread_spunlock(&__sig_lock); - - if (!restartable) { - return true; // always send EINTR for wait4(), poll(), etc. - } else if (flags & SA_RESTART) { - STRACE("restarting syscall on %s", strsignal(sig)); - return false; // resume syscall for read(), write(), etc. - } else { - return true; // default course is to raise EINTR - } -} - -/** - * Returns true if signal default action is to end process. - */ -static textwindows bool __sig_isfatal(int sig) { - return sig != SIGCHLD; -} - -/** - * Handles signal. - * - * @param restartable can be used to suppress true return if SA_RESTART - * @return true if signal was delivered - */ -textwindows bool __sig_handle(bool restartable, int sig, int si_code, - ucontext_t *ctx) { - bool delivered; - switch (__sighandrvas[sig]) { - case (intptr_t)SIG_DFL: - if (__sig_isfatal(sig)) { - STRACE("terminating on %s", strsignal(sig)); - __restorewintty(); - _Exit(128 + sig); - } - // fallthrough - case (intptr_t)SIG_IGN: - STRACE("ignoring %s", strsignal(sig)); - delivered = false; - break; - default: - delivered = __sig_deliver(restartable, sig, si_code, ctx); - break; - } - return delivered; -} - -/** - * Handles signal immediately if not blocked. - * - * @param restartable is for functions like read() but not poll() - * @return true if EINTR should be returned by caller - * @return 1 if delivered, 0 if enqueued, otherwise -1 w/ errno - * @note called from main thread - * @threadsafe - */ -textwindows int __sig_raise(int sig, int si_code) { - int rc; - int candeliver; - cthread_spinlock(&__sig_lock); - candeliver = !sigismember(&__sig.mask, sig); - cthread_spunlock(&__sig_lock); - switch (candeliver) { - case 1: - __sig_handle(false, sig, si_code, 0); - return 0; - case 0: - STRACE("%s is masked", strsignal(sig)); - return __sig_add(sig, si_code); - default: - return -1; // sigismember() validates `sig` - } -} - -/** - * Enqueues generic signal for delivery on New Technology. - * @return 0 if enqueued, otherwise -1 w/ errno - * @threadsafe - */ -textwindows int __sig_add(int sig, int si_code) { - int rc; - struct Signal *mem; - if (1 <= sig && sig <= NSIG) { - STRACE("enqueuing %s", strsignal(sig)); - cthread_spinlock(&__sig_lock); - if ((mem = __sig_alloc())) { - mem->sig = sig; - mem->si_code = si_code; - mem->next = __sig.queue; - __sig.queue = mem; - rc = 0; - } else { - rc = enomem(); - } - cthread_spunlock(&__sig_lock); - } else { - rc = einval(); - } - return rc; -} - -/** - * Enqueues generic signal for delivery on New Technology. - * - * @param restartable is for functions like read() but not poll() - * @return true if EINTR should be returned by caller - * @note called from main thread - * @threadsafe - */ -textwindows bool __sig_check(bool restartable) { - unsigned rva; - bool delivered; - struct Signal *sig; - delivered = false; - while ((sig = __sig_remove())) { - delivered |= __sig_handle(restartable, sig->sig, sig->si_code, 0); - __sig_free(sig); - } - return delivered; -} - /** * Changes signal mask for main thread. * @return 0 on success, or -1 w/ errno diff --git a/libc/calls/sig.internal.h b/libc/calls/sig.internal.h index f4b907d77..40d3fabd9 100644 --- a/libc/calls/sig.internal.h +++ b/libc/calls/sig.internal.h @@ -10,6 +10,21 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ +struct Signal { + struct Signal *next; + bool used; + int sig; + int si_code; +}; + +struct Signals { + sigset_t mask; + struct Signal *queue; + struct Signal mem[__SIG_QUEUE_LENGTH]; +}; + +extern struct Signals __sig; // TODO(jart): Need TLS + bool __sig_check(bool) hidden; bool __sig_handle(bool, int, int, ucontext_t *) hidden; int __sig_add(int, int) hidden; diff --git a/libc/calls/sig2.c b/libc/calls/sig2.c new file mode 100644 index 000000000..bb4b8630d --- /dev/null +++ b/libc/calls/sig2.c @@ -0,0 +1,256 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 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/calls/internal.h" +#include "libc/calls/sig.internal.h" +#include "libc/calls/sigbits.h" +#include "libc/calls/strace.internal.h" +#include "libc/intrin/cmpxchg.h" +#include "libc/intrin/spinlock.h" +#include "libc/macros.internal.h" +#include "libc/runtime/internal.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/sa.h" +#include "libc/sysv/errfuns.h" + +/** + * @fileoverview UNIX signals for the New Technology, Part 2. + * @threadsafe + */ + +/** + * Allocates piece of memory for storing pending signal. + * @assume lock is held + */ +static textwindows struct Signal *__sig_alloc(void) { + int i; + struct Signal *res = 0; + for (i = 0; i < ARRAYLEN(__sig.mem); ++i) { + if (!__sig.mem[i].used) { + __sig.mem[i].used = true; + res = __sig.mem + i; + break; + } + } + return res; +} + +/** + * Returns signal memory to static pool. + */ +static textwindows void __sig_free(struct Signal *mem) { + mem->used = false; +} + +/** + * Dequeues signal that isn't masked. + * @return signal or null if empty or none unmasked + */ +static textwindows struct Signal *__sig_remove(void) { + struct Signal *prev, *res; + if (__sig.queue) { + cthread_spinlock(&__sig_lock); + for (prev = 0, res = __sig.queue; res; prev = res, res = res->next) { + if (!sigismember(&__sig.mask, res->sig)) { + if (res == __sig.queue) { + __sig.queue = res->next; + } else if (prev) { + prev->next = res->next; + } + res->next = 0; + break; + } else { + STRACE("%G is masked", res->sig); + } + } + cthread_spunlock(&__sig_lock); + } else { + res = 0; + } + return res; +} + +/** + * Delivers signal to callback. + * @note called from main thread + * @return true if EINTR should be returned by caller + */ +static textwindows bool __sig_deliver(bool restartable, int sig, int si_code, + ucontext_t *ctx) { + unsigned rva, flags; + siginfo_t info, *infop; + STRACE("delivering %G", sig); + + // enter the signal + cthread_spinlock(&__sig_lock); + rva = __sighandrvas[sig]; + flags = __sighandflags[sig]; + if (~flags & SA_NODEFER) { + // by default we try to avoid reentering a signal handler. for + // example, if a sigsegv handler segfaults, then we'd want the + // second signal to just kill the process. doing this means we + // track state. that's bad if you want to longjmp() out of the + // signal handler. in that case you must use SA_NODEFER. + __sighandrvas[sig] = (int32_t)(intptr_t)SIG_DFL; + } + cthread_spunlock(&__sig_lock); + + // setup the somewhat expensive information args + // only if they're requested by the user in sigaction() + if (flags & SA_SIGINFO) { + bzero(&info, sizeof(info)); + info.si_signo = sig; + info.si_code = si_code; + infop = &info; + } else { + infop = 0; + ctx = 0; + } + + // handover control to user + ((sigaction_f)(_base + rva))(sig, infop, ctx); + + // leave the signal + cthread_spinlock(&__sig_lock); + if (~flags & SA_NODEFER) { + _cmpxchg(__sighandrvas + sig, (int32_t)(intptr_t)SIG_DFL, rva); + } + if (flags & SA_RESETHAND) { + STRACE("resetting oneshot signal handler"); + __sighandrvas[sig] = (int32_t)(intptr_t)SIG_DFL; + } + cthread_spunlock(&__sig_lock); + + if (!restartable) { + return true; // always send EINTR for wait4(), poll(), etc. + } else if (flags & SA_RESTART) { + STRACE("restarting syscall on %G", sig); + return false; // resume syscall for read(), write(), etc. + } else { + return true; // default course is to raise EINTR + } +} + +/** + * Returns true if signal default action is to end process. + */ +static textwindows bool __sig_isfatal(int sig) { + return sig != SIGCHLD; +} + +/** + * Handles signal. + * + * @param restartable can be used to suppress true return if SA_RESTART + * @return true if signal was delivered + */ +textwindows bool __sig_handle(bool restartable, int sig, int si_code, + ucontext_t *ctx) { + bool delivered; + switch (__sighandrvas[sig]) { + case (intptr_t)SIG_DFL: + if (__sig_isfatal(sig)) { + STRACE("terminating on %G", sig); + __restorewintty(); + _Exit(128 + sig); + } + // fallthrough + case (intptr_t)SIG_IGN: + STRACE("ignoring %G", sig); + delivered = false; + break; + default: + delivered = __sig_deliver(restartable, sig, si_code, ctx); + break; + } + return delivered; +} + +/** + * Handles signal immediately if not blocked. + * + * @param restartable is for functions like read() but not poll() + * @return true if EINTR should be returned by caller + * @return 1 if delivered, 0 if enqueued, otherwise -1 w/ errno + * @note called from main thread + * @threadsafe + */ +textwindows int __sig_raise(int sig, int si_code) { + int rc; + int candeliver; + cthread_spinlock(&__sig_lock); + candeliver = !sigismember(&__sig.mask, sig); + cthread_spunlock(&__sig_lock); + switch (candeliver) { + case 1: + __sig_handle(false, sig, si_code, 0); + return 0; + case 0: + STRACE("%G is masked", sig); + return __sig_add(sig, si_code); + default: + return -1; // sigismember() validates `sig` + } +} + +/** + * Enqueues generic signal for delivery on New Technology. + * @return 0 if enqueued, otherwise -1 w/ errno + * @threadsafe + */ +textwindows int __sig_add(int sig, int si_code) { + int rc; + struct Signal *mem; + if (1 <= sig && sig <= NSIG) { + STRACE("enqueuing %G", sig); + cthread_spinlock(&__sig_lock); + if ((mem = __sig_alloc())) { + mem->sig = sig; + mem->si_code = si_code; + mem->next = __sig.queue; + __sig.queue = mem; + rc = 0; + } else { + rc = enomem(); + } + cthread_spunlock(&__sig_lock); + } else { + rc = einval(); + } + return rc; +} + +/** + * Enqueues generic signal for delivery on New Technology. + * + * @param restartable is for functions like read() but not poll() + * @return true if EINTR should be returned by caller + * @note called from main thread + * @threadsafe + */ +textwindows bool __sig_check(bool restartable) { + unsigned rva; + bool delivered; + struct Signal *sig; + delivered = false; + while ((sig = __sig_remove())) { + delivered |= __sig_handle(restartable, sig->sig, sig->si_code, 0); + __sig_free(sig); + } + return delivered; +} diff --git a/libc/calls/sigaction.c b/libc/calls/sigaction.c index fbabb0728..e7740404b 100644 --- a/libc/calls/sigaction.c +++ b/libc/calls/sigaction.c @@ -301,7 +301,7 @@ int(sigaction)(int sig, const struct sigaction *act, struct sigaction *oldact) { } else { rc = __sigaction(sig, act, oldact); } - STRACE("sigaction(%s, %s, [%s]) → %d% m", strsignal(sig), + STRACE("sigaction(%G, %s, [%s]) → %d% m", sig, __strace_sigaction(buf[0], sizeof(buf[0]), 0, act), __strace_sigaction(buf[1], sizeof(buf[1]), rc, oldact), rc); return rc; diff --git a/libc/intrin/kprintf.greg.c b/libc/intrin/kprintf.greg.c index ed95a040d..05d3d299d 100644 --- a/libc/intrin/kprintf.greg.c +++ b/libc/intrin/kprintf.greg.c @@ -498,6 +498,21 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt, va_list va, goto FormatDecimal; } + case 'G': + x = va_arg(va, int); + if (weaken(strsignal)) { + s = weaken(strsignal)(x); + goto FormatString; + } else { + if (p + 3 <= e) { + p[0] = 'S'; + p[1] = 'I'; + p[2] = 'G'; + } + p += 3; + goto FormatDecimal; + } + case 'n': // nonstandard %n specifier // used to print newlines that work in raw terminal modes @@ -823,6 +838,7 @@ privileged void kvprintf(const char *fmt, va_list v) { * - `u` unsigned * - `r` carriage * - `m` strerror + * - `G` strsignal * - `X` uppercase * - `T` timestamp * - `x` hexadecimal diff --git a/libc/log/oncrash.c b/libc/log/oncrash.c index 36f3d665b..94e364b02 100644 --- a/libc/log/oncrash.c +++ b/libc/log/oncrash.c @@ -41,6 +41,7 @@ */ STATIC_YOINK("strerror_r"); /* for kprintf %m */ +STATIC_YOINK("strsignal"); /* for kprintf %G */ static const char kGregOrder[17] forcealign(1) = { 13, 11, 8, 14, 12, 9, 10, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, @@ -54,29 +55,8 @@ static const char kGregNames[17][4] forcealign(1) = { static const char kCpuFlags[12] forcealign(1) = "CVPRAKZSTIDO"; static const char kFpuExceptions[6] forcealign(1) = "IDZOUP"; -/* : showcrashreports.c, oncrashthunks.S, oncrash.c */ int kCrashSigs[7]; struct sigaction g_oldcrashacts[7]; -static const char kCrashSigNames[7][5] forcealign(1) = { - "QUIT", // - "FPE", // - "ILL", // - "SEGV", // - "TRAP", // - "ABRT", // - "BUS", // -}; -/* : showcrashreports.c, oncrashthunks.S, oncrash.c */ - -static relegated noinstrument const char *TinyStrSignal(int sig) { - size_t i; - for (i = 0; i < ARRAYLEN(kCrashSigs); ++i) { - if (kCrashSigs[i] && sig == kCrashSigs[i]) { - return kCrashSigNames[i]; - } - } - return "???"; -} relegated static void ShowFunctionCalls(ucontext_t *ctx) { struct StackFrame *bp; @@ -222,12 +202,11 @@ relegated void ShowCrashReport(int err, int sig, struct siginfo *si, uname(&names); p = buf; errno = err; - kprintf("%n%serror%s: Uncaught SIG%s (%s) on %s pid %d%n" + kprintf("%n%serror%s: Uncaught %G (%s) on %s pid %d%n" " %s%n" " %m%n" " %s %s %s %s%n", - !__nocolor ? "\e[30;101m" : "", !__nocolor ? "\e[0m" : "", - TinyStrSignal(sig), + !__nocolor ? "\e[30;101m" : "", !__nocolor ? "\e[0m" : "", sig, (ctx && (ctx->uc_mcontext.rsp >= GetStaticStackAddr(0) && ctx->uc_mcontext.rsp <= GetStaticStackAddr(0) + PAGESIZE)) ? "Stack Overflow" @@ -269,13 +248,13 @@ static wontreturn relegated noinstrument void __minicrash(int sig, const char *kind) { kprintf("%n" "%n" - "CRASHED %s WITH SIG%s%n" + "CRASHED %s WITH %G%n" "%s%n" "RIP %x%n" "RSP %x%n" "RBP %x%n" "%n", - kind, TinyStrSignal(sig), __argv[0], ctx ? ctx->uc_mcontext.rip : 0, + kind, sig, __argv[0], ctx ? ctx->uc_mcontext.rip : 0, ctx ? ctx->uc_mcontext.rsp : 0, ctx ? ctx->uc_mcontext.rbp : 0); __restorewintty(); _Exit(119); diff --git a/libc/nt/kernel32/SetDefaultDllDirectories.s b/libc/nt/kernel32/SetDefaultDllDirectories.s index 77305268b..881f29690 100644 --- a/libc/nt/kernel32/SetDefaultDllDirectories.s +++ b/libc/nt/kernel32/SetDefaultDllDirectories.s @@ -1,2 +1,15 @@ .include "o/libc/nt/codegen.inc" .imp kernel32,__imp_SetDefaultDllDirectories,SetDefaultDllDirectories,0 + + .text.windows +SetDefaultDllDirectories: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_SetDefaultDllDirectories(%rip) + leave + ret + .endfn SetDefaultDllDirectories,globl + .previous diff --git a/libc/nt/kernel32/SetLastError.s b/libc/nt/kernel32/SetLastError.s index 03a1f7d39..779f9bee4 100644 --- a/libc/nt/kernel32/SetLastError.s +++ b/libc/nt/kernel32/SetLastError.s @@ -1,5 +1,5 @@ .include "o/libc/nt/codegen.inc" -.imp kernel32,__imp_SetLastError,SetLastError,1336 +.imp kernel32,__imp_SetLastError,SetLastError,0 .text.windows SetLastError: diff --git a/libc/nt/master.sh b/libc/nt/master.sh index 984798d1f..8483e0acb 100755 --- a/libc/nt/master.sh +++ b/libc/nt/master.sh @@ -1103,7 +1103,7 @@ imp 'SetCurrentDirectory' SetCurrentDirectoryW kernel32 0 1 imp 'SetCurrentDirectoryA' SetCurrentDirectoryA kernel32 0 1 imp 'SetDefaultCommConfig' SetDefaultCommConfigW kernel32 1298 imp 'SetDefaultCommConfigA' SetDefaultCommConfigA kernel32 1297 -imp 'SetDefaultDllDirectories' SetDefaultDllDirectories kernel32 0 1, Windows 8+, KB2533623 on Windows 7 +imp 'SetDefaultDllDirectories' SetDefaultDllDirectories kernel32 0 1 # Windows 8+, KB2533623 on Windows 7 imp 'SetDllDirectory' SetDllDirectoryW kernel32 1301 imp 'SetDllDirectoryA' SetDllDirectoryA kernel32 1300 imp 'SetDynamicTimeZoneInformation' SetDynamicTimeZoneInformation kernel32 0 @@ -1137,7 +1137,7 @@ imp 'SetHandleCount' SetHandleCount kernel32 0 1 imp 'SetHandleInformation' SetHandleInformation kernel32 0 3 imp 'SetInformationJobObject' SetInformationJobObject kernel32 1333 imp 'SetIoRateControlInformationJobObject' SetIoRateControlInformationJobObject kernel32 1334 -imp 'SetLastError' SetLastError kernel32 1336 1 +imp 'SetLastError' SetLastError kernel32 0 1 imp 'SetLocalPrimaryComputerName' SetLocalPrimaryComputerNameW kernel32 1338 imp 'SetLocalPrimaryComputerNameA' SetLocalPrimaryComputerNameA kernel32 1337 imp 'SetLocalTime' SetLocalTime kernel32 0 diff --git a/libc/runtime/munmap.c b/libc/runtime/munmap.c index 6073bc969..47e2a51fe 100644 --- a/libc/runtime/munmap.c +++ b/libc/runtime/munmap.c @@ -109,7 +109,6 @@ noasan int munmap(void *v, size_t n) { } else { rc = -1; } - STRACE("munmap(%.12p, %'zu) → %d %s", p, n, rc, - rc == -1 ? strerror(errno) : ""); + STRACE("munmap(%.12p, %'zu) → %d% m", p, n, rc); return rc; } diff --git a/libc/runtime/printargs.c b/libc/runtime/printargs.c index bf1fedf81..945390cc9 100644 --- a/libc/runtime/printargs.c +++ b/libc/runtime/printargs.c @@ -151,7 +151,7 @@ textstartup void __printargs(void) { PRINT("BLOCKED SIGNALS {%#lx, %#lx}", ss.__bits[0], ss.__bits[1]); for (i = 0; i < 32; ++i) { if (ss.__bits[0] & (1u << i)) { - PRINT(" ☼ %s (%d)", strsignal(i + 1), i + 1); + PRINT(" ☼ %G (%d)", i + 1, i + 1); } } }