mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +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
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
|
@ -17,7 +17,7 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
mode: ["", tiny, rel, tinylinux, optlinux]
|
mode: ["", tiny, rel, nox87, aarch64, tinylinux, optlinux]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,7 @@ APE_LOADER_FLAGS = \
|
||||||
-Os \
|
-Os \
|
||||||
-ffreestanding \
|
-ffreestanding \
|
||||||
-mgeneral-regs-only \
|
-mgeneral-regs-only \
|
||||||
|
-fno-stack-protector \
|
||||||
-fno-ident \
|
-fno-ident \
|
||||||
-fno-gnu-unique \
|
-fno-gnu-unique \
|
||||||
-c \
|
-c \
|
||||||
|
|
Binary file not shown.
|
@ -92,7 +92,6 @@ endif
|
||||||
# - Turns off support for other operating systems
|
# - Turns off support for other operating systems
|
||||||
#
|
#
|
||||||
ifeq ($(MODE), optlinux)
|
ifeq ($(MODE), optlinux)
|
||||||
ENABLE_FTRACE = 1
|
|
||||||
CONFIG_OFLAGS ?= -g
|
CONFIG_OFLAGS ?= -g
|
||||||
CONFIG_CPPFLAGS += -DNDEBUG -DSYSDEBUG -DSUPPORT_VECTOR=1
|
CONFIG_CPPFLAGS += -DNDEBUG -DSYSDEBUG -DSUPPORT_VECTOR=1
|
||||||
CONFIG_CCFLAGS += -O3 -fmerge-all-constants
|
CONFIG_CCFLAGS += -O3 -fmerge-all-constants
|
||||||
|
@ -388,7 +387,15 @@ TARGET_ARCH ?= -msse3
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# LLVM Mode
|
# LLVM Mode
|
||||||
|
#
|
||||||
|
# We aim to support:
|
||||||
|
#
|
||||||
|
# make -j8 m=llvm o/llvm/libc
|
||||||
|
#
|
||||||
|
# The rest of the monorepo may not work with llvm.
|
||||||
|
#
|
||||||
ifeq ($(MODE), llvm)
|
ifeq ($(MODE), llvm)
|
||||||
|
.STRICT = 0
|
||||||
TARGET_ARCH ?= -msse3
|
TARGET_ARCH ?= -msse3
|
||||||
CONFIG_CCFLAGS += $(BACKTRACES) -DSYSDEBUG -O2
|
CONFIG_CCFLAGS += $(BACKTRACES) -DSYSDEBUG -O2
|
||||||
AS = clang
|
AS = clang
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
* @see ITU G.711
|
* @see ITU G.711
|
||||||
*/
|
*/
|
||||||
int alaw(int x) {
|
int alaw(int x) {
|
||||||
int a, b, e, i;
|
int a, b, i;
|
||||||
if ((a = x) < 0) a = ~a;
|
if ((a = x) < 0) a = ~a;
|
||||||
a >>= 4;
|
a >>= 4;
|
||||||
if (a > 15) {
|
if (a > 15) {
|
||||||
|
@ -36,7 +36,6 @@ int alaw(int x) {
|
||||||
a -= 16;
|
a -= 16;
|
||||||
a += (b + 1) << 4;
|
a += (b + 1) << 4;
|
||||||
} else {
|
} else {
|
||||||
e = 1;
|
|
||||||
a -= 16;
|
a -= 16;
|
||||||
a += 16;
|
a += 16;
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,7 +191,8 @@ o/$(MODE)/libc/calls/pledge-linux.o \
|
||||||
o/$(MODE)/libc/calls/siginfo2cosmo.o: private \
|
o/$(MODE)/libc/calls/siginfo2cosmo.o: private \
|
||||||
CFLAGS += \
|
CFLAGS += \
|
||||||
-ffreestanding \
|
-ffreestanding \
|
||||||
-fno-sanitize=all
|
-fno-sanitize=all \
|
||||||
|
-fno-stack-protector
|
||||||
|
|
||||||
o/$(MODE)/libc/calls/pledge-linux.o \
|
o/$(MODE)/libc/calls/pledge-linux.o \
|
||||||
o/$(MODE)/libc/calls/unveil.o: private \
|
o/$(MODE)/libc/calls/unveil.o: private \
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "libc/calls/state.internal.h"
|
#include "libc/calls/state.internal.h"
|
||||||
#include "libc/calls/struct/fd.internal.h"
|
#include "libc/calls/struct/fd.internal.h"
|
||||||
#include "libc/calls/struct/sigaction.h"
|
#include "libc/calls/struct/sigaction.h"
|
||||||
|
#include "libc/calls/struct/sigaction.internal.h"
|
||||||
#include "libc/calls/syscall_support-nt.internal.h"
|
#include "libc/calls/syscall_support-nt.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
|
|
|
@ -59,7 +59,6 @@ static int ioctl_siocgifconf_sysv(int fd, struct ifconf *ifc) {
|
||||||
char *b, *p, *e;
|
char *b, *p, *e;
|
||||||
char ifcBsd[16];
|
char ifcBsd[16];
|
||||||
struct ifreq *req;
|
struct ifreq *req;
|
||||||
struct ifreq *end;
|
|
||||||
uint32_t bufLen, ip;
|
uint32_t bufLen, ip;
|
||||||
size_t numReq, bufMax;
|
size_t numReq, bufMax;
|
||||||
if (IsLinux()) return sys_ioctl(fd, SIOCGIFCONF, ifc);
|
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);
|
memcpy(&bufLen, b, 4);
|
||||||
req = ifc->ifc_req;
|
req = ifc->ifc_req;
|
||||||
end = req + ifc->ifc_len / sizeof(*req);
|
|
||||||
for (p = b, e = p + MIN(bufMax, READ32LE(ifcBsd)); p + 16 + 16 <= e;
|
for (p = b, e = p + MIN(bufMax, READ32LE(ifcBsd)); p + 16 + 16 <= e;
|
||||||
p += IsBsd() ? 16 + MAX(16, p[16] & 255) : 40) {
|
p += IsBsd() ? 16 + MAX(16, p[16] & 255) : 40) {
|
||||||
fam = p[IsBsd() ? 17 : 16] & 255;
|
fam = p[IsBsd() ? 17 : 16] & 255;
|
||||||
|
|
|
@ -26,9 +26,6 @@
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
|
||||||
textwindows int sys_pause_nt(void) {
|
textwindows int sys_pause_nt(void) {
|
||||||
long ms, totoms;
|
|
||||||
ms = 0;
|
|
||||||
totoms = 0;
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
|
||||||
if (_check_interrupts(false, g_fds.p)) {
|
if (_check_interrupts(false, g_fds.p)) {
|
||||||
|
@ -40,7 +37,8 @@ textwindows int sys_pause_nt(void) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(SYSDEBUG) && defined(_POLLTRACE)
|
#if defined(SYSDEBUG) && _POLLTRACE
|
||||||
|
long ms = 0, totoms = 0;
|
||||||
ms += __SIG_POLLING_INTERVAL_MS;
|
ms += __SIG_POLLING_INTERVAL_MS;
|
||||||
if (ms >= __SIG_LOGGING_INTERVAL_MS) {
|
if (ms >= __SIG_LOGGING_INTERVAL_MS) {
|
||||||
totoms += ms, ms = 0;
|
totoms += ms, ms = 0;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "libc/calls/struct/seccomp.internal.h"
|
#include "libc/calls/struct/seccomp.internal.h"
|
||||||
#include "libc/calls/struct/sigaction.h"
|
#include "libc/calls/struct/sigaction.h"
|
||||||
#include "libc/calls/syscall_support-sysv.internal.h"
|
#include "libc/calls/syscall_support-sysv.internal.h"
|
||||||
|
#include "libc/calls/ucontext.h"
|
||||||
#include "libc/intrin/bsr.h"
|
#include "libc/intrin/bsr.h"
|
||||||
#include "libc/intrin/likely.h"
|
#include "libc/intrin/likely.h"
|
||||||
#include "libc/intrin/promises.internal.h"
|
#include "libc/intrin/promises.internal.h"
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/sig.internal.h"
|
#include "libc/calls/sig.internal.h"
|
||||||
#include "libc/calls/state.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/sigaction.internal.h"
|
||||||
#include "libc/calls/struct/siginfo.internal.h"
|
#include "libc/calls/struct/siginfo.internal.h"
|
||||||
#include "libc/calls/struct/sigset.h"
|
#include "libc/calls/struct/sigset.h"
|
||||||
|
@ -53,6 +54,12 @@
|
||||||
STATIC_YOINK("strsignal"); // for kprintf()
|
STATIC_YOINK("strsignal"); // for kprintf()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if SupportsWindows()
|
||||||
|
STATIC_YOINK("_init_onntconsoleevent");
|
||||||
|
STATIC_YOINK("_check_sigwinch");
|
||||||
|
STATIC_YOINK("_init_wincrash");
|
||||||
|
#endif
|
||||||
|
|
||||||
#define SA_RESTORER 0x04000000
|
#define SA_RESTORER 0x04000000
|
||||||
|
|
||||||
static void sigaction_cosmo2native(union metasigaction *sa) {
|
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.err = ctx->uc_mcontext.err;
|
||||||
uc.uc_mcontext.rip = ctx->uc_mcontext.rip;
|
uc.uc_mcontext.rip = ctx->uc_mcontext.rip;
|
||||||
uc.uc_mcontext.rsp = ctx->uc_mcontext.rsp;
|
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);
|
((sigaction_f)(__executable_start + rva))(sig, &si2, &uc);
|
||||||
ctx->uc_stack.ss_sp = uc.uc_stack.ss_sp;
|
ctx->uc_stack.ss_sp = uc.uc_stack.ss_sp;
|
||||||
ctx->uc_stack.ss_size = uc.uc_stack.ss_size;
|
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.err = uc.uc_mcontext.err;
|
||||||
ctx->uc_mcontext.rip = uc.uc_mcontext.rip;
|
ctx->uc_mcontext.rip = uc.uc_mcontext.rip;
|
||||||
ctx->uc_mcontext.rsp = uc.uc_mcontext.rsp;
|
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.rip = ctx->sc_rip;
|
||||||
g.uc.uc_mcontext.rsp = ctx->sc_rsp;
|
g.uc.uc_mcontext.rsp = ctx->sc_rsp;
|
||||||
if (ctx->sc_fpstate) {
|
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);
|
((sigaction_f)(__executable_start + rva))(sig, &g.si, &g.uc);
|
||||||
ctx->sc_mask = g.uc.uc_sigmask.__bits[0];
|
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_rip = g.uc.uc_mcontext.rip;
|
||||||
ctx->sc_rsp = g.uc.uc_mcontext.rsp;
|
ctx->sc_rsp = g.uc.uc_mcontext.rsp;
|
||||||
if (ctx->sc_fpstate) {
|
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;
|
struct sigaction sa;
|
||||||
bzero(&sa, sizeof(sa));
|
bzero(&sa, sizeof(sa));
|
||||||
sa.sa_handler = SIG_IGN;
|
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 == SIGBUS || //
|
||||||
si_signo == SIGTRAP) {
|
si_signo == SIGTRAP) {
|
||||||
si->si_addr = si_addr;
|
si->si_addr = si_addr;
|
||||||
|
} else if (si_signo == SIGCHLD) {
|
||||||
|
si->si_status = si_status;
|
||||||
} else if (si_signo == SIGALRM) {
|
} else if (si_signo == SIGALRM) {
|
||||||
si->si_timerid = si_timerid;
|
si->si_timerid = si_timerid;
|
||||||
si->si_overrun = si_overrun;
|
si->si_overrun = si_overrun;
|
||||||
|
|
|
@ -30,9 +30,9 @@
|
||||||
* @note this function has BSD semantics, i.e. SA_RESTART
|
* @note this function has BSD semantics, i.e. SA_RESTART
|
||||||
* @see sigaction() which has more features and docs
|
* @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};
|
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;
|
return old.sa_handler;
|
||||||
} else {
|
} else {
|
||||||
return SIG_ERR;
|
return SIG_ERR;
|
||||||
|
|
|
@ -47,7 +47,6 @@
|
||||||
*/
|
*/
|
||||||
int sigsuspend(const sigset_t *ignore) {
|
int sigsuspend(const sigset_t *ignore) {
|
||||||
int rc;
|
int rc;
|
||||||
long ms, totoms;
|
|
||||||
sigset_t save, *arg, mask = {0};
|
sigset_t save, *arg, mask = {0};
|
||||||
STRACE("sigsuspend(%s) → ...", DescribeSigset(0, ignore));
|
STRACE("sigsuspend(%s) → ...", DescribeSigset(0, ignore));
|
||||||
BEGIN_CANCELLATION_POINT;
|
BEGIN_CANCELLATION_POINT;
|
||||||
|
@ -73,8 +72,10 @@ int sigsuspend(const sigset_t *ignore) {
|
||||||
rc = sys_sigsuspend(arg, 8);
|
rc = sys_sigsuspend(arg, 8);
|
||||||
} else {
|
} else {
|
||||||
__sig_mask(SIG_SETMASK, arg, &save);
|
__sig_mask(SIG_SETMASK, arg, &save);
|
||||||
ms = 0;
|
#if defined(SYSDEBUG) && _POLLTRACE
|
||||||
totoms = 0;
|
long ms = 0;
|
||||||
|
long totoms = 0;
|
||||||
|
#endif
|
||||||
do {
|
do {
|
||||||
if ((rc = _check_interrupts(false, g_fds.p))) {
|
if ((rc = _check_interrupts(false, g_fds.p))) {
|
||||||
break;
|
break;
|
||||||
|
@ -83,7 +84,7 @@ int sigsuspend(const sigset_t *ignore) {
|
||||||
POLLTRACE("IOCP EINTR");
|
POLLTRACE("IOCP EINTR");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#if defined(SYSDEBUG) && defined(_POLLTRACE)
|
#if defined(SYSDEBUG) && _POLLTRACE
|
||||||
ms += __SIG_POLLING_INTERVAL_MS;
|
ms += __SIG_POLLING_INTERVAL_MS;
|
||||||
if (ms >= __SIG_LOGGING_INTERVAL_MS) {
|
if (ms >= __SIG_LOGGING_INTERVAL_MS) {
|
||||||
totoms += ms, ms = 0;
|
totoms += ms, ms = 0;
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
#include "libc/sysv/consts/sicode.h"
|
#include "libc/sysv/consts/sicode.h"
|
||||||
#include "libc/sysv/consts/sig.h"
|
#include "libc/sysv/consts/sig.h"
|
||||||
#include "libc/thread/tls.h"
|
#include "libc/thread/tls.h"
|
||||||
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
|
|
||||||
static struct winsize __ws;
|
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_namelen = f_namelen;
|
||||||
f->f_frsize = f_frsize;
|
f->f_frsize = f_frsize;
|
||||||
f->f_flags = f_flags;
|
f->f_flags = f_flags;
|
||||||
|
f->f_owner = f_owner;
|
||||||
memcpy(f->f_fstypename, f_fstypename, 16);
|
memcpy(f->f_fstypename, f_fstypename, 16);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,15 +2,11 @@
|
||||||
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_H_
|
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_H_
|
||||||
#include "libc/calls/struct/siginfo.h"
|
#include "libc/calls/struct/siginfo.h"
|
||||||
#include "libc/calls/struct/sigset.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)
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
COSMOPOLITAN_C_START_
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
typedef void (*sighandler_t)(int);
|
typedef void (*sighandler_t)(int);
|
||||||
typedef void (*sigaction_f)(int, struct siginfo *,
|
typedef void (*sigaction_f)(int, struct siginfo *, void *);
|
||||||
void * /*struct ucontext **/);
|
|
||||||
|
|
||||||
struct sigaction { /* cosmo abi */
|
struct sigaction { /* cosmo abi */
|
||||||
union {
|
union {
|
||||||
|
@ -25,60 +21,6 @@ struct sigaction { /* cosmo abi */
|
||||||
sighandler_t signal(int, sighandler_t);
|
sighandler_t signal(int, sighandler_t);
|
||||||
int sigaction(int, const struct sigaction *, struct sigaction *);
|
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_
|
COSMOPOLITAN_C_END_
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_H_ */
|
#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 *);
|
const char *DescribeSigaction(char[256], int, const struct sigaction *);
|
||||||
#define DescribeSigaction(rc, sa) DescribeSigaction(alloca(256), rc, sa)
|
#define DescribeSigaction(rc, sa) DescribeSigaction(alloca(256), rc, sa)
|
||||||
|
|
||||||
|
void _init_onntconsoleevent(void);
|
||||||
|
void _init_wincrash(void);
|
||||||
|
void _check_sigwinch();
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
COSMOPOLITAN_C_END_
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_SIGACTION_INTERNAL_H_ */
|
#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;
|
inmode |= kNtEnableVirtualTerminalInput;
|
||||||
}
|
}
|
||||||
ok = SetConsoleMode(in, inmode);
|
ok = SetConsoleMode(in, inmode);
|
||||||
|
(void)ok;
|
||||||
NTTRACE("SetConsoleMode(%p, %s) → %hhhd", in,
|
NTTRACE("SetConsoleMode(%p, %s) → %hhhd", in,
|
||||||
DescribeNtConsoleInFlags(inmode), ok);
|
DescribeNtConsoleInFlags(inmode), ok);
|
||||||
}
|
}
|
||||||
|
@ -75,6 +76,7 @@ textwindows int tcsetattr_nt(int ignored, int opt, const struct termios *tio) {
|
||||||
outmode |= kNtEnableVirtualTerminalProcessing;
|
outmode |= kNtEnableVirtualTerminalProcessing;
|
||||||
}
|
}
|
||||||
ok = SetConsoleMode(out, outmode);
|
ok = SetConsoleMode(out, outmode);
|
||||||
|
(void)ok;
|
||||||
NTTRACE("SetConsoleMode(%p, %s) → %hhhd", out,
|
NTTRACE("SetConsoleMode(%p, %s) → %hhhd", out,
|
||||||
DescribeNtConsoleOutFlags(outmode), ok);
|
DescribeNtConsoleOutFlags(outmode), ok);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,6 @@
|
||||||
*/
|
*/
|
||||||
int ResolveDns(const struct ResolvConf *resolvconf, int af, const char *name,
|
int ResolveDns(const struct ResolvConf *resolvconf, int af, const char *name,
|
||||||
struct sockaddr *addr, uint32_t addrsize) {
|
struct sockaddr *addr, uint32_t addrsize) {
|
||||||
int32_t ttl;
|
|
||||||
int rc, fd, n;
|
int rc, fd, n;
|
||||||
struct DnsQuestion q;
|
struct DnsQuestion q;
|
||||||
struct DnsHeader h, h2;
|
struct DnsHeader h, h2;
|
||||||
|
@ -94,7 +93,7 @@ int ResolveDns(const struct ResolvConf *resolvconf, int af, const char *name,
|
||||||
if (p + 10 <= pe) {
|
if (p + 10 <= pe) {
|
||||||
rtype = READ16BE(p);
|
rtype = READ16BE(p);
|
||||||
rclass = READ16BE(p + 2);
|
rclass = READ16BE(p + 2);
|
||||||
ttl = READ32BE(p + 4);
|
// ttl = READ32BE(p + 4);
|
||||||
rdlength = READ16BE(p + 8);
|
rdlength = READ16BE(p + 8);
|
||||||
if (p + 10 + rdlength <= pe && rdlength == 4 &&
|
if (p + 10 + rdlength <= pe && rdlength == 4 &&
|
||||||
rclass == DNS_CLASS_IN && rtype == DNS_TYPE_A) {
|
rclass == DNS_CLASS_IN && rtype == DNS_TYPE_A) {
|
||||||
|
|
|
@ -89,8 +89,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef __cplusplus
|
#ifndef __cplusplus
|
||||||
|
#if defined(__GNUC__) && !defined(__llvm__)
|
||||||
#pragma GCC push_options
|
#pragma GCC push_options
|
||||||
#pragma GCC diagnostic ignored "-Wc++-compat"
|
#pragma GCC diagnostic ignored "-Wc++-compat"
|
||||||
|
#endif
|
||||||
#define HAVE_STDBOOL_H 1
|
#define HAVE_STDBOOL_H 1
|
||||||
#if __STDC_VERSION__ + 0 >= 201112
|
#if __STDC_VERSION__ + 0 >= 201112
|
||||||
typedef _Bool bool;
|
typedef _Bool bool;
|
||||||
|
@ -102,7 +104,9 @@ typedef _Bool bool;
|
||||||
typedef __WCHAR_TYPE__ wchar_t;
|
typedef __WCHAR_TYPE__ wchar_t;
|
||||||
typedef __CHAR16_TYPE__ char16_t;
|
typedef __CHAR16_TYPE__ char16_t;
|
||||||
typedef __CHAR32_TYPE__ char32_t;
|
typedef __CHAR32_TYPE__ char32_t;
|
||||||
|
#if defined(__GNUC__) && !defined(__llvm__)
|
||||||
#pragma GCC pop_options
|
#pragma GCC pop_options
|
||||||
|
#endif
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
#define _LIBCPP_STDINT_H
|
#define _LIBCPP_STDINT_H
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
│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 │
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
│ any purpose with or without fee is hereby granted, provided that the │
|
│ 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 │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/sysv/consts/at.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/x/x.h"
|
|
||||||
|
|
||||||
/**
|
GetCpuidBrand:
|
||||||
* Reads symbolic link.
|
mov %esi,%eax
|
||||||
*
|
xor %ecx,%ecx
|
||||||
* @return nul-terminated string, or null w/ errno
|
push %rbx
|
||||||
* @see readlink()
|
cpuid
|
||||||
*/
|
mov %ebx,0(%rdi)
|
||||||
char *xreadlink(const char *path) {
|
mov %ecx,4(%rdi)
|
||||||
return xreadlinkat(AT_FDCWD, path);
|
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;
|
return b;
|
||||||
#ifdef __x86__
|
#ifdef __x86__
|
||||||
} else if (IsTiny()) {
|
} 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;
|
return p;
|
||||||
} else if (X86_HAVE(AVX)) {
|
} else if (X86_HAVE(AVX)) {
|
||||||
return memset_avx(b, c, n);
|
return memset_avx(b, c, n);
|
||||||
|
|
|
@ -16,11 +16,11 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/intrin/kprintf.h"
|
||||||
#include "libc/runtime/internal.h"
|
#include "libc/runtime/internal.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
|
||||||
__attribute__((__weak__)) void __stack_chk_fail(void) {
|
__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();
|
__builtin_trap();
|
||||||
}
|
}
|
|
@ -6,5 +6,6 @@
|
||||||
#include "libc/calls/struct/siginfo.h"
|
#include "libc/calls/struct/siginfo.h"
|
||||||
#include "libc/sysv/consts/sa.h"
|
#include "libc/sysv/consts/sa.h"
|
||||||
#include "libc/sysv/consts/sicode.h"
|
#include "libc/sysv/consts/sicode.h"
|
||||||
|
#include "libc/sysv/consts/sig.h"
|
||||||
#include "libc/sysv/consts/ss.h"
|
#include "libc/sysv/consts/ss.h"
|
||||||
#endif /* _SIGNAL_H */
|
#endif /* _SIGNAL_H */
|
||||||
|
|
|
@ -5,9 +5,14 @@ PKGS += LIBC
|
||||||
|
|
||||||
LIBC_HDRS = $(filter %.h,$(LIBC_FILES))
|
LIBC_HDRS = $(filter %.h,$(LIBC_FILES))
|
||||||
LIBC_INCS = $(filter %.inc,$(LIBC_FILES))
|
LIBC_INCS = $(filter %.inc,$(LIBC_FILES))
|
||||||
LIBC_FILES := $(wildcard libc/*) $(wildcard libc/isystem/*)
|
|
||||||
LIBC_CHECKS = $(LIBC_HDRS:%=o/$(MODE)/%.ok)
|
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
|
.PHONY: o/$(MODE)/libc
|
||||||
o/$(MODE)/libc: o/$(MODE)/libc/calls \
|
o/$(MODE)/libc: o/$(MODE)/libc/calls \
|
||||||
o/$(MODE)/libc/crt \
|
o/$(MODE)/libc/crt \
|
||||||
|
|
|
@ -46,14 +46,12 @@ relegated void __check_fail(const char *suffix, //
|
||||||
int line, //
|
int line, //
|
||||||
const char *fmt, //
|
const char *fmt, //
|
||||||
...) {
|
...) {
|
||||||
int e;
|
|
||||||
char *p;
|
char *p;
|
||||||
size_t i;
|
size_t i;
|
||||||
va_list va;
|
va_list va;
|
||||||
char hostname[32];
|
char hostname[32];
|
||||||
strace_enabled(-1);
|
strace_enabled(-1);
|
||||||
ftrace_enabled(-1);
|
ftrace_enabled(-1);
|
||||||
e = errno;
|
|
||||||
__start_fatal(file, line);
|
__start_fatal(file, line);
|
||||||
__stpcpy(hostname, "unknown");
|
__stpcpy(hostname, "unknown");
|
||||||
gethostname(hostname, sizeof(hostname));
|
gethostname(hostname, sizeof(hostname));
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
relegated int(gdbexec)(const char *cmd) {
|
relegated int(gdbexec)(const char *cmd) {
|
||||||
struct StackFrame *bp;
|
struct StackFrame *bp;
|
||||||
int pid, ttyin, ttyout;
|
int pid, ttyin, ttyout;
|
||||||
intptr_t continuetoaddr;
|
|
||||||
const char *se, *elf, *gdb;
|
const char *se, *elf, *gdb;
|
||||||
char pidstr[11], breakcmd[40];
|
char pidstr[11], breakcmd[40];
|
||||||
if (!(gdb = GetGdbPath())) return -1;
|
if (!(gdb = GetGdbPath())) return -1;
|
||||||
|
@ -43,7 +42,6 @@ relegated int(gdbexec)(const char *cmd) {
|
||||||
elf = "-q";
|
elf = "-q";
|
||||||
}
|
}
|
||||||
bp = __builtin_frame_address(0);
|
bp = __builtin_frame_address(0);
|
||||||
continuetoaddr = bp->addr;
|
|
||||||
sprintf(breakcmd, "%s *%#p", "break", bp->addr);
|
sprintf(breakcmd, "%s *%#p", "break", bp->addr);
|
||||||
if (!(pid = vfork())) {
|
if (!(pid = vfork())) {
|
||||||
execv(gdb, (char *const[]){
|
execv(gdb, (char *const[]){
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/assert.h"
|
#include "libc/assert.h"
|
||||||
|
#include "libc/atomic.h"
|
||||||
#include "libc/intrin/atomic.h"
|
#include "libc/intrin/atomic.h"
|
||||||
#include "libc/intrin/kprintf.h"
|
#include "libc/intrin/kprintf.h"
|
||||||
#include "libc/log/backtrace.internal.h"
|
#include "libc/log/backtrace.internal.h"
|
||||||
|
@ -67,7 +68,7 @@ static struct Memlog {
|
||||||
long size;
|
long size;
|
||||||
} * p;
|
} * p;
|
||||||
} allocs;
|
} allocs;
|
||||||
long usage;
|
atomic_long usage;
|
||||||
} __memlog;
|
} __memlog;
|
||||||
|
|
||||||
static pthread_mutex_t __memlog_lock_obj;
|
static pthread_mutex_t __memlog_lock_obj;
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "libc/calls/struct/sigaction.h"
|
#include "libc/calls/struct/sigaction.h"
|
||||||
#include "libc/calls/struct/utsname.h"
|
#include "libc/calls/struct/utsname.h"
|
||||||
#include "libc/calls/syscall-sysv.internal.h"
|
#include "libc/calls/syscall-sysv.internal.h"
|
||||||
|
#include "libc/calls/ucontext.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/fmt/itoa.h"
|
#include "libc/fmt/itoa.h"
|
||||||
|
@ -44,6 +45,7 @@
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/stdio/stdio.h"
|
#include "libc/stdio/stdio.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
|
#include "libc/sysv/consts/sig.h"
|
||||||
#include "libc/thread/thread.h"
|
#include "libc/thread/thread.h"
|
||||||
#include "libc/thread/tls.h"
|
#include "libc/thread/tls.h"
|
||||||
#ifdef __x86_64__
|
#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) {
|
relegated void __oncrash_amd64(int sig, struct siginfo *si, void *arg) {
|
||||||
int bZero;
|
int bZero;
|
||||||
|
#ifdef ATTACH_GDB_ON_CRASH
|
||||||
intptr_t rip;
|
intptr_t rip;
|
||||||
|
#endif
|
||||||
int me, owner;
|
int me, owner;
|
||||||
int gdbpid, err;
|
int gdbpid, err;
|
||||||
ucontext_t *ctx = arg;
|
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(
|
if (atomic_compare_exchange_strong_explicit(
|
||||||
&once, &owner, me, memory_order_relaxed, memory_order_relaxed)) {
|
&once, &owner, me, memory_order_relaxed, memory_order_relaxed)) {
|
||||||
if (!__vforked) {
|
if (!__vforked) {
|
||||||
|
#ifdef ATTACH_GDB_ON_CRASH
|
||||||
rip = ctx ? ctx->uc_mcontext.rip : 0;
|
rip = ctx ? ctx->uc_mcontext.rip : 0;
|
||||||
|
#endif
|
||||||
err = errno;
|
err = errno;
|
||||||
if ((gdbpid = IsDebuggerPresent(true))) {
|
if ((gdbpid = IsDebuggerPresent(true))) {
|
||||||
DebugBreak();
|
DebugBreak();
|
||||||
} else if (__nocolor || g_isrunningundermake) {
|
} else if (__nocolor || g_isrunningundermake) {
|
||||||
gdbpid = -1;
|
gdbpid = -1;
|
||||||
#if 0
|
#if ATTACH_GDB_ON_CRASH
|
||||||
} else if (!IsTiny() && IsLinux() && FindDebugBinary() && !__isworker) {
|
} else if (!IsTiny() && IsLinux() && FindDebugBinary() && !__isworker) {
|
||||||
// RestoreDefaultCrashSignalHandlers();
|
// RestoreDefaultCrashSignalHandlers();
|
||||||
gdbpid = AttachDebugger(
|
gdbpid = AttachDebugger(
|
||||||
|
|
|
@ -169,7 +169,7 @@ asm("XnuThreadThunk:\n\t"
|
||||||
"push\t%rax\n\t"
|
"push\t%rax\n\t"
|
||||||
"jmp\tXnuThreadMain\n\t"
|
"jmp\tXnuThreadMain\n\t"
|
||||||
".size\tXnuThreadThunk,.-XnuThreadThunk");
|
".size\tXnuThreadThunk,.-XnuThreadThunk");
|
||||||
__attribute__((__used__, __no_reorder__))
|
__attribute__((__used__))
|
||||||
|
|
||||||
static wontreturn void
|
static wontreturn void
|
||||||
XnuThreadMain(void *pthread, // rdi
|
XnuThreadMain(void *pthread, // rdi
|
||||||
|
|
|
@ -121,7 +121,7 @@ textstartup void __enable_tls(void) {
|
||||||
|
|
||||||
#ifdef __x86_64__
|
#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 (siz <= sizeof(__static_tls)) {
|
||||||
// if tls requirement is small then use the static tls block
|
// if tls requirement is small then use the static tls block
|
||||||
// which helps avoid a system call for appes with little tls
|
// 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()
|
// like __errno_location which can be called from an inline asm()
|
||||||
// statement. It's nice to have the flexibility anyway.
|
// statement. It's nice to have the flexibility anyway.
|
||||||
|
|
||||||
cmp $0,__ftrace(%rip)
|
cmpl $0,__ftrace(%rip)
|
||||||
jle 1f
|
jle 1f
|
||||||
push %rbp
|
push %rbp
|
||||||
mov %rsp,%rbp
|
mov %rsp,%rbp
|
||||||
|
|
|
@ -54,8 +54,6 @@ int __inflate(void *out, size_t outsize, const void *in, size_t insize) {
|
||||||
rc = 0;
|
rc = 0;
|
||||||
} else if (rc == Z_OK) {
|
} else if (rc == Z_OK) {
|
||||||
rc = Z_STREAM_END; // coerce to nonzero
|
rc = Z_STREAM_END; // coerce to nonzero
|
||||||
} else {
|
|
||||||
rc = rc;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rc = _puff(out, &outsize, in, &insize);
|
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) {
|
noasan void ReleaseMemoryNt(struct MemoryIntervals *mm, int l, int r) {
|
||||||
int i, ok;
|
int i;
|
||||||
size_t size;
|
|
||||||
char *addr, *last;
|
|
||||||
for (i = l; i <= r; ++i) {
|
for (i = l; i <= r; ++i) {
|
||||||
addr = GetFrameAddr(mm->p[i].x);
|
UnmapViewOfFile(GetFrameAddr(mm->p[i].x));
|
||||||
last = GetFrameAddr(mm->p[i].y);
|
|
||||||
UnmapViewOfFile(addr);
|
|
||||||
CloseHandle(mm->p[i].h);
|
CloseHandle(mm->p[i].h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,7 +128,8 @@ o/$(MODE)/libc/runtime/enable_threads.o \
|
||||||
o/$(MODE)/libc/runtime/morph_tls.o: private \
|
o/$(MODE)/libc/runtime/morph_tls.o: private \
|
||||||
CFLAGS += \
|
CFLAGS += \
|
||||||
-ffreestanding \
|
-ffreestanding \
|
||||||
-fno-sanitize=all
|
-fno-sanitize=all \
|
||||||
|
-fno-stack-protector
|
||||||
|
|
||||||
# TODO(jart): We need a way to avoid WinThreadEntry() being hooked.
|
# TODO(jart): We need a way to avoid WinThreadEntry() being hooked.
|
||||||
o/$(MODE)/libc/runtime/clone.o: private \
|
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]),
|
: (DescribeNtConsoleInFlags)(inflagsbuf, kConsoleModes[i]),
|
||||||
rc);
|
rc);
|
||||||
}
|
}
|
||||||
|
(void)rc;
|
||||||
}
|
}
|
||||||
_Static_assert(sizeof(struct WinArgs) % FRAMESIZE == 0, "");
|
_Static_assert(sizeof(struct WinArgs) % FRAMESIZE == 0, "");
|
||||||
_mmi.p = _mmi.s;
|
_mmi.p = _mmi.s;
|
||||||
|
|
|
@ -38,6 +38,7 @@ _Hide struct NtWsaData kNtWsaData;
|
||||||
|
|
||||||
static textwindows void WinSockCleanup(void) {
|
static textwindows void WinSockCleanup(void) {
|
||||||
int i, rc;
|
int i, rc;
|
||||||
|
(void)rc;
|
||||||
rc = WSACleanup();
|
rc = WSACleanup();
|
||||||
NTTRACE("WSACleanup() → %d% lm", rc);
|
NTTRACE("WSACleanup() → %d% lm", rc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,9 +67,6 @@
|
||||||
|
|
||||||
#define PRINTF_NTOA_BUFFER_SIZE 144
|
#define PRINTF_NTOA_BUFFER_SIZE 144
|
||||||
|
|
||||||
#define __FMT_CONSUMED_DOUBLE 1
|
|
||||||
#define __FMT_CONSUMED_LONG_DOUBLE 2
|
|
||||||
|
|
||||||
#define FLAGS_ZEROPAD 0x01
|
#define FLAGS_ZEROPAD 0x01
|
||||||
#define FLAGS_LEFT 0x02
|
#define FLAGS_LEFT 0x02
|
||||||
#define FLAGS_PLUS 0x04
|
#define FLAGS_PLUS 0x04
|
||||||
|
@ -423,7 +420,7 @@ static int __fmt_stoa(int out(const char *, void *, size_t), void *arg,
|
||||||
} else {
|
} else {
|
||||||
emit = __fmt_stoa_wide;
|
emit = __fmt_stoa_wide;
|
||||||
}
|
}
|
||||||
} else if ((flags & FLAGS_HASH) && kCp437) {
|
} else if (flags & FLAGS_HASH) {
|
||||||
justdobytes = true;
|
justdobytes = true;
|
||||||
emit = __fmt_stoa_bing;
|
emit = __fmt_stoa_bing;
|
||||||
ignorenul = flags & FLAGS_PRECISION;
|
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);
|
int (*out)(const char *, void *, size_t);
|
||||||
char *se, *s0, *s, *q, qchar, special[8];
|
char *se, *s0, *s, *q, qchar, special[8];
|
||||||
int d, w, n, sign, prec, flags, width, lasterr;
|
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;
|
x = 0;
|
||||||
lasterr = errno;
|
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 (!(flags & FLAGS_PRECISION)) prec = 6;
|
||||||
if (!longdouble) {
|
if (!longdouble) {
|
||||||
x = va_arg(va, double);
|
x = va_arg(va, double);
|
||||||
consumed = __FMT_CONSUMED_DOUBLE;
|
|
||||||
s = s0 = dtoa(x, 3, prec, &decpt, &fpb.sign, &se);
|
s = s0 = dtoa(x, 3, prec, &decpt, &fpb.sign, &se);
|
||||||
if (decpt == 9999) {
|
if (decpt == 9999) {
|
||||||
if (s && s[0] == 'N') {
|
if (s && s[0] == 'N') {
|
||||||
|
@ -1080,7 +1076,6 @@ _Hide int __fmt(void *fn, void *arg, const char *format, va_list va) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
un.ld = va_arg(va, long double);
|
un.ld = va_arg(va, long double);
|
||||||
consumed = __FMT_CONSUMED_LONG_DOUBLE;
|
|
||||||
__fmt_ldfpbits(&un, &fpb);
|
__fmt_ldfpbits(&un, &fpb);
|
||||||
s = s0 =
|
s = s0 =
|
||||||
gdtoa(fpb.fpi, fpb.ex, fpb.bits, &fpb.kind, 3, prec, &decpt, &se);
|
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;
|
prec = 0;
|
||||||
rc = __fmt_stoa(out, arg, s, flags, prec, width, signbit, qchar);
|
rc = __fmt_stoa(out, arg, s, flags, prec, width, signbit, qchar);
|
||||||
if (rc == -1) return -1;
|
if (rc == -1) return -1;
|
||||||
return consumed;
|
break;
|
||||||
}
|
}
|
||||||
FormatReal:
|
FormatReal:
|
||||||
if (fpb.sign /* && (x || sign) */) sign = '-';
|
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 (prec < 1) prec = 1;
|
||||||
if (!longdouble) {
|
if (!longdouble) {
|
||||||
x = va_arg(va, double);
|
x = va_arg(va, double);
|
||||||
consumed = __FMT_CONSUMED_DOUBLE;
|
|
||||||
s = s0 = dtoa(x, 2, prec, &decpt, &fpb.sign, &se);
|
s = s0 = dtoa(x, 2, prec, &decpt, &fpb.sign, &se);
|
||||||
if (decpt == 9999) {
|
if (decpt == 9999) {
|
||||||
if (s && s[0] == 'N') {
|
if (s && s[0] == 'N') {
|
||||||
|
@ -1177,7 +1171,6 @@ _Hide int __fmt(void *fn, void *arg, const char *format, va_list va) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
un.ld = va_arg(va, long double);
|
un.ld = va_arg(va, long double);
|
||||||
consumed = __FMT_CONSUMED_LONG_DOUBLE;
|
|
||||||
__fmt_ldfpbits(&un, &fpb);
|
__fmt_ldfpbits(&un, &fpb);
|
||||||
s = s0 = gdtoa(fpb.fpi, fpb.ex, fpb.bits, &fpb.kind, prec ? 2 : 0,
|
s = s0 = gdtoa(fpb.fpi, fpb.ex, fpb.bits, &fpb.kind, prec ? 2 : 0,
|
||||||
prec, &decpt, &se);
|
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 (prec < 0) prec = 0;
|
||||||
if (!longdouble) {
|
if (!longdouble) {
|
||||||
x = va_arg(va, double);
|
x = va_arg(va, double);
|
||||||
consumed = __FMT_CONSUMED_DOUBLE;
|
|
||||||
s = s0 = dtoa(x, 2, prec + 1, &decpt, &fpb.sign, &se);
|
s = s0 = dtoa(x, 2, prec + 1, &decpt, &fpb.sign, &se);
|
||||||
if (decpt == 9999) {
|
if (decpt == 9999) {
|
||||||
if (s && s[0] == 'N') {
|
if (s && s[0] == 'N') {
|
||||||
|
@ -1220,7 +1212,6 @@ _Hide int __fmt(void *fn, void *arg, const char *format, va_list va) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
un.ld = va_arg(va, long double);
|
un.ld = va_arg(va, long double);
|
||||||
consumed = __FMT_CONSUMED_LONG_DOUBLE;
|
|
||||||
__fmt_ldfpbits(&un, &fpb);
|
__fmt_ldfpbits(&un, &fpb);
|
||||||
s = s0 = gdtoa(fpb.fpi, fpb.ex, fpb.bits, &fpb.kind, prec ? 2 : 0,
|
s = s0 = gdtoa(fpb.fpi, fpb.ex, fpb.bits, &fpb.kind, prec ? 2 : 0,
|
||||||
prec, &decpt, &se);
|
prec, &decpt, &se);
|
||||||
|
@ -1289,11 +1280,9 @@ _Hide int __fmt(void *fn, void *arg, const char *format, va_list va) {
|
||||||
FormatBinary:
|
FormatBinary:
|
||||||
if (longdouble) {
|
if (longdouble) {
|
||||||
un.ld = va_arg(va, long double);
|
un.ld = va_arg(va, long double);
|
||||||
consumed = __FMT_CONSUMED_LONG_DOUBLE;
|
|
||||||
__fmt_ldfpbits(&un, &fpb);
|
__fmt_ldfpbits(&un, &fpb);
|
||||||
} else {
|
} else {
|
||||||
un.d = va_arg(va, double);
|
un.d = va_arg(va, double);
|
||||||
consumed = __FMT_CONSUMED_DOUBLE;
|
|
||||||
__fmt_dfpbits(&un, &fpb);
|
__fmt_dfpbits(&un, &fpb);
|
||||||
}
|
}
|
||||||
if (fpb.kind == STRTOG_Infinite || fpb.kind == STRTOG_NaN) {
|
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 (sign) --width;
|
||||||
if (prec1 || (flags & FLAGS_HASH)) --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)) {
|
!(flags & FLAGS_ZEROPAD)) {
|
||||||
do __FMT_PUT(' ');
|
do __FMT_PUT(' ');
|
||||||
while (--width > 0);
|
while (--width > 0);
|
||||||
|
|
|
@ -25,10 +25,8 @@ struct _posix_spawna {
|
||||||
struct _posix_faction {
|
struct _posix_faction {
|
||||||
struct _posix_faction *next;
|
struct _posix_faction *next;
|
||||||
int action;
|
int action;
|
||||||
union {
|
|
||||||
int fildes;
|
int fildes;
|
||||||
int oflag;
|
int oflag;
|
||||||
};
|
|
||||||
union {
|
union {
|
||||||
int newfildes;
|
int newfildes;
|
||||||
unsigned mode;
|
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 posix_spawn_file_actions_addopen(posix_spawn_file_actions_t *file_actions,
|
||||||
int fildes, const char *path, int oflag,
|
int fildes, const char *path, int oflag,
|
||||||
unsigned mode) {
|
unsigned mode) {
|
||||||
|
if (fildes < 0) return EBADF;
|
||||||
if (!(path = strdup(path))) return ENOMEM;
|
if (!(path = strdup(path))) return ENOMEM;
|
||||||
return AddFileAction(file_actions, (struct _posix_faction){
|
return AddFileAction(file_actions, (struct _posix_faction){
|
||||||
.action = _POSIX_SPAWN_OPEN,
|
.action = _POSIX_SPAWN_OPEN,
|
||||||
|
|
|
@ -47,7 +47,8 @@ void *GetZipEocd(const void *f, size_t n, int *e) {
|
||||||
i = n - 4;
|
i = n - 4;
|
||||||
err = kZipErrorEocdNotFound;
|
err = kZipErrorEocdNotFound;
|
||||||
do {
|
do {
|
||||||
#ifdef __x86_64__
|
#if defined(__x86_64__) && defined(__GNUC__) && !defined(__llvm__) && \
|
||||||
|
!defined(__chibicc__)
|
||||||
v8hi pk = {READ16LE("PK"), READ16LE("PK"), READ16LE("PK"), READ16LE("PK"),
|
v8hi pk = {READ16LE("PK"), READ16LE("PK"), READ16LE("PK"), READ16LE("PK"),
|
||||||
READ16LE("PK"), READ16LE("PK"), READ16LE("PK"), READ16LE("PK")};
|
READ16LE("PK"), READ16LE("PK"), READ16LE("PK"), READ16LE("PK")};
|
||||||
asm("" : "+x"(pk));
|
asm("" : "+x"(pk));
|
||||||
|
|
|
@ -16,9 +16,10 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/errno.h"
|
|
||||||
#include "libc/thread/tls2.h"
|
#include "libc/thread/tls2.h"
|
||||||
|
|
||||||
|
extern errno_t __errno;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns address of errno variable.
|
* Returns address of errno variable.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -121,7 +121,7 @@ systemfive_cancellable: // our pthread_cancel() miracle code
|
||||||
testb $PT_INCANCEL,0x00(%r10)
|
testb $PT_INCANCEL,0x00(%r10)
|
||||||
jz 5f
|
jz 5f
|
||||||
#endif
|
#endif
|
||||||
cmp $0,0x04(%r10) // PosixThread::cancelled
|
cmpl $0,0x04(%r10) // PosixThread::cancelled
|
||||||
jne systemfive_cancel // we will tail call below
|
jne systemfive_cancel // we will tail call below
|
||||||
1: mov %rcx,%r10 // move the fourth argument
|
1: mov %rcx,%r10 // move the fourth argument
|
||||||
clc // no cancellable system calls exist
|
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
|
jz systemfive_errno // it's spawn() probably
|
||||||
testb $PT_NOCANCEL,0x00(%rcx) // PosixThread::flags
|
testb $PT_NOCANCEL,0x00(%rcx) // PosixThread::flags
|
||||||
jnz systemfive_errno // cancellation is disabled
|
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
|
je systemfive_errno // we aren't actually cancelled
|
||||||
jmp 4f // now we are in fact cancelled
|
jmp 4f // now we are in fact cancelled
|
||||||
systemfive_cancel: // SIGTHR will jump here too
|
systemfive_cancel: // SIGTHR will jump here too
|
||||||
|
|
|
@ -46,7 +46,6 @@ COSMOPOLITAN_C_START_
|
||||||
EXPR; \
|
EXPR; \
|
||||||
MemoryStrict = BENCHLOOP(__startbench_m, __endbench_m, 32, ({ \
|
MemoryStrict = BENCHLOOP(__startbench_m, __endbench_m, 32, ({ \
|
||||||
INIT; \
|
INIT; \
|
||||||
thrashcodecache(); \
|
|
||||||
__polluteregisters(); \
|
__polluteregisters(); \
|
||||||
}), \
|
}), \
|
||||||
(EXPR)); \
|
(EXPR)); \
|
||||||
|
@ -88,7 +87,6 @@ COSMOPOLITAN_C_START_
|
||||||
EXPR; \
|
EXPR; \
|
||||||
MemoryStrict = BENCHLOOP(__startbench_m, __endbench_m, NUM, ({ \
|
MemoryStrict = BENCHLOOP(__startbench_m, __endbench_m, NUM, ({ \
|
||||||
INIT; \
|
INIT; \
|
||||||
thrashcodecache(); \
|
|
||||||
__polluteregisters(); \
|
__polluteregisters(); \
|
||||||
}), \
|
}), \
|
||||||
(EXPR)); \
|
(EXPR)); \
|
||||||
|
@ -110,11 +108,8 @@ COSMOPOLITAN_C_START_
|
||||||
__testlib_yield(); \
|
__testlib_yield(); \
|
||||||
Core = __testlib_getcore(); \
|
Core = __testlib_getcore(); \
|
||||||
Interrupts = __testlib_getinterrupts(); \
|
Interrupts = __testlib_getinterrupts(); \
|
||||||
Control = BENCHLOOP(__startbench_m, __endbench_m, EZBENCH_COUNT, ({ \
|
Control = BENCHLOOP(__startbench_m, __endbench_m, EZBENCH_COUNT, \
|
||||||
thrashcodecache(); \
|
({ __polluteregisters(); }), (CONTROL)); \
|
||||||
__polluteregisters(); \
|
|
||||||
}), \
|
|
||||||
(CONTROL)); \
|
|
||||||
} while (++Tries < EZBENCH_TRIES && \
|
} while (++Tries < EZBENCH_TRIES && \
|
||||||
(__testlib_getcore() != Core && \
|
(__testlib_getcore() != Core && \
|
||||||
__testlib_getinterrupts() > Interrupts)); \
|
__testlib_getinterrupts() > Interrupts)); \
|
||||||
|
@ -137,11 +132,8 @@ COSMOPOLITAN_C_START_
|
||||||
Core = __testlib_getcore(); \
|
Core = __testlib_getcore(); \
|
||||||
Interrupts = __testlib_getinterrupts(); \
|
Interrupts = __testlib_getinterrupts(); \
|
||||||
EXPR; \
|
EXPR; \
|
||||||
MemoryStrict = BENCHLOOP(__startbench_m, __endbench_m, 8, ({ \
|
MemoryStrict = BENCHLOOP(__startbench_m, __endbench_m, 8, \
|
||||||
thrashcodecache(); \
|
({ __polluteregisters(); }), (EXPR)); \
|
||||||
__polluteregisters(); \
|
|
||||||
}), \
|
|
||||||
(EXPR)); \
|
|
||||||
} while (++Tries < EZBENCH_TRIES && \
|
} while (++Tries < EZBENCH_TRIES && \
|
||||||
(__testlib_getcore() != Core && \
|
(__testlib_getcore() != Core && \
|
||||||
__testlib_getinterrupts() > Interrupts)); \
|
__testlib_getinterrupts() > Interrupts)); \
|
||||||
|
|
|
@ -63,6 +63,7 @@ noasan bool testlib_memoryexists(const void *p) {
|
||||||
_npassert(!sigaction(SIGSEGV, &sa, old + 0));
|
_npassert(!sigaction(SIGSEGV, &sa, old + 0));
|
||||||
_npassert(!sigaction(SIGBUS, &sa, old + 1));
|
_npassert(!sigaction(SIGBUS, &sa, old + 1));
|
||||||
c = atomic_load(mem);
|
c = atomic_load(mem);
|
||||||
|
(void)c;
|
||||||
_npassert(!sigaction(SIGBUS, old + 1, 0));
|
_npassert(!sigaction(SIGBUS, old + 1, 0));
|
||||||
_npassert(!sigaction(SIGSEGV, old + 0, 0));
|
_npassert(!sigaction(SIGSEGV, old + 0, 0));
|
||||||
return !gotsignal;
|
return !gotsignal;
|
||||||
|
|
|
@ -382,8 +382,6 @@ void testlib_error_enter(const char *, const char *);
|
||||||
void testlib_showerror(const char *, int, const char *, const char *,
|
void testlib_showerror(const char *, int, const char *, const char *,
|
||||||
const char *, const char *, char *, char *);
|
const char *, const char *, char *, char *);
|
||||||
|
|
||||||
void thrashcodecache(void);
|
|
||||||
|
|
||||||
void testlib_finish(void);
|
void testlib_finish(void);
|
||||||
int testlib_geterrno(void);
|
int testlib_geterrno(void);
|
||||||
void testlib_seterrno(int);
|
void testlib_seterrno(int);
|
||||||
|
|
|
@ -38,7 +38,6 @@ LIBC_TESTLIB_A_SRCS_S = \
|
||||||
libc/testlib/moby.S \
|
libc/testlib/moby.S \
|
||||||
libc/testlib/polluteregisters.S \
|
libc/testlib/polluteregisters.S \
|
||||||
libc/testlib/testcase.S \
|
libc/testlib/testcase.S \
|
||||||
libc/testlib/thrashcodecache.S \
|
|
||||||
libc/testlib/viewables.S
|
libc/testlib/viewables.S
|
||||||
|
|
||||||
LIBC_TESTLIB_A_SRCS_C = \
|
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 $<
|
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
||||||
o/$(MODE)/libc/testlib/testcase.o: libc/testlib/testcase.S
|
o/$(MODE)/libc/testlib/testcase.o: libc/testlib/testcase.S
|
||||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
@$(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
|
o/$(MODE)/libc/testlib/viewables.o: libc/testlib/viewables.S
|
||||||
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
|
@$(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 += uc->uc_stack.ss_size;
|
||||||
sp -= 16; // openbsd:stackbound
|
sp -= 16; // openbsd:stackbound
|
||||||
sp -= sizeof(*call);
|
sp -= sizeof(*call);
|
||||||
sp &= -alignof(*call);
|
sp &= -alignof(struct Gadget);
|
||||||
call = (struct Gadget *)sp;
|
call = (struct Gadget *)sp;
|
||||||
|
|
||||||
// get arguments
|
// get arguments
|
||||||
|
|
|
@ -38,10 +38,9 @@
|
||||||
*/
|
*/
|
||||||
errno_t pthread_getaffinity_np(pthread_t thread, size_t size,
|
errno_t pthread_getaffinity_np(pthread_t thread, size_t size,
|
||||||
cpu_set_t *bitset) {
|
cpu_set_t *bitset) {
|
||||||
int e, rc, tid;
|
int rc, tid;
|
||||||
|
|
||||||
if (!(rc = pthread_getunique_np(thread, &tid))) {
|
if (!(rc = pthread_getunique_np(thread, &tid))) {
|
||||||
e = errno;
|
|
||||||
if (size != sizeof(cpu_set_t)) {
|
if (size != sizeof(cpu_set_t)) {
|
||||||
rc = einval();
|
rc = einval();
|
||||||
} else if (IsWindows() || IsMetal() || IsOpenbsd()) {
|
} 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
|
* @return 0 on success, or -1 w/ errno
|
||||||
*/
|
*/
|
||||||
int sem_close(sem_t *sem) {
|
int sem_close(sem_t *sem) {
|
||||||
int rc, prefs;
|
int prefs;
|
||||||
bool unmap, delete;
|
bool unmap, delete;
|
||||||
struct Semaphore *s, **p;
|
struct Semaphore *s, **p;
|
||||||
_npassert(sem->sem_magic == SEM_MAGIC_NAMED);
|
_npassert(sem->sem_magic == SEM_MAGIC_NAMED);
|
||||||
|
@ -275,7 +275,7 @@ int sem_close(sem_t *sem) {
|
||||||
_npassert(!munmap(sem, PAGESIZE));
|
_npassert(!munmap(sem, PAGESIZE));
|
||||||
}
|
}
|
||||||
if (delete) {
|
if (delete) {
|
||||||
rc = unlink(s->path);
|
unlink(s->path);
|
||||||
}
|
}
|
||||||
if (unmap) {
|
if (unmap) {
|
||||||
free(s->path);
|
free(s->path);
|
||||||
|
|
|
@ -69,7 +69,7 @@ static int Spawner(void *arg, int tid) {
|
||||||
rc = spawner->fun(spawner->arg, tid);
|
rc = spawner->fun(spawner->arg, tid);
|
||||||
_pthread_ungarbage();
|
_pthread_ungarbage();
|
||||||
free(spawner);
|
free(spawner);
|
||||||
return 0;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -28,7 +28,9 @@
|
||||||
#include "libc/math.h"
|
#include "libc/math.h"
|
||||||
#include "libc/runtime/fenv.h"
|
#include "libc/runtime/fenv.h"
|
||||||
#include "libc/tinymath/internal.h"
|
#include "libc/tinymath/internal.h"
|
||||||
|
#ifndef __llvm__
|
||||||
#include "third_party/intel/smmintrin.internal.h"
|
#include "third_party/intel/smmintrin.internal.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
asm(".ident\t\"\\n\\n\
|
asm(".ident\t\"\\n\\n\
|
||||||
Musl libc (MIT License)\\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));
|
asm("fidbra\t%0,6,%1,4" : "=f"(x) : "f"(x));
|
||||||
return 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"
|
asm("roundsd\t%2,%1,%0"
|
||||||
: "=x"(x)
|
: "=x"(x)
|
||||||
|
|
|
@ -27,7 +27,9 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/math.h"
|
#include "libc/math.h"
|
||||||
#include "libc/tinymath/internal.h"
|
#include "libc/tinymath/internal.h"
|
||||||
|
#ifndef __llvm__
|
||||||
#include "third_party/intel/smmintrin.internal.h"
|
#include "third_party/intel/smmintrin.internal.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
asm(".ident\t\"\\n\\n\
|
asm(".ident\t\"\\n\\n\
|
||||||
Musl libc (MIT License)\\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));
|
asm("fiebra\t%0,6,%1,4" : "=f"(x) : "f"(x));
|
||||||
return 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"
|
asm("roundss\t%2,%1,%0"
|
||||||
: "=x"(x)
|
: "=x"(x)
|
||||||
|
|
|
@ -28,7 +28,9 @@
|
||||||
#include "libc/math.h"
|
#include "libc/math.h"
|
||||||
#include "libc/runtime/fenv.h"
|
#include "libc/runtime/fenv.h"
|
||||||
#include "libc/tinymath/internal.h"
|
#include "libc/tinymath/internal.h"
|
||||||
|
#ifndef __llvm__
|
||||||
#include "third_party/intel/smmintrin.internal.h"
|
#include "third_party/intel/smmintrin.internal.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
asm(".ident\t\"\\n\\n\
|
asm(".ident\t\"\\n\\n\
|
||||||
Musl libc (MIT License)\\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));
|
asm("fidbra\t%0,7,%1,4" : "=f"(x) : "f"(x));
|
||||||
return 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"
|
asm("roundsd\t%2,%1,%0"
|
||||||
: "=x"(x)
|
: "=x"(x)
|
||||||
|
|
|
@ -27,7 +27,9 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/math.h"
|
#include "libc/math.h"
|
||||||
#include "libc/tinymath/internal.h"
|
#include "libc/tinymath/internal.h"
|
||||||
|
#ifndef __llvm__
|
||||||
#include "third_party/intel/smmintrin.internal.h"
|
#include "third_party/intel/smmintrin.internal.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
asm(".ident\t\"\\n\\n\
|
asm(".ident\t\"\\n\\n\
|
||||||
Musl libc (MIT License)\\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));
|
asm("fiebra\t%0,7,%1,4" : "=f"(x) : "f"(x));
|
||||||
return 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"
|
asm("roundss\t%2,%1,%0"
|
||||||
: "=x"(x)
|
: "=x"(x)
|
||||||
|
|
|
@ -29,16 +29,19 @@ static inline double eval_as_double(double x) {
|
||||||
static inline void fp_force_evall(long double x) {
|
static inline void fp_force_evall(long double x) {
|
||||||
volatile long double y;
|
volatile long double y;
|
||||||
y = x;
|
y = x;
|
||||||
|
(void)y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void fp_force_evalf(float x) {
|
static inline void fp_force_evalf(float x) {
|
||||||
volatile float y;
|
volatile float y;
|
||||||
y = x;
|
y = x;
|
||||||
|
(void)y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void fp_force_eval(double x) {
|
static inline void fp_force_eval(double x) {
|
||||||
volatile double y;
|
volatile double y;
|
||||||
y = x;
|
y = x;
|
||||||
|
(void)y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline double fp_barrier(double x) {
|
static inline double fp_barrier(double x) {
|
||||||
|
|
|
@ -27,7 +27,9 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/math.h"
|
#include "libc/math.h"
|
||||||
#include "libc/tinymath/internal.h"
|
#include "libc/tinymath/internal.h"
|
||||||
|
#ifndef __llvm__
|
||||||
#include "third_party/intel/smmintrin.internal.h"
|
#include "third_party/intel/smmintrin.internal.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
asm(".ident\t\"\\n\\n\
|
asm(".ident\t\"\\n\\n\
|
||||||
Musl libc (MIT License)\\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));
|
asm("fidbra\t%0,5,%1,4" : "=f"(x) : "f"(x));
|
||||||
return 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"
|
asm("roundsd\t%2,%1,%0"
|
||||||
: "=x"(x)
|
: "=x"(x)
|
||||||
|
|
|
@ -27,7 +27,9 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/math.h"
|
#include "libc/math.h"
|
||||||
#include "libc/tinymath/internal.h"
|
#include "libc/tinymath/internal.h"
|
||||||
|
#ifndef __llvm__
|
||||||
#include "third_party/intel/smmintrin.internal.h"
|
#include "third_party/intel/smmintrin.internal.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
asm(".ident\t\"\\n\\n\
|
asm(".ident\t\"\\n\\n\
|
||||||
Musl libc (MIT License)\\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));
|
asm("fiebra\t%0,5,%1,4" : "=f"(x) : "f"(x));
|
||||||
return 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"
|
asm("roundss\t%2,%1,%0"
|
||||||
: "=x"(x)
|
: "=x"(x)
|
||||||
|
|
|
@ -435,7 +435,7 @@ _rlinit_vesa:
|
||||||
mov $PC_VIDEO_TEXT,%al # if text mode, simply say so
|
mov $PC_VIDEO_TEXT,%al # if text mode, simply say so
|
||||||
test $0b00010000,%cl
|
test $0b00010000,%cl
|
||||||
jz .ok4
|
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
|
jnz .fail4 # color; bail out if not
|
||||||
mov %es:0x19(%di),%cl # check actual color fields & bits
|
mov %es:0x19(%di),%cl # check actual color fields & bits
|
||||||
mov %es:0x1f(%di),%ax # per pixel, against a list
|
mov %es:0x1f(%di),%ax # per pixel, against a list
|
||||||
|
|
|
@ -39,7 +39,9 @@
|
||||||
* @see libc/vga/tty-graph.inc
|
* @see libc/vga/tty-graph.inc
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef __llvm__
|
||||||
#pragma GCC optimize("s")
|
#pragma GCC optimize("s")
|
||||||
|
#endif
|
||||||
|
|
||||||
#define KLOGTTY
|
#define KLOGTTY
|
||||||
#define MAYUNROLLLOOPS /* do not unroll loops; keep the code small! */
|
#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 (n == -1) n = p ? strlen(p) : 0;
|
||||||
if ((q = r = malloc((n + 16) * sizeof(char16_t) * 2 + sizeof(char16_t)))) {
|
if ((q = r = malloc((n + 16) * sizeof(char16_t) * 2 + sizeof(char16_t)))) {
|
||||||
for (i = 0; i < n;) {
|
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) {
|
if (i + 16 < n) {
|
||||||
typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(1)));
|
typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(1)));
|
||||||
xmm_t vi, vz = {0};
|
xmm_t vi, vz = {0};
|
||||||
|
|
|
@ -27,13 +27,10 @@ COSMOPOLITAN_C_START_
|
||||||
#define xstripext __xstripext
|
#define xstripext __xstripext
|
||||||
#define xstripexts __xstripexts
|
#define xstripexts __xstripexts
|
||||||
#define xload __xload
|
#define xload __xload
|
||||||
#define xloadzd __xloadzd
|
|
||||||
#define rmrf __rmrf
|
#define rmrf __rmrf
|
||||||
#define xbasename __xbasename
|
#define xbasename __xbasename
|
||||||
#define xdirname __xdirname
|
#define xdirname __xdirname
|
||||||
#define xjoinpaths __xjoinpaths
|
#define xjoinpaths __xjoinpaths
|
||||||
#define xreadlink __xreadlink
|
|
||||||
#define xreadlinkat __xreadlinkat
|
|
||||||
#define xfixpath __xfixpath
|
#define xfixpath __xfixpath
|
||||||
#define xslurp __xslurp
|
#define xslurp __xslurp
|
||||||
#define xbarf __xbarf
|
#define xbarf __xbarf
|
||||||
|
@ -84,8 +81,6 @@ char *xhomedir(void) dontdiscard;
|
||||||
char *xstripext(const char *) dontdiscard;
|
char *xstripext(const char *) dontdiscard;
|
||||||
char *xstripexts(const char *) dontdiscard;
|
char *xstripexts(const char *) dontdiscard;
|
||||||
void *xload(_Atomic(void *) *, const void *, size_t, size_t);
|
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 *);
|
int rmrf(const char *);
|
||||||
char *xbasename(const char *) paramsnonnull()
|
char *xbasename(const char *) paramsnonnull()
|
||||||
returnspointerwithnoaliases dontthrow nocallback dontdiscard returnsnonnull;
|
returnspointerwithnoaliases dontthrow nocallback dontdiscard returnsnonnull;
|
||||||
|
@ -93,10 +88,6 @@ char *xdirname(const char *) paramsnonnull()
|
||||||
returnspointerwithnoaliases dontthrow nocallback dontdiscard returnsnonnull;
|
returnspointerwithnoaliases dontthrow nocallback dontdiscard returnsnonnull;
|
||||||
char *xjoinpaths(const char *, const char *) paramsnonnull()
|
char *xjoinpaths(const char *, const char *) paramsnonnull()
|
||||||
returnspointerwithnoaliases dontthrow nocallback dontdiscard returnsnonnull;
|
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 xfixpath(void);
|
||||||
void *xslurp(const char *, size_t *)
|
void *xslurp(const char *, size_t *)
|
||||||
paramsnonnull((1)) returnspointerwithnoaliases
|
paramsnonnull((1)) returnspointerwithnoaliases
|
||||||
|
|
|
@ -35,8 +35,7 @@ LIBC_X_A_DIRECTDEPS = \
|
||||||
LIBC_STR \
|
LIBC_STR \
|
||||||
LIBC_SYSV \
|
LIBC_SYSV \
|
||||||
THIRD_PARTY_GDTOA \
|
THIRD_PARTY_GDTOA \
|
||||||
THIRD_PARTY_MUSL \
|
THIRD_PARTY_MUSL
|
||||||
THIRD_PARTY_ZLIB
|
|
||||||
|
|
||||||
LIBC_X_A_DEPS := \
|
LIBC_X_A_DEPS := \
|
||||||
$(call uniq,$(foreach x,$(LIBC_X_A_DIRECTDEPS),$($(x))))
|
$(call uniq,$(foreach x,$(LIBC_X_A_DIRECTDEPS),$($(x))))
|
||||||
|
|
|
@ -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,7 +39,7 @@
|
||||||
* @asyncsignalsafe
|
* @asyncsignalsafe
|
||||||
* @vforksafe
|
* @vforksafe
|
||||||
*/
|
*/
|
||||||
int(xsigaction)(int sig, void *handler, uint64_t flags, uint64_t mask,
|
int xsigaction(int sig, void *handler, uint64_t flags, uint64_t mask,
|
||||||
struct sigaction *old) {
|
struct sigaction *old) {
|
||||||
/* This API is superior to sigaction() because (1) it offers feature
|
/* This API is superior to sigaction() because (1) it offers feature
|
||||||
parity; (2) compiler emits 1/3rd as much binary code at call-site;
|
parity; (2) compiler emits 1/3rd as much binary code at call-site;
|
||||||
|
|
|
@ -6,14 +6,6 @@ COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
int xsigaction(int, void *, uint64_t, uint64_t, struct sigaction *);
|
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_
|
COSMOPOLITAN_C_END_
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
#endif /* COSMOPOLITAN_LIBC_X_XSIGACTION_H_ */
|
#endif /* COSMOPOLITAN_LIBC_X_XSIGACTION_H_ */
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/struct/sigaction.h"
|
#include "libc/calls/struct/sigaction.h"
|
||||||
|
#include "libc/calls/ucontext.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/log/check.h"
|
#include "libc/log/check.h"
|
||||||
#include "libc/log/log.h"
|
#include "libc/log/log.h"
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/struct/sigaction.h"
|
#include "libc/calls/struct/sigaction.h"
|
||||||
#include "libc/calls/struct/sigset.h"
|
#include "libc/calls/struct/sigset.h"
|
||||||
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/sysv/consts/sig.h"
|
#include "libc/sysv/consts/sig.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/mem/alg.h"
|
#include "libc/mem/alg.h"
|
||||||
#include "libc/mem/gc.h"
|
#include "libc/mem/gc.h"
|
||||||
|
#include "libc/mem/gc.internal.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/stdio/rand.h"
|
#include "libc/stdio/rand.h"
|
||||||
|
@ -28,6 +29,47 @@
|
||||||
#include "libc/testlib/ezbench.h"
|
#include "libc/testlib/ezbench.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
||||||
|
int CompareLow(const void *a, const void *b) {
|
||||||
|
const int *x = a;
|
||||||
|
const int *y = b;
|
||||||
|
if ((char)*x < (char)*y) return -1;
|
||||||
|
if ((char)*x > (char)*y) return +1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InsertionSortLow(int *A, int n) {
|
||||||
|
int i, j, t;
|
||||||
|
for (i = 1; i < n; i++) {
|
||||||
|
t = A[i];
|
||||||
|
j = i - 1;
|
||||||
|
while (j >= 0 && (char)A[j] > (char)t) {
|
||||||
|
A[j + 1] = A[j];
|
||||||
|
j = j - 1;
|
||||||
|
}
|
||||||
|
A[j + 1] = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsStableSort(void sort(void *, size_t, size_t,
|
||||||
|
int (*)(const void *, const void *))) {
|
||||||
|
int n = 256;
|
||||||
|
int *A = gc(malloc(n * sizeof(int)));
|
||||||
|
int *B = gc(malloc(n * sizeof(int)));
|
||||||
|
rngset(A, n * sizeof(int), 0, 0);
|
||||||
|
memcpy(B, A, n * sizeof(int));
|
||||||
|
InsertionSortLow(A, n);
|
||||||
|
sort(B, n, sizeof(int), CompareLow);
|
||||||
|
return !memcmp(A, B, n * sizeof(int));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(sort, stability) {
|
||||||
|
ASSERT_FALSE(IsStableSort(qsort));
|
||||||
|
ASSERT_FALSE(IsStableSort(smoothsort));
|
||||||
|
ASSERT_FALSE(IsStableSort((void *)qsort_r));
|
||||||
|
ASSERT_FALSE(IsStableSort((void *)heapsort));
|
||||||
|
ASSERT_TRUE(IsStableSort((void *)mergesort));
|
||||||
|
}
|
||||||
|
|
||||||
int CompareInt(const void *a, const void *b) {
|
int CompareInt(const void *a, const void *b) {
|
||||||
const int *x = a;
|
const int *x = a;
|
||||||
const int *y = b;
|
const int *y = b;
|
||||||
|
@ -44,7 +86,7 @@ int CompareLong(const void *a, const void *b) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(qsort, test) {
|
TEST(qsort, words) {
|
||||||
const int32_t A[][2] = {{4, 'a'}, {65, 'b'}, {2, 'c'}, {-31, 'd'},
|
const int32_t A[][2] = {{4, 'a'}, {65, 'b'}, {2, 'c'}, {-31, 'd'},
|
||||||
{0, 'e'}, {99, 'f'}, {2, 'g'}, {83, 'h'},
|
{0, 'e'}, {99, 'f'}, {2, 'g'}, {83, 'h'},
|
||||||
{782, 'i'}, {1, 'j'}};
|
{782, 'i'}, {1, 'j'}};
|
||||||
|
@ -58,12 +100,38 @@ TEST(qsort, test) {
|
||||||
free(M);
|
free(M);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Record {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int z;
|
||||||
|
int a[2];
|
||||||
|
int b;
|
||||||
|
};
|
||||||
|
|
||||||
|
int CompareRecord(const void *a, const void *b) {
|
||||||
|
const struct Record *x = a;
|
||||||
|
const struct Record *y = b;
|
||||||
|
if (x->z > y->z) return -1;
|
||||||
|
if (x->z < y->z) return +1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(qsort, records) {
|
||||||
|
int i, n = 256;
|
||||||
|
struct Record *A = gc(calloc(n, sizeof(struct Record)));
|
||||||
|
struct Record *B = gc(calloc(n, sizeof(struct Record)));
|
||||||
|
for (i = 0; i < n; ++i) A[i].z = B[i].z = lemur64();
|
||||||
|
qsort(A, n, sizeof(struct Record), CompareRecord);
|
||||||
|
mergesort(B, n, sizeof(struct Record), CompareRecord);
|
||||||
|
ASSERT_EQ(0, memcmp(A, B, n * sizeof(struct Record)));
|
||||||
|
}
|
||||||
|
|
||||||
TEST(qsort, equivalence_random) {
|
TEST(qsort, equivalence_random) {
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t n = 1000;
|
size_t n = 1000;
|
||||||
long *a = _gc(malloc(n * sizeof(long)));
|
long *a = gc(malloc(n * sizeof(long)));
|
||||||
long *b = _gc(malloc(n * sizeof(long)));
|
long *b = gc(malloc(n * sizeof(long)));
|
||||||
long *c = _gc(malloc(n * sizeof(long)));
|
long *c = gc(malloc(n * sizeof(long)));
|
||||||
for (i = 0; i < n; ++i) a[i] = lemur64();
|
for (i = 0; i < n; ++i) a[i] = lemur64();
|
||||||
memcpy(b, a, n * sizeof(long));
|
memcpy(b, a, n * sizeof(long));
|
||||||
memcpy(c, a, n * sizeof(long));
|
memcpy(c, a, n * sizeof(long));
|
||||||
|
@ -84,9 +152,9 @@ TEST(qsort, equivalence_random) {
|
||||||
TEST(qsort, equivalence_reverse) {
|
TEST(qsort, equivalence_reverse) {
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t n = 1000;
|
size_t n = 1000;
|
||||||
long *a = _gc(malloc(n * sizeof(long)));
|
long *a = gc(malloc(n * sizeof(long)));
|
||||||
long *b = _gc(malloc(n * sizeof(long)));
|
long *b = gc(malloc(n * sizeof(long)));
|
||||||
long *c = _gc(malloc(n * sizeof(long)));
|
long *c = gc(malloc(n * sizeof(long)));
|
||||||
for (i = 0; i < n; ++i) a[n - i - 1] = i;
|
for (i = 0; i < n; ++i) a[n - i - 1] = i;
|
||||||
memcpy(b, a, n * sizeof(long));
|
memcpy(b, a, n * sizeof(long));
|
||||||
memcpy(c, a, n * sizeof(long));
|
memcpy(c, a, n * sizeof(long));
|
||||||
|
@ -107,13 +175,15 @@ TEST(qsort, equivalence_reverse) {
|
||||||
BENCH(qsort, bench) {
|
BENCH(qsort, bench) {
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t n = 1000;
|
size_t n = 1000;
|
||||||
long *p1 = _gc(malloc(n * sizeof(long)));
|
long *p1 = gc(malloc(n * sizeof(long)));
|
||||||
long *p2 = _gc(malloc(n * sizeof(long)));
|
long *p2 = gc(malloc(n * sizeof(long)));
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
for (i = 0; i < n; ++i) p1[i] = i + ((lemur64() % 3) - 1);
|
for (i = 0; i < n; ++i) p1[i] = i + ((lemur64() % 3) - 1);
|
||||||
EZBENCH2("qsort nearly", memcpy(p2, p1, n * sizeof(long)),
|
EZBENCH2("qsort nearly", memcpy(p2, p1, n * sizeof(long)),
|
||||||
qsort(p2, n, sizeof(long), CompareLong));
|
qsort(p2, n, sizeof(long), CompareLong));
|
||||||
|
EZBENCH2("qsort_r nearly", memcpy(p2, p1, n * sizeof(long)),
|
||||||
|
qsort_r(p2, n, sizeof(long), (void *)CompareLong, 0));
|
||||||
EZBENCH2("heapsort nearly", memcpy(p2, p1, n * sizeof(long)),
|
EZBENCH2("heapsort nearly", memcpy(p2, p1, n * sizeof(long)),
|
||||||
heapsort(p2, n, sizeof(long), CompareLong));
|
heapsort(p2, n, sizeof(long), CompareLong));
|
||||||
EZBENCH2("mergesort nearly", memcpy(p2, p1, n * sizeof(long)),
|
EZBENCH2("mergesort nearly", memcpy(p2, p1, n * sizeof(long)),
|
||||||
|
@ -127,6 +197,8 @@ BENCH(qsort, bench) {
|
||||||
for (i = 0; i < n; ++i) p1[i] = n - i;
|
for (i = 0; i < n; ++i) p1[i] = n - i;
|
||||||
EZBENCH2("qsort reverse", memcpy(p2, p1, n * sizeof(long)),
|
EZBENCH2("qsort reverse", memcpy(p2, p1, n * sizeof(long)),
|
||||||
qsort(p2, n, sizeof(long), CompareLong));
|
qsort(p2, n, sizeof(long), CompareLong));
|
||||||
|
EZBENCH2("qsort_r reverse", memcpy(p2, p1, n * sizeof(long)),
|
||||||
|
qsort_r(p2, n, sizeof(long), (void *)CompareLong, 0));
|
||||||
EZBENCH2("heapsort reverse", memcpy(p2, p1, n * sizeof(long)),
|
EZBENCH2("heapsort reverse", memcpy(p2, p1, n * sizeof(long)),
|
||||||
heapsort(p2, n, sizeof(long), CompareLong));
|
heapsort(p2, n, sizeof(long), CompareLong));
|
||||||
EZBENCH2("mergesort reverse", memcpy(p2, p1, n * sizeof(long)),
|
EZBENCH2("mergesort reverse", memcpy(p2, p1, n * sizeof(long)),
|
||||||
|
@ -140,6 +212,8 @@ BENCH(qsort, bench) {
|
||||||
rngset(p1, n * sizeof(long), 0, 0);
|
rngset(p1, n * sizeof(long), 0, 0);
|
||||||
EZBENCH2("qsort random", memcpy(p2, p1, n * sizeof(long)),
|
EZBENCH2("qsort random", memcpy(p2, p1, n * sizeof(long)),
|
||||||
qsort(p2, n, sizeof(long), CompareLong));
|
qsort(p2, n, sizeof(long), CompareLong));
|
||||||
|
EZBENCH2("qsort_r random", memcpy(p2, p1, n * sizeof(long)),
|
||||||
|
qsort_r(p2, n, sizeof(long), (void *)CompareLong, 0));
|
||||||
EZBENCH2("heapsort random", memcpy(p2, p1, n * sizeof(long)),
|
EZBENCH2("heapsort random", memcpy(p2, p1, n * sizeof(long)),
|
||||||
heapsort(p2, n, sizeof(long), CompareLong));
|
heapsort(p2, n, sizeof(long), CompareLong));
|
||||||
EZBENCH2("mergesort random", memcpy(p2, p1, n * sizeof(long)),
|
EZBENCH2("mergesort random", memcpy(p2, p1, n * sizeof(long)),
|
||||||
|
@ -156,6 +230,8 @@ BENCH(qsort, bench) {
|
||||||
}
|
}
|
||||||
EZBENCH2("qsort 2n", memcpy(p2, p1, n * sizeof(long)),
|
EZBENCH2("qsort 2n", memcpy(p2, p1, n * sizeof(long)),
|
||||||
qsort(p2, n, sizeof(long), CompareLong));
|
qsort(p2, n, sizeof(long), CompareLong));
|
||||||
|
EZBENCH2("qsort_r 2n", memcpy(p2, p1, n * sizeof(long)),
|
||||||
|
qsort_r(p2, n, sizeof(long), (void *)CompareLong, 0));
|
||||||
EZBENCH2("heapsort 2n", memcpy(p2, p1, n * sizeof(long)),
|
EZBENCH2("heapsort 2n", memcpy(p2, p1, n * sizeof(long)),
|
||||||
heapsort(p2, n, sizeof(long), CompareLong));
|
heapsort(p2, n, sizeof(long), CompareLong));
|
||||||
EZBENCH2("mergesort 2n", memcpy(p2, p1, n * sizeof(long)),
|
EZBENCH2("mergesort 2n", memcpy(p2, p1, n * sizeof(long)),
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/struct/sigaction.h"
|
#include "libc/calls/struct/sigaction.h"
|
||||||
|
#include "libc/calls/ucontext.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/fmt/fmt.h"
|
#include "libc/fmt/fmt.h"
|
||||||
|
@ -31,6 +32,7 @@
|
||||||
#include "libc/sysv/consts/o.h"
|
#include "libc/sysv/consts/o.h"
|
||||||
#include "libc/sysv/consts/prot.h"
|
#include "libc/sysv/consts/prot.h"
|
||||||
#include "libc/sysv/consts/sa.h"
|
#include "libc/sysv/consts/sa.h"
|
||||||
|
#include "libc/sysv/consts/sig.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
#include "third_party/xed/x86.h"
|
#include "third_party/xed/x86.h"
|
||||||
|
|
|
@ -310,7 +310,14 @@ TEST(fmt, e) {
|
||||||
TEST(fmt, a) {
|
TEST(fmt, a) {
|
||||||
EXPECT_STREQ("0x0p+0", _gc(xasprintf("%a", 0.)));
|
EXPECT_STREQ("0x0p+0", _gc(xasprintf("%a", 0.)));
|
||||||
EXPECT_STREQ("0x0p+0", _gc(xasprintf("%.a", 0.)));
|
EXPECT_STREQ("0x0p+0", _gc(xasprintf("%.a", 0.)));
|
||||||
|
EXPECT_STREQ(" 0x0p+0", _gc(xasprintf("%7.a", 0.)));
|
||||||
EXPECT_STREQ("0x0.000p+0", _gc(xasprintf("%.3a", 0.)));
|
EXPECT_STREQ("0x0.000p+0", _gc(xasprintf("%.3a", 0.)));
|
||||||
|
// EXPECT_STREQ(" 0x0.000p+0\n", _gc(xasprintf("%11.3a\n", 0.))); // TODO
|
||||||
|
EXPECT_STREQ("inf\n", _gc(xasprintf("%g\n", INFINITY)));
|
||||||
|
EXPECT_STREQ(" inf\n", _gc(xasprintf("%5g\n", INFINITY)));
|
||||||
|
EXPECT_STREQ(" +inf\n", _gc(xasprintf("%+5g\n", INFINITY)));
|
||||||
|
EXPECT_STREQ(" inf\n", _gc(xasprintf("% g\n", INFINITY)));
|
||||||
|
EXPECT_STREQ("-inf\n", _gc(xasprintf("% g\n", -INFINITY)));
|
||||||
EXPECT_STREQ("0x1.921fb54442d18p+1",
|
EXPECT_STREQ("0x1.921fb54442d18p+1",
|
||||||
_gc(xasprintf("%a", 0x1.921fb54442d1846ap+1)));
|
_gc(xasprintf("%a", 0x1.921fb54442d1846ap+1)));
|
||||||
EXPECT_STREQ("0X1.921FB54442D18P+1",
|
EXPECT_STREQ("0X1.921FB54442D18P+1",
|
||||||
|
|
1
third_party/awk/main.c
vendored
1
third_party/awk/main.c
vendored
|
@ -36,6 +36,7 @@
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/sysv/consts/sa.h"
|
#include "libc/sysv/consts/sa.h"
|
||||||
#include "libc/sysv/consts/sicode.h"
|
#include "libc/sysv/consts/sicode.h"
|
||||||
|
#include "libc/sysv/consts/sig.h"
|
||||||
#include "third_party/awk/awk.h"
|
#include "third_party/awk/awk.h"
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|
||||||
|
|
1
third_party/lua/lrepl.c
vendored
1
third_party/lua/lrepl.c
vendored
|
@ -40,6 +40,7 @@
|
||||||
#include "libc/stdio/stdio.h"
|
#include "libc/stdio/stdio.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/sysv/consts/sa.h"
|
#include "libc/sysv/consts/sa.h"
|
||||||
|
#include "libc/sysv/consts/sig.h"
|
||||||
#include "libc/thread/thread.h"
|
#include "libc/thread/thread.h"
|
||||||
#include "third_party/linenoise/linenoise.h"
|
#include "third_party/linenoise/linenoise.h"
|
||||||
#include "third_party/lua/cosmo.h"
|
#include "third_party/lua/cosmo.h"
|
||||||
|
|
1
third_party/make/commands.c
vendored
1
third_party/make/commands.c
vendored
|
@ -22,6 +22,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
#include "third_party/make/variable.h"
|
#include "third_party/make/variable.h"
|
||||||
/**/
|
/**/
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
#include "libc/sysv/consts/sig.h"
|
||||||
#include "third_party/make/commands.h"
|
#include "third_party/make/commands.h"
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
||||||
|
|
1
third_party/make/job.c
vendored
1
third_party/make/job.c
vendored
|
@ -57,6 +57,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
#include "libc/sysv/consts/pr.h"
|
#include "libc/sysv/consts/pr.h"
|
||||||
#include "libc/sysv/consts/prot.h"
|
#include "libc/sysv/consts/prot.h"
|
||||||
#include "libc/sysv/consts/rlimit.h"
|
#include "libc/sysv/consts/rlimit.h"
|
||||||
|
#include "libc/sysv/consts/sig.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
#include "libc/time/time.h"
|
#include "libc/time/time.h"
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
|
12
third_party/musl/strfmon.c
vendored
12
third_party/musl/strfmon.c
vendored
|
@ -41,7 +41,7 @@ static ssize_t vstrfmon_l(char *s, size_t n, locale_t loc, const char *fmt, va_l
|
||||||
{
|
{
|
||||||
size_t l;
|
size_t l;
|
||||||
double x;
|
double x;
|
||||||
int fill, nogrp, negpar, nosym, left, intl;
|
int left;
|
||||||
int lp, rp, w, fw;
|
int lp, rp, w, fw;
|
||||||
char *s0=s;
|
char *s0=s;
|
||||||
for (; n && *fmt; ) {
|
for (; n && *fmt; ) {
|
||||||
|
@ -54,25 +54,17 @@ static ssize_t vstrfmon_l(char *s, size_t n, locale_t loc, const char *fmt, va_l
|
||||||
fmt++;
|
fmt++;
|
||||||
if (*fmt == '%') goto literal;
|
if (*fmt == '%') goto literal;
|
||||||
|
|
||||||
fill = ' ';
|
|
||||||
nogrp = 0;
|
|
||||||
negpar = 0;
|
|
||||||
nosym = 0;
|
|
||||||
left = 0;
|
left = 0;
|
||||||
for (; ; fmt++) {
|
for (; ; fmt++) {
|
||||||
switch (*fmt) {
|
switch (*fmt) {
|
||||||
case '=':
|
case '=':
|
||||||
fill = *++fmt;
|
|
||||||
continue;
|
continue;
|
||||||
case '^':
|
case '^':
|
||||||
nogrp = 1;
|
|
||||||
continue;
|
continue;
|
||||||
case '(':
|
case '(':
|
||||||
negpar = 1;
|
|
||||||
case '+':
|
case '+':
|
||||||
continue;
|
continue;
|
||||||
case '!':
|
case '!':
|
||||||
nosym = 1;
|
|
||||||
continue;
|
continue;
|
||||||
case '-':
|
case '-':
|
||||||
left = 1;
|
left = 1;
|
||||||
|
@ -90,8 +82,6 @@ static ssize_t vstrfmon_l(char *s, size_t n, locale_t loc, const char *fmt, va_l
|
||||||
if (*fmt=='.') for (rp=0, fmt++; isdigit(*fmt); fmt++)
|
if (*fmt=='.') for (rp=0, fmt++; isdigit(*fmt); fmt++)
|
||||||
rp = 10*rp + (*fmt-'0');
|
rp = 10*rp + (*fmt-'0');
|
||||||
|
|
||||||
intl = *fmt++ == 'i';
|
|
||||||
|
|
||||||
w = lp + 1 + rp;
|
w = lp + 1 + rp;
|
||||||
if (!left && fw>w) w = fw;
|
if (!left && fw>w) w = fw;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
#include "third_party/python/Modules/cjkcodecs/xloadzd.h"
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
||||||
static _Atomic(void *) __big5_decmap_ptr;
|
static _Atomic(void *) __big5_decmap_ptr;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
#include "third_party/python/Modules/cjkcodecs/xloadzd.h"
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
||||||
static _Atomic(void *) __cp932ext_decmap_ptr;
|
static _Atomic(void *) __cp932ext_decmap_ptr;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
#include "third_party/python/Modules/cjkcodecs/xloadzd.h"
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
||||||
static _Atomic(void *) __cp949_encmap_ptr;
|
static _Atomic(void *) __cp949_encmap_ptr;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
#include "third_party/python/Modules/cjkcodecs/xloadzd.h"
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
||||||
static _Atomic(void *) __cp949ext_decmap_ptr;
|
static _Atomic(void *) __cp949ext_decmap_ptr;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
#include "third_party/python/Modules/cjkcodecs/xloadzd.h"
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
||||||
static _Atomic(void *) __cp950ext_decmap_ptr;
|
static _Atomic(void *) __cp950ext_decmap_ptr;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
#include "third_party/python/Modules/cjkcodecs/xloadzd.h"
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
||||||
static _Atomic(void *) __gb18030ext_decmap_ptr;
|
static _Atomic(void *) __gb18030ext_decmap_ptr;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
#include "third_party/python/Modules/cjkcodecs/xloadzd.h"
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
||||||
static _Atomic(void *) __gb18030ext_encmap_ptr;
|
static _Atomic(void *) __gb18030ext_encmap_ptr;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
#include "third_party/python/Modules/cjkcodecs/xloadzd.h"
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
||||||
static _Atomic(void *) __gb2312_decmap_ptr;
|
static _Atomic(void *) __gb2312_decmap_ptr;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
#include "third_party/python/Modules/cjkcodecs/xloadzd.h"
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
||||||
static _Atomic(void *) __gbcommon_encmap_ptr;
|
static _Atomic(void *) __gbcommon_encmap_ptr;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
#include "third_party/python/Modules/cjkcodecs/xloadzd.h"
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
||||||
static _Atomic(void *) __gbkext_decmap_ptr;
|
static _Atomic(void *) __gbkext_decmap_ptr;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
#include "third_party/python/Modules/cjkcodecs/xloadzd.h"
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
||||||
static _Atomic(void *) __jisx0208_decmap_ptr;
|
static _Atomic(void *) __jisx0208_decmap_ptr;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
#include "third_party/python/Modules/cjkcodecs/xloadzd.h"
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
||||||
static _Atomic(void *) __jisx0212_decmap_ptr;
|
static _Atomic(void *) __jisx0212_decmap_ptr;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
#include "third_party/python/Modules/cjkcodecs/xloadzd.h"
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
||||||
static _Atomic(void *) __jisx0213_1_bmp_decmap_ptr;
|
static _Atomic(void *) __jisx0213_1_bmp_decmap_ptr;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
#include "third_party/python/Modules/cjkcodecs/xloadzd.h"
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
||||||
static _Atomic(void *) __jisx0213_2_bmp_decmap_ptr;
|
static _Atomic(void *) __jisx0213_2_bmp_decmap_ptr;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
#include "third_party/python/Modules/cjkcodecs/xloadzd.h"
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
||||||
static _Atomic(void *) __jisx0213_pair_decmap_ptr;
|
static _Atomic(void *) __jisx0213_pair_decmap_ptr;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
#include "third_party/python/Modules/cjkcodecs/xloadzd.h"
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
||||||
static _Atomic(void *) __ksx1001_decmap_ptr;
|
static _Atomic(void *) __ksx1001_decmap_ptr;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue