Make fixes and improvements

- Introduce __assert_disable global
- Improve strsignal() thread safety
- Make system call tracing thread safe
- Fix SO_RCVTIMEO / SO_SNDTIMEO on Windows
- Refactor DescribeFoo() functions into one place
- Fix fork() on Windows when TLS and MAP_STACK exist
- Round upwards in setsockopt(SO_RCVTIMEO) on Windows
- Disable futexes on OpenBSD which seem extremely broken
- Implement a better kludge for monotonic time on Windows
This commit is contained in:
Justine Tunney 2022-06-25 18:17:31 -07:00
parent 5d837c4e7c
commit fbc053e018
186 changed files with 1836 additions and 1325 deletions

View file

@ -16,15 +16,27 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/bits/likely.h"
#include "libc/calls/internal.h"
#include "libc/calls/struct/timespec.h"
#include "libc/fmt/conv.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/spinlock.h"
#include "libc/nexgen32e/rdtsc.h"
#include "libc/nexgen32e/threaded.h"
#include "libc/nexgen32e/x86feature.h"
#include "libc/nt/struct/filetime.h"
#include "libc/nt/synchronization.h"
#include "libc/sysv/consts/clock.h"
#include "libc/sysv/errfuns.h"
#include "libc/time/clockstonanos.internal.h"
textwindows int sys_clock_gettime_nt(int clockid, struct timespec *ts) {
int64_t ms;
uint64_t nanos;
static bool once;
static char lock;
struct timespec res;
static uint64_t base;
struct NtFileTime ft;
static struct timespec mono;
if (!ts) return efault();
@ -32,21 +44,21 @@ textwindows int sys_clock_gettime_nt(int clockid, struct timespec *ts) {
GetSystemTimeAsFileTime(&ft);
*ts = FileTimeToTimeSpec(ft);
return 0;
} else if (clockid == CLOCK_MONOTONIC || clockid == CLOCK_MONOTONIC_RAW) {
ms = GetTickCount64();
res.tv_sec = ms / 1000;
res.tv_nsec = ms % 1000 * 1000000;
res.tv_nsec += rdtsc() / 3 % 1000000000;
if (res.tv_nsec > 1000000000) {
res.tv_nsec -= 1000000000;
res.tv_sec += 1;
}
if (res.tv_sec > mono.tv_sec ||
(res.tv_sec == mono.tv_sec && res.tv_nsec > mono.tv_nsec)) {
mono = res;
} else {
res = mono;
} else if ((clockid == CLOCK_MONOTONIC || clockid == CLOCK_MONOTONIC_RAW) &&
X86_HAVE(INVTSC)) {
// this routine stops being monotonic after 194 years of uptime
if (__threaded) _spinlock(&lock);
if (UNLIKELY(!once)) {
GetSystemTimeAsFileTime(&ft);
mono = FileTimeToTimeSpec(ft);
base = rdtsc();
once = true;
}
nanos = ClocksToNanos(rdtsc(), base);
res = mono;
res.tv_sec += nanos / 1000000000;
res.tv_nsec += nanos % 1000000000;
_spunlock(&lock);
*ts = res;
return 0;
} else {

View file

@ -57,7 +57,6 @@
*/
int clock_gettime(int clockid, struct timespec *ts) {
int rc;
char *buf;
if (IsAsan() && !__asan_is_valid_timespec(ts)) {
rc = efault();
} else {
@ -65,9 +64,8 @@ int clock_gettime(int clockid, struct timespec *ts) {
}
#if SYSDEBUG
if (!__time_critical) {
buf = alloca(45);
STRACE("clock_gettime(%d, [%s]) → %d% m", clockid,
DescribeTimespec(buf, 45, rc, ts), rc);
STRACE("clock_gettime(%d, [%s]) → %d% m", clockid, DescribeTimespec(rc, ts),
rc);
}
#endif
return rc;

View file

@ -1,38 +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 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/fmt/itoa.h"
#include "libc/fmt/magnumstrs.internal.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/sol.h"
/**
* Describes clock_gettime() clock argument.
*/
char *DescribeClockName(int x) {
int i;
char *s;
_Alignas(char) static char buf[32];
if ((s = GetMagnumStr(kClockNames, x))) {
stpcpy(stpcpy(buf, "CLOCK_"), s);
return buf;
} else {
FormatInt32(buf, x);
return buf;
}
}

View file

@ -1,38 +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/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h"
const char *DescribeSigaction(char *buf, size_t bufsize, int rc,
const struct sigaction *sa) {
char maskbuf[64];
if (rc == -1) return "n/a";
if (!sa) return "NULL";
if ((!IsAsan() && kisdangerous(sa)) ||
(IsAsan() && !__asan_is_valid(sa, sizeof(*sa)))) {
ksnprintf(buf, sizeof(buf), "%p", sa);
} else {
ksnprintf(buf, bufsize, "{.sa_handler=%p, .sa_flags=%#lx, .sa_mask=%s}",
sa->sa_handler, sa->sa_flags,
DescribeSigset(maskbuf, sizeof(maskbuf), rc, &sa->sa_mask));
}
return buf;
}

View file

@ -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 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/struct/sigaltstack.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h"
const char *DescribeSigaltstk(char *buf, size_t bufsize, int rc,
const struct sigaltstack *ss) {
if (rc == -1) return "n/a";
if (!ss) return "NULL";
if ((!IsAsan() && kisdangerous(ss)) ||
(IsAsan() && !__asan_is_valid(ss, sizeof(*ss)))) {
ksnprintf(buf, sizeof(buf), "%p", ss);
} else {
ksnprintf(buf, bufsize, "{.ss_sp=%p, .ss_flags=%#lx, .ss_size=%'zu}",
ss->ss_sp, ss->ss_flags, ss->ss_size);
}
return buf;
}

View file

@ -1,63 +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/bits/popcnt.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/str/str.h"
const char *DescribeSigset(char *buf, size_t bufsize, int rc,
const sigset_t *ss) {
bool gotsome;
int i, n, sig;
sigset_t sigset;
if (rc == -1) return "n/a";
if (!ss) return "NULL";
if ((!IsAsan() && kisdangerous(ss)) ||
(IsAsan() && !__asan_is_valid(ss, sizeof(*ss)))) {
ksnprintf(buf, sizeof(buf), "%p", ss);
return buf;
}
i = 0;
n = bufsize;
sigset = *ss;
gotsome = false;
if (popcnt(sigset.__bits[0]) + popcnt(sigset.__bits[1]) > 64) {
i += ksnprintf(buf + i, n - i, "~");
sigset.__bits[0] = ~sigset.__bits[0];
sigset.__bits[1] = ~sigset.__bits[1];
}
i += ksnprintf(buf + i, n - i, "{");
for (sig = 1; sig < 128; ++sig) {
if (sigismember(&sigset, sig)) {
if (gotsome) {
sig += ksnprintf(buf + sig, n - sig, ", ");
} else {
gotsome = true;
}
sig += ksnprintf(buf + sig, n - sig, "%s", strsignal(sig));
}
}
i += ksnprintf(buf + i, n - i, "}");
return buf;
}

View file

@ -16,10 +16,13 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/bits/likely.h"
#include "libc/calls/strace.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/errno.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/spinlock.h"
#include "libc/nt/runtime.h"
#include "libc/runtime/directmap.internal.h"
#include "libc/runtime/memtrack.internal.h"
@ -38,7 +41,6 @@
*/
struct DirectMap sys_mmap(void *addr, size_t size, int prot, int flags, int fd,
int64_t off) {
/* asan runtime depends on this function */
struct DirectMap d;
if (!IsWindows() && !IsMetal()) {
d.addr = __sys_mmap(addr, size, prot, flags, fd, off, off);

View file

@ -41,7 +41,6 @@
*/
int faccessat(int dirfd, const char *path, int mode, uint32_t flags) {
int rc;
char buf[12];
if (IsAsan() && !__asan_is_valid(path, 1)) {
rc = efault();
} else if (weaken(__zipos_notat) &&
@ -52,7 +51,7 @@ int faccessat(int dirfd, const char *path, int mode, uint32_t flags) {
} else {
rc = sys_faccessat_nt(dirfd, path, mode, flags);
}
STRACE("faccessat(%s, %#s, %#o, %#x) → %d% m", DescribeDirfd(buf, dirfd),
path, mode, flags, rc);
STRACE("faccessat(%s, %#s, %#o, %#x) → %d% m", DescribeDirfd(dirfd), path,
mode, flags, rc);
return rc;
}

View file

@ -43,7 +43,6 @@
*/
int fchmodat(int dirfd, const char *path, uint32_t mode, int flags) {
int rc;
char buf[12];
if (IsAsan() && !__asan_is_valid(path, 1)) {
rc = efault();
} else if (weaken(__zipos_notat) && (rc = __zipos_notat(dirfd, path)) == -1) {
@ -53,7 +52,7 @@ int fchmodat(int dirfd, const char *path, uint32_t mode, int flags) {
} else {
rc = sys_fchmodat_nt(dirfd, path, mode, flags);
}
STRACE("fchmodat(%s, %#s, %#o, %d) → %d% m", DescribeDirfd(buf, dirfd), path,
mode, flags, rc);
STRACE("fchmodat(%s, %#s, %#o, %d) → %d% m", DescribeDirfd(dirfd), path, mode,
flags, rc);
return rc;
}

View file

@ -42,7 +42,6 @@
int fchownat(int dirfd, const char *path, uint32_t uid, uint32_t gid,
int flags) {
int rc;
char sb[12];
if (IsAsan() && !__asan_is_valid(path, 1)) {
rc = efault();
} else if (weaken(__zipos_notat) && (rc = __zipos_notat(dirfd, path)) == -1) {
@ -50,7 +49,7 @@ int fchownat(int dirfd, const char *path, uint32_t uid, uint32_t gid,
} else {
rc = sys_fchownat(dirfd, path, uid, gid, flags);
}
STRACE("fchownat(%s, %#s, %d, %d, %#b) → %d% m", DescribeDirfd(sb, dirfd),
path, uid, gid, flags, rc);
STRACE("fchownat(%s, %#s, %d, %d, %#b) → %d% m", DescribeDirfd(dirfd), path,
uid, gid, flags, rc);
return rc;
}

View file

@ -28,13 +28,13 @@
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/log/log.h"
#include "libc/mem/alloca.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/at.h"
#include "libc/sysv/errfuns.h"
#include "libc/zipos/zipos.internal.h"
static inline const char *__strace_fstatat_flags(int flags) {
static char buf[12];
static inline const char *__strace_fstatat_flags(char buf[12], int flags) {
if (flags == AT_SYMLINK_NOFOLLOW) return "AT_SYMLINK_NOFOLLOW";
FormatInt32(buf, flags);
return buf;
@ -55,7 +55,6 @@ static inline const char *__strace_fstatat_flags(int flags) {
int fstatat(int dirfd, const char *path, struct stat *st, int flags) {
/* execve() depends on this */
int rc;
char buf[12];
struct ZiposUri zipname;
if (__isfdkind(dirfd, kFdZip)) {
STRACE("zipos dirfd not supported yet");
@ -72,7 +71,7 @@ int fstatat(int dirfd, const char *path, struct stat *st, int flags) {
} else {
rc = sys_fstatat_nt(dirfd, path, st, flags);
}
STRACE("fstatat(%s, %#s, [%s], %s) → %d% m", DescribeDirfd(buf, dirfd), path,
DescribeStat(rc, st), __strace_fstatat_flags(flags), rc);
STRACE("fstatat(%s, %#s, [%s], %s) → %d% m", DescribeDirfd(dirfd), path,
DescribeStat(rc, st), __strace_fstatat_flags(alloca(12), flags), rc);
return rc;
}

View file

@ -35,7 +35,6 @@
*/
int getrlimit(int resource, struct rlimit *rlim) {
int rc;
char buf[64];
if (resource == 127) {
rc = einval();
} else if (!rlim || (IsAsan() && !__asan_is_valid(rlim, sizeof(*rlim)))) {
@ -50,6 +49,6 @@ int getrlimit(int resource, struct rlimit *rlim) {
rc = einval();
}
STRACE("getrlimit(%s, [%s]) → %d% m", DescribeRlimitName(resource),
DescribeRlimit(buf, sizeof(buf), rc, rlim), rc);
DescribeRlimit(rc, rlim), rc);
return rc;
}

View file

@ -63,7 +63,7 @@ textwindows int ioctl_tcsets_nt(int ignored, uint64_t request,
}
ok = SetConsoleMode(in, inmode);
NTTRACE("SetConsoleMode(%p, %s) → %hhhd", in,
DescribeNtConsoleModeInputFlags(inmode), ok);
DescribeNtConsoleInFlags(inmode), ok);
}
if (outok) {
@ -77,7 +77,7 @@ textwindows int ioctl_tcsets_nt(int ignored, uint64_t request,
}
ok = SetConsoleMode(out, outmode);
NTTRACE("SetConsoleMode(%p, %s) → %hhhd", out,
DescribeNtConsoleModeOutputFlags(outmode), ok);
DescribeNtConsoleOutFlags(outmode), ok);
}
return 0;

View file

@ -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 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/fmt/magnumstrs.internal.h"
#include "libc/macros.internal.h"
.macro .e e s
.long \e - kClockNames
.long 1f - kClockNames
.rodata.str1.1
1: .string "\s"
.previous
.endm
.section .rodata
.align 4
.underrun
kClockNames:
.e CLOCK_REALTIME,"REALTIME"
.e CLOCK_REALTIME_FAST,"REALTIME_FAST"
.e CLOCK_MONOTONIC,"MONOTONIC"
.e CLOCK_MONOTONIC_FAST,"MONOTONIC_FAST"
.e CLOCK_MONOTONIC_RAW,"MONOTONIC_RAW"
.e CLOCK_REALTIME_COARSE,"REALTIME_COARSE"
.e CLOCK_MONOTONIC_COARSE,"MONOTONIC_COARSE"
.e CLOCK_PROCESS_CPUTIME_ID,"PROCESS_CPUTIME_ID"
.e CLOCK_TAI,"TAI"
.e CLOCK_PROF,"PROF"
.e CLOCK_BOOTTIME,"BOOTTIME"
.e CLOCK_REALTIME_ALARM,"REALTIME_ALARM"
.e CLOCK_BOOTTIME_ALARM,"BOOTTIME_ALARM"
.long MAGNUM_TERMINATOR
.endobj kClockNames,globl,hidden
.overrun

View file

@ -40,7 +40,6 @@
int linkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath,
int flags) {
int rc;
char buf[2][12];
if (IsAsan() &&
(!__asan_is_valid(oldpath, 1) || !__asan_is_valid(newpath, 1))) {
rc = efault();
@ -53,8 +52,7 @@ int linkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath,
} else {
rc = sys_linkat_nt(olddirfd, oldpath, newdirfd, newpath);
}
STRACE("linkat(%s, %#s, %s, %#s, %#b) → %d% m",
DescribeDirfd(buf[0], olddirfd), oldpath,
DescribeDirfd(buf[1], newdirfd), newpath, flags, rc);
STRACE("linkat(%s, %#s, %s, %#s, %#b) → %d% m", DescribeDirfd(olddirfd),
oldpath, DescribeDirfd(newdirfd), newpath, flags, rc);
return rc;
}

View file

@ -42,7 +42,6 @@
*/
int mkdirat(int dirfd, const char *path, unsigned mode) {
int rc;
char buf[12];
if (IsAsan() && !__asan_is_valid(path, 1)) {
rc = efault();
} else if (weaken(__zipos_notat) && (rc = __zipos_notat(dirfd, path)) == -1) {
@ -52,7 +51,6 @@ int mkdirat(int dirfd, const char *path, unsigned mode) {
} else {
rc = sys_mkdirat_nt(dirfd, path, mode);
}
STRACE("mkdirat(%s, %#s, %#o) → %d% m", DescribeDirfd(buf, dirfd), path, mode,
rc);
STRACE("mkdirat(%s, %#s, %#o) → %d% m", DescribeDirfd(dirfd), path, mode, rc);
return rc;
}

View file

@ -18,6 +18,7 @@
*/
#include "libc/calls/strace.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/runtime/directmap.internal.h"
#include "libc/runtime/memtrack.internal.h"

View file

@ -31,7 +31,6 @@
*/
noinstrument int nanosleep(const struct timespec *req, struct timespec *rem) {
int rc;
char buf[2][45];
if (!req || (IsAsan() && (!__asan_is_valid_timespec(req) ||
(rem && !__asan_is_valid_timespec(rem))))) {
rc = efault();
@ -48,9 +47,8 @@ noinstrument int nanosleep(const struct timespec *req, struct timespec *rem) {
rc = sys_nanosleep_nt(req, rem);
}
if (!__time_critical) {
POLLTRACE("nanosleep(%s, [%s]) → %d% m",
DescribeTimespec(buf[0], sizeof(buf[0]), rc, req),
DescribeTimespec(buf[1], sizeof(buf[1]), rc, rem), rc);
POLLTRACE("nanosleep(%s, [%s]) → %d% m", DescribeTimespec(rc, req),
DescribeTimespec(rc, rem), rc);
}
return rc;
}

View file

@ -16,6 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/assert.h"
#include "libc/bits/bits.h"
#include "libc/bits/initializer.internal.h"
#include "libc/bits/safemacros.internal.h"
@ -44,10 +45,10 @@ static long double GetTimeSample(void) {
uint64_t tick1, tick2;
long double time1, time2;
sched_yield();
time1 = dtime(CLOCK_MONOTONIC_FAST);
time1 = dtime(CLOCK_REALTIME_FAST);
tick1 = rdtsc();
nanosleep(&(struct timespec){0, 1000000}, NULL);
time2 = dtime(CLOCK_MONOTONIC_FAST);
time2 = dtime(CLOCK_REALTIME_FAST);
tick2 = rdtsc();
return (time2 - time1) * 1e9 / MAX(1, tick2 - tick1);
}
@ -75,13 +76,13 @@ static long double MeasureNanosPerCycle(void) {
void RefreshTime(void) {
struct Now now;
now.cpn = MeasureNanosPerCycle();
now.r0 = dtime(CLOCK_REALTIME);
now.r0 = dtime(CLOCK_REALTIME_FAST);
now.k0 = rdtsc();
memcpy(&g_now, &now, sizeof(now));
}
static long double nowl_sys(void) {
return dtime(CLOCK_REALTIME);
return dtime(CLOCK_REALTIME_FAST);
}
static long double nowl_art(void) {
@ -92,7 +93,8 @@ static long double nowl_art(void) {
static long double nowl_vdso(void) {
long double secs;
struct timespec tv;
__gettime(CLOCK_REALTIME, &tv);
assert(__gettime);
__gettime(CLOCK_REALTIME_FAST, &tv);
secs = tv.tv_nsec;
secs *= 1 / 1e9L;
secs += tv.tv_sec;

View file

@ -24,7 +24,6 @@
#include "libc/calls/syscall-nt.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/fmt/magnumstrs.internal.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/log/log.h"
@ -52,7 +51,6 @@
int openat(int dirfd, const char *file, int flags, ...) {
int rc;
va_list va;
char buf[12];
unsigned mode;
struct ZiposUri zipname;
va_start(va, flags);
@ -80,7 +78,7 @@ int openat(int dirfd, const char *file, int flags, ...) {
} else {
rc = efault();
}
STRACE("openat(%s, %#s, %s, %#o) → %d% m", DescribeDirfd(buf, dirfd), file,
STRACE("openat(%s, %#s, %s, %#o) → %d% m", DescribeDirfd(dirfd), file,
DescribeOpenFlags(flags), (flags & (O_CREAT | O_TMPFILE)) ? mode : 0,
rc);
return rc;

View file

@ -89,13 +89,11 @@ int poll(struct pollfd *fds, size_t nfds, int timeout_ms) {
(IsAsan() && !__asan_is_valid(fds, nfds * sizeof(struct pollfd)))) {
kprintf("%p", fds);
} else {
char flagbuf[2][64];
kprintf("[{");
for (i = 0; i < MIN(5, nfds); ++i) {
kprintf(
"%s{%d, %s, %s}", i ? ", " : "", fds[i].fd,
DescribePollFlags(flagbuf[0], sizeof(flagbuf[0]), fds[i].events),
DescribePollFlags(flagbuf[1], sizeof(flagbuf[1]), fds[i].revents));
kprintf("%s{%d, %s, %s}", i ? ", " : "", fds[i].fd,
DescribePollFlags(fds[i].events),
DescribePollFlags(fds[i].revents));
}
kprintf("%s}]", i == 5 ? "..." : "");
}

View file

@ -19,22 +19,10 @@
#include "libc/calls/calls.h"
#include "libc/calls/strace.internal.h"
#include "libc/errno.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/sysv/consts/pr.h"
#include "libc/sysv/errfuns.h"
static const char *DescribePrctlOperation(int x) {
switch (x) {
case PR_SET_NO_NEW_PRIVS:
return "PR_SET_NO_NEW_PRIVS";
case PR_SET_SECCOMP:
return "PR_SET_SECCOMP";
case PR_GET_SECCOMP:
return "PR_GET_SECCOMP";
default:
return "PRCTL_???";
}
}
/**
* Tunes process on Linux.
*

View file

@ -45,7 +45,6 @@
* @asyncsignalsafe
*/
ssize_t readlinkat(int dirfd, const char *path, char *buf, size_t bufsiz) {
char sb[12];
ssize_t bytes;
if ((IsAsan() && !__asan_is_valid(buf, bufsiz)) || (bufsiz && !buf)) {
bytes = efault();
@ -58,7 +57,7 @@ ssize_t readlinkat(int dirfd, const char *path, char *buf, size_t bufsiz) {
} else {
bytes = sys_readlinkat_nt(dirfd, path, buf, bufsiz);
}
STRACE("readlinkat(%s, %#s, [%#.*s]) → %d% m", DescribeDirfd(sb, dirfd), path,
STRACE("readlinkat(%s, %#s, [%#.*s]) → %d% m", DescribeDirfd(dirfd), path,
MAX(0, bytes), buf, bytes);
return bytes;
}

View file

@ -46,7 +46,6 @@
int renameat(int olddirfd, const char *oldpath, int newdirfd,
const char *newpath) {
int rc;
char buf[2][12];
if (IsAsan() &&
(!__asan_is_valid(oldpath, 1) || !__asan_is_valid(newpath, 1))) {
rc = efault();
@ -59,7 +58,7 @@ int renameat(int olddirfd, const char *oldpath, int newdirfd,
} else {
rc = sys_renameat_nt(olddirfd, oldpath, newdirfd, newpath);
}
STRACE("renameat(%s, %#s, %s, %#s) → %d% m", DescribeDirfd(buf[0], olddirfd),
oldpath, DescribeDirfd(buf[1], newdirfd), newpath, rc);
STRACE("renameat(%s, %#s, %s, %#s) → %d% m", DescribeDirfd(olddirfd), oldpath,
DescribeDirfd(newdirfd), newpath, rc);
return rc;
}

View file

@ -19,6 +19,8 @@
#include "libc/assert.h"
#include "libc/calls/internal.h"
#include "libc/dce.h"
#include "libc/intrin/spinlock.h"
#include "libc/nexgen32e/threaded.h"
#include "libc/rand/lcg.internal.h"
/**
@ -33,9 +35,12 @@
textwindows int __sample_pids(int pids[hasatleast 64],
int64_t handles[hasatleast 64],
bool exploratory) {
static char lock;
static uint64_t rando = 1;
uint32_t i, j, base, count;
if (__threaded) _spinlock(&lock);
base = KnuthLinearCongruentialGenerator(&rando) >> 32;
_spunlock(&lock);
for (count = i = 0; i < g_fds.n; ++i) {
j = (base + i) % g_fds.n;
if (g_fds.p[j].kind == kFdProcess && (!exploratory || !g_fds.p[j].zombie)) {

View file

@ -25,21 +25,6 @@
#include "libc/sysv/consts/pr.h"
#include "libc/sysv/errfuns.h"
static const char *DescribeSeccompOperation(int x) {
switch (x) {
case SECCOMP_SET_MODE_STRICT:
return "SECCOMP_SET_MODE_STRICT";
case SECCOMP_SET_MODE_FILTER:
return "SECCOMP_SET_MODE_FILTER";
case SECCOMP_GET_ACTION_AVAIL:
return "SECCOMP_GET_ACTION_AVAIL";
case SECCOMP_GET_NOTIF_SIZES:
return "SECCOMP_GET_NOTIF_SIZES";
default:
return "SECCOMP_???";
}
}
/**
* Tunes Linux security policy.
*

View file

@ -66,7 +66,6 @@
*/
int setrlimit(int resource, const struct rlimit *rlim) {
int rc;
char buf[64];
if (resource == 127) {
rc = einval();
} else if (!rlim || (IsAsan() && !__asan_is_valid(rlim, sizeof(*rlim)))) {
@ -84,6 +83,6 @@ int setrlimit(int resource, const struct rlimit *rlim) {
rc = einval();
}
STRACE("setrlimit(%s, %s) → %d% m", DescribeRlimitName(resource),
DescribeRlimit(buf, sizeof(buf), 0, rlim), rc);
DescribeRlimit(0, rlim), rc);
return rc;
}

View file

@ -444,7 +444,6 @@ static int __sigaction(int sig, const struct sigaction *act,
*/
int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact) {
int rc;
char buf[2][128];
if (sig == SIGKILL || sig == SIGSTOP) {
rc = einval();
} else {
@ -452,8 +451,7 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact) {
rc = __sigaction(sig, act, oldact);
__sig_unlock();
}
STRACE("sigaction(%G, %s, [%s]) → %d% m", sig,
DescribeSigaction(buf[0], sizeof(buf[0]), 0, act),
DescribeSigaction(buf[1], sizeof(buf[1]), rc, oldact), rc);
STRACE("sigaction(%G, %s, [%s]) → %d% m", sig, DescribeSigaction(0, act),
DescribeSigaction(rc, oldact), rc);
return rc;
}

View file

@ -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 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/calls/struct/sigset.h"
#include "libc/sysv/errfuns.h"
/**
* Adds signal to set.
*
* @return 0 on success, or -1 w/ errno
* @raises EINVAL if `1 sig NSIG` isn't the case
* @asyncsignalsafe
*/
int sigaddset(sigset_t *set, int sig) {
_Static_assert(sizeof(set->__bits[0]) * CHAR_BIT == 64, "");
if (1 <= sig && sig <= NSIG) {
set->__bits[(sig - 1) >> 6] |= 1ull << ((sig - 1) & 63);
return 0;
} else {
return einval();
}
}

View file

@ -80,7 +80,6 @@ int sigaltstack(const struct sigaltstack *neu, struct sigaltstack *old) {
int rc;
void *b;
const void *a;
char buf[2][128];
struct sigaltstack_bsd bsd;
if (IsAsan() && ((old && __asan_check(old, sizeof(*old)).kind) ||
(neu && (__asan_check(neu, sizeof(*neu)).kind ||
@ -114,8 +113,7 @@ int sigaltstack(const struct sigaltstack *neu, struct sigaltstack *old) {
} else {
rc = enosys();
}
STRACE("sigaltstack(%s, [%s]) → %d% m",
DescribeSigaltstk(buf[0], sizeof(buf[0]), 0, neu),
DescribeSigaltstk(buf[0], sizeof(buf[0]), 0, old), rc);
STRACE("sigaltstack(%s, [%s]) → %d% m", DescribeSigaltstk(0, neu),
DescribeSigaltstk(0, old), rc);
return rc;
}

View file

@ -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 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/calls/struct/sigset.h"
#include "libc/sysv/errfuns.h"
/**
* Removes signal from set.
*
* @return 0 on success, or -1 w/ errno
* @raises EINVAL if `1 sig NSIG` isn't the case
* @asyncsignalsafe
*/
int sigdelset(sigset_t *set, int sig) {
_Static_assert(sizeof(set->__bits[0]) * CHAR_BIT == 64, "");
if (1 <= sig && sig <= NSIG) {
set->__bits[(sig - 1) >> 6] &= ~(1ull << ((sig - 1) & 63));
return 0;
} else {
return einval();
}
}

View file

@ -1,31 +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 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/calls/struct/sigset.h"
#include "libc/str/str.h"
/**
* Removes all signals from set.
*
* @return 0 on success, or -1 w/ errno
* @asyncsignalsafe
*/
int sigemptyset(sigset_t *set) {
bzero(set->__bits, sizeof(set->__bits));
return 0;
}

View file

@ -1,32 +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 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/calls/struct/sigset.h"
#include "libc/str/str.h"
/**
* Adds all signals to set.
*
* @return 0 on success, or -1 w/ errno
* @asyncsignalsafe
* @vforksafe
*/
int sigfillset(sigset_t *set) {
memset(set->__bits, -1, sizeof(set->__bits));
return 0;
}

View file

@ -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 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/calls/struct/sigset.h"
#include "libc/sysv/errfuns.h"
/**
* Returns true if signal is member of set.
*
* @return 1 if set, 0 if not set, or -1 w/ errno
* @raises EINVAL if `1 sig NSIG` isn't the case
* @asyncsignalsafe
* @vforksafe
*/
int sigismember(const sigset_t *set, int sig) {
_Static_assert(sizeof(set->__bits[0]) * CHAR_BIT == 64, "");
if (1 <= sig && sig <= NSIG) {
return !!(set->__bits[(sig - 1) >> 6] & (1ull << ((sig - 1) & 63)));
} else {
return einval();
}
}

View file

@ -32,14 +32,6 @@
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/errfuns.h"
static const char *DescribeHow(char buf[12], int how) {
if (how == SIG_BLOCK) return "SIG_BLOCK";
if (how == SIG_UNBLOCK) return "SIG_UNBLOCK";
if (how == SIG_SETMASK) return "SIG_SETMASK";
FormatInt32(buf, how);
return buf;
}
/**
* Changes signal blocking state of calling thread, e.g.:
*
@ -58,8 +50,6 @@ static const char *DescribeHow(char buf[12], int how) {
*/
int sigprocmask(int how, const sigset_t *opt_set, sigset_t *opt_out_oldset) {
sigset_t old;
char howbuf[12];
char buf[2][41];
int res, rc, arg1;
const sigset_t *arg2;
sigemptyset(&old);
@ -77,8 +67,7 @@ int sigprocmask(int how, const sigset_t *opt_set, sigset_t *opt_out_oldset) {
if (rc != -1 && opt_out_oldset) {
*opt_out_oldset = old;
}
STRACE("sigprocmask(%s, %s, [%s]) → %d% m", DescribeHow(howbuf, how),
DescribeSigset(buf[0], sizeof(buf[0]), 0, opt_set),
DescribeSigset(buf[1], sizeof(buf[1]), rc, opt_out_oldset), rc);
STRACE("sigprocmask(%s, %s, [%s]) → %d% m", DescribeHow(how),
DescribeSigset(0, opt_set), DescribeSigset(rc, opt_out_oldset), rc);
return rc;
}

View file

@ -44,10 +44,9 @@
*/
int sigsuspend(const sigset_t *ignore) {
int rc;
char buf[41];
long ms, totoms;
sigset_t save, mask, *arg;
STRACE("sigsuspend(%s) → ...", DescribeSigset(buf, sizeof(buf), 0, ignore));
STRACE("sigsuspend(%s) → ...", DescribeSigset(0, ignore));
if (IsAsan() && ignore && !__asan_is_valid(ignore, sizeof(*ignore))) {
rc = efault();
} else if (IsXnu() || IsOpenbsd()) {

View file

@ -41,7 +41,6 @@
*/
int symlinkat(const char *target, int newdirfd, const char *linkpath) {
int rc;
char buf[12];
if (IsAsan() &&
(!__asan_is_valid(target, 1) || !__asan_is_valid(linkpath, 1))) {
rc = efault();
@ -51,7 +50,7 @@ int symlinkat(const char *target, int newdirfd, const char *linkpath) {
} else {
rc = sys_symlinkat_nt(target, newdirfd, linkpath);
}
STRACE("symlinkat(%#s, %s, %#s) → %d% m", target,
DescribeDirfd(buf, newdirfd), linkpath);
STRACE("symlinkat(%#s, %s, %#s) → %d% m", target, DescribeDirfd(newdirfd),
linkpath);
return rc;
}

View file

@ -40,7 +40,6 @@
*/
int unlinkat(int dirfd, const char *path, int flags) {
int rc;
char buf[12];
if (IsAsan() && !__asan_is_valid(path, 1)) {
rc = efault();
} else if (weaken(__zipos_notat) && (rc = __zipos_notat(dirfd, path)) == -1) {
@ -50,7 +49,7 @@ int unlinkat(int dirfd, const char *path, int flags) {
} else {
rc = sys_unlinkat_nt(dirfd, path, flags);
}
STRACE("unlinkat(%s, %#s, %#b) → %d% m", DescribeDirfd(buf, dirfd), path,
flags, rc);
STRACE("unlinkat(%s, %#s, %#b) → %d% m", DescribeDirfd(dirfd), path, flags,
rc);
return rc;
}

View file

@ -54,7 +54,6 @@
int utimensat(int dirfd, const char *path, const struct timespec ts[2],
int flags) {
int rc;
char buf[12];
if (IsAsan() && ((dirfd == AT_FDCWD && !__asan_is_valid(path, 1)) ||
(ts && (!__asan_is_valid_timespec(ts + 0) ||
!__asan_is_valid_timespec(ts + 1))))) {
@ -72,11 +71,11 @@ int utimensat(int dirfd, const char *path, const struct timespec ts[2],
}
if (ts) {
STRACE("utimensat(%s, %#s, {{%,ld, %,ld}, {%,ld, %,ld}}, %#b) → %d% m",
DescribeDirfd(buf, dirfd), path, ts[0].tv_sec, ts[0].tv_nsec,
DescribeDirfd(dirfd), path, ts[0].tv_sec, ts[0].tv_nsec,
ts[1].tv_sec, ts[1].tv_nsec, flags, rc);
} else {
STRACE("utimensat(%s, %#s, 0, %#b) → %d% m", DescribeDirfd(buf, dirfd),
path, flags, rc);
STRACE("utimensat(%s, %#s, 0, %#b) → %d% m", DescribeDirfd(dirfd), path,
flags, rc);
}
return rc;
}