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
HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 win7 win10 xnu
#SANITY := $(shell build/sanitycheck $$PPID)
.SUFFIXES:
.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
`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
maps your program into memory without needing to copy it. It's possible
to install the APE loader systemwide as follows.
it'll instead do, is extract a 4kb program to `${TMPDIR:-${HOME:-.}}`
that maps your program into memory without needing to copy it. It's
possible to install the APE loader systemwide as follows.
```sh
# (1) linux systems that want binfmt_misc

View file

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

View file

@ -3,7 +3,8 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
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
#define assert(EXPR) ((void)0)

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -25,11 +25,7 @@ hidden extern const struct MagnumStr kSignalNames[];
hidden extern const struct MagnumStr kSockOptnames[];
hidden extern const struct MagnumStr kTcpOptnames[];
char *DescribeClockName(int) hidden;
char *DescribeOpenFlags(int) hidden;
char *DescribeSockLevel(int) hidden;
char *DescribeSockOptname(int, int) hidden;
char *GetMagnumStr(const struct MagnumStr *, int) hidden;
char *GetMagnumStr(const struct MagnumStr *, int);
COSMOPOLITAN_C_END_
#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;
addr = (void *)(intptr_t)((int64_t)((uint64_t)a << 32) >> 16);
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);
if (sm.addr == MAP_FAILED ||
weaken(TrackMemoryInterval)(
m, a, a + i - 1, sm.maphandle, PROT_READ | PROT_WRITE,
MAP_PRIVATE | *weaken(MAP_ANONYMOUS) | MAP_FIXED, false, false, 0,
size) == -1) {
weaken(TrackMemoryInterval)(m, a, a + i - 1, sm.maphandle,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
false, false, 0, size) == -1) {
kprintf("error: could not map asan shadow memory\n");
__asan_die()();
__asan_unreachable();
@ -1379,7 +1379,6 @@ textstartup void __asan_init(int argc, char **argv, char **envp,
}
REQUIRE(_mmi);
REQUIRE(sys_mmap);
REQUIRE(MAP_ANONYMOUS);
REQUIRE(TrackMemoryInterval);
if (weaken(hook_malloc) || weaken(hook_calloc) || weaken(hook_realloc) ||
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/bits/weaken.h"
#include "libc/calls/calls.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/lockcmpxchgp.h"
#include "libc/log/backtrace.internal.h"
@ -30,32 +31,33 @@
/**
* Handles failure of assert() macro.
*/
relegated wontreturn void __assert_fail(const char *expr, const char *file,
int line) {
relegated void __assert_fail(const char *expr, const char *file, int line) {
int me, owner;
static int sync;
--__strace;
--__ftrace;
owner = 0;
me = gettid();
kprintf("%s:%d: assert(%s) failed (tid %d)\n", file, line, expr, me);
if (_lockcmpxchgp(&sync, &owner, me)) {
__restore_tty();
if (weaken(ShowBacktrace)) {
weaken(ShowBacktrace)(2, __builtin_frame_address(0));
} else if (weaken(PrintBacktraceUsingSymbols) && weaken(GetSymbolTable)) {
weaken(PrintBacktraceUsingSymbols)(2, __builtin_frame_address(0),
weaken(GetSymbolTable)());
if (!__assert_disable) {
--__strace;
--__ftrace;
owner = 0;
me = sys_gettid();
kprintf("%s:%d: assert(%s) failed (tid %d)\n", file, line, expr, me);
if (_lockcmpxchgp(&sync, &owner, me)) {
__restore_tty();
if (weaken(ShowBacktrace)) {
weaken(ShowBacktrace)(2, __builtin_frame_address(0));
} else if (weaken(PrintBacktraceUsingSymbols) && 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 {
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),
DescribeNtSecurityAttributes(opt_lpSecurityAttributes),
DescribeNtCreationDisposition(dwCreationDisposition),
DescribeNtFileFlagsAndAttributes(dwFlagsAndAttributes),
opt_hTemplateFile, hHandle);
DescribeNtFileFlagAttr(dwFlagsAndAttributes), opt_hTemplateFile,
hHandle);
return hHandle;
}

View file

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

View file

@ -18,18 +18,34 @@
*/
#include "libc/fmt/itoa.h"
#include "libc/fmt/magnumstrs.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/str/str.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.
*/
char *DescribeClockName(int x) {
const char *(DescribeClockName)(char buf[32], int x) {
int i;
char *s;
_Alignas(char) static char buf[32];
char *s, *p;
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;
} else {
FormatInt32(buf, x);

View file

@ -20,7 +20,7 @@
#include "libc/intrin/describeflags.internal.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";
FormatInt32(buf, dirfd);
return buf;

View file

@ -19,6 +19,7 @@
#include "libc/intrin/describeflags.internal.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 *prefix, unsigned x) {
bool t;

View file

@ -7,7 +7,10 @@
#include "libc/calls/struct/sigset.h"
#include "libc/calls/struct/stat.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/sock/struct/sockaddr.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
@ -19,39 +22,90 @@ struct thatispacked DescribeFlags {
const char *DescribeFlags(char *, size_t, struct DescribeFlags *, size_t,
const char *, unsigned);
const char *DescribeMapFlags(int);
const char *DescribeProtFlags(int);
const char *DescribeRemapFlags(int);
const char *DescribeRlimitName(int);
const char *DescribePersonalityFlags(int);
const char *DescribeSeccompOperationFlags(int);
const char *DescribePollFlags(char *, size_t, int);
const char *DescribeStat(int, const struct stat *);
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 *DescribeClockName(char[32], int);
const char *DescribeDirfd(char[12], int);
const char *DescribeFrame(char[32], int);
const char *DescribeHow(char[12], int);
const char *DescribeMapFlags(char[64], int);
const char *DescribeMapping(char[8], int, int);
const char *DescribeNtConsoleInFlags(char[256], uint32_t);
const char *DescribeNtConsoleOutFlags(char[128], uint32_t);
const char *DescribeNtCreationDisposition(uint32_t);
const char *DescribeNtConsoleModeInputFlags(uint32_t);
const char *DescribeNtConsoleModeOutputFlags(uint32_t);
const char *DescribeNtFileFlagsAndAttributes(uint32_t);
const char *DescribeNtFileAccessFlags(char[512], uint32_t);
const char *DescribeNtFileFlagAttr(char[256], 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 *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 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_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -16,6 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/macros.internal.h"
#include "libc/runtime/memtrack.internal.h"
@ -25,12 +26,11 @@
#define UNSHADOW(x) ((int64_t)(MAX(0, (x)-0x7fff8000)) << 3)
#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 */
char *p;
static char buf[32];
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 " shadow ";
} 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/prot.h"
const char *DescribeMapFlags(int x) {
_Alignas(char) static char mapflags[256];
const char *(DescribeMapFlags)(char buf[64], int x) {
const struct DescribeFlags kMapFlags[] = {
{MAP_STACK, "STACK"}, // order matters
{MAP_PRIVATE, "PRIVATE"}, //
@ -39,6 +38,5 @@ const char *DescribeMapFlags(int x) {
{MAP_NONBLOCK, "NONBLOCK"}, //
{MAP_POPULATE, "POPULATE"}, //
};
return DescribeFlags(mapflags, sizeof(mapflags), kMapFlags,
ARRAYLEN(kMapFlags), "MAP_", x);
return DescribeFlags(buf, 64, kMapFlags, ARRAYLEN(kMapFlags), "MAP_", x);
}

View file

@ -16,11 +16,12 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/intrin/describeflags.internal.h"
#include "libc/runtime/memtrack.internal.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/prot.h"
static noasan char DescribeMapType(int flags) {
static char DescribeMapType(int flags) {
switch (flags & MAP_TYPE) {
case MAP_FILE:
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[1] = (prot & PROT_WRITE) ? 'w' : '-';
p[2] = (prot & PROT_EXEC) ? 'x' : '-';
@ -43,9 +44,9 @@ noasan char *DescribeProt(int prot, char p[hasatleast 4]) {
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 */
DescribeProt(prot, p);
DescribeProt(p, prot);
p[3] = DescribeMapType(flags);
p[4] = (flags & MAP_ANONYMOUS) ? 'a' : '-';
p[5] = (flags & MAP_GROWSDOWN) ? 'G' : '-';

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -21,7 +21,7 @@
#include "libc/nt/enum/filemapflags.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[] = {
{POLLIN, "IN"}, // order matters
{POLLOUT, "OUT"}, // order matters
@ -35,5 +35,5 @@ const char *DescribePollFlags(char *buf, size_t size, int x) {
{POLLWRBAND, "WRBAND"}, //
{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"}, //
};
const char *DescribeProtFlags(int x) {
_Alignas(char) static char protflags[64];
return DescribeFlags(protflags, sizeof(protflags), kProtFlags,
ARRAYLEN(kProtFlags), "PROT_", x);
const char *(DescribeProtFlags)(char buf[48], int x) {
return DescribeFlags(buf, 48, kProtFlags, ARRAYLEN(kProtFlags), "PROT_", x);
}

View file

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

View file

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

View file

@ -20,8 +20,7 @@
#include "libc/fmt/itoa.h"
#include "libc/sysv/consts/rlimit.h"
const char *DescribeRlimitName(int resource) {
static char buf[12];
const char *(DescribeRlimitName)(char buf[12], int resource) {
if (resource == 127) return "n/a";
if (resource == RLIMIT_AS) return "RLIMIT_AS";
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/kprintf.h"
const char *DescribeSigaction(char *buf, size_t bufsize, int rc,
const struct sigaction *sa) {
char maskbuf[64];
const char *(DescribeSigaction)(char buf[128], int rc,
const struct sigaction *sa) {
if (rc == -1) return "n/a";
if (!sa) return "NULL";
if ((!IsAsan() && kisdangerous(sa)) ||
(IsAsan() && !__asan_is_valid(sa, sizeof(*sa)))) {
ksnprintf(buf, sizeof(buf), "%p", sa);
ksnprintf(buf, 128, "%p", sa);
} else {
ksnprintf(buf, bufsize, "{.sa_handler=%p, .sa_flags=%#lx, .sa_mask=%s}",
sa->sa_handler, sa->sa_flags,
DescribeSigset(maskbuf, sizeof(maskbuf), rc, &sa->sa_mask));
ksnprintf(buf, 128, "{.sa_handler=%p, .sa_flags=%#lx, .sa_mask=%s}",
sa->sa_handler, sa->sa_flags, DescribeSigset(rc, &sa->sa_mask));
}
return buf;
}

View file

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

View file

@ -23,8 +23,7 @@
#include "libc/intrin/kprintf.h"
#include "libc/str/str.h"
const char *DescribeSigset(char *buf, size_t bufsize, int rc,
const sigset_t *ss) {
const char *(DescribeSigset)(char buf[64], int rc, const sigset_t *ss) {
bool gotsome;
int i, n, sig;
sigset_t sigset;
@ -33,12 +32,12 @@ const char *DescribeSigset(char *buf, size_t bufsize, int rc,
if (!ss) return "NULL";
if ((!IsAsan() && kisdangerous(ss)) ||
(IsAsan() && !__asan_is_valid(ss, sizeof(*ss)))) {
ksnprintf(buf, sizeof(buf), "%p", ss);
ksnprintf(buf, 64, "%p", ss);
return buf;
}
i = 0;
n = bufsize;
n = 64;
sigset = *ss;
gotsome = false;
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.
*/
#include "libc/fmt/itoa.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/sysv/consts/sol.h"
/**
* Describes setsockopt() level arguments.
*/
char *DescribeSockLevel(int x) {
static char buf[12];
const char *(DescribeSockLevel)(char buf[12], int x) {
if (x == SOL_IP) return "SOL_IP";
if (x == SOL_TCP) return "SOL_TCP";
if (x == SOL_UDP) return "SOL_UDP";

View file

@ -18,34 +18,56 @@
*/
#include "libc/fmt/itoa.h"
#include "libc/fmt/magnumstrs.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/str/str.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.
*/
char *DescribeSockOptname(int l, int x) {
const char *(DescribeSockOptname)(char buf[32], int l, int x) {
int i;
char *ps, *s;
const struct MagnumStr *ms = 0;
_Alignas(char) static char buf[32];
char *s, *p;
const struct MagnumStr *ms;
p = buf;
if (x) {
if (l == SOL_SOCKET) {
ps = "SO_";
*p++ = 'S';
*p++ = 'O';
*p++ = '_';
*p = 0;
ms = kSockOptnames;
} else if (l == SOL_TCP) {
ps = "TCP_";
*p++ = 'T';
*p++ = 'C';
*p++ = 'P';
*p++ = '_';
ms = kTcpOptnames;
} else if (l == SOL_IP) {
ps = "IP_";
*p++ = 'I';
*p++ = 'P';
*p++ = '_';
*p = 0;
ms = kIpOptnames;
} else {
ms = 0;
}
} else {
ms = 0;
}
if (ms && (s = GetMagnumStr(ms, x))) {
stpcpy(stpcpy(buf, ps), s);
return buf;
StpCpy(p, s);
} else {
FormatInt32(buf, x);
return buf;
FormatInt32(p, x);
}
return buf;
}

View file

@ -21,20 +21,19 @@
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h"
const char *DescribeStat(int rc, const struct stat *st) {
_Alignas(char) static char buf[300];
const char *(DescribeStat)(char buf[300], int rc, const struct stat *st) {
int i, n;
if (rc == -1) return "n/a";
if (!st) return "NULL";
if ((!IsAsan() && kisdangerous(st)) ||
(IsAsan() && !__asan_is_valid(st, sizeof(*st)))) {
ksnprintf(buf, sizeof(buf), "%p", st);
ksnprintf(buf, 300, "%p", st);
return buf;
}
i = 0;
n = sizeof(buf);
n = 300;
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/kprintf.h"
const char *DescribeTimespec(char *buf, size_t bufsize, int rc,
const struct timespec *ts) {
const char *(DescribeTimespec)(char buf[45], int rc,
const struct timespec *ts) {
if (rc == -1) return "n/a";
if (!ts) return "NULL";
if ((!IsAsan() && kisdangerous(ts)) ||
(IsAsan() && !__asan_is_valid(ts, sizeof(*ts)))) {
ksnprintf(buf, bufsize, "%p", ts);
ksnprintf(buf, 45, "%p", ts);
} 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;
}

View file

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

View file

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

View file

@ -37,15 +37,14 @@ textwindows bool32 FindNextFile(int64_t hFindFile,
bool32 ok;
ok = __imp_FindNextFileW(hFindFile, out_lpFindFileData);
if (ok) {
NTTRACE(
"FindNextFile(%ld, [{"
".cFileName=%#hs, "
".dwFileAttributes=%s, "
".dwFileType=%s"
"}]) → %hhhd% m",
hFindFile, out_lpFindFileData->cFileName,
DescribeNtFileFlagsAndAttributes(out_lpFindFileData->dwFileAttributes),
DescribeNtFiletypeFlags(out_lpFindFileData->dwFileType), ok);
NTTRACE("FindNextFile(%ld, [{"
".cFileName=%#hs, "
".dwFileAttributes=%s, "
".dwFileType=%s"
"}]) → %hhhd% m",
hFindFile, out_lpFindFileData->cFileName,
DescribeNtFileFlagAttr(out_lpFindFileData->dwFileAttributes),
DescribeNtFiletypeFlags(out_lpFindFileData->dwFileType), ok);
} else {
if (GetLastError() != kNtErrorNoMoreFiles) __winerr();
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)
COSMOPOLITAN_C_START_
int _futex_wait(void *, int, struct timespec *);
int _futex_wake(void *, int);
int _futex(void *, int, int, struct timespec *, int *) hidden;
int _futex_wait(void *, int, struct timespec *) hidden;
int _futex_wake(void *, int) hidden;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -16,29 +16,29 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/bits/asmflag.h"
#include "libc/calls/strace.internal.h"
#include "libc/calls/struct/timespec.h"
#include "libc/fmt/itoa.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/futex.internal.h"
#include "libc/mem/alloca.h"
#include "libc/str/str.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;
bool cf;
char buf[45];
asm volatile(CFLAG_ASM("mov\t%6,%%r10\n\t"
"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");
ax = _futex(addr, FUTEX_WAIT, expect, timeout, 0);
STRACE("futex(%t[%p], FUTEX_WAIT, %d, %s) → %s", addr, addr, expect,
DescribeTimespec(0, timeout), DescribeFutexWaitResult(alloca(12), ax));
return ax;
}

View file

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

View file

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

View file

@ -18,7 +18,7 @@
*/
#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;
for (i = 0; ms[i].x != MAGNUM_TERMINATOR; ++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
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/assert.h"
#include "libc/calls/calls.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/nexgen32e/gettls.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.
@ -54,60 +51,10 @@ __msabi extern typeof(GetCurrentThreadId) *const __imp_GetCurrentThreadId;
* @threadsafe
*/
privileged int gettid(void) {
int rc;
int64_t wut;
struct WinThread *wt;
int tid;
if (__tls_enabled) {
rc = *(int *)(__get_tls_inline() + 0x38);
return rc;
tid = *(int *)(__get_tls_inline() + 0x38);
if (tid > 0) return tid;
}
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;
return sys_gettid();
}

View file

@ -28,7 +28,8 @@ LIBC_INTRIN_A_DIRECTDEPS = \
LIBC_SYSV \
LIBC_SYSV_CALLS \
LIBC_NEXGEN32E \
LIBC_NT_KERNEL32
LIBC_NT_KERNEL32 \
LIBC_NT_WS2_32
LIBC_INTRIN_A_DEPS := \
$(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_wake.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_unlock.o \
o/$(MODE)/libc/intrin/pthread_mutex_trylock.o \
@ -97,18 +99,21 @@ o/$(MODE)/libc/intrin/restorewintty.o: \
OVERRIDE_CFLAGS += \
-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/exit.greg.o \
o/$(MODE)/libc/intrin/exit1.greg.o \
o/$(MODE)/libc/intrin/getenv.greg.o \
o/$(MODE)/libc/intrin/assertfail.greg.o \
o/$(MODE)/libc/intrin/describeiov.greg.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/wsarecv.o \
o/$(MODE)/libc/intrin/wsarecvfrom.o \
o/$(MODE)/libc/intrin/createfile.o \
o/$(MODE)/libc/intrin/reopenfile.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/waitformultipleobjects.o \
o/$(MODE)/libc/intrin/generateconsolectrlevent.o \
o/$(MODE)/libc/intrin/wsawaitformultipleevents.o \
o/$(MODE)/libc/intrin/kstarttsc.o \
o/$(MODE)/libc/intrin/nomultics.o \
o/$(MODE)/libc/intrin/ntconsolemode.o: \
@ -150,10 +156,6 @@ o/$(MODE)/libc/intrin/ntconsolemode.o: \
-fno-stack-protector \
-fno-sanitize=all
o/$(MODE)/libc/intrin/describeopenflags.greg.o: \
OVERRIDE_CPPFLAGS += \
-DSTACK_FRAME_UNLIMITED
o//libc/intrin/memmove.o: \
OVERRIDE_CFLAGS += \
-fno-toplevel-reorder

View file

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

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