mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-06 09:50:28 +00:00
Make improvements
- Fix unused local variable errors - Remove yoinks from sigaction() header - Add nox87 and aarch64 to github actions - Fix cosmocc -fportcosmo in linking mode - It's now possible to build `make m=llvm o/llvm/libc`
This commit is contained in:
parent
3dc86ce154
commit
f7ae50462a
118 changed files with 342 additions and 392 deletions
|
@ -191,7 +191,8 @@ o/$(MODE)/libc/calls/pledge-linux.o \
|
|||
o/$(MODE)/libc/calls/siginfo2cosmo.o: private \
|
||||
CFLAGS += \
|
||||
-ffreestanding \
|
||||
-fno-sanitize=all
|
||||
-fno-sanitize=all \
|
||||
-fno-stack-protector
|
||||
|
||||
o/$(MODE)/libc/calls/pledge-linux.o \
|
||||
o/$(MODE)/libc/calls/unveil.o: private \
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "libc/calls/state.internal.h"
|
||||
#include "libc/calls/struct/fd.internal.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/sigaction.internal.h"
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
|
|
|
@ -59,7 +59,6 @@ static int ioctl_siocgifconf_sysv(int fd, struct ifconf *ifc) {
|
|||
char *b, *p, *e;
|
||||
char ifcBsd[16];
|
||||
struct ifreq *req;
|
||||
struct ifreq *end;
|
||||
uint32_t bufLen, ip;
|
||||
size_t numReq, bufMax;
|
||||
if (IsLinux()) return sys_ioctl(fd, SIOCGIFCONF, ifc);
|
||||
|
@ -77,7 +76,6 @@ static int ioctl_siocgifconf_sysv(int fd, struct ifconf *ifc) {
|
|||
*/
|
||||
memcpy(&bufLen, b, 4);
|
||||
req = ifc->ifc_req;
|
||||
end = req + ifc->ifc_len / sizeof(*req);
|
||||
for (p = b, e = p + MIN(bufMax, READ32LE(ifcBsd)); p + 16 + 16 <= e;
|
||||
p += IsBsd() ? 16 + MAX(16, p[16] & 255) : 40) {
|
||||
fam = p[IsBsd() ? 17 : 16] & 255;
|
||||
|
|
|
@ -26,9 +26,6 @@
|
|||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int sys_pause_nt(void) {
|
||||
long ms, totoms;
|
||||
ms = 0;
|
||||
totoms = 0;
|
||||
for (;;) {
|
||||
|
||||
if (_check_interrupts(false, g_fds.p)) {
|
||||
|
@ -40,7 +37,8 @@ textwindows int sys_pause_nt(void) {
|
|||
continue;
|
||||
}
|
||||
|
||||
#if defined(SYSDEBUG) && defined(_POLLTRACE)
|
||||
#if defined(SYSDEBUG) && _POLLTRACE
|
||||
long ms = 0, totoms = 0;
|
||||
ms += __SIG_POLLING_INTERVAL_MS;
|
||||
if (ms >= __SIG_LOGGING_INTERVAL_MS) {
|
||||
totoms += ms, ms = 0;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "libc/calls/struct/seccomp.internal.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/syscall_support-sysv.internal.h"
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/intrin/bsr.h"
|
||||
#include "libc/intrin/likely.h"
|
||||
#include "libc/intrin/promises.internal.h"
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/sig.internal.h"
|
||||
#include "libc/calls/state.internal.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/sigaction.internal.h"
|
||||
#include "libc/calls/struct/siginfo.internal.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
|
@ -53,6 +54,12 @@
|
|||
STATIC_YOINK("strsignal"); // for kprintf()
|
||||
#endif
|
||||
|
||||
#if SupportsWindows()
|
||||
STATIC_YOINK("_init_onntconsoleevent");
|
||||
STATIC_YOINK("_check_sigwinch");
|
||||
STATIC_YOINK("_init_wincrash");
|
||||
#endif
|
||||
|
||||
#define SA_RESTORER 0x04000000
|
||||
|
||||
static void sigaction_cosmo2native(union metasigaction *sa) {
|
||||
|
|
|
@ -74,7 +74,8 @@ privileged void __sigenter_netbsd(int sig, struct siginfo_netbsd *si,
|
|||
uc.uc_mcontext.err = ctx->uc_mcontext.err;
|
||||
uc.uc_mcontext.rip = ctx->uc_mcontext.rip;
|
||||
uc.uc_mcontext.rsp = ctx->uc_mcontext.rsp;
|
||||
*uc.uc_mcontext.fpregs = ctx->uc_mcontext.__fpregs;
|
||||
__repmovsb(uc.uc_mcontext.fpregs, &ctx->uc_mcontext.__fpregs,
|
||||
sizeof(ctx->uc_mcontext.__fpregs));
|
||||
((sigaction_f)(__executable_start + rva))(sig, &si2, &uc);
|
||||
ctx->uc_stack.ss_sp = uc.uc_stack.ss_sp;
|
||||
ctx->uc_stack.ss_size = uc.uc_stack.ss_size;
|
||||
|
@ -102,7 +103,8 @@ privileged void __sigenter_netbsd(int sig, struct siginfo_netbsd *si,
|
|||
ctx->uc_mcontext.err = uc.uc_mcontext.err;
|
||||
ctx->uc_mcontext.rip = uc.uc_mcontext.rip;
|
||||
ctx->uc_mcontext.rsp = uc.uc_mcontext.rsp;
|
||||
ctx->uc_mcontext.__fpregs = *uc.uc_mcontext.fpregs;
|
||||
__repmovsb(&ctx->uc_mcontext.__fpregs, uc.uc_mcontext.fpregs,
|
||||
sizeof(ctx->uc_mcontext.__fpregs));
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
|
|
@ -74,7 +74,8 @@ privileged void __sigenter_openbsd(int sig, struct siginfo_openbsd *openbsdinfo,
|
|||
g.uc.uc_mcontext.rip = ctx->sc_rip;
|
||||
g.uc.uc_mcontext.rsp = ctx->sc_rsp;
|
||||
if (ctx->sc_fpstate) {
|
||||
*g.uc.uc_mcontext.fpregs = *ctx->sc_fpstate;
|
||||
__repmovsb(g.uc.uc_mcontext.fpregs, ctx->sc_fpstate,
|
||||
sizeof(*ctx->sc_fpstate));
|
||||
}
|
||||
((sigaction_f)(__executable_start + rva))(sig, &g.si, &g.uc);
|
||||
ctx->sc_mask = g.uc.uc_sigmask.__bits[0];
|
||||
|
@ -100,7 +101,8 @@ privileged void __sigenter_openbsd(int sig, struct siginfo_openbsd *openbsdinfo,
|
|||
ctx->sc_rip = g.uc.uc_mcontext.rip;
|
||||
ctx->sc_rsp = g.uc.uc_mcontext.rsp;
|
||||
if (ctx->sc_fpstate) {
|
||||
*ctx->sc_fpstate = *g.uc.uc_mcontext.fpregs;
|
||||
__repmovsb(ctx->sc_fpstate, g.uc.uc_mcontext.fpregs,
|
||||
sizeof(*ctx->sc_fpstate));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,5 +27,5 @@ int sigignore(int sig) {
|
|||
struct sigaction sa;
|
||||
bzero(&sa, sizeof(sa));
|
||||
sa.sa_handler = SIG_IGN;
|
||||
return (sigaction)(sig, &sa, 0);
|
||||
return sigaction(sig, &sa, 0);
|
||||
}
|
||||
|
|
|
@ -96,6 +96,8 @@ privileged void __siginfo2cosmo(struct siginfo *si,
|
|||
si_signo == SIGBUS || //
|
||||
si_signo == SIGTRAP) {
|
||||
si->si_addr = si_addr;
|
||||
} else if (si_signo == SIGCHLD) {
|
||||
si->si_status = si_status;
|
||||
} else if (si_signo == SIGALRM) {
|
||||
si->si_timerid = si_timerid;
|
||||
si->si_overrun = si_overrun;
|
||||
|
|
|
@ -30,9 +30,9 @@
|
|||
* @note this function has BSD semantics, i.e. SA_RESTART
|
||||
* @see sigaction() which has more features and docs
|
||||
*/
|
||||
sighandler_t(signal)(int sig, sighandler_t func) {
|
||||
sighandler_t signal(int sig, sighandler_t func) {
|
||||
struct sigaction old, sa = {.sa_handler = func, .sa_flags = SA_RESTART};
|
||||
if ((sigaction)(sig, &sa, &old) != -1) {
|
||||
if (sigaction(sig, &sa, &old) != -1) {
|
||||
return old.sa_handler;
|
||||
} else {
|
||||
return SIG_ERR;
|
||||
|
|
|
@ -47,7 +47,6 @@
|
|||
*/
|
||||
int sigsuspend(const sigset_t *ignore) {
|
||||
int rc;
|
||||
long ms, totoms;
|
||||
sigset_t save, *arg, mask = {0};
|
||||
STRACE("sigsuspend(%s) → ...", DescribeSigset(0, ignore));
|
||||
BEGIN_CANCELLATION_POINT;
|
||||
|
@ -73,8 +72,10 @@ int sigsuspend(const sigset_t *ignore) {
|
|||
rc = sys_sigsuspend(arg, 8);
|
||||
} else {
|
||||
__sig_mask(SIG_SETMASK, arg, &save);
|
||||
ms = 0;
|
||||
totoms = 0;
|
||||
#if defined(SYSDEBUG) && _POLLTRACE
|
||||
long ms = 0;
|
||||
long totoms = 0;
|
||||
#endif
|
||||
do {
|
||||
if ((rc = _check_interrupts(false, g_fds.p))) {
|
||||
break;
|
||||
|
@ -83,7 +84,7 @@ int sigsuspend(const sigset_t *ignore) {
|
|||
POLLTRACE("IOCP EINTR");
|
||||
continue;
|
||||
}
|
||||
#if defined(SYSDEBUG) && defined(_POLLTRACE)
|
||||
#if defined(SYSDEBUG) && _POLLTRACE
|
||||
ms += __SIG_POLLING_INTERVAL_MS;
|
||||
if (ms >= __SIG_LOGGING_INTERVAL_MS) {
|
||||
totoms += ms, ms = 0;
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include "libc/sysv/consts/sicode.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/thread/tls.h"
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
static struct winsize __ws;
|
||||
|
|
|
@ -299,5 +299,6 @@ void statfs2cosmo(struct statfs *f, const union statfs_meta *m) {
|
|||
f->f_namelen = f_namelen;
|
||||
f->f_frsize = f_frsize;
|
||||
f->f_flags = f_flags;
|
||||
f->f_owner = f_owner;
|
||||
memcpy(f->f_fstypename, f_fstypename, 16);
|
||||
}
|
||||
|
|
|
@ -2,15 +2,11 @@
|
|||
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_H_
|
||||
#include "libc/calls/struct/siginfo.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
typedef void (*sighandler_t)(int);
|
||||
typedef void (*sigaction_f)(int, struct siginfo *,
|
||||
void * /*struct ucontext **/);
|
||||
typedef void (*sigaction_f)(int, struct siginfo *, void *);
|
||||
|
||||
struct sigaction { /* cosmo abi */
|
||||
union {
|
||||
|
@ -25,60 +21,6 @@ struct sigaction { /* cosmo abi */
|
|||
sighandler_t signal(int, sighandler_t);
|
||||
int sigaction(int, const struct sigaction *, struct sigaction *);
|
||||
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && defined(COSMO)
|
||||
|
||||
void _init_onntconsoleevent(void);
|
||||
void _init_wincrash(void);
|
||||
void _check_sigwinch();
|
||||
|
||||
#ifndef __SIGACTION_YOINK
|
||||
#define __SIGACTION_YOINK(SIG) \
|
||||
do { \
|
||||
if (SupportsWindows()) { \
|
||||
if (__builtin_constant_p(SIG)) { \
|
||||
switch (SIG) { \
|
||||
case SIGINT: \
|
||||
case SIGQUIT: \
|
||||
case SIGHUP: \
|
||||
case SIGTERM: \
|
||||
YOINK(_init_onntconsoleevent); \
|
||||
break; \
|
||||
case SIGTRAP: \
|
||||
case SIGILL: \
|
||||
case SIGSEGV: \
|
||||
case SIGABRT: \
|
||||
case SIGFPE: \
|
||||
YOINK(_init_wincrash); \
|
||||
break; \
|
||||
case SIGWINCH: \
|
||||
YOINK(_check_sigwinch); \
|
||||
break; \
|
||||
default: \
|
||||
break; \
|
||||
} \
|
||||
} else { \
|
||||
YOINK(_init_onntconsoleevent); \
|
||||
YOINK(_init_wincrash); \
|
||||
YOINK(_check_sigwinch); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define sigaction(SIG, ACT, OLD) \
|
||||
({ \
|
||||
__SIGACTION_YOINK(SIG); \
|
||||
sigaction(SIG, (ACT), OLD); \
|
||||
})
|
||||
|
||||
#define signal(SIG, HAND) \
|
||||
({ \
|
||||
__SIGACTION_YOINK(SIG); \
|
||||
signal(SIG, HAND); \
|
||||
})
|
||||
|
||||
#endif /* GNU && !ANSI */
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_H_ */
|
||||
|
|
|
@ -63,6 +63,10 @@ void __sigenter_openbsd(int, struct siginfo *, void *) _Hide;
|
|||
const char *DescribeSigaction(char[256], int, const struct sigaction *);
|
||||
#define DescribeSigaction(rc, sa) DescribeSigaction(alloca(256), rc, sa)
|
||||
|
||||
void _init_onntconsoleevent(void);
|
||||
void _init_wincrash(void);
|
||||
void _check_sigwinch();
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_INTERNAL_H_ */
|
||||
|
|
|
@ -61,6 +61,7 @@ textwindows int tcsetattr_nt(int ignored, int opt, const struct termios *tio) {
|
|||
inmode |= kNtEnableVirtualTerminalInput;
|
||||
}
|
||||
ok = SetConsoleMode(in, inmode);
|
||||
(void)ok;
|
||||
NTTRACE("SetConsoleMode(%p, %s) → %hhhd", in,
|
||||
DescribeNtConsoleInFlags(inmode), ok);
|
||||
}
|
||||
|
@ -75,6 +76,7 @@ textwindows int tcsetattr_nt(int ignored, int opt, const struct termios *tio) {
|
|||
outmode |= kNtEnableVirtualTerminalProcessing;
|
||||
}
|
||||
ok = SetConsoleMode(out, outmode);
|
||||
(void)ok;
|
||||
NTTRACE("SetConsoleMode(%p, %s) → %hhhd", out,
|
||||
DescribeNtConsoleOutFlags(outmode), ok);
|
||||
}
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
*/
|
||||
int ResolveDns(const struct ResolvConf *resolvconf, int af, const char *name,
|
||||
struct sockaddr *addr, uint32_t addrsize) {
|
||||
int32_t ttl;
|
||||
int rc, fd, n;
|
||||
struct DnsQuestion q;
|
||||
struct DnsHeader h, h2;
|
||||
|
@ -94,7 +93,7 @@ int ResolveDns(const struct ResolvConf *resolvconf, int af, const char *name,
|
|||
if (p + 10 <= pe) {
|
||||
rtype = READ16BE(p);
|
||||
rclass = READ16BE(p + 2);
|
||||
ttl = READ32BE(p + 4);
|
||||
// ttl = READ32BE(p + 4);
|
||||
rdlength = READ16BE(p + 8);
|
||||
if (p + 10 + rdlength <= pe && rdlength == 4 &&
|
||||
rclass == DNS_CLASS_IN && rtype == DNS_TYPE_A) {
|
||||
|
|
|
@ -89,8 +89,10 @@
|
|||
#endif
|
||||
|
||||
#ifndef __cplusplus
|
||||
#if defined(__GNUC__) && !defined(__llvm__)
|
||||
#pragma GCC push_options
|
||||
#pragma GCC diagnostic ignored "-Wc++-compat"
|
||||
#endif
|
||||
#define HAVE_STDBOOL_H 1
|
||||
#if __STDC_VERSION__ + 0 >= 201112
|
||||
typedef _Bool bool;
|
||||
|
@ -102,7 +104,9 @@ typedef _Bool bool;
|
|||
typedef __WCHAR_TYPE__ wchar_t;
|
||||
typedef __CHAR16_TYPE__ char16_t;
|
||||
typedef __CHAR32_TYPE__ char32_t;
|
||||
#if defined(__GNUC__) && !defined(__llvm__)
|
||||
#pragma GCC pop_options
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define _LIBCPP_STDINT_H
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*-*- 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│
|
||||
/*-*- 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 2021 Justine Alexandra Roberts Tunney │
|
||||
│ Copyright 2023 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 │
|
||||
|
@ -16,15 +16,18 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
/**
|
||||
* Reads symbolic link.
|
||||
*
|
||||
* @return nul-terminated string, or null w/ errno
|
||||
* @see readlink()
|
||||
*/
|
||||
char *xreadlink(const char *path) {
|
||||
return xreadlinkat(AT_FDCWD, path);
|
||||
}
|
||||
GetCpuidBrand:
|
||||
mov %esi,%eax
|
||||
xor %ecx,%ecx
|
||||
push %rbx
|
||||
cpuid
|
||||
mov %ebx,0(%rdi)
|
||||
mov %ecx,4(%rdi)
|
||||
mov %edx,8(%rdi)
|
||||
movb $0,12(%rdi)
|
||||
pop %rbx
|
||||
movb $0,12(%rdi)
|
||||
ret
|
||||
.endfn GetCpuidBrand,globl
|
|
@ -1,37 +0,0 @@
|
|||
/*-*- 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 2023 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/runtime/runtime.h"
|
||||
#ifdef __x86_64__
|
||||
|
||||
void GetCpuidBrand(char s[13], uint32_t leaf) {
|
||||
int ax, cx;
|
||||
asm("push\t%%rbx\r\n"
|
||||
"cpuid\r\n"
|
||||
"mov\t%%ebx,0+%2\r\n"
|
||||
"mov\t%%ecx,4+%2\r\n"
|
||||
"mov\t%%edx,8+%2\r\n"
|
||||
"movb\t$0,12+%2\r\n"
|
||||
"pop\t%%rbx"
|
||||
: "=a"(ax), "=c"(cx), "=o"(*(char(*)[13])s)
|
||||
: "0"(leaf), "1"(0)
|
||||
: "rdx");
|
||||
s[12] = 0;
|
||||
}
|
||||
|
||||
#endif /* __x86_64__ */
|
|
@ -160,7 +160,7 @@ void *memset(void *p, int c, size_t n) {
|
|||
return b;
|
||||
#ifdef __x86__
|
||||
} else if (IsTiny()) {
|
||||
asm("rep stosb" : "+D"(b), "+c"(n), "=m"(*(char(*)[n])b) : "0"(p), "a"(c));
|
||||
asm("rep stosb" : "+D"(b), "+c"(n), "=m"(*(char(*)[n])b) : "a"(c));
|
||||
return p;
|
||||
} else if (X86_HAVE(AVX)) {
|
||||
return memset_avx(b, c, n);
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
__attribute__((__weak__)) void __stack_chk_fail(void) {
|
||||
tinyprint(2, program_invocation_name, ": stack smashed\n", NULL);
|
||||
kprintf("%s: stack smashed\n", program_invocation_name);
|
||||
__builtin_trap();
|
||||
}
|
14
libc/intrin/udivti3.c
Normal file
14
libc/intrin/udivti3.c
Normal file
|
@ -0,0 +1,14 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to division, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "third_party/compiler_rt/int_lib.h"
|
||||
|
||||
COMPILER_RT_ABI tu_int __udivti3(tu_int a, tu_int b) {
|
||||
return __udivmodti4(a, b, NULL);
|
||||
}
|
|
@ -6,5 +6,6 @@
|
|||
#include "libc/calls/struct/siginfo.h"
|
||||
#include "libc/sysv/consts/sa.h"
|
||||
#include "libc/sysv/consts/sicode.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/sysv/consts/ss.h"
|
||||
#endif /* _SIGNAL_H */
|
||||
|
|
|
@ -5,9 +5,14 @@ PKGS += LIBC
|
|||
|
||||
LIBC_HDRS = $(filter %.h,$(LIBC_FILES))
|
||||
LIBC_INCS = $(filter %.inc,$(LIBC_FILES))
|
||||
LIBC_FILES := $(wildcard libc/*) $(wildcard libc/isystem/*)
|
||||
LIBC_CHECKS = $(LIBC_HDRS:%=o/$(MODE)/%.ok)
|
||||
|
||||
ifneq ($(MODE), llvm)
|
||||
LIBC_FILES := $(wildcard libc/*) $(wildcard libc/isystem/*)
|
||||
else
|
||||
LIBC_FILES := $(wildcard libc/*)
|
||||
endif
|
||||
|
||||
.PHONY: o/$(MODE)/libc
|
||||
o/$(MODE)/libc: o/$(MODE)/libc/calls \
|
||||
o/$(MODE)/libc/crt \
|
||||
|
|
|
@ -46,14 +46,12 @@ relegated void __check_fail(const char *suffix, //
|
|||
int line, //
|
||||
const char *fmt, //
|
||||
...) {
|
||||
int e;
|
||||
char *p;
|
||||
size_t i;
|
||||
va_list va;
|
||||
char hostname[32];
|
||||
strace_enabled(-1);
|
||||
ftrace_enabled(-1);
|
||||
e = errno;
|
||||
__start_fatal(file, line);
|
||||
__stpcpy(hostname, "unknown");
|
||||
gethostname(hostname, sizeof(hostname));
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
relegated int(gdbexec)(const char *cmd) {
|
||||
struct StackFrame *bp;
|
||||
int pid, ttyin, ttyout;
|
||||
intptr_t continuetoaddr;
|
||||
const char *se, *elf, *gdb;
|
||||
char pidstr[11], breakcmd[40];
|
||||
if (!(gdb = GetGdbPath())) return -1;
|
||||
|
@ -43,7 +42,6 @@ relegated int(gdbexec)(const char *cmd) {
|
|||
elf = "-q";
|
||||
}
|
||||
bp = __builtin_frame_address(0);
|
||||
continuetoaddr = bp->addr;
|
||||
sprintf(breakcmd, "%s *%#p", "break", bp->addr);
|
||||
if (!(pid = vfork())) {
|
||||
execv(gdb, (char *const[]){
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/atomic.h"
|
||||
#include "libc/intrin/atomic.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/log/backtrace.internal.h"
|
||||
|
@ -67,7 +68,7 @@ static struct Memlog {
|
|||
long size;
|
||||
} * p;
|
||||
} allocs;
|
||||
long usage;
|
||||
atomic_long usage;
|
||||
} __memlog;
|
||||
|
||||
static pthread_mutex_t __memlog_lock_obj;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/utsname.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
|
@ -44,6 +45,7 @@
|
|||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#include "libc/thread/tls.h"
|
||||
#ifdef __x86_64__
|
||||
|
@ -292,7 +294,9 @@ static wontreturn relegated dontinstrument void __minicrash(int sig,
|
|||
*/
|
||||
relegated void __oncrash_amd64(int sig, struct siginfo *si, void *arg) {
|
||||
int bZero;
|
||||
#ifdef ATTACH_GDB_ON_CRASH
|
||||
intptr_t rip;
|
||||
#endif
|
||||
int me, owner;
|
||||
int gdbpid, err;
|
||||
ucontext_t *ctx = arg;
|
||||
|
@ -307,13 +311,15 @@ relegated void __oncrash_amd64(int sig, struct siginfo *si, void *arg) {
|
|||
if (atomic_compare_exchange_strong_explicit(
|
||||
&once, &owner, me, memory_order_relaxed, memory_order_relaxed)) {
|
||||
if (!__vforked) {
|
||||
#ifdef ATTACH_GDB_ON_CRASH
|
||||
rip = ctx ? ctx->uc_mcontext.rip : 0;
|
||||
#endif
|
||||
err = errno;
|
||||
if ((gdbpid = IsDebuggerPresent(true))) {
|
||||
DebugBreak();
|
||||
} else if (__nocolor || g_isrunningundermake) {
|
||||
gdbpid = -1;
|
||||
#if 0
|
||||
#if ATTACH_GDB_ON_CRASH
|
||||
} else if (!IsTiny() && IsLinux() && FindDebugBinary() && !__isworker) {
|
||||
// RestoreDefaultCrashSignalHandlers();
|
||||
gdbpid = AttachDebugger(
|
||||
|
|
|
@ -169,7 +169,7 @@ asm("XnuThreadThunk:\n\t"
|
|||
"push\t%rax\n\t"
|
||||
"jmp\tXnuThreadMain\n\t"
|
||||
".size\tXnuThreadThunk,.-XnuThreadThunk");
|
||||
__attribute__((__used__, __no_reorder__))
|
||||
__attribute__((__used__))
|
||||
|
||||
static wontreturn void
|
||||
XnuThreadMain(void *pthread, // rdi
|
||||
|
|
|
@ -121,7 +121,7 @@ textstartup void __enable_tls(void) {
|
|||
|
||||
#ifdef __x86_64__
|
||||
|
||||
siz = ROUNDUP(I(_tls_size) + sizeof(*tib), _Alignof(__static_tls));
|
||||
siz = ROUNDUP(I(_tls_size) + sizeof(*tib), TLS_ALIGNMENT);
|
||||
if (siz <= sizeof(__static_tls)) {
|
||||
// if tls requirement is small then use the static tls block
|
||||
// which helps avoid a system call for appes with little tls
|
||||
|
|
|
@ -26,7 +26,7 @@ ftrace_hook:
|
|||
// like __errno_location which can be called from an inline asm()
|
||||
// statement. It's nice to have the flexibility anyway.
|
||||
|
||||
cmp $0,__ftrace(%rip)
|
||||
cmpl $0,__ftrace(%rip)
|
||||
jle 1f
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
|
|
|
@ -54,8 +54,6 @@ int __inflate(void *out, size_t outsize, const void *in, size_t insize) {
|
|||
rc = 0;
|
||||
} else if (rc == Z_OK) {
|
||||
rc = Z_STREAM_END; // coerce to nonzero
|
||||
} else {
|
||||
rc = rc;
|
||||
}
|
||||
} else {
|
||||
rc = _puff(out, &outsize, in, &insize);
|
||||
|
|
|
@ -31,13 +31,9 @@ static inline noasan void *GetFrameAddr(int f) {
|
|||
}
|
||||
|
||||
noasan void ReleaseMemoryNt(struct MemoryIntervals *mm, int l, int r) {
|
||||
int i, ok;
|
||||
size_t size;
|
||||
char *addr, *last;
|
||||
int i;
|
||||
for (i = l; i <= r; ++i) {
|
||||
addr = GetFrameAddr(mm->p[i].x);
|
||||
last = GetFrameAddr(mm->p[i].y);
|
||||
UnmapViewOfFile(addr);
|
||||
UnmapViewOfFile(GetFrameAddr(mm->p[i].x));
|
||||
CloseHandle(mm->p[i].h);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -128,7 +128,8 @@ o/$(MODE)/libc/runtime/enable_threads.o \
|
|||
o/$(MODE)/libc/runtime/morph_tls.o: private \
|
||||
CFLAGS += \
|
||||
-ffreestanding \
|
||||
-fno-sanitize=all
|
||||
-fno-sanitize=all \
|
||||
-fno-stack-protector
|
||||
|
||||
# TODO(jart): We need a way to avoid WinThreadEntry() being hooked.
|
||||
o/$(MODE)/libc/runtime/clone.o: private \
|
||||
|
|
|
@ -154,6 +154,7 @@ __msabi static textwindows wontreturn void WinMainNew(const char16_t *cmdline) {
|
|||
: (DescribeNtConsoleInFlags)(inflagsbuf, kConsoleModes[i]),
|
||||
rc);
|
||||
}
|
||||
(void)rc;
|
||||
}
|
||||
_Static_assert(sizeof(struct WinArgs) % FRAMESIZE == 0, "");
|
||||
_mmi.p = _mmi.s;
|
||||
|
|
|
@ -38,6 +38,7 @@ _Hide struct NtWsaData kNtWsaData;
|
|||
|
||||
static textwindows void WinSockCleanup(void) {
|
||||
int i, rc;
|
||||
(void)rc;
|
||||
rc = WSACleanup();
|
||||
NTTRACE("WSACleanup() → %d% lm", rc);
|
||||
}
|
||||
|
|
|
@ -67,9 +67,6 @@
|
|||
|
||||
#define PRINTF_NTOA_BUFFER_SIZE 144
|
||||
|
||||
#define __FMT_CONSUMED_DOUBLE 1
|
||||
#define __FMT_CONSUMED_LONG_DOUBLE 2
|
||||
|
||||
#define FLAGS_ZEROPAD 0x01
|
||||
#define FLAGS_LEFT 0x02
|
||||
#define FLAGS_PLUS 0x04
|
||||
|
@ -423,7 +420,7 @@ static int __fmt_stoa(int out(const char *, void *, size_t), void *arg,
|
|||
} else {
|
||||
emit = __fmt_stoa_wide;
|
||||
}
|
||||
} else if ((flags & FLAGS_HASH) && kCp437) {
|
||||
} else if (flags & FLAGS_HASH) {
|
||||
justdobytes = true;
|
||||
emit = __fmt_stoa_bing;
|
||||
ignorenul = flags & FLAGS_PRECISION;
|
||||
|
@ -796,7 +793,7 @@ _Hide int __fmt(void *fn, void *arg, const char *format, va_list va) {
|
|||
int (*out)(const char *, void *, size_t);
|
||||
char *se, *s0, *s, *q, qchar, special[8];
|
||||
int d, w, n, sign, prec, flags, width, lasterr;
|
||||
int c, k, i1, ui, bw, rc, bex, sgn, prec1, decpt, consumed;
|
||||
int c, k, i1, ui, bw, rc, bex, sgn, prec1, decpt;
|
||||
|
||||
x = 0;
|
||||
lasterr = errno;
|
||||
|
@ -1069,7 +1066,6 @@ _Hide int __fmt(void *fn, void *arg, const char *format, va_list va) {
|
|||
if (!(flags & FLAGS_PRECISION)) prec = 6;
|
||||
if (!longdouble) {
|
||||
x = va_arg(va, double);
|
||||
consumed = __FMT_CONSUMED_DOUBLE;
|
||||
s = s0 = dtoa(x, 3, prec, &decpt, &fpb.sign, &se);
|
||||
if (decpt == 9999) {
|
||||
if (s && s[0] == 'N') {
|
||||
|
@ -1080,7 +1076,6 @@ _Hide int __fmt(void *fn, void *arg, const char *format, va_list va) {
|
|||
}
|
||||
} else {
|
||||
un.ld = va_arg(va, long double);
|
||||
consumed = __FMT_CONSUMED_LONG_DOUBLE;
|
||||
__fmt_ldfpbits(&un, &fpb);
|
||||
s = s0 =
|
||||
gdtoa(fpb.fpi, fpb.ex, fpb.bits, &fpb.kind, 3, prec, &decpt, &se);
|
||||
|
@ -1102,7 +1097,7 @@ _Hide int __fmt(void *fn, void *arg, const char *format, va_list va) {
|
|||
prec = 0;
|
||||
rc = __fmt_stoa(out, arg, s, flags, prec, width, signbit, qchar);
|
||||
if (rc == -1) return -1;
|
||||
return consumed;
|
||||
break;
|
||||
}
|
||||
FormatReal:
|
||||
if (fpb.sign /* && (x || sign) */) sign = '-';
|
||||
|
@ -1166,7 +1161,6 @@ _Hide int __fmt(void *fn, void *arg, const char *format, va_list va) {
|
|||
if (prec < 1) prec = 1;
|
||||
if (!longdouble) {
|
||||
x = va_arg(va, double);
|
||||
consumed = __FMT_CONSUMED_DOUBLE;
|
||||
s = s0 = dtoa(x, 2, prec, &decpt, &fpb.sign, &se);
|
||||
if (decpt == 9999) {
|
||||
if (s && s[0] == 'N') {
|
||||
|
@ -1177,7 +1171,6 @@ _Hide int __fmt(void *fn, void *arg, const char *format, va_list va) {
|
|||
}
|
||||
} else {
|
||||
un.ld = va_arg(va, long double);
|
||||
consumed = __FMT_CONSUMED_LONG_DOUBLE;
|
||||
__fmt_ldfpbits(&un, &fpb);
|
||||
s = s0 = gdtoa(fpb.fpi, fpb.ex, fpb.bits, &fpb.kind, prec ? 2 : 0,
|
||||
prec, &decpt, &se);
|
||||
|
@ -1209,7 +1202,6 @@ _Hide int __fmt(void *fn, void *arg, const char *format, va_list va) {
|
|||
if (prec < 0) prec = 0;
|
||||
if (!longdouble) {
|
||||
x = va_arg(va, double);
|
||||
consumed = __FMT_CONSUMED_DOUBLE;
|
||||
s = s0 = dtoa(x, 2, prec + 1, &decpt, &fpb.sign, &se);
|
||||
if (decpt == 9999) {
|
||||
if (s && s[0] == 'N') {
|
||||
|
@ -1220,7 +1212,6 @@ _Hide int __fmt(void *fn, void *arg, const char *format, va_list va) {
|
|||
}
|
||||
} else {
|
||||
un.ld = va_arg(va, long double);
|
||||
consumed = __FMT_CONSUMED_LONG_DOUBLE;
|
||||
__fmt_ldfpbits(&un, &fpb);
|
||||
s = s0 = gdtoa(fpb.fpi, fpb.ex, fpb.bits, &fpb.kind, prec ? 2 : 0,
|
||||
prec, &decpt, &se);
|
||||
|
@ -1289,11 +1280,9 @@ _Hide int __fmt(void *fn, void *arg, const char *format, va_list va) {
|
|||
FormatBinary:
|
||||
if (longdouble) {
|
||||
un.ld = va_arg(va, long double);
|
||||
consumed = __FMT_CONSUMED_LONG_DOUBLE;
|
||||
__fmt_ldfpbits(&un, &fpb);
|
||||
} else {
|
||||
un.d = va_arg(va, double);
|
||||
consumed = __FMT_CONSUMED_DOUBLE;
|
||||
__fmt_dfpbits(&un, &fpb);
|
||||
}
|
||||
if (fpb.kind == STRTOG_Infinite || fpb.kind == STRTOG_NaN) {
|
||||
|
@ -1320,7 +1309,7 @@ _Hide int __fmt(void *fn, void *arg, const char *format, va_list va) {
|
|||
if (sign) --width;
|
||||
if (prec1 || (flags & FLAGS_HASH)) --width;
|
||||
}
|
||||
if ((width -= prec1) > 0 && !(flags & FLAGS_LEFT) &&
|
||||
if ((width -= MAX(prec, prec1)) > 0 && !(flags & FLAGS_LEFT) &&
|
||||
!(flags & FLAGS_ZEROPAD)) {
|
||||
do __FMT_PUT(' ');
|
||||
while (--width > 0);
|
||||
|
|
|
@ -25,10 +25,8 @@ struct _posix_spawna {
|
|||
struct _posix_faction {
|
||||
struct _posix_faction *next;
|
||||
int action;
|
||||
union {
|
||||
int fildes;
|
||||
int oflag;
|
||||
};
|
||||
int fildes;
|
||||
int oflag;
|
||||
union {
|
||||
int newfildes;
|
||||
unsigned mode;
|
||||
|
|
|
@ -105,6 +105,7 @@ int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *file_actions,
|
|||
int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t *file_actions,
|
||||
int fildes, const char *path, int oflag,
|
||||
unsigned mode) {
|
||||
if (fildes < 0) return EBADF;
|
||||
if (!(path = strdup(path))) return ENOMEM;
|
||||
return AddFileAction(file_actions, (struct _posix_faction){
|
||||
.action = _POSIX_SPAWN_OPEN,
|
||||
|
|
|
@ -47,7 +47,8 @@ void *GetZipEocd(const void *f, size_t n, int *e) {
|
|||
i = n - 4;
|
||||
err = kZipErrorEocdNotFound;
|
||||
do {
|
||||
#ifdef __x86_64__
|
||||
#if defined(__x86_64__) && defined(__GNUC__) && !defined(__llvm__) && \
|
||||
!defined(__chibicc__)
|
||||
v8hi pk = {READ16LE("PK"), READ16LE("PK"), READ16LE("PK"), READ16LE("PK"),
|
||||
READ16LE("PK"), READ16LE("PK"), READ16LE("PK"), READ16LE("PK")};
|
||||
asm("" : "+x"(pk));
|
||||
|
|
|
@ -16,9 +16,10 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/errno.h"
|
||||
#include "libc/thread/tls2.h"
|
||||
|
||||
extern errno_t __errno;
|
||||
|
||||
/**
|
||||
* Returns address of errno variable.
|
||||
*/
|
||||
|
|
|
@ -121,7 +121,7 @@ systemfive_cancellable: // our pthread_cancel() miracle code
|
|||
testb $PT_INCANCEL,0x00(%r10)
|
||||
jz 5f
|
||||
#endif
|
||||
cmp $0,0x04(%r10) // PosixThread::cancelled
|
||||
cmpl $0,0x04(%r10) // PosixThread::cancelled
|
||||
jne systemfive_cancel // we will tail call below
|
||||
1: mov %rcx,%r10 // move the fourth argument
|
||||
clc // no cancellable system calls exist
|
||||
|
@ -144,7 +144,7 @@ systemfive_cancellable_end: // i/o calls park here for long time
|
|||
jz systemfive_errno // it's spawn() probably
|
||||
testb $PT_NOCANCEL,0x00(%rcx) // PosixThread::flags
|
||||
jnz systemfive_errno // cancellation is disabled
|
||||
cmp $0,0x04(%rcx) // PosixThread::cancelled
|
||||
cmpl $0,0x04(%rcx) // PosixThread::cancelled
|
||||
je systemfive_errno // we aren't actually cancelled
|
||||
jmp 4f // now we are in fact cancelled
|
||||
systemfive_cancel: // SIGTHR will jump here too
|
||||
|
|
|
@ -46,7 +46,6 @@ COSMOPOLITAN_C_START_
|
|||
EXPR; \
|
||||
MemoryStrict = BENCHLOOP(__startbench_m, __endbench_m, 32, ({ \
|
||||
INIT; \
|
||||
thrashcodecache(); \
|
||||
__polluteregisters(); \
|
||||
}), \
|
||||
(EXPR)); \
|
||||
|
@ -88,7 +87,6 @@ COSMOPOLITAN_C_START_
|
|||
EXPR; \
|
||||
MemoryStrict = BENCHLOOP(__startbench_m, __endbench_m, NUM, ({ \
|
||||
INIT; \
|
||||
thrashcodecache(); \
|
||||
__polluteregisters(); \
|
||||
}), \
|
||||
(EXPR)); \
|
||||
|
@ -101,53 +99,47 @@ COSMOPOLITAN_C_START_
|
|||
MAX(.001, MemoryStrict - __testlib_ezbenchcontrol())); \
|
||||
} while (0)
|
||||
|
||||
#define EZBENCH_C(NAME, CONTROL, EXPR) \
|
||||
do { \
|
||||
int Core, Tries, Interrupts; \
|
||||
double Control, Speculative, MemoryStrict; \
|
||||
Tries = 0; \
|
||||
do { \
|
||||
__testlib_yield(); \
|
||||
Core = __testlib_getcore(); \
|
||||
Interrupts = __testlib_getinterrupts(); \
|
||||
Control = BENCHLOOP(__startbench_m, __endbench_m, EZBENCH_COUNT, ({ \
|
||||
thrashcodecache(); \
|
||||
__polluteregisters(); \
|
||||
}), \
|
||||
(CONTROL)); \
|
||||
} while (++Tries < EZBENCH_TRIES && \
|
||||
(__testlib_getcore() != Core && \
|
||||
__testlib_getinterrupts() > Interrupts)); \
|
||||
if (Tries == EZBENCH_TRIES) __testlib_ezbenchwarn(" control"); \
|
||||
Tries = 0; \
|
||||
do { \
|
||||
__testlib_yield(); \
|
||||
Core = __testlib_getcore(); \
|
||||
Interrupts = __testlib_getinterrupts(); \
|
||||
EXPR; \
|
||||
Speculative = BENCHLOOP(__startbench, __endbench, EZBENCH_COUNT, \
|
||||
__polluteregisters(), (EXPR)); \
|
||||
} while (++Tries < EZBENCH_TRIES && \
|
||||
(__testlib_getcore() != Core && \
|
||||
__testlib_getinterrupts() > Interrupts)); \
|
||||
if (Tries == EZBENCH_TRIES) __testlib_ezbenchwarn(" speculative"); \
|
||||
Tries = 0; \
|
||||
do { \
|
||||
__testlib_yield(); \
|
||||
Core = __testlib_getcore(); \
|
||||
Interrupts = __testlib_getinterrupts(); \
|
||||
EXPR; \
|
||||
MemoryStrict = BENCHLOOP(__startbench_m, __endbench_m, 8, ({ \
|
||||
thrashcodecache(); \
|
||||
__polluteregisters(); \
|
||||
}), \
|
||||
(EXPR)); \
|
||||
} while (++Tries < EZBENCH_TRIES && \
|
||||
(__testlib_getcore() != Core && \
|
||||
__testlib_getinterrupts() > Interrupts)); \
|
||||
if (Tries == EZBENCH_TRIES) __testlib_ezbenchwarn(" memory strict"); \
|
||||
__testlib_ezbenchreport(NAME, MAX(.001, Speculative - Control), \
|
||||
MAX(.001, MemoryStrict - Control)); \
|
||||
#define EZBENCH_C(NAME, CONTROL, EXPR) \
|
||||
do { \
|
||||
int Core, Tries, Interrupts; \
|
||||
double Control, Speculative, MemoryStrict; \
|
||||
Tries = 0; \
|
||||
do { \
|
||||
__testlib_yield(); \
|
||||
Core = __testlib_getcore(); \
|
||||
Interrupts = __testlib_getinterrupts(); \
|
||||
Control = BENCHLOOP(__startbench_m, __endbench_m, EZBENCH_COUNT, \
|
||||
({ __polluteregisters(); }), (CONTROL)); \
|
||||
} while (++Tries < EZBENCH_TRIES && \
|
||||
(__testlib_getcore() != Core && \
|
||||
__testlib_getinterrupts() > Interrupts)); \
|
||||
if (Tries == EZBENCH_TRIES) __testlib_ezbenchwarn(" control"); \
|
||||
Tries = 0; \
|
||||
do { \
|
||||
__testlib_yield(); \
|
||||
Core = __testlib_getcore(); \
|
||||
Interrupts = __testlib_getinterrupts(); \
|
||||
EXPR; \
|
||||
Speculative = BENCHLOOP(__startbench, __endbench, EZBENCH_COUNT, \
|
||||
__polluteregisters(), (EXPR)); \
|
||||
} while (++Tries < EZBENCH_TRIES && \
|
||||
(__testlib_getcore() != Core && \
|
||||
__testlib_getinterrupts() > Interrupts)); \
|
||||
if (Tries == EZBENCH_TRIES) __testlib_ezbenchwarn(" speculative"); \
|
||||
Tries = 0; \
|
||||
do { \
|
||||
__testlib_yield(); \
|
||||
Core = __testlib_getcore(); \
|
||||
Interrupts = __testlib_getinterrupts(); \
|
||||
EXPR; \
|
||||
MemoryStrict = BENCHLOOP(__startbench_m, __endbench_m, 8, \
|
||||
({ __polluteregisters(); }), (EXPR)); \
|
||||
} while (++Tries < EZBENCH_TRIES && \
|
||||
(__testlib_getcore() != Core && \
|
||||
__testlib_getinterrupts() > Interrupts)); \
|
||||
if (Tries == EZBENCH_TRIES) __testlib_ezbenchwarn(" memory strict"); \
|
||||
__testlib_ezbenchreport(NAME, MAX(.001, Speculative - Control), \
|
||||
MAX(.001, MemoryStrict - Control)); \
|
||||
} while (0)
|
||||
|
||||
#define EZBENCH_N(NAME, N, EXPR) \
|
||||
|
|
|
@ -63,6 +63,7 @@ noasan bool testlib_memoryexists(const void *p) {
|
|||
_npassert(!sigaction(SIGSEGV, &sa, old + 0));
|
||||
_npassert(!sigaction(SIGBUS, &sa, old + 1));
|
||||
c = atomic_load(mem);
|
||||
(void)c;
|
||||
_npassert(!sigaction(SIGBUS, old + 1, 0));
|
||||
_npassert(!sigaction(SIGSEGV, old + 0, 0));
|
||||
return !gotsignal;
|
||||
|
|
|
@ -382,8 +382,6 @@ void testlib_error_enter(const char *, const char *);
|
|||
void testlib_showerror(const char *, int, const char *, const char *,
|
||||
const char *, const char *, char *, char *);
|
||||
|
||||
void thrashcodecache(void);
|
||||
|
||||
void testlib_finish(void);
|
||||
int testlib_geterrno(void);
|
||||
void testlib_seterrno(int);
|
||||
|
|
|
@ -38,7 +38,6 @@ LIBC_TESTLIB_A_SRCS_S = \
|
|||
libc/testlib/moby.S \
|
||||
libc/testlib/polluteregisters.S \
|
||||
libc/testlib/testcase.S \
|
||||
libc/testlib/thrashcodecache.S \
|
||||
libc/testlib/viewables.S
|
||||
|
||||
LIBC_TESTLIB_A_SRCS_C = \
|
||||
|
@ -147,8 +146,6 @@ o/$(MODE)/libc/testlib/polluteregisters.o: libc/testlib/polluteregisters.S
|
|||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
o/$(MODE)/libc/testlib/testcase.o: libc/testlib/testcase.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
o/$(MODE)/libc/testlib/thrashcodecache.o: libc/testlib/thrashcodecache.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
o/$(MODE)/libc/testlib/viewables.o: libc/testlib/viewables.S
|
||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||
|
||||
|
|
|
@ -1,49 +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 2020 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"
|
||||
.testonly
|
||||
|
||||
// Empties L1 instruction cache.
|
||||
thrashcodecache:
|
||||
#ifdef __x86_64__
|
||||
.leafprologue
|
||||
push %rbx
|
||||
xor %eax,%eax
|
||||
xor %ecx,%ecx
|
||||
cpuid
|
||||
add %r9,%r8
|
||||
// Generate 32kb of junk code clobbering r8,r9,r10,r11
|
||||
i = 0xdeadbeef
|
||||
0: .rept 32768/(3+7)
|
||||
rex.wrb
|
||||
.byte 0001|(i&030) // ADD/OR/... Evqp Gvqp
|
||||
.byte 0300|(i&033) // %r8-%r11 to %r8-%r11
|
||||
.byte 0x49,0x81,0360|(i&003) // XOR immed32,%r8-%r11
|
||||
.long i
|
||||
i = ((i * 1103515245 + 12345) >> 16) & 0xffffffff
|
||||
.endr
|
||||
xor %eax,%eax
|
||||
xor %ecx,%ecx
|
||||
cpuid
|
||||
pop %rbx
|
||||
.leafepilogue
|
||||
#else
|
||||
ret
|
||||
#endif
|
||||
.endfn thrashcodecache,globl
|
|
@ -101,7 +101,7 @@ void makecontext(ucontext_t *uc, void func(), int argc, ...) {
|
|||
sp += uc->uc_stack.ss_size;
|
||||
sp -= 16; // openbsd:stackbound
|
||||
sp -= sizeof(*call);
|
||||
sp &= -alignof(*call);
|
||||
sp &= -alignof(struct Gadget);
|
||||
call = (struct Gadget *)sp;
|
||||
|
||||
// get arguments
|
||||
|
|
|
@ -38,10 +38,9 @@
|
|||
*/
|
||||
errno_t pthread_getaffinity_np(pthread_t thread, size_t size,
|
||||
cpu_set_t *bitset) {
|
||||
int e, rc, tid;
|
||||
int rc, tid;
|
||||
|
||||
if (!(rc = pthread_getunique_np(thread, &tid))) {
|
||||
e = errno;
|
||||
if (size != sizeof(cpu_set_t)) {
|
||||
rc = einval();
|
||||
} else if (IsWindows() || IsMetal() || IsOpenbsd()) {
|
||||
|
|
|
@ -253,7 +253,7 @@ sem_t *sem_open(const char *name, int oflag, ...) {
|
|||
* @return 0 on success, or -1 w/ errno
|
||||
*/
|
||||
int sem_close(sem_t *sem) {
|
||||
int rc, prefs;
|
||||
int prefs;
|
||||
bool unmap, delete;
|
||||
struct Semaphore *s, **p;
|
||||
_npassert(sem->sem_magic == SEM_MAGIC_NAMED);
|
||||
|
@ -275,7 +275,7 @@ int sem_close(sem_t *sem) {
|
|||
_npassert(!munmap(sem, PAGESIZE));
|
||||
}
|
||||
if (delete) {
|
||||
rc = unlink(s->path);
|
||||
unlink(s->path);
|
||||
}
|
||||
if (unmap) {
|
||||
free(s->path);
|
||||
|
|
|
@ -69,7 +69,7 @@ static int Spawner(void *arg, int tid) {
|
|||
rc = spawner->fun(spawner->arg, tid);
|
||||
_pthread_ungarbage();
|
||||
free(spawner);
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -28,7 +28,9 @@
|
|||
#include "libc/math.h"
|
||||
#include "libc/runtime/fenv.h"
|
||||
#include "libc/tinymath/internal.h"
|
||||
#ifndef __llvm__
|
||||
#include "third_party/intel/smmintrin.internal.h"
|
||||
#endif
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Musl libc (MIT License)\\n\
|
||||
|
@ -63,7 +65,7 @@ double ceil(double x)
|
|||
asm("fidbra\t%0,6,%1,4" : "=f"(x) : "f"(x));
|
||||
return x;
|
||||
|
||||
#elif defined(__x86_64__) && defined(__SSE4_1__)
|
||||
#elif defined(__x86_64__) && defined(__SSE4_1__) && !defined(__llvm__) && !defined(__chibicc__)
|
||||
|
||||
asm("roundsd\t%2,%1,%0"
|
||||
: "=x"(x)
|
||||
|
|
|
@ -27,7 +27,9 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/math.h"
|
||||
#include "libc/tinymath/internal.h"
|
||||
#ifndef __llvm__
|
||||
#include "third_party/intel/smmintrin.internal.h"
|
||||
#endif
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Musl libc (MIT License)\\n\
|
||||
|
@ -55,7 +57,7 @@ float ceilf(float x)
|
|||
asm("fiebra\t%0,6,%1,4" : "=f"(x) : "f"(x));
|
||||
return x;
|
||||
|
||||
#elif defined(__x86_64__) && defined(__SSE4_1__)
|
||||
#elif defined(__x86_64__) && defined(__SSE4_1__) && !defined(__llvm__) && !defined(__chibicc__)
|
||||
|
||||
asm("roundss\t%2,%1,%0"
|
||||
: "=x"(x)
|
||||
|
|
|
@ -28,7 +28,9 @@
|
|||
#include "libc/math.h"
|
||||
#include "libc/runtime/fenv.h"
|
||||
#include "libc/tinymath/internal.h"
|
||||
#ifndef __llvm__
|
||||
#include "third_party/intel/smmintrin.internal.h"
|
||||
#endif
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Musl libc (MIT License)\\n\
|
||||
|
@ -63,7 +65,7 @@ double floor(double x)
|
|||
asm("fidbra\t%0,7,%1,4" : "=f"(x) : "f"(x));
|
||||
return x;
|
||||
|
||||
#elif defined(__x86_64__) && defined(__SSE4_1__)
|
||||
#elif defined(__x86_64__) && defined(__SSE4_1__) && !defined(__llvm__) && !defined(__chibicc__)
|
||||
|
||||
asm("roundsd\t%2,%1,%0"
|
||||
: "=x"(x)
|
||||
|
|
|
@ -27,7 +27,9 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/math.h"
|
||||
#include "libc/tinymath/internal.h"
|
||||
#ifndef __llvm__
|
||||
#include "third_party/intel/smmintrin.internal.h"
|
||||
#endif
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Musl libc (MIT License)\\n\
|
||||
|
@ -55,7 +57,7 @@ float floorf(float x)
|
|||
asm("fiebra\t%0,7,%1,4" : "=f"(x) : "f"(x));
|
||||
return x;
|
||||
|
||||
#elif defined(__x86_64__) && defined(__SSE4_1__)
|
||||
#elif defined(__x86_64__) && defined(__SSE4_1__) && !defined(__llvm__) && !defined(__chibicc__)
|
||||
|
||||
asm("roundss\t%2,%1,%0"
|
||||
: "=x"(x)
|
||||
|
|
|
@ -29,16 +29,19 @@ static inline double eval_as_double(double x) {
|
|||
static inline void fp_force_evall(long double x) {
|
||||
volatile long double y;
|
||||
y = x;
|
||||
(void)y;
|
||||
}
|
||||
|
||||
static inline void fp_force_evalf(float x) {
|
||||
volatile float y;
|
||||
y = x;
|
||||
(void)y;
|
||||
}
|
||||
|
||||
static inline void fp_force_eval(double x) {
|
||||
volatile double y;
|
||||
y = x;
|
||||
(void)y;
|
||||
}
|
||||
|
||||
static inline double fp_barrier(double x) {
|
||||
|
|
|
@ -27,7 +27,9 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/math.h"
|
||||
#include "libc/tinymath/internal.h"
|
||||
#ifndef __llvm__
|
||||
#include "third_party/intel/smmintrin.internal.h"
|
||||
#endif
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Musl libc (MIT License)\\n\
|
||||
|
@ -55,7 +57,7 @@ double trunc(double x)
|
|||
asm("fidbra\t%0,5,%1,4" : "=f"(x) : "f"(x));
|
||||
return x;
|
||||
|
||||
#elif defined(__x86_64__) && defined(__SSE4_1__)
|
||||
#elif defined(__x86_64__) && defined(__SSE4_1__) && !defined(__llvm__) && !defined(__chibicc__)
|
||||
|
||||
asm("roundsd\t%2,%1,%0"
|
||||
: "=x"(x)
|
||||
|
|
|
@ -27,7 +27,9 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/math.h"
|
||||
#include "libc/tinymath/internal.h"
|
||||
#ifndef __llvm__
|
||||
#include "third_party/intel/smmintrin.internal.h"
|
||||
#endif
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
Musl libc (MIT License)\\n\
|
||||
|
@ -55,7 +57,7 @@ float truncf(float x)
|
|||
asm("fiebra\t%0,5,%1,4" : "=f"(x) : "f"(x));
|
||||
return x;
|
||||
|
||||
#elif defined(__x86_64__) && defined(__SSE4_1__)
|
||||
#elif defined(__x86_64__) && defined(__SSE4_1__) && !defined(__llvm__) && !defined(__chibicc__)
|
||||
|
||||
asm("roundss\t%2,%1,%0"
|
||||
: "=x"(x)
|
||||
|
|
|
@ -435,7 +435,7 @@ _rlinit_vesa:
|
|||
mov $PC_VIDEO_TEXT,%al # if text mode, simply say so
|
||||
test $0b00010000,%cl
|
||||
jz .ok4
|
||||
cmp $6,%es:0x1b(%di) # if graphics mode, check if direct
|
||||
cmpl $6,%es:0x1b(%di) # if graphics mode, check if direct
|
||||
jnz .fail4 # color; bail out if not
|
||||
mov %es:0x19(%di),%cl # check actual color fields & bits
|
||||
mov %es:0x1f(%di),%ax # per pixel, against a list
|
||||
|
|
|
@ -39,7 +39,9 @@
|
|||
* @see libc/vga/tty-graph.inc
|
||||
*/
|
||||
|
||||
#ifndef __llvm__
|
||||
#pragma GCC optimize("s")
|
||||
#endif
|
||||
|
||||
#define KLOGTTY
|
||||
#define MAYUNROLLLOOPS /* do not unroll loops; keep the code small! */
|
||||
|
|
|
@ -38,7 +38,8 @@ char16_t *utf8to16(const char *p, size_t n, size_t *z) {
|
|||
if (n == -1) n = p ? strlen(p) : 0;
|
||||
if ((q = r = malloc((n + 16) * sizeof(char16_t) * 2 + sizeof(char16_t)))) {
|
||||
for (i = 0; i < n;) {
|
||||
#if defined(__SSE2__) && defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
#if defined(__SSE2__) && defined(__GNUC__) && !defined(__STRICT_ANSI__) && \
|
||||
!defined(__llvm__) && !defined(__chibicc__)
|
||||
if (i + 16 < n) {
|
||||
typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(1)));
|
||||
xmm_t vi, vz = {0};
|
||||
|
|
|
@ -27,13 +27,10 @@ COSMOPOLITAN_C_START_
|
|||
#define xstripext __xstripext
|
||||
#define xstripexts __xstripexts
|
||||
#define xload __xload
|
||||
#define xloadzd __xloadzd
|
||||
#define rmrf __rmrf
|
||||
#define xbasename __xbasename
|
||||
#define xdirname __xdirname
|
||||
#define xjoinpaths __xjoinpaths
|
||||
#define xreadlink __xreadlink
|
||||
#define xreadlinkat __xreadlinkat
|
||||
#define xfixpath __xfixpath
|
||||
#define xslurp __xslurp
|
||||
#define xbarf __xbarf
|
||||
|
@ -84,8 +81,6 @@ char *xhomedir(void) dontdiscard;
|
|||
char *xstripext(const char *) dontdiscard;
|
||||
char *xstripexts(const char *) dontdiscard;
|
||||
void *xload(_Atomic(void *) *, const void *, size_t, size_t);
|
||||
void *xloadzd(_Atomic(void *) *, const void *, size_t, size_t, size_t, size_t,
|
||||
uint32_t);
|
||||
int rmrf(const char *);
|
||||
char *xbasename(const char *) paramsnonnull()
|
||||
returnspointerwithnoaliases dontthrow nocallback dontdiscard returnsnonnull;
|
||||
|
@ -93,10 +88,6 @@ char *xdirname(const char *) paramsnonnull()
|
|||
returnspointerwithnoaliases dontthrow nocallback dontdiscard returnsnonnull;
|
||||
char *xjoinpaths(const char *, const char *) paramsnonnull()
|
||||
returnspointerwithnoaliases dontthrow nocallback dontdiscard returnsnonnull;
|
||||
char *xreadlink(const char *) paramsnonnull()
|
||||
returnspointerwithnoaliases dontthrow nocallback dontdiscard returnsnonnull;
|
||||
char *xreadlinkat(int, const char *) paramsnonnull()
|
||||
returnspointerwithnoaliases dontthrow nocallback dontdiscard returnsnonnull;
|
||||
void xfixpath(void);
|
||||
void *xslurp(const char *, size_t *)
|
||||
paramsnonnull((1)) returnspointerwithnoaliases
|
||||
|
|
|
@ -35,8 +35,7 @@ LIBC_X_A_DIRECTDEPS = \
|
|||
LIBC_STR \
|
||||
LIBC_SYSV \
|
||||
THIRD_PARTY_GDTOA \
|
||||
THIRD_PARTY_MUSL \
|
||||
THIRD_PARTY_ZLIB
|
||||
THIRD_PARTY_MUSL
|
||||
|
||||
LIBC_X_A_DEPS := \
|
||||
$(call uniq,$(foreach x,$(LIBC_X_A_DIRECTDEPS),$($(x))))
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
/*-*- 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 2021 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/assert.h"
|
||||
#include "libc/fmt/leb128.h"
|
||||
#include "libc/intrin/atomic.h"
|
||||
#include "libc/intrin/kmalloc.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nexgen32e/crc32.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "third_party/zlib/zlib.h"
|
||||
|
||||
/**
|
||||
* Loads δzd encoded data once atomically.
|
||||
*
|
||||
* @param a points to your static pointer holder
|
||||
* @param p is read-only data compressed using raw deflate
|
||||
* @param n is byte length of deflated data
|
||||
* @param m is byte length of inflated data
|
||||
* @param c is number of items in array
|
||||
* @param z is byte length of items
|
||||
* @param s is crc32 checksum
|
||||
* @return pointer to decoded data
|
||||
* @threadsafe
|
||||
*/
|
||||
void *xloadzd(_Atomic(void *) *a, const void *p, size_t n, size_t m, size_t c,
|
||||
size_t z, uint32_t s) {
|
||||
size_t i;
|
||||
char *q, *b;
|
||||
void *r, *g;
|
||||
int64_t x, y;
|
||||
if ((r = atomic_load_explicit(a, memory_order_acquire))) return r;
|
||||
_unassert(z == 2 || z == 4);
|
||||
if (!(b = q = malloc(m))) return 0;
|
||||
if (__inflate(q, m, p, n)) {
|
||||
free(q);
|
||||
return 0;
|
||||
}
|
||||
if (!(r = kmalloc(c * z))) {
|
||||
free(q);
|
||||
return 0;
|
||||
}
|
||||
for (x = i = 0; i < c; ++i) {
|
||||
b += unzleb64(b, 10, &y);
|
||||
x += y;
|
||||
if (z == 2) {
|
||||
((uint16_t *)r)[i] = x;
|
||||
} else {
|
||||
((uint32_t *)r)[i] = x;
|
||||
}
|
||||
}
|
||||
free(q);
|
||||
assert(crc32_z(0, r, c * z) == s);
|
||||
g = 0;
|
||||
if (!atomic_compare_exchange_strong_explicit(a, &g, r, memory_order_relaxed,
|
||||
memory_order_relaxed)) {
|
||||
r = g;
|
||||
}
|
||||
return r;
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
/*-*- 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 2021 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/calls.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
/**
|
||||
* Reads symbolic link.
|
||||
*
|
||||
* @return nul-terminated string, or null w/ errno
|
||||
* @see readlinkat()
|
||||
*/
|
||||
char *xreadlinkat(int dirfd, const char *path) {
|
||||
ssize_t rc;
|
||||
size_t n, c;
|
||||
char *p, *q;
|
||||
c = PAGESIZE;
|
||||
p = xmalloc(c);
|
||||
if ((rc = readlinkat(dirfd, path, p, c)) != -1) {
|
||||
if ((n = rc) < c) {
|
||||
p[n] = 0;
|
||||
if ((q = realloc(p, n + 1))) p = q;
|
||||
return p;
|
||||
} else {
|
||||
enametoolong();
|
||||
}
|
||||
}
|
||||
free(p);
|
||||
return 0;
|
||||
}
|
|
@ -39,8 +39,8 @@
|
|||
* @asyncsignalsafe
|
||||
* @vforksafe
|
||||
*/
|
||||
int(xsigaction)(int sig, void *handler, uint64_t flags, uint64_t mask,
|
||||
struct sigaction *old) {
|
||||
int xsigaction(int sig, void *handler, uint64_t flags, uint64_t mask,
|
||||
struct sigaction *old) {
|
||||
/* This API is superior to sigaction() because (1) it offers feature
|
||||
parity; (2) compiler emits 1/3rd as much binary code at call-site;
|
||||
and (3) it removes typing that just whines without added safety. */
|
||||
|
|
|
@ -6,14 +6,6 @@ COSMOPOLITAN_C_START_
|
|||
|
||||
int xsigaction(int, void *, uint64_t, uint64_t, struct sigaction *);
|
||||
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
#define xsigaction(SIG, HANDLER, FLAGS, MASK, OLD) \
|
||||
({ \
|
||||
__SIGACTION_YOINK(SIG); \
|
||||
xsigaction(SIG, HANDLER, FLAGS, MASK, OLD); \
|
||||
})
|
||||
#endif
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_X_XSIGACTION_H_ */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue