mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
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:
parent
5d837c4e7c
commit
fbc053e018
186 changed files with 1836 additions and 1325 deletions
1
Makefile
1
Makefile
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ? "..." : "");
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) */
|
||||
|
|
|
@ -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) ||
|
||||
|
|
23
libc/intrin/assertdisable.c
Normal file
23
libc/intrin/assertdisable.c
Normal 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;
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
|
@ -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;
|
|
@ -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;
|
|
@ -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) */
|
||||
|
|
|
@ -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
29
libc/intrin/describehow.c
Normal 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;
|
||||
}
|
42
libc/intrin/describeiovnt.c
Normal file
42
libc/intrin/describeiovnt.c
Normal 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 ? "..." : "");
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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' : '-';
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
33
libc/intrin/describeprctloperation.c
Normal file
33
libc/intrin/describeprctloperation.c
Normal 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_???";
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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";
|
35
libc/intrin/describeseccompoperation.c
Normal file
35
libc/intrin/describeseccompoperation.c
Normal 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_???";
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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) {
|
29
libc/intrin/describesocketfamily.c
Normal file
29
libc/intrin/describesocketfamily.c
Normal 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;
|
||||
}
|
32
libc/intrin/describesocketprotocol.c
Normal file
32
libc/intrin/describesocketprotocol.c
Normal 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;
|
||||
}
|
54
libc/intrin/describesockettype.c
Normal file
54
libc/intrin/describesockettype.c
Normal 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;
|
||||
}
|
|
@ -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";
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
28
libc/intrin/futex.S
Normal 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
|
|
@ -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) */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)) {
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue