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

@ -61,7 +61,6 @@
SHELL = build/bootstrap/cocmd.com SHELL = build/bootstrap/cocmd.com
HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 win7 win10 xnu HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 win7 win10 xnu
#SANITY := $(shell build/sanitycheck $$PPID)
.SUFFIXES: .SUFFIXES:
.DELETE_ON_ERROR: .DELETE_ON_ERROR:

View file

@ -42,9 +42,9 @@ bash -c './hello.com' # zsh/fish workaround (we patched them in 2021)
Since we used the `ape-no-modify-self.o` bootloader (rather than Since we used the `ape-no-modify-self.o` bootloader (rather than
`ape.o`) your executable will not modify itself when it's run. What `ape.o`) your executable will not modify itself when it's run. What
it'll instead do, is extract a 4kb program to `${TMPDIR:-/tmp}` that it'll instead do, is extract a 4kb program to `${TMPDIR:-${HOME:-.}}`
maps your program into memory without needing to copy it. It's possible that maps your program into memory without needing to copy it. It's
to install the APE loader systemwide as follows. possible to install the APE loader systemwide as follows.
```sh ```sh
# (1) linux systems that want binfmt_misc # (1) linux systems that want binfmt_misc

View file

@ -63,7 +63,7 @@ PKG = build/bootstrap/package.com
MKDEPS = build/bootstrap/mkdeps.com MKDEPS = build/bootstrap/mkdeps.com
ZIPOBJ = build/bootstrap/zipobj.com ZIPOBJ = build/bootstrap/zipobj.com
MKDIR = build/bootstrap/mkdir.com -p MKDIR = build/bootstrap/mkdir.com -p
COMPILE = build/bootstrap/compile.com -V9 $(QUOTA) COMPILE = build/bootstrap/compile.com -V9 -P4096 $(QUOTA)
COMMA := , COMMA := ,
PWD := $(shell build/bootstrap/pwd.com) PWD := $(shell build/bootstrap/pwd.com)

View file

@ -3,7 +3,8 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0) #if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_ COSMOPOLITAN_C_START_
void __assert_fail(const char *, const char *, int) hidden wontreturn relegated; extern bool __assert_disable;
void __assert_fail(const char *, const char *, int) hidden relegated;
#ifdef NDEBUG #ifdef NDEBUG
#define assert(EXPR) ((void)0) #define assert(EXPR) ((void)0)

View file

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

View file

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

View file

@ -16,10 +16,13 @@
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/bits/likely.h"
#include "libc/calls/strace.internal.h" #include "libc/calls/strace.internal.h"
#include "libc/calls/syscall-sysv.internal.h" #include "libc/calls/syscall-sysv.internal.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/intrin/describeflags.internal.h" #include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/spinlock.h"
#include "libc/nt/runtime.h" #include "libc/nt/runtime.h"
#include "libc/runtime/directmap.internal.h" #include "libc/runtime/directmap.internal.h"
#include "libc/runtime/memtrack.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, struct DirectMap sys_mmap(void *addr, size_t size, int prot, int flags, int fd,
int64_t off) { int64_t off) {
/* asan runtime depends on this function */
struct DirectMap d; struct DirectMap d;
if (!IsWindows() && !IsMetal()) { if (!IsWindows() && !IsMetal()) {
d.addr = __sys_mmap(addr, size, prot, flags, fd, off, off); 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 faccessat(int dirfd, const char *path, int mode, uint32_t flags) {
int rc; int rc;
char buf[12];
if (IsAsan() && !__asan_is_valid(path, 1)) { if (IsAsan() && !__asan_is_valid(path, 1)) {
rc = efault(); rc = efault();
} else if (weaken(__zipos_notat) && } else if (weaken(__zipos_notat) &&
@ -52,7 +51,7 @@ int faccessat(int dirfd, const char *path, int mode, uint32_t flags) {
} else { } else {
rc = sys_faccessat_nt(dirfd, path, mode, flags); rc = sys_faccessat_nt(dirfd, path, mode, flags);
} }
STRACE("faccessat(%s, %#s, %#o, %#x) → %d% m", DescribeDirfd(buf, dirfd), STRACE("faccessat(%s, %#s, %#o, %#x) → %d% m", DescribeDirfd(dirfd), path,
path, mode, flags, rc); mode, flags, rc);
return rc; return rc;
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -24,7 +24,6 @@
#include "libc/calls/syscall-nt.internal.h" #include "libc/calls/syscall-nt.internal.h"
#include "libc/calls/syscall-sysv.internal.h" #include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/fmt/magnumstrs.internal.h"
#include "libc/intrin/asan.internal.h" #include "libc/intrin/asan.internal.h"
#include "libc/intrin/describeflags.internal.h" #include "libc/intrin/describeflags.internal.h"
#include "libc/log/log.h" #include "libc/log/log.h"
@ -52,7 +51,6 @@
int openat(int dirfd, const char *file, int flags, ...) { int openat(int dirfd, const char *file, int flags, ...) {
int rc; int rc;
va_list va; va_list va;
char buf[12];
unsigned mode; unsigned mode;
struct ZiposUri zipname; struct ZiposUri zipname;
va_start(va, flags); va_start(va, flags);
@ -80,7 +78,7 @@ int openat(int dirfd, const char *file, int flags, ...) {
} else { } else {
rc = efault(); 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, DescribeOpenFlags(flags), (flags & (O_CREAT | O_TMPFILE)) ? mode : 0,
rc); rc);
return 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)))) { (IsAsan() && !__asan_is_valid(fds, nfds * sizeof(struct pollfd)))) {
kprintf("%p", fds); kprintf("%p", fds);
} else { } else {
char flagbuf[2][64];
kprintf("[{"); kprintf("[{");
for (i = 0; i < MIN(5, nfds); ++i) { for (i = 0; i < MIN(5, nfds); ++i) {
kprintf( kprintf("%s{%d, %s, %s}", i ? ", " : "", fds[i].fd,
"%s{%d, %s, %s}", i ? ", " : "", fds[i].fd, DescribePollFlags(fds[i].events),
DescribePollFlags(flagbuf[0], sizeof(flagbuf[0]), fds[i].events), DescribePollFlags(fds[i].revents));
DescribePollFlags(flagbuf[1], sizeof(flagbuf[1]), fds[i].revents));
} }
kprintf("%s}]", i == 5 ? "..." : ""); kprintf("%s}]", i == 5 ? "..." : "");
} }

View file

@ -19,22 +19,10 @@
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/strace.internal.h" #include "libc/calls/strace.internal.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/sysv/consts/pr.h" #include "libc/sysv/consts/pr.h"
#include "libc/sysv/errfuns.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. * Tunes process on Linux.
* *

View file

@ -45,7 +45,6 @@
* @asyncsignalsafe * @asyncsignalsafe
*/ */
ssize_t readlinkat(int dirfd, const char *path, char *buf, size_t bufsiz) { ssize_t readlinkat(int dirfd, const char *path, char *buf, size_t bufsiz) {
char sb[12];
ssize_t bytes; ssize_t bytes;
if ((IsAsan() && !__asan_is_valid(buf, bufsiz)) || (bufsiz && !buf)) { if ((IsAsan() && !__asan_is_valid(buf, bufsiz)) || (bufsiz && !buf)) {
bytes = efault(); bytes = efault();
@ -58,7 +57,7 @@ ssize_t readlinkat(int dirfd, const char *path, char *buf, size_t bufsiz) {
} else { } else {
bytes = sys_readlinkat_nt(dirfd, path, buf, bufsiz); 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); MAX(0, bytes), buf, bytes);
return bytes; return bytes;
} }

View file

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

View file

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

View file

@ -66,7 +66,6 @@
*/ */
int setrlimit(int resource, const struct rlimit *rlim) { int setrlimit(int resource, const struct rlimit *rlim) {
int rc; int rc;
char buf[64];
if (resource == 127) { if (resource == 127) {
rc = einval(); rc = einval();
} else if (!rlim || (IsAsan() && !__asan_is_valid(rlim, sizeof(*rlim)))) { } else if (!rlim || (IsAsan() && !__asan_is_valid(rlim, sizeof(*rlim)))) {
@ -84,6 +83,6 @@ int setrlimit(int resource, const struct rlimit *rlim) {
rc = einval(); rc = einval();
} }
STRACE("setrlimit(%s, %s) → %d% m", DescribeRlimitName(resource), STRACE("setrlimit(%s, %s) → %d% m", DescribeRlimitName(resource),
DescribeRlimit(buf, sizeof(buf), 0, rlim), rc); DescribeRlimit(0, rlim), rc);
return 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 sigaction(int sig, const struct sigaction *act, struct sigaction *oldact) {
int rc; int rc;
char buf[2][128];
if (sig == SIGKILL || sig == SIGSTOP) { if (sig == SIGKILL || sig == SIGSTOP) {
rc = einval(); rc = einval();
} else { } else {
@ -452,8 +451,7 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact) {
rc = __sigaction(sig, act, oldact); rc = __sigaction(sig, act, oldact);
__sig_unlock(); __sig_unlock();
} }
STRACE("sigaction(%G, %s, [%s]) → %d% m", sig, STRACE("sigaction(%G, %s, [%s]) → %d% m", sig, DescribeSigaction(0, act),
DescribeSigaction(buf[0], sizeof(buf[0]), 0, act), DescribeSigaction(rc, oldact), rc);
DescribeSigaction(buf[1], sizeof(buf[1]), rc, oldact), rc);
return rc; return rc;
} }

View file

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

View file

@ -32,14 +32,6 @@
#include "libc/sysv/consts/sig.h" #include "libc/sysv/consts/sig.h"
#include "libc/sysv/errfuns.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.: * 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) { int sigprocmask(int how, const sigset_t *opt_set, sigset_t *opt_out_oldset) {
sigset_t old; sigset_t old;
char howbuf[12];
char buf[2][41];
int res, rc, arg1; int res, rc, arg1;
const sigset_t *arg2; const sigset_t *arg2;
sigemptyset(&old); 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) { if (rc != -1 && opt_out_oldset) {
*opt_out_oldset = old; *opt_out_oldset = old;
} }
STRACE("sigprocmask(%s, %s, [%s]) → %d% m", DescribeHow(howbuf, how), STRACE("sigprocmask(%s, %s, [%s]) → %d% m", DescribeHow(how),
DescribeSigset(buf[0], sizeof(buf[0]), 0, opt_set), DescribeSigset(0, opt_set), DescribeSigset(rc, opt_out_oldset), rc);
DescribeSigset(buf[1], sizeof(buf[1]), rc, opt_out_oldset), rc);
return rc; return rc;
} }

View file

@ -44,10 +44,9 @@
*/ */
int sigsuspend(const sigset_t *ignore) { int sigsuspend(const sigset_t *ignore) {
int rc; int rc;
char buf[41];
long ms, totoms; long ms, totoms;
sigset_t save, mask, *arg; 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))) { if (IsAsan() && ignore && !__asan_is_valid(ignore, sizeof(*ignore))) {
rc = efault(); rc = efault();
} else if (IsXnu() || IsOpenbsd()) { } else if (IsXnu() || IsOpenbsd()) {

View file

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

View file

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

View file

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

View file

@ -25,11 +25,7 @@ hidden extern const struct MagnumStr kSignalNames[];
hidden extern const struct MagnumStr kSockOptnames[]; hidden extern const struct MagnumStr kSockOptnames[];
hidden extern const struct MagnumStr kTcpOptnames[]; hidden extern const struct MagnumStr kTcpOptnames[];
char *DescribeClockName(int) hidden; char *GetMagnumStr(const struct MagnumStr *, int);
char *DescribeOpenFlags(int) hidden;
char *DescribeSockLevel(int) hidden;
char *DescribeSockOptname(int, int) hidden;
char *GetMagnumStr(const struct MagnumStr *, int) hidden;
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -1308,13 +1308,13 @@ void __asan_map_shadow(uintptr_t p, size_t n) {
size = (size_t)i << 16; size = (size_t)i << 16;
addr = (void *)(intptr_t)((int64_t)((uint64_t)a << 32) >> 16); addr = (void *)(intptr_t)((int64_t)((uint64_t)a << 32) >> 16);
prot = PROT_READ | PROT_WRITE; prot = PROT_READ | PROT_WRITE;
flag = MAP_PRIVATE | MAP_FIXED | *weaken(MAP_ANONYMOUS); flag = MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS;
sm = weaken(sys_mmap)(addr, size, prot, flag, -1, 0); sm = weaken(sys_mmap)(addr, size, prot, flag, -1, 0);
if (sm.addr == MAP_FAILED || if (sm.addr == MAP_FAILED ||
weaken(TrackMemoryInterval)( weaken(TrackMemoryInterval)(m, a, a + i - 1, sm.maphandle,
m, a, a + i - 1, sm.maphandle, PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | *weaken(MAP_ANONYMOUS) | MAP_FIXED, false, false, 0, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
size) == -1) { false, false, 0, size) == -1) {
kprintf("error: could not map asan shadow memory\n"); kprintf("error: could not map asan shadow memory\n");
__asan_die()(); __asan_die()();
__asan_unreachable(); __asan_unreachable();
@ -1379,7 +1379,6 @@ textstartup void __asan_init(int argc, char **argv, char **envp,
} }
REQUIRE(_mmi); REQUIRE(_mmi);
REQUIRE(sys_mmap); REQUIRE(sys_mmap);
REQUIRE(MAP_ANONYMOUS);
REQUIRE(TrackMemoryInterval); REQUIRE(TrackMemoryInterval);
if (weaken(hook_malloc) || weaken(hook_calloc) || weaken(hook_realloc) || if (weaken(hook_malloc) || weaken(hook_calloc) || weaken(hook_realloc) ||
weaken(hook_realloc_in_place) || weaken(hook_free) || weaken(hook_realloc_in_place) || weaken(hook_free) ||

View file

@ -0,0 +1,23 @@
/*-*- 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.
*/
/**
* Disables assert() failures at runtime.
*/
bool __assert_disable;

View file

@ -19,6 +19,7 @@
#include "libc/assert.h" #include "libc/assert.h"
#include "libc/bits/weaken.h" #include "libc/bits/weaken.h"
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/intrin/kprintf.h" #include "libc/intrin/kprintf.h"
#include "libc/intrin/lockcmpxchgp.h" #include "libc/intrin/lockcmpxchgp.h"
#include "libc/log/backtrace.internal.h" #include "libc/log/backtrace.internal.h"
@ -30,32 +31,33 @@
/** /**
* Handles failure of assert() macro. * Handles failure of assert() macro.
*/ */
relegated wontreturn void __assert_fail(const char *expr, const char *file, relegated void __assert_fail(const char *expr, const char *file, int line) {
int line) {
int me, owner; int me, owner;
static int sync; static int sync;
--__strace; if (!__assert_disable) {
--__ftrace; --__strace;
owner = 0; --__ftrace;
me = gettid(); owner = 0;
kprintf("%s:%d: assert(%s) failed (tid %d)\n", file, line, expr, me); me = sys_gettid();
if (_lockcmpxchgp(&sync, &owner, me)) { kprintf("%s:%d: assert(%s) failed (tid %d)\n", file, line, expr, me);
__restore_tty(); if (_lockcmpxchgp(&sync, &owner, me)) {
if (weaken(ShowBacktrace)) { __restore_tty();
weaken(ShowBacktrace)(2, __builtin_frame_address(0)); if (weaken(ShowBacktrace)) {
} else if (weaken(PrintBacktraceUsingSymbols) && weaken(GetSymbolTable)) { weaken(ShowBacktrace)(2, __builtin_frame_address(0));
weaken(PrintBacktraceUsingSymbols)(2, __builtin_frame_address(0), } else if (weaken(PrintBacktraceUsingSymbols) && weaken(GetSymbolTable)) {
weaken(GetSymbolTable)()); weaken(PrintBacktraceUsingSymbols)(2, __builtin_frame_address(0),
weaken(GetSymbolTable)());
} else {
kprintf("can't backtrace b/c `ShowCrashReports` not linked\n");
}
__restorewintty();
_Exit(23);
} else if (owner == me) {
kprintf("assert failed while failing\n");
__restorewintty();
_Exit(24);
} else { } else {
kprintf("can't backtrace b/c `ShowCrashReports` not linked\n"); _Exit1(25);
} }
__restorewintty();
_Exit(23);
} else if (owner == me) {
kprintf("assert failed while failing\n");
__restorewintty();
_Exit(24);
} else {
_Exit1(25);
} }
} }

View file

@ -45,7 +45,7 @@ textwindows int64_t CreateFile(
DescribeNtFileShareFlags(dwShareMode), DescribeNtFileShareFlags(dwShareMode),
DescribeNtSecurityAttributes(opt_lpSecurityAttributes), DescribeNtSecurityAttributes(opt_lpSecurityAttributes),
DescribeNtCreationDisposition(dwCreationDisposition), DescribeNtCreationDisposition(dwCreationDisposition),
DescribeNtFileFlagsAndAttributes(dwFlagsAndAttributes), DescribeNtFileFlagAttr(dwFlagsAndAttributes), opt_hTemplateFile,
opt_hTemplateFile, hHandle); hHandle);
return hHandle; return hHandle;
} }

View file

@ -34,6 +34,6 @@ bool32 CreateSymbolicLink(const char16_t *lpSymlinkFileName,
ok = __imp_CreateSymbolicLinkW(lpSymlinkFileName, lpTargetPathName, dwFlags); ok = __imp_CreateSymbolicLinkW(lpSymlinkFileName, lpTargetPathName, dwFlags);
if (!ok) __winerr(); if (!ok) __winerr();
NTTRACE("CreateSymbolicLink(%#hs, %#hs, %s) → %hhhd% m", lpSymlinkFileName, NTTRACE("CreateSymbolicLink(%#hs, %#hs, %s) → %hhhd% m", lpSymlinkFileName,
lpTargetPathName, DescribeNtSymbolicLinkFlags(dwFlags), ok); lpTargetPathName, DescribeNtSymlinkFlags(dwFlags), ok);
return ok; return ok;
} }

View file

@ -18,18 +18,34 @@
*/ */
#include "libc/fmt/itoa.h" #include "libc/fmt/itoa.h"
#include "libc/fmt/magnumstrs.internal.h" #include "libc/fmt/magnumstrs.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/sysv/consts/sol.h" #include "libc/sysv/consts/sol.h"
static inline char *StpCpy(char *d, const char *s) {
size_t i;
for (i = 0;; ++i) {
if (!(d[i] = s[i])) {
return d + i;
}
}
}
/** /**
* Describes clock_gettime() clock argument. * Describes clock_gettime() clock argument.
*/ */
char *DescribeClockName(int x) { const char *(DescribeClockName)(char buf[32], int x) {
int i; int i;
char *s; char *s, *p;
_Alignas(char) static char buf[32];
if ((s = GetMagnumStr(kClockNames, x))) { if ((s = GetMagnumStr(kClockNames, x))) {
stpcpy(stpcpy(buf, "CLOCK_"), s); p = buf;
*p++ = 'C';
*p++ = 'L';
*p++ = 'O';
*p++ = 'C';
*p++ = 'K';
*p++ = '_';
StpCpy(p, s);
return buf; return buf;
} else { } else {
FormatInt32(buf, x); FormatInt32(buf, x);

View file

@ -20,7 +20,7 @@
#include "libc/intrin/describeflags.internal.h" #include "libc/intrin/describeflags.internal.h"
#include "libc/sysv/consts/at.h" #include "libc/sysv/consts/at.h"
const char *DescribeDirfd(char buf[hasatleast 12], int dirfd) { const char *(DescribeDirfd)(char buf[12], int dirfd) {
if (dirfd == AT_FDCWD) return "AT_FDCWD"; if (dirfd == AT_FDCWD) return "AT_FDCWD";
FormatInt32(buf, dirfd); FormatInt32(buf, dirfd);
return buf; return buf;

View file

@ -19,6 +19,7 @@
#include "libc/intrin/describeflags.internal.h" #include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h" #include "libc/intrin/kprintf.h"
// TODO(jart): Fork this function into ASAN and non-ASAN versions.
const char *DescribeFlags(char *p, size_t n, struct DescribeFlags *d, size_t m, const char *DescribeFlags(char *p, size_t n, struct DescribeFlags *d, size_t m,
const char *prefix, unsigned x) { const char *prefix, unsigned x) {
bool t; bool t;

View file

@ -7,7 +7,10 @@
#include "libc/calls/struct/sigset.h" #include "libc/calls/struct/sigset.h"
#include "libc/calls/struct/stat.h" #include "libc/calls/struct/stat.h"
#include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timespec.h"
#include "libc/mem/alloca.h"
#include "libc/nt/struct/iovec.h"
#include "libc/nt/struct/securityattributes.h" #include "libc/nt/struct/securityattributes.h"
#include "libc/sock/struct/sockaddr.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0) #if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_ COSMOPOLITAN_C_START_
@ -19,39 +22,90 @@ struct thatispacked DescribeFlags {
const char *DescribeFlags(char *, size_t, struct DescribeFlags *, size_t, const char *DescribeFlags(char *, size_t, struct DescribeFlags *, size_t,
const char *, unsigned); const char *, unsigned);
const char *DescribeMapFlags(int); const char *DescribeClockName(char[32], int);
const char *DescribeProtFlags(int); const char *DescribeDirfd(char[12], int);
const char *DescribeRemapFlags(int); const char *DescribeFrame(char[32], int);
const char *DescribeRlimitName(int); const char *DescribeHow(char[12], int);
const char *DescribePersonalityFlags(int); const char *DescribeMapFlags(char[64], int);
const char *DescribeSeccompOperationFlags(int); const char *DescribeMapping(char[8], int, int);
const char *DescribePollFlags(char *, size_t, int); const char *DescribeNtConsoleInFlags(char[256], uint32_t);
const char *DescribeStat(int, const struct stat *); const char *DescribeNtConsoleOutFlags(char[128], uint32_t);
const char *DescribeDirfd(char[hasatleast 12], int);
const char *DescribeSigaction(char *, size_t, int, const struct sigaction *);
const char *DescribeSigaltstk(char *, size_t, int, const struct sigaltstack *);
const char *DescribeSigset(char *, size_t, int, const sigset_t *);
const char *DescribeRlimit(char *, size_t, int, const struct rlimit *);
const char *DescribeTimespec(char *, size_t, int, const struct timespec *);
const char *DescribeNtPageFlags(uint32_t);
const char *DescribeNtStartFlags(uint32_t);
const char *DescribeNtFileMapFlags(uint32_t);
const char *DescribeNtFiletypeFlags(uint32_t);
const char *DescribeNtPipeOpenFlags(uint32_t);
const char *DescribeNtPipeModeFlags(uint32_t);
const char *DescribeNtFileShareFlags(uint32_t);
const char *DescribeNtFileAccessFlags(uint32_t);
const char *DescribeNtSymbolicLinkFlags(uint32_t);
const char *DescribeNtProcessAccessFlags(uint32_t);
const char *DescribeNtMoveFileInputFlags(uint32_t);
const char *DescribeNtCreationDisposition(uint32_t); const char *DescribeNtCreationDisposition(uint32_t);
const char *DescribeNtConsoleModeInputFlags(uint32_t); const char *DescribeNtFileAccessFlags(char[512], uint32_t);
const char *DescribeNtConsoleModeOutputFlags(uint32_t); const char *DescribeNtFileFlagAttr(char[256], uint32_t);
const char *DescribeNtFileFlagsAndAttributes(uint32_t); const char *DescribeNtFileMapFlags(char[64], uint32_t);
const char *DescribeNtFileShareFlags(char[64], uint32_t);
const char *DescribeNtFiletypeFlags(char[64], uint32_t);
const char *DescribeNtMovFileInpFlags(char[256], uint32_t);
const char *DescribeNtPageFlags(char[64], uint32_t);
const char *DescribeNtPipeModeFlags(char[64], uint32_t);
const char *DescribeNtPipeOpenFlags(char[64], uint32_t);
const char *DescribeNtProcAccessFlags(char[256], uint32_t);
const char *DescribeNtSecurityAttributes(struct NtSecurityAttributes *); const char *DescribeNtSecurityAttributes(struct NtSecurityAttributes *);
const char *DescribeNtStartFlags(char[128], uint32_t);
const char *DescribeNtSymlinkFlags(char[64], uint32_t);
const char *DescribeOpenFlags(char[128], int);
const char *DescribePersonalityFlags(char[128], int);
const char *DescribePollFlags(char[64], int);
const char *DescribePrctlOperation(int);
const char *DescribeProtFlags(char[48], int);
const char *DescribeRemapFlags(char[48], int);
const char *DescribeRlimit(char[64], int, const struct rlimit *);
const char *DescribeRlimitName(char[12], int);
const char *DescribeSeccompOperation(int);
const char *DescribeSigaction(char[128], int, const struct sigaction *);
const char *DescribeSigaltstk(char[128], int, const struct sigaltstack *);
const char *DescribeSigset(char[64], int, const sigset_t *);
const char *DescribeSockLevel(char[12], int);
const char *DescribeSockOptname(char[32], int, int);
const char *DescribeSockaddr(char[128], const struct sockaddr *, size_t);
const char *DescribeSocketFamily(char[12], int);
const char *DescribeSocketProtocol(char[12], int);
const char *DescribeSocketType(char[64], int);
const char *DescribeStat(char[300], int, const struct stat *);
const char *DescribeTimespec(char[45], int, const struct timespec *);
void DescribeIov(const struct iovec *, int, ssize_t); void DescribeIov(const struct iovec *, int, ssize_t);
void DescribeIovNt(const struct NtIovec *, uint32_t, ssize_t);
#define DescribeClockName(x) DescribeClockName(alloca(32), x)
#define DescribeDirfd(dirfd) DescribeDirfd(alloca(12), dirfd)
#define DescribeFrame(x) DescribeFrame(alloca(32), x)
#define DescribeHow(x) DescribeHow(alloca(12), x)
#define DescribeMapFlags(dirfd) DescribeMapFlags(alloca(64), dirfd)
#define DescribeMapping(x, y) DescribeMapping(alloca(8), x, y)
#define DescribeNtConsoleInFlags(x) DescribeNtConsoleInFlags(alloca(256), x)
#define DescribeNtConsoleOutFlags(x) DescribeNtConsoleOutFlags(alloca(128), x)
#define DescribeNtFileAccessFlags(x) DescribeNtFileAccessFlags(alloca(512), x)
#define DescribeNtFileFlagAttr(x) DescribeNtFileFlagAttr(alloca(256), x)
#define DescribeNtFileMapFlags(x) DescribeNtFileMapFlags(alloca(64), x)
#define DescribeNtFileShareFlags(x) DescribeNtFileShareFlags(alloca(64), x)
#define DescribeNtFiletypeFlags(x) DescribeNtFiletypeFlags(alloca(64), x)
#define DescribeNtMovFileInpFlags(x) DescribeNtMovFileInpFlags(alloca(256), x)
#define DescribeNtPageFlags(x) DescribeNtPageFlags(alloca(64), x)
#define DescribeNtPipeModeFlags(x) DescribeNtPipeModeFlags(alloca(64), x)
#define DescribeNtPipeOpenFlags(x) DescribeNtPipeOpenFlags(alloca(64), x)
#define DescribeNtProcAccessFlags(x) DescribeNtProcAccessFlags(alloca(256), x)
#define DescribeNtStartFlags(x) DescribeNtStartFlags(alloca(128), x)
#define DescribeNtSymlinkFlags(x) DescribeNtSymlinkFlags(alloca(64), x)
#define DescribeOpenFlags(x) DescribeOpenFlags(alloca(128), x)
#define DescribePersonalityFlags(p) DescribePersonalityFlags(alloca(128), p)
#define DescribePollFlags(p) DescribePollFlags(alloca(64), p)
#define DescribeProtFlags(dirfd) DescribeProtFlags(alloca(48), dirfd)
#define DescribeRemapFlags(dirfd) DescribeRemapFlags(alloca(48), dirfd)
#define DescribeRlimit(rc, rl) DescribeRlimit(alloca(64), rc, rl)
#define DescribeRlimitName(rl) DescribeRlimitName(alloca(12), rl)
#define DescribeSigaction(rc, sa) DescribeSigaction(alloca(128), rc, sa)
#define DescribeSigaltstk(rc, ss) DescribeSigaltstk(alloca(128), rc, ss)
#define DescribeSigset(rc, ss) DescribeSigset(alloca(64), rc, ss)
#define DescribeSockLevel(x) DescribeSockLevel(alloca(12), x)
#define DescribeSockOptname(x, y) DescribeSockOptname(alloca(32), x, y)
#define DescribeSockaddr(sa, sz) DescribeSockaddr(alloca(128), sa, sz)
#define DescribeSocketFamily(x) DescribeSocketFamily(alloca(12), x)
#define DescribeSocketProtocol(x) DescribeSocketProtocol(alloca(12), x)
#define DescribeSocketType(x) DescribeSocketType(alloca(64), x)
#define DescribeStat(rc, st) DescribeStat(alloca(300), rc, st)
#define DescribeTimespec(rc, ts) DescribeTimespec(alloca(45), rc, ts)
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -16,6 +16,7 @@
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/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h" #include "libc/intrin/kprintf.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/runtime/memtrack.internal.h" #include "libc/runtime/memtrack.internal.h"
@ -25,12 +26,11 @@
#define UNSHADOW(x) ((int64_t)(MAX(0, (x)-0x7fff8000)) << 3) #define UNSHADOW(x) ((int64_t)(MAX(0, (x)-0x7fff8000)) << 3)
#define FRAME(x) ((int)((x) >> 16)) #define FRAME(x) ((int)((x) >> 16))
noasan const char *DescribeFrame(int x) { const char *(DescribeFrame)(char buf[32], int x) {
/* asan runtime depends on this function */ /* asan runtime depends on this function */
char *p; char *p;
static char buf[32];
if (IsShadowFrame(x)) { if (IsShadowFrame(x)) {
ksnprintf(buf, sizeof(buf), " shadow=%.8x", FRAME(UNSHADOW(ADDR(x)))); ksnprintf(buf, 32, " shadow=%.8x", FRAME(UNSHADOW(ADDR(x))));
return buf; return buf;
return " shadow "; return " shadow ";
} else if (IsAutoFrame(x)) { } else if (IsAutoFrame(x)) {

29
libc/intrin/describehow.c Normal file
View file

@ -0,0 +1,29 @@
/*-*- 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/intrin/describeflags.internal.h"
#include "libc/sysv/consts/sig.h"
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;
}

View file

@ -0,0 +1,42 @@
/*-*- 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/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/macros.internal.h"
#include "libc/nt/winsock.h"
void DescribeIovNt(const struct NtIovec *iov, uint32_t iovlen, ssize_t rem) {
int i;
if ((!IsAsan() && kisdangerous(iov)) ||
(IsAsan() && !__asan_is_valid(iov, iovlen * sizeof(struct NtIovec)))) {
kprintf("%p", iov);
return;
}
kprintf("{");
for (i = 0; rem && i < MIN(5, iovlen); ++i) {
kprintf("%s{%#.*hhs%s, %'zu}", i ? ", " : "",
MAX(0, MIN(40, MIN(rem, iov[i].len))), iov[i].buf,
MAX(0, MIN(40, MIN(rem, iov[i].len))) < iov[i].len ? "..." : "",
iov[i].len);
rem -= iov[i].len;
}
kprintf("%s}", iovlen > 5 ? "..." : "");
}

View file

@ -22,8 +22,7 @@
#include "libc/sysv/consts/map.h" #include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/prot.h" #include "libc/sysv/consts/prot.h"
const char *DescribeMapFlags(int x) { const char *(DescribeMapFlags)(char buf[64], int x) {
_Alignas(char) static char mapflags[256];
const struct DescribeFlags kMapFlags[] = { const struct DescribeFlags kMapFlags[] = {
{MAP_STACK, "STACK"}, // order matters {MAP_STACK, "STACK"}, // order matters
{MAP_PRIVATE, "PRIVATE"}, // {MAP_PRIVATE, "PRIVATE"}, //
@ -39,6 +38,5 @@ const char *DescribeMapFlags(int x) {
{MAP_NONBLOCK, "NONBLOCK"}, // {MAP_NONBLOCK, "NONBLOCK"}, //
{MAP_POPULATE, "POPULATE"}, // {MAP_POPULATE, "POPULATE"}, //
}; };
return DescribeFlags(mapflags, sizeof(mapflags), kMapFlags, return DescribeFlags(buf, 64, kMapFlags, ARRAYLEN(kMapFlags), "MAP_", x);
ARRAYLEN(kMapFlags), "MAP_", x);
} }

View file

@ -16,11 +16,12 @@
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/intrin/describeflags.internal.h"
#include "libc/runtime/memtrack.internal.h" #include "libc/runtime/memtrack.internal.h"
#include "libc/sysv/consts/map.h" #include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/prot.h" #include "libc/sysv/consts/prot.h"
static noasan char DescribeMapType(int flags) { static char DescribeMapType(int flags) {
switch (flags & MAP_TYPE) { switch (flags & MAP_TYPE) {
case MAP_FILE: case MAP_FILE:
return 'f'; return 'f';
@ -35,7 +36,7 @@ static noasan char DescribeMapType(int flags) {
} }
} }
noasan char *DescribeProt(int prot, char p[hasatleast 4]) { char *DescribeProt(char p[4], int prot) {
p[0] = (prot & PROT_READ) ? 'r' : '-'; p[0] = (prot & PROT_READ) ? 'r' : '-';
p[1] = (prot & PROT_WRITE) ? 'w' : '-'; p[1] = (prot & PROT_WRITE) ? 'w' : '-';
p[2] = (prot & PROT_EXEC) ? 'x' : '-'; p[2] = (prot & PROT_EXEC) ? 'x' : '-';
@ -43,9 +44,9 @@ noasan char *DescribeProt(int prot, char p[hasatleast 4]) {
return p; return p;
} }
noasan char *DescribeMapping(int prot, int flags, char p[hasatleast 8]) { const char *(DescribeMapping)(char p[8], int prot, int flags) {
/* asan runtime depends on this function */ /* asan runtime depends on this function */
DescribeProt(prot, p); DescribeProt(p, prot);
p[3] = DescribeMapType(flags); p[3] = DescribeMapType(flags);
p[4] = (flags & MAP_ANONYMOUS) ? 'a' : '-'; p[4] = (flags & MAP_ANONYMOUS) ? 'a' : '-';
p[5] = (flags & MAP_GROWSDOWN) ? 'G' : '-'; p[5] = (flags & MAP_GROWSDOWN) ? 'G' : '-';

View file

@ -33,9 +33,7 @@ static const struct DescribeFlags kConsoleModeInputFlags[] = {
{kNtEnableVirtualTerminalInput, "VirtualTerminalInput"}, // {kNtEnableVirtualTerminalInput, "VirtualTerminalInput"}, //
}; };
const char *DescribeNtConsoleModeInputFlags(uint32_t x) { const char *(DescribeNtConsoleInFlags)(char buf[256], uint32_t x) {
_Alignas(char) static char consolemodeinputflags[256]; return DescribeFlags(buf, 256, kConsoleModeInputFlags,
return DescribeFlags(consolemodeinputflags, sizeof(consolemodeinputflags), ARRAYLEN(kConsoleModeInputFlags), "kNtEnable", x);
kConsoleModeInputFlags, ARRAYLEN(kConsoleModeInputFlags),
"kNtEnable", x);
} }

View file

@ -28,9 +28,7 @@ static const struct DescribeFlags kConsoleModeOutputFlags[] = {
{kNtEnableLvbGridWorldwide, "EnableLvbGridWorldwide"}, // {kNtEnableLvbGridWorldwide, "EnableLvbGridWorldwide"}, //
}; };
const char *DescribeNtConsoleModeOutputFlags(uint32_t x) { const char *(DescribeNtConsoleOutFlags)(char buf[128], uint32_t x) {
_Alignas(char) static char consolemodeoutputflags[128]; return DescribeFlags(buf, 128, kConsoleModeOutputFlags,
return DescribeFlags(consolemodeoutputflags, sizeof(consolemodeoutputflags),
kConsoleModeOutputFlags,
ARRAYLEN(kConsoleModeOutputFlags), "kNt", x); ARRAYLEN(kConsoleModeOutputFlags), "kNt", x);
} }

View file

@ -63,8 +63,7 @@ static const struct DescribeFlags kFileAccessflags[] = {
{kNtTokenAdjustSessionid, "TokenAdjustSessionid"}, // {kNtTokenAdjustSessionid, "TokenAdjustSessionid"}, //
}; };
const char *DescribeNtFileAccessFlags(uint32_t x) { const char *(DescribeNtFileAccessFlags)(char buf[512], uint32_t x) {
_Alignas(char) static char ntfileaccessflags[512]; return DescribeFlags(buf, 512, kFileAccessflags, ARRAYLEN(kFileAccessflags),
return DescribeFlags(ntfileaccessflags, sizeof(ntfileaccessflags), "kNt", x);
kFileAccessflags, ARRAYLEN(kFileAccessflags), "kNt", x);
} }

View file

@ -51,9 +51,8 @@ static const struct DescribeFlags kFileFlags[] = {
{kNtFileFlagFirstPipeInstance, "FlagFirstPipeInstance"}, // {kNtFileFlagFirstPipeInstance, "FlagFirstPipeInstance"}, //
}; };
const char *DescribeNtFileFlagsAndAttributes(uint32_t x) { const char *(DescribeNtFileFlagAttr)(char buf[256], uint32_t x) {
_Alignas(char) static char ntfileflags[256];
if (x == -1u) return "-1u"; if (x == -1u) return "-1u";
return DescribeFlags(ntfileflags, sizeof(ntfileflags), kFileFlags, return DescribeFlags(buf, 256, kFileFlags, ARRAYLEN(kFileFlags), "kNtFile",
ARRAYLEN(kFileFlags), "kNtFile", x); x);
} }

View file

@ -30,8 +30,7 @@ static const struct DescribeFlags kFileMapFlags[] = {
{kNtFileMapLargePages, "LargePages"}, // {kNtFileMapLargePages, "LargePages"}, //
}; };
const char *DescribeNtFileMapFlags(uint32_t x) { const char *(DescribeNtFileMapFlags)(char buf[64], uint32_t x) {
_Alignas(char) static char filemapflags[64]; return DescribeFlags(buf, 64, kFileMapFlags, ARRAYLEN(kFileMapFlags),
return DescribeFlags(filemapflags, sizeof(filemapflags), kFileMapFlags, "kNtFileMap", x);
ARRAYLEN(kFileMapFlags), "kNtFileMap", x);
} }

View file

@ -26,9 +26,7 @@ static const struct DescribeFlags kFileShareflags[] = {
{kNtFileShareDelete, "Delete"}, // {kNtFileShareDelete, "Delete"}, //
}; };
const char *DescribeNtFileShareFlags(uint32_t x) { const char *(DescribeNtFileShareFlags)(char buf[64], uint32_t x) {
_Alignas(char) static char ntfileshareflags[64]; return DescribeFlags(buf, 64, kFileShareflags, ARRAYLEN(kFileShareflags),
return DescribeFlags(ntfileshareflags, sizeof(ntfileshareflags),
kFileShareflags, ARRAYLEN(kFileShareflags),
"kNtFileShare", x); "kNtFileShare", x);
} }

View file

@ -28,8 +28,7 @@ static const struct DescribeFlags kFiletypeFlags[] = {
{kNtFileTypeChar, "Char"}, // {kNtFileTypeChar, "Char"}, //
}; };
const char *DescribeNtFiletypeFlags(uint32_t x) { const char *(DescribeNtFiletypeFlags)(char buf[64], uint32_t x) {
_Alignas(char) static char filetypeflags[64]; return DescribeFlags(buf, 64, kFiletypeFlags, ARRAYLEN(kFiletypeFlags),
return DescribeFlags(filetypeflags, sizeof(filetypeflags), kFiletypeFlags, "kNtFileType", x);
ARRAYLEN(kFiletypeFlags), "kNtFileType", x);
} }

View file

@ -29,9 +29,7 @@ static const struct DescribeFlags kMoveFileInputFlags[] = {
{kNtMovefileFailIfNotTrackable, "FailIfNotTrackable"}, // {kNtMovefileFailIfNotTrackable, "FailIfNotTrackable"}, //
}; };
const char *DescribeNtMoveFileInputFlags(uint32_t x) { const char *(DescribeNtMovFileInpFlags)(char buf[256], uint32_t x) {
_Alignas(char) static char movefileflags[256]; return DescribeFlags(buf, 256, kMoveFileInputFlags,
return DescribeFlags(movefileflags, sizeof(movefileflags), ARRAYLEN(kMoveFileInputFlags), "kNtMovefile", x);
kMoveFileInputFlags, ARRAYLEN(kMoveFileInputFlags),
"kNtMovefile", x);
} }

View file

@ -41,8 +41,6 @@ static const struct DescribeFlags kPageFlags[] = {
{kNtSecWritecombine, "SecWritecombine"}, // {kNtSecWritecombine, "SecWritecombine"}, //
}; };
const char *DescribeNtPageFlags(uint32_t x) { const char *(DescribeNtPageFlags)(char buf[64], uint32_t x) {
_Alignas(char) static char pageflags[64]; return DescribeFlags(buf, 64, kPageFlags, ARRAYLEN(kPageFlags), "kNt", x);
return DescribeFlags(pageflags, sizeof(pageflags), kPageFlags,
ARRAYLEN(kPageFlags), "kNt", x);
} }

View file

@ -32,8 +32,7 @@ static const struct DescribeFlags kPipeModeFlags[] = {
//{kNtPipeTypeByte, "TypeByte"}, // 0x00000000 //{kNtPipeTypeByte, "TypeByte"}, // 0x00000000
}; };
const char *DescribeNtPipeModeFlags(uint32_t x) { const char *(DescribeNtPipeModeFlags)(char buf[64], uint32_t x) {
_Alignas(char) static char pipemodeflags[64]; return DescribeFlags(buf, 64, kPipeModeFlags, ARRAYLEN(kPipeModeFlags),
return DescribeFlags(pipemodeflags, sizeof(pipemodeflags), kPipeModeFlags, "kNtPipe", x);
ARRAYLEN(kPipeModeFlags), "kNtPipe", x);
} }

View file

@ -27,8 +27,7 @@ static const struct DescribeFlags kPipeOpenFlags[] = {
{kNtPipeAccessInbound, "Inbound"}, // 0x00000001 {kNtPipeAccessInbound, "Inbound"}, // 0x00000001
}; };
const char *DescribeNtPipeOpenFlags(uint32_t x) { const char *(DescribeNtPipeOpenFlags)(char buf[64], uint32_t x) {
_Alignas(char) static char pipeopenflags[64]; return DescribeFlags(buf, 64, kPipeOpenFlags, ARRAYLEN(kPipeOpenFlags),
return DescribeFlags(pipeopenflags, sizeof(pipeopenflags), kPipeOpenFlags, "kNtPipeAccess", x);
ARRAYLEN(kPipeOpenFlags), "kNtPipeAccess", x);
} }

View file

@ -37,9 +37,7 @@ static const struct DescribeFlags kProcessAccessflags[] = {
{kNtProcessSynchronize, "Synchronize"}, // {kNtProcessSynchronize, "Synchronize"}, //
}; };
const char *DescribeNtProcessAccessFlags(uint32_t x) { const char *(DescribeNtProcAccessFlags)(char buf[256], uint32_t x) {
_Alignas(char) static char ntprocessaccessflags[256]; return DescribeFlags(buf, 256, kProcessAccessflags,
return DescribeFlags(ntprocessaccessflags, sizeof(ntprocessaccessflags), ARRAYLEN(kProcessAccessflags), "kNtProcess", x);
kProcessAccessflags, ARRAYLEN(kProcessAccessflags),
"kNtProcess", x);
} }

View file

@ -38,8 +38,7 @@ static const struct DescribeFlags kNtStartFlags[] = {
{kNtStartfUntrustedsource, "Untrustedsource"}, // {kNtStartfUntrustedsource, "Untrustedsource"}, //
}; };
const char *DescribeNtStartFlags(uint32_t x) { const char *(DescribeNtStartFlags)(char buf[128], uint32_t x) {
_Alignas(char) static char startflags[128]; return DescribeFlags(buf, 128, kNtStartFlags, ARRAYLEN(kNtStartFlags),
return DescribeFlags(startflags, sizeof(startflags), kNtStartFlags, "kNtStartf", x);
ARRAYLEN(kNtStartFlags), "kNtStartf", x);
} }

View file

@ -25,9 +25,7 @@ static const struct DescribeFlags kSymbolicLinkflags[] = {
{kNtSymbolicLinkFlagAllowUnprivilegedCreate, "AllowUnprivilegedCreate"}, // {kNtSymbolicLinkFlagAllowUnprivilegedCreate, "AllowUnprivilegedCreate"}, //
}; };
const char *DescribeNtSymbolicLinkFlags(uint32_t x) { const char *(DescribeNtSymlinkFlags)(char buf[64], uint32_t x) {
_Alignas(char) static char ntsymboliclinkflags[64]; return DescribeFlags(buf, 64, kSymbolicLinkflags,
return DescribeFlags(ntsymboliclinkflags, sizeof(ntsymboliclinkflags), ARRAYLEN(kSymbolicLinkflags), "kNtSymbolicLinkFlag", x);
kSymbolicLinkflags, ARRAYLEN(kSymbolicLinkflags),
"kNtSymbolicLinkFlag", x);
} }

View file

@ -16,26 +16,32 @@
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/assert.h"
#include "libc/fmt/itoa.h" #include "libc/fmt/itoa.h"
#include "libc/fmt/magnumstrs.internal.h" #include "libc/fmt/magnumstrs.internal.h"
#include "libc/intrin/describeflags.internal.h" #include "libc/intrin/describeflags.internal.h"
#include "libc/mem/alloca.h" #include "libc/macros.internal.h"
#include "libc/sysv/consts/sol.h" #include "libc/sysv/consts/sol.h"
#define N (PAGESIZE / 2 / sizeof(struct DescribeFlags))
/** /**
* Describes clock_gettime() clock argument. * Describes clock_gettime() clock argument.
*/ */
char *DescribeOpenFlags(int x) { const char *(DescribeOpenFlags)(char buf[128], int x) {
char *s; char *s;
int i, n; int i, n;
struct DescribeFlags *d; struct DescribeFlags d[N];
_Alignas(char) static char openflags[128];
// TODO(jart): unify DescribeFlags and MagnumStr data structures // TODO(jart): unify DescribeFlags and MagnumStr data structures
for (n = 0; kOpenFlags[n].x != MAGNUM_TERMINATOR;) ++n; for (n = 0; kOpenFlags[n].x != MAGNUM_TERMINATOR; ++n) {
d = alloca(n * sizeof(struct DescribeFlags)); if (n == N) {
assert(!"too many open flags");
break;
}
}
for (i = 0; i < n; ++i) { for (i = 0; i < n; ++i) {
d[i].flag = MAGNUM_NUMBER(kOpenFlags, i); d[i].flag = MAGNUM_NUMBER(kOpenFlags, i);
d[i].name = MAGNUM_STRING(kOpenFlags, i); d[i].name = MAGNUM_STRING(kOpenFlags, i);
} }
return DescribeFlags(openflags, sizeof(openflags), d, n, "O_", x); return DescribeFlags(buf, 128, d, n, "O_", x);
} }

View file

@ -36,8 +36,7 @@ static const struct DescribeFlags kPersonalityFlags[] = {
{UNAME26, "UNAME26"}, // {UNAME26, "UNAME26"}, //
}; };
const char *DescribePersonalityFlags(int x) { const char *(DescribePersonalityFlags)(char buf[128], int x) {
_Alignas(char) static char personalityflags[128]; return DescribeFlags(buf, 128, kPersonalityFlags, ARRAYLEN(kPersonalityFlags),
return DescribeFlags(personalityflags, sizeof(personalityflags), "", x);
kPersonalityFlags, ARRAYLEN(kPersonalityFlags), "", x);
} }

View file

@ -21,7 +21,7 @@
#include "libc/nt/enum/filemapflags.h" #include "libc/nt/enum/filemapflags.h"
#include "libc/sysv/consts/poll.h" #include "libc/sysv/consts/poll.h"
const char *DescribePollFlags(char *buf, size_t size, int x) { const char *(DescribePollFlags)(char buf[64], int x) {
const struct DescribeFlags kPollFlags[] = { const struct DescribeFlags kPollFlags[] = {
{POLLIN, "IN"}, // order matters {POLLIN, "IN"}, // order matters
{POLLOUT, "OUT"}, // order matters {POLLOUT, "OUT"}, // order matters
@ -35,5 +35,5 @@ const char *DescribePollFlags(char *buf, size_t size, int x) {
{POLLWRBAND, "WRBAND"}, // {POLLWRBAND, "WRBAND"}, //
{POLLWRNORM, "WRNORM"}, // {POLLWRNORM, "WRNORM"}, //
}; };
return DescribeFlags(buf, size, kPollFlags, ARRAYLEN(kPollFlags), "POLL", x); return DescribeFlags(buf, 64, kPollFlags, ARRAYLEN(kPollFlags), "POLL", x);
} }

View file

@ -0,0 +1,33 @@
/*-*- 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/intrin/describeflags.internal.h"
#include "libc/sysv/consts/pr.h"
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_???";
}
}

View file

@ -26,8 +26,6 @@ static const struct DescribeFlags kProtFlags[] = {
{PROT_EXEC, "EXEC"}, // {PROT_EXEC, "EXEC"}, //
}; };
const char *DescribeProtFlags(int x) { const char *(DescribeProtFlags)(char buf[48], int x) {
_Alignas(char) static char protflags[64]; return DescribeFlags(buf, 48, kProtFlags, ARRAYLEN(kProtFlags), "PROT_", x);
return DescribeFlags(protflags, sizeof(protflags), kProtFlags,
ARRAYLEN(kProtFlags), "PROT_", x);
} }

View file

@ -25,8 +25,7 @@ static const struct DescribeFlags kRemapFlags[] = {
{MREMAP_FIXED, "FIXED"}, // {MREMAP_FIXED, "FIXED"}, //
}; };
const char *DescribeRemapFlags(int x) { const char *(DescribeRemapFlags)(char buf[48], int x) {
_Alignas(char) static char remapflags[64]; return DescribeFlags(buf, 48, kRemapFlags, ARRAYLEN(kRemapFlags), "MREMAP_",
return DescribeFlags(remapflags, sizeof(remapflags), kRemapFlags, x);
ARRAYLEN(kRemapFlags), "MREMAP_", x);
} }

View file

@ -21,15 +21,14 @@
#include "libc/intrin/asan.internal.h" #include "libc/intrin/asan.internal.h"
#include "libc/intrin/kprintf.h" #include "libc/intrin/kprintf.h"
const char *DescribeRlimit(char *buf, size_t bufsize, int rc, const char *DescribeRlimit(char buf[64], int rc, const struct rlimit *rlim) {
const struct rlimit *rlim) {
if (rc == -1) return "n/a"; if (rc == -1) return "n/a";
if (!rlim) return "NULL"; if (!rlim) return "NULL";
if ((!IsAsan() && kisdangerous(rlim)) || if ((!IsAsan() && kisdangerous(rlim)) ||
(IsAsan() && !__asan_is_valid(rlim, sizeof(*rlim)))) { (IsAsan() && !__asan_is_valid(rlim, sizeof(*rlim)))) {
ksnprintf(buf, sizeof(buf), "%p", rlim); ksnprintf(buf, 64, "%p", rlim);
} else { } else {
ksnprintf(buf, bufsize, "{%'ld, %'ld}", rlim->rlim_cur, rlim->rlim_max); ksnprintf(buf, 64, "{%'ld, %'ld}", rlim->rlim_cur, rlim->rlim_max);
} }
return buf; return buf;
} }

View file

@ -20,8 +20,7 @@
#include "libc/fmt/itoa.h" #include "libc/fmt/itoa.h"
#include "libc/sysv/consts/rlimit.h" #include "libc/sysv/consts/rlimit.h"
const char *DescribeRlimitName(int resource) { const char *(DescribeRlimitName)(char buf[12], int resource) {
static char buf[12];
if (resource == 127) return "n/a"; if (resource == 127) return "n/a";
if (resource == RLIMIT_AS) return "RLIMIT_AS"; if (resource == RLIMIT_AS) return "RLIMIT_AS";
if (resource == RLIMIT_CPU) return "RLIMIT_CPU"; if (resource == RLIMIT_CPU) return "RLIMIT_CPU";

View file

@ -0,0 +1,35 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/struct/seccomp.h"
#include "libc/intrin/describeflags.internal.h"
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_???";
}
}

View file

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

View file

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

View file

@ -23,8 +23,7 @@
#include "libc/intrin/kprintf.h" #include "libc/intrin/kprintf.h"
#include "libc/str/str.h" #include "libc/str/str.h"
const char *DescribeSigset(char *buf, size_t bufsize, int rc, const char *(DescribeSigset)(char buf[64], int rc, const sigset_t *ss) {
const sigset_t *ss) {
bool gotsome; bool gotsome;
int i, n, sig; int i, n, sig;
sigset_t sigset; sigset_t sigset;
@ -33,12 +32,12 @@ const char *DescribeSigset(char *buf, size_t bufsize, int rc,
if (!ss) return "NULL"; if (!ss) return "NULL";
if ((!IsAsan() && kisdangerous(ss)) || if ((!IsAsan() && kisdangerous(ss)) ||
(IsAsan() && !__asan_is_valid(ss, sizeof(*ss)))) { (IsAsan() && !__asan_is_valid(ss, sizeof(*ss)))) {
ksnprintf(buf, sizeof(buf), "%p", ss); ksnprintf(buf, 64, "%p", ss);
return buf; return buf;
} }
i = 0; i = 0;
n = bufsize; n = 64;
sigset = *ss; sigset = *ss;
gotsome = false; gotsome = false;
if (popcnt(sigset.__bits[0]) + popcnt(sigset.__bits[1]) > 64) { if (popcnt(sigset.__bits[0]) + popcnt(sigset.__bits[1]) > 64) {

View file

@ -0,0 +1,29 @@
/*-*- 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/intrin/describeflags.internal.h"
#include "libc/sysv/consts/af.h"
const char *(DescribeSocketFamily)(char buf[12], int family) {
if (family == AF_UNIX) return "AF_UNIX";
if (family == AF_INET) return "AF_INET";
if (family == AF_INET6) return "AF_INET6";
FormatInt32(buf, family);
return buf;
}

View file

@ -0,0 +1,32 @@
/*-*- 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/intrin/describeflags.internal.h"
#include "libc/sysv/consts/ipproto.h"
const char *(DescribeSocketProtocol)(char buf[12], int family) {
if (family == IPPROTO_IP) return "IPPROTO_IP";
if (family == IPPROTO_ICMP) return "IPPROTO_ICMP";
if (family == IPPROTO_TCP) return "IPPROTO_TCP";
if (family == IPPROTO_UDP) return "IPPROTO_UDP";
if (family == IPPROTO_RAW) return "IPPROTO_RAW";
if (family == IPPROTO_IPV6) return "IPPROTO_IPv6";
FormatInt32(buf, family);
return buf;
}

View file

@ -0,0 +1,54 @@
/*-*- 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/intrin/describeflags.internal.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/sock.h"
static char *StpCpy(char *d, const char *s) {
size_t i;
for (i = 0;; ++i) {
if (!(d[i] = s[i])) {
return d + i;
}
}
}
const char *(DescribeSocketType)(char buf[64], int type) {
int x;
char *p;
p = buf;
x = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
if (x == SOCK_STREAM) {
p = StpCpy(p, "SOCK_STREAM");
} else if (x == SOCK_DGRAM) {
p = StpCpy(p, "SOCK_DGRAM");
} else if (x == SOCK_RAW) {
p = StpCpy(p, "SOCK_RAW");
} else if (x == SOCK_RDM) {
p = StpCpy(p, "SOCK_RDM");
} else if (x == SOCK_SEQPACKET) {
p = StpCpy(p, "SOCK_SEQPACKET");
} else {
p = FormatInt32(p, x);
}
if (type & SOCK_CLOEXEC) p = StpCpy(p, "|SOCK_CLOEXEC");
if (type & SOCK_NONBLOCK) p = StpCpy(p, "|SOCK_NONBLOCK");
return buf;
}

View file

@ -17,13 +17,13 @@
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/fmt/itoa.h" #include "libc/fmt/itoa.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/sysv/consts/sol.h" #include "libc/sysv/consts/sol.h"
/** /**
* Describes setsockopt() level arguments. * Describes setsockopt() level arguments.
*/ */
char *DescribeSockLevel(int x) { const char *(DescribeSockLevel)(char buf[12], int x) {
static char buf[12];
if (x == SOL_IP) return "SOL_IP"; if (x == SOL_IP) return "SOL_IP";
if (x == SOL_TCP) return "SOL_TCP"; if (x == SOL_TCP) return "SOL_TCP";
if (x == SOL_UDP) return "SOL_UDP"; if (x == SOL_UDP) return "SOL_UDP";

View file

@ -18,34 +18,56 @@
*/ */
#include "libc/fmt/itoa.h" #include "libc/fmt/itoa.h"
#include "libc/fmt/magnumstrs.internal.h" #include "libc/fmt/magnumstrs.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/sysv/consts/sol.h" #include "libc/sysv/consts/sol.h"
static inline char *StpCpy(char *d, const char *s) {
size_t i;
for (i = 0;; ++i) {
if (!(d[i] = s[i])) {
return d + i;
}
}
}
/** /**
* Describes setsockopt() optname arguments. * Describes setsockopt() optname arguments.
*/ */
char *DescribeSockOptname(int l, int x) { const char *(DescribeSockOptname)(char buf[32], int l, int x) {
int i; int i;
char *ps, *s; char *s, *p;
const struct MagnumStr *ms = 0; const struct MagnumStr *ms;
_Alignas(char) static char buf[32]; p = buf;
if (x) { if (x) {
if (l == SOL_SOCKET) { if (l == SOL_SOCKET) {
ps = "SO_"; *p++ = 'S';
*p++ = 'O';
*p++ = '_';
*p = 0;
ms = kSockOptnames; ms = kSockOptnames;
} else if (l == SOL_TCP) { } else if (l == SOL_TCP) {
ps = "TCP_"; *p++ = 'T';
*p++ = 'C';
*p++ = 'P';
*p++ = '_';
ms = kTcpOptnames; ms = kTcpOptnames;
} else if (l == SOL_IP) { } else if (l == SOL_IP) {
ps = "IP_"; *p++ = 'I';
*p++ = 'P';
*p++ = '_';
*p = 0;
ms = kIpOptnames; ms = kIpOptnames;
} else {
ms = 0;
} }
} else {
ms = 0;
} }
if (ms && (s = GetMagnumStr(ms, x))) { if (ms && (s = GetMagnumStr(ms, x))) {
stpcpy(stpcpy(buf, ps), s); StpCpy(p, s);
return buf;
} else { } else {
FormatInt32(buf, x); FormatInt32(p, x);
return buf;
} }
return buf;
} }

View file

@ -21,20 +21,19 @@
#include "libc/intrin/describeflags.internal.h" #include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h" #include "libc/intrin/kprintf.h"
const char *DescribeStat(int rc, const struct stat *st) { const char *(DescribeStat)(char buf[300], int rc, const struct stat *st) {
_Alignas(char) static char buf[300];
int i, n; int i, n;
if (rc == -1) return "n/a"; if (rc == -1) return "n/a";
if (!st) return "NULL"; if (!st) return "NULL";
if ((!IsAsan() && kisdangerous(st)) || if ((!IsAsan() && kisdangerous(st)) ||
(IsAsan() && !__asan_is_valid(st, sizeof(*st)))) { (IsAsan() && !__asan_is_valid(st, sizeof(*st)))) {
ksnprintf(buf, sizeof(buf), "%p", st); ksnprintf(buf, 300, "%p", st);
return buf; return buf;
} }
i = 0; i = 0;
n = sizeof(buf); n = 300;
i += ksnprintf(buf + i, n - i, "{.st_%s=%'ld", "size", st->st_size); i += ksnprintf(buf + i, n - i, "{.st_%s=%'ld", "size", st->st_size);

View file

@ -21,15 +21,15 @@
#include "libc/intrin/describeflags.internal.h" #include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h" #include "libc/intrin/kprintf.h"
const char *DescribeTimespec(char *buf, size_t bufsize, int rc, const char *(DescribeTimespec)(char buf[45], int rc,
const struct timespec *ts) { const struct timespec *ts) {
if (rc == -1) return "n/a"; if (rc == -1) return "n/a";
if (!ts) return "NULL"; if (!ts) return "NULL";
if ((!IsAsan() && kisdangerous(ts)) || if ((!IsAsan() && kisdangerous(ts)) ||
(IsAsan() && !__asan_is_valid(ts, sizeof(*ts)))) { (IsAsan() && !__asan_is_valid(ts, sizeof(*ts)))) {
ksnprintf(buf, bufsize, "%p", ts); ksnprintf(buf, 45, "%p", ts);
} else { } else {
ksnprintf(buf, bufsize, "{%ld, %ld}", ts->tv_sec, ts->tv_nsec); ksnprintf(buf, 45, "{%ld, %ld}", ts->tv_sec, ts->tv_nsec);
} }
return buf; return buf;
} }

View file

@ -18,6 +18,7 @@
*/ */
#include "libc/calls/strace.internal.h" #include "libc/calls/strace.internal.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/intrin/kprintf.h"
#include "libc/nt/thread.h" #include "libc/nt/thread.h"
#include "libc/runtime/runtime.h" #include "libc/runtime/runtime.h"
#include "libc/sysv/consts/nr.h" #include "libc/sysv/consts/nr.h"

View file

@ -35,15 +35,14 @@ textwindows int64_t FindFirstFile(const char16_t *lpFileName,
int64_t hFindFile; int64_t hFindFile;
hFindFile = __imp_FindFirstFileW(lpFileName, out_lpFindFileData); hFindFile = __imp_FindFirstFileW(lpFileName, out_lpFindFileData);
if (hFindFile != -1) { if (hFindFile != -1) {
NTTRACE( NTTRACE("FindFirstFile(%#hs, [{"
"FindFirstFile(%#hs, [{" ".cFileName=%#hs, "
".cFileName=%#hs, " ".dwFileAttributes=%s, "
".dwFileAttributes=%s, " ".dwFileType=%s"
".dwFileType=%s" "}]) → %ld% m",
"}]) → %ld% m", lpFileName, out_lpFindFileData->cFileName,
lpFileName, out_lpFindFileData->cFileName, DescribeNtFileFlagAttr(out_lpFindFileData->dwFileAttributes),
DescribeNtFileFlagsAndAttributes(out_lpFindFileData->dwFileAttributes), DescribeNtFiletypeFlags(out_lpFindFileData->dwFileType), hFindFile);
DescribeNtFiletypeFlags(out_lpFindFileData->dwFileType), hFindFile);
} else { } else {
__winerr(); __winerr();
NTTRACE("FindFirstFile(%#hs, [n/a]) → %ld% m", lpFileName, hFindFile); NTTRACE("FindFirstFile(%#hs, [n/a]) → %ld% m", lpFileName, hFindFile);

View file

@ -37,15 +37,14 @@ textwindows bool32 FindNextFile(int64_t hFindFile,
bool32 ok; bool32 ok;
ok = __imp_FindNextFileW(hFindFile, out_lpFindFileData); ok = __imp_FindNextFileW(hFindFile, out_lpFindFileData);
if (ok) { if (ok) {
NTTRACE( NTTRACE("FindNextFile(%ld, [{"
"FindNextFile(%ld, [{" ".cFileName=%#hs, "
".cFileName=%#hs, " ".dwFileAttributes=%s, "
".dwFileAttributes=%s, " ".dwFileType=%s"
".dwFileType=%s" "}]) → %hhhd% m",
"}]) → %hhhd% m", hFindFile, out_lpFindFileData->cFileName,
hFindFile, out_lpFindFileData->cFileName, DescribeNtFileFlagAttr(out_lpFindFileData->dwFileAttributes),
DescribeNtFileFlagsAndAttributes(out_lpFindFileData->dwFileAttributes), DescribeNtFiletypeFlags(out_lpFindFileData->dwFileType), ok);
DescribeNtFiletypeFlags(out_lpFindFileData->dwFileType), ok);
} else { } else {
if (GetLastError() != kNtErrorNoMoreFiles) __winerr(); if (GetLastError() != kNtErrorNoMoreFiles) __winerr();
NTTRACE("FindNextFile(%ld) → %hhhd% m", hFindFile, ok); NTTRACE("FindNextFile(%ld) → %hhhd% m", hFindFile, ok);

28
libc/intrin/futex.S Normal file
View file

@ -0,0 +1,28 @@
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/sysv/consts/nr.h"
#include "libc/macros.internal.h"
_futex: mov __NR_futex,%eax
clc
syscall
jnc 1f
neg %eax
1: ret
.endfn _futex,globl,hidden

View file

@ -4,8 +4,9 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0) #if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_ COSMOPOLITAN_C_START_
int _futex_wait(void *, int, struct timespec *); int _futex(void *, int, int, struct timespec *, int *) hidden;
int _futex_wake(void *, int); int _futex_wait(void *, int, struct timespec *) hidden;
int _futex_wake(void *, int) hidden;
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -16,29 +16,29 @@
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/bits/asmflag.h"
#include "libc/calls/strace.internal.h" #include "libc/calls/strace.internal.h"
#include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timespec.h"
#include "libc/fmt/itoa.h"
#include "libc/intrin/describeflags.internal.h" #include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/futex.internal.h" #include "libc/intrin/futex.internal.h"
#include "libc/mem/alloca.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/sysv/consts/futex.h" #include "libc/sysv/consts/futex.h"
#include "libc/sysv/consts/nr.h"
privileged int _futex_wait(void *addr, int expect, struct timespec *timeout) { static const char *DescribeFutexWaitResult(char buf[12], int ax) {
const char *s;
if (ax && ((s = strerrno(ax)) || (s = strerrno(-ax)))) {
return s;
} else {
FormatInt32(buf, ax);
return buf;
}
}
int _futex_wait(void *addr, int expect, struct timespec *timeout) {
int ax; int ax;
bool cf; ax = _futex(addr, FUTEX_WAIT, expect, timeout, 0);
char buf[45]; STRACE("futex(%t[%p], FUTEX_WAIT, %d, %s) → %s", addr, addr, expect,
asm volatile(CFLAG_ASM("mov\t%6,%%r10\n\t" DescribeTimespec(0, timeout), DescribeFutexWaitResult(alloca(12), ax));
"clc\n\t"
"syscall")
: CFLAG_CONSTRAINT(cf), "=a"(ax)
: "1"(__NR_futex), "D"(addr), "S"(FUTEX_WAIT), "d"(expect),
"g"(timeout)
: "rcx", "r10", "r11", "memory");
if (cf) ax = -ax;
STRACE("futex(%p, FUTEX_WAIT, %d, %s) → %s", addr, expect,
DescribeTimespec(buf, sizeof(buf), 0, timeout),
ax ? strerrno(-ax) : "0");
return ax; return ax;
} }

View file

@ -19,31 +19,27 @@
#include "libc/bits/asmflag.h" #include "libc/bits/asmflag.h"
#include "libc/calls/strace.internal.h" #include "libc/calls/strace.internal.h"
#include "libc/fmt/itoa.h" #include "libc/fmt/itoa.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/futex.internal.h" #include "libc/intrin/futex.internal.h"
#include "libc/mem/alloca.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/sysv/consts/futex.h" #include "libc/sysv/consts/futex.h"
#include "libc/sysv/consts/nr.h" #include "libc/sysv/consts/nr.h"
static const char *FormatFutexWakeResult(char buf[12], int ax) { static const char *DescribeFutexWakeResult(char buf[12], int ax) {
if (ax >= 0) { const char *s;
if (ax < 0 && (s = strerrno(ax))) {
return s;
} else {
FormatInt32(buf, ax); FormatInt32(buf, ax);
return buf; return buf;
} else {
return strerrno(-ax);
} }
} }
privileged int _futex_wake(void *addr, int count) { int _futex_wake(void *addr, int count) {
int ax; int ax;
bool cf; ax = _futex(addr, FUTEX_WAKE, count, 0, 0);
char buf[12]; STRACE("futex(%t[%p], FUTEX_WAKE, %d) → %s", addr, addr, count,
asm volatile(CFLAG_ASM("clc\n\t" DescribeFutexWakeResult(alloca(12), ax));
"syscall")
: CFLAG_CONSTRAINT(cf), "=a"(ax)
: "1"(__NR_futex), "D"(addr), "S"(FUTEX_WAKE), "d"(count)
: "rcx", "r11", "memory");
if (cf) ax = -ax;
STRACE("futex(%p, FUTEX_WAKE, %d) → %s", addr, count,
FormatFutexWakeResult(buf, ax));
return ax; return ax;
} }

View file

@ -36,6 +36,6 @@ textwindows uint32_t GetFileAttributes(const char16_t *lpPathName) {
flags = __imp_GetFileAttributesW(lpPathName); flags = __imp_GetFileAttributesW(lpPathName);
if (flags == -1u) __winerr(); if (flags == -1u) __winerr();
NTTRACE("GetFileAttributes(%#hs) → %s% m", lpPathName, NTTRACE("GetFileAttributes(%#hs) → %s% m", lpPathName,
DescribeNtFileFlagsAndAttributes(flags)); DescribeNtFileFlagAttr(flags));
return flags; return flags;
} }

View file

@ -18,7 +18,7 @@
*/ */
#include "libc/fmt/magnumstrs.internal.h" #include "libc/fmt/magnumstrs.internal.h"
privileged char *GetMagnumStr(const struct MagnumStr *ms, int x) { char *GetMagnumStr(const struct MagnumStr *ms, int x) {
int i; int i;
for (i = 0; ms[i].x != MAGNUM_TERMINATOR; ++i) { for (i = 0; ms[i].x != MAGNUM_TERMINATOR; ++i) {
if (x == MAGNUM_NUMBER(ms, i)) { if (x == MAGNUM_NUMBER(ms, i)) {

View file

@ -16,15 +16,12 @@
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/assert.h"
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/nexgen32e/gettls.h" #include "libc/nexgen32e/gettls.h"
#include "libc/nexgen32e/threaded.h" #include "libc/nexgen32e/threaded.h"
#include "libc/nt/thread.h"
#include "libc/nt/thunk/msabi.h"
#include "libc/runtime/internal.h"
__msabi extern typeof(GetCurrentThreadId) *const __imp_GetCurrentThreadId;
/** /**
* Returns current thread id. * Returns current thread id.
@ -54,60 +51,10 @@ __msabi extern typeof(GetCurrentThreadId) *const __imp_GetCurrentThreadId;
* @threadsafe * @threadsafe
*/ */
privileged int gettid(void) { privileged int gettid(void) {
int rc; int tid;
int64_t wut;
struct WinThread *wt;
if (__tls_enabled) { if (__tls_enabled) {
rc = *(int *)(__get_tls_inline() + 0x38); tid = *(int *)(__get_tls_inline() + 0x38);
return rc; if (tid > 0) return tid;
} }
return sys_gettid();
if (IsWindows()) {
return __imp_GetCurrentThreadId();
}
if (IsLinux()) {
asm("syscall"
: "=a"(rc) // man says always succeeds
: "0"(186) // __NR_gettid
: "rcx", "r11", "memory");
return rc;
}
if (IsXnu()) {
asm("syscall" // xnu/osfmk/kern/ipc_tt.c
: "=a"(rc) // assume success
: "0"(0x1000000 | 27) // Mach thread_self_trap()
: "rcx", "r11", "memory", "cc");
return rc;
}
if (IsOpenbsd()) {
asm("syscall"
: "=a"(rc) // man says always succeeds
: "0"(299) // getthrid()
: "rcx", "r11", "memory", "cc");
return rc;
}
if (IsNetbsd()) {
asm("syscall"
: "=a"(rc) // man says always succeeds
: "0"(311) // _lwp_self()
: "rcx", "rdx", "r11", "memory", "cc");
return rc;
}
if (IsFreebsd()) {
asm("syscall"
: "=a"(rc), // only fails w/ EFAULT, which isn't possible
"=m"(wut) // must be 64-bit
: "0"(432), // thr_self()
"D"(&wut) // but not actually 64-bit
: "rcx", "r11", "memory", "cc");
return wut; // narrowing intentional
}
return __pid;
} }

View file

@ -28,7 +28,8 @@ LIBC_INTRIN_A_DIRECTDEPS = \
LIBC_SYSV \ LIBC_SYSV \
LIBC_SYSV_CALLS \ LIBC_SYSV_CALLS \
LIBC_NEXGEN32E \ LIBC_NEXGEN32E \
LIBC_NT_KERNEL32 LIBC_NT_KERNEL32 \
LIBC_NT_WS2_32
LIBC_INTRIN_A_DEPS := \ LIBC_INTRIN_A_DEPS := \
$(call uniq,$(foreach x,$(LIBC_INTRIN_A_DIRECTDEPS),$($(x)))) $(call uniq,$(foreach x,$(LIBC_INTRIN_A_DIRECTDEPS),$($(x))))
@ -76,6 +77,7 @@ o/$(MODE)/libc/intrin/kprintf.greg.o: \
o/$(MODE)/libc/intrin/futex_wait.o \ o/$(MODE)/libc/intrin/futex_wait.o \
o/$(MODE)/libc/intrin/futex_wake.o \ o/$(MODE)/libc/intrin/futex_wake.o \
o/$(MODE)/libc/intrin/gettid.greg.o \ o/$(MODE)/libc/intrin/gettid.greg.o \
o/$(MODE)/libc/intrin/sys_gettid.greg.o \
o/$(MODE)/libc/intrin/pthread_mutex_lock.o \ o/$(MODE)/libc/intrin/pthread_mutex_lock.o \
o/$(MODE)/libc/intrin/pthread_mutex_unlock.o \ o/$(MODE)/libc/intrin/pthread_mutex_unlock.o \
o/$(MODE)/libc/intrin/pthread_mutex_trylock.o \ o/$(MODE)/libc/intrin/pthread_mutex_trylock.o \
@ -97,18 +99,21 @@ o/$(MODE)/libc/intrin/restorewintty.o: \
OVERRIDE_CFLAGS += \ OVERRIDE_CFLAGS += \
-fno-sanitize=all -fno-sanitize=all
# we can't use asan because:
# sys_mmap() calls these which sets up shadow memory
o/$(MODE)/libc/intrin/describeflags.o \
o/$(MODE)/libc/intrin/describeframe.o \
o/$(MODE)/libc/intrin/describemapflags.o \
o/$(MODE)/libc/intrin/describeprotflags.o: \
OVERRIDE_CFLAGS += \
-fno-sanitize=address
o/$(MODE)/libc/intrin/tls.greg.o \ o/$(MODE)/libc/intrin/tls.greg.o \
o/$(MODE)/libc/intrin/exit.greg.o \ o/$(MODE)/libc/intrin/exit.greg.o \
o/$(MODE)/libc/intrin/exit1.greg.o \ o/$(MODE)/libc/intrin/exit1.greg.o \
o/$(MODE)/libc/intrin/getenv.greg.o \ o/$(MODE)/libc/intrin/getenv.greg.o \
o/$(MODE)/libc/intrin/assertfail.greg.o \ o/$(MODE)/libc/intrin/wsarecv.o \
o/$(MODE)/libc/intrin/describeiov.greg.o \ o/$(MODE)/libc/intrin/wsarecvfrom.o \
o/$(MODE)/libc/intrin/describestat.greg.o \
o/$(MODE)/libc/intrin/describeflags.greg.o \
o/$(MODE)/libc/intrin/describerlimit.greg.o \
o/$(MODE)/libc/intrin/deviceiocontrol.greg.o \
o/$(MODE)/libc/intrin/describemapflags.greg.o \
o/$(MODE)/libc/intrin/describetimespec.greg.o \
o/$(MODE)/libc/intrin/createfile.o \ o/$(MODE)/libc/intrin/createfile.o \
o/$(MODE)/libc/intrin/reopenfile.o \ o/$(MODE)/libc/intrin/reopenfile.o \
o/$(MODE)/libc/intrin/deletefile.o \ o/$(MODE)/libc/intrin/deletefile.o \
@ -140,6 +145,7 @@ o/$(MODE)/libc/intrin/createfilemapping.o \
o/$(MODE)/libc/intrin/createfilemappingnuma.o \ o/$(MODE)/libc/intrin/createfilemappingnuma.o \
o/$(MODE)/libc/intrin/waitformultipleobjects.o \ o/$(MODE)/libc/intrin/waitformultipleobjects.o \
o/$(MODE)/libc/intrin/generateconsolectrlevent.o \ o/$(MODE)/libc/intrin/generateconsolectrlevent.o \
o/$(MODE)/libc/intrin/wsawaitformultipleevents.o \
o/$(MODE)/libc/intrin/kstarttsc.o \ o/$(MODE)/libc/intrin/kstarttsc.o \
o/$(MODE)/libc/intrin/nomultics.o \ o/$(MODE)/libc/intrin/nomultics.o \
o/$(MODE)/libc/intrin/ntconsolemode.o: \ o/$(MODE)/libc/intrin/ntconsolemode.o: \
@ -150,10 +156,6 @@ o/$(MODE)/libc/intrin/ntconsolemode.o: \
-fno-stack-protector \ -fno-stack-protector \
-fno-sanitize=all -fno-sanitize=all
o/$(MODE)/libc/intrin/describeopenflags.greg.o: \
OVERRIDE_CPPFLAGS += \
-DSTACK_FRAME_UNLIMITED
o//libc/intrin/memmove.o: \ o//libc/intrin/memmove.o: \
OVERRIDE_CFLAGS += \ OVERRIDE_CFLAGS += \
-fno-toplevel-reorder -fno-toplevel-reorder

View file

@ -23,6 +23,7 @@
#include "libc/bits/weaken.h" #include "libc/bits/weaken.h"
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/state.internal.h" #include "libc/calls/state.internal.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/fmt/divmod10.internal.h" #include "libc/fmt/divmod10.internal.h"

Some files were not shown because too many files have changed in this diff Show more