Make fixes and improvements

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

View file

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

View file

@ -0,0 +1,23 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
/**
* Disables assert() failures at runtime.
*/
bool __assert_disable;

View file

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

View file

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

View file

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

View file

@ -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/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.
*/
const char *(DescribeClockName)(char buf[32], int x) {
int i;
char *s, *p;
if ((s = GetMagnumStr(kClockNames, x))) {
p = buf;
*p++ = 'C';
*p++ = 'L';
*p++ = 'O';
*p++ = 'C';
*p++ = 'K';
*p++ = '_';
StpCpy(p, s);
return buf;
} else {
FormatInt32(buf, x);
return buf;
}
}

View file

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

View file

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

View file

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

View file

@ -16,6 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/macros.internal.h"
#include "libc/runtime/memtrack.internal.h"
@ -25,12 +26,11 @@
#define UNSHADOW(x) ((int64_t)(MAX(0, (x)-0x7fff8000)) << 3)
#define FRAME(x) ((int)((x) >> 16))
noasan const char *DescribeFrame(int x) {
const char *(DescribeFrame)(char buf[32], int x) {
/* asan runtime depends on this function */
char *p;
static char buf[32];
if (IsShadowFrame(x)) {
ksnprintf(buf, sizeof(buf), " shadow=%.8x", FRAME(UNSHADOW(ADDR(x))));
ksnprintf(buf, 32, " shadow=%.8x", FRAME(UNSHADOW(ADDR(x))));
return buf;
return " shadow ";
} else if (IsAutoFrame(x)) {

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

@ -0,0 +1,29 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/fmt/itoa.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/sysv/consts/sig.h"
const char *(DescribeHow)(char buf[12], int how) {
if (how == SIG_BLOCK) return "SIG_BLOCK";
if (how == SIG_UNBLOCK) return "SIG_UNBLOCK";
if (how == SIG_SETMASK) return "SIG_SETMASK";
FormatInt32(buf, how);
return buf;
}

View file

@ -0,0 +1,42 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/macros.internal.h"
#include "libc/nt/winsock.h"
void DescribeIovNt(const struct NtIovec *iov, uint32_t iovlen, ssize_t rem) {
int i;
if ((!IsAsan() && kisdangerous(iov)) ||
(IsAsan() && !__asan_is_valid(iov, iovlen * sizeof(struct NtIovec)))) {
kprintf("%p", iov);
return;
}
kprintf("{");
for (i = 0; rem && i < MIN(5, iovlen); ++i) {
kprintf("%s{%#.*hhs%s, %'zu}", i ? ", " : "",
MAX(0, MIN(40, MIN(rem, iov[i].len))), iov[i].buf,
MAX(0, MIN(40, MIN(rem, iov[i].len))) < iov[i].len ? "..." : "",
iov[i].len);
rem -= iov[i].len;
}
kprintf("%s}", iovlen > 5 ? "..." : "");
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -0,0 +1,36 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h"
const char *(DescribeSigaction)(char buf[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, 128, "%p", sa);
} else {
ksnprintf(buf, 128, "{.sa_handler=%p, .sa_flags=%#lx, .sa_mask=%s}",
sa->sa_handler, sa->sa_flags, DescribeSigset(rc, &sa->sa_mask));
}
return buf;
}

View file

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

View file

@ -0,0 +1,62 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/bits/popcnt.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/str/str.h"
const char *(DescribeSigset)(char buf[64], int rc, const sigset_t *ss) {
bool gotsome;
int i, n, sig;
sigset_t sigset;
if (rc == -1) return "n/a";
if (!ss) return "NULL";
if ((!IsAsan() && kisdangerous(ss)) ||
(IsAsan() && !__asan_is_valid(ss, sizeof(*ss)))) {
ksnprintf(buf, 64, "%p", ss);
return buf;
}
i = 0;
n = 64;
sigset = *ss;
gotsome = false;
if (popcnt(sigset.__bits[0]) + popcnt(sigset.__bits[1]) > 64) {
i += ksnprintf(buf + i, n - i, "~");
sigset.__bits[0] = ~sigset.__bits[0];
sigset.__bits[1] = ~sigset.__bits[1];
}
i += ksnprintf(buf + i, n - i, "{");
for (sig = 1; sig < 128; ++sig) {
if (sigismember(&sigset, sig)) {
if (gotsome) {
sig += ksnprintf(buf + sig, n - sig, ", ");
} else {
gotsome = true;
}
sig += ksnprintf(buf + sig, n - sig, "%s", strsignal(sig));
}
}
i += ksnprintf(buf + i, n - i, "}");
return buf;
}

View file

@ -0,0 +1,29 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/fmt/itoa.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/sysv/consts/af.h"
const char *(DescribeSocketFamily)(char buf[12], int family) {
if (family == AF_UNIX) return "AF_UNIX";
if (family == AF_INET) return "AF_INET";
if (family == AF_INET6) return "AF_INET6";
FormatInt32(buf, family);
return buf;
}

View file

@ -0,0 +1,32 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/fmt/itoa.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/sysv/consts/ipproto.h"
const char *(DescribeSocketProtocol)(char buf[12], int family) {
if (family == IPPROTO_IP) return "IPPROTO_IP";
if (family == IPPROTO_ICMP) return "IPPROTO_ICMP";
if (family == IPPROTO_TCP) return "IPPROTO_TCP";
if (family == IPPROTO_UDP) return "IPPROTO_UDP";
if (family == IPPROTO_RAW) return "IPPROTO_RAW";
if (family == IPPROTO_IPV6) return "IPPROTO_IPv6";
FormatInt32(buf, family);
return buf;
}

View file

@ -0,0 +1,54 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/fmt/itoa.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/sock.h"
static char *StpCpy(char *d, const char *s) {
size_t i;
for (i = 0;; ++i) {
if (!(d[i] = s[i])) {
return d + i;
}
}
}
const char *(DescribeSocketType)(char buf[64], int type) {
int x;
char *p;
p = buf;
x = type & ~(SOCK_CLOEXEC | SOCK_NONBLOCK);
if (x == SOCK_STREAM) {
p = StpCpy(p, "SOCK_STREAM");
} else if (x == SOCK_DGRAM) {
p = StpCpy(p, "SOCK_DGRAM");
} else if (x == SOCK_RAW) {
p = StpCpy(p, "SOCK_RAW");
} else if (x == SOCK_RDM) {
p = StpCpy(p, "SOCK_RDM");
} else if (x == SOCK_SEQPACKET) {
p = StpCpy(p, "SOCK_SEQPACKET");
} else {
p = FormatInt32(p, x);
}
if (type & SOCK_CLOEXEC) p = StpCpy(p, "|SOCK_CLOEXEC");
if (type & SOCK_NONBLOCK) p = StpCpy(p, "|SOCK_NONBLOCK");
return buf;
}

View file

@ -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/fmt/itoa.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/sysv/consts/sol.h"
/**
* Describes setsockopt() level arguments.
*/
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";
if (x == SOL_SOCKET) return "SOL_SOCKET";
FormatInt32(buf, x);
return buf;
}

View file

@ -0,0 +1,73 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2022 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/fmt/itoa.h"
#include "libc/fmt/magnumstrs.internal.h"
#include "libc/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.
*/
const char *(DescribeSockOptname)(char buf[32], int l, int x) {
int i;
char *s, *p;
const struct MagnumStr *ms;
p = buf;
if (x) {
if (l == SOL_SOCKET) {
*p++ = 'S';
*p++ = 'O';
*p++ = '_';
*p = 0;
ms = kSockOptnames;
} else if (l == SOL_TCP) {
*p++ = 'T';
*p++ = 'C';
*p++ = 'P';
*p++ = '_';
ms = kTcpOptnames;
} else if (l == SOL_IP) {
*p++ = 'I';
*p++ = 'P';
*p++ = '_';
*p = 0;
ms = kIpOptnames;
} else {
ms = 0;
}
} else {
ms = 0;
}
if (ms && (s = GetMagnumStr(ms, x))) {
StpCpy(p, s);
} else {
FormatInt32(p, x);
}
return buf;
}

View file

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

View file

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

View file

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

View file

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

View file

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

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

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

49
libc/intrin/kclocknames.S Normal file
View file

@ -0,0 +1,49 @@
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/fmt/magnumstrs.internal.h"
#include "libc/macros.internal.h"
.macro .e e s
.long \e - kClockNames
.long 1f - kClockNames
.rodata.str1.1
1: .string "\s"
.previous
.endm
.section .rodata
.align 4
.underrun
kClockNames:
.e CLOCK_REALTIME,"REALTIME"
.e CLOCK_REALTIME_FAST,"REALTIME_FAST"
.e CLOCK_MONOTONIC,"MONOTONIC"
.e CLOCK_MONOTONIC_FAST,"MONOTONIC_FAST"
.e CLOCK_MONOTONIC_RAW,"MONOTONIC_RAW"
.e CLOCK_REALTIME_COARSE,"REALTIME_COARSE"
.e CLOCK_MONOTONIC_COARSE,"MONOTONIC_COARSE"
.e CLOCK_PROCESS_CPUTIME_ID,"PROCESS_CPUTIME_ID"
.e CLOCK_TAI,"TAI"
.e CLOCK_PROF,"PROF"
.e CLOCK_BOOTTIME,"BOOTTIME"
.e CLOCK_REALTIME_ALARM,"REALTIME_ALARM"
.e CLOCK_BOOTTIME_ALARM,"BOOTTIME_ALARM"
.long MAGNUM_TERMINATOR
.endobj kClockNames,globl,hidden
.overrun

40
libc/intrin/kipoptnames.S Normal file
View file

@ -0,0 +1,40 @@
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/fmt/magnumstrs.internal.h"
#include "libc/macros.internal.h"
.macro .e e s
.long \e - kIpOptnames
.long 1f - kIpOptnames
.rodata.str1.1
1: .string "\s"
.previous
.endm
.section .rodata
.align 4
.underrun
kIpOptnames:
.e IP_TOS,"TOS" # int
.e IP_MTU,"MTU" # int
.e IP_TTL,"TTL" # int
.e IP_HDRINCL,"HDRINCL" # bool32
.long MAGNUM_TERMINATOR
.endobj kIpOptnames,globl,hidden
.overrun

View file

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

View file

@ -0,0 +1,71 @@
/*-*- 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/fmt/magnumstrs.internal.h"
#include "libc/macros.internal.h"
.macro .e e s
.long \e - kSignalNames
.long 1f - kSignalNames
.rodata.str1.1
1: .string "\s"
.previous
.endm
.section .rodata
.align 4
.underrun
kSignalNames:
.e SIGHUP,"SIGHUP"
.e SIGINT,"SIGINT"
.e SIGQUIT,"SIGQUIT"
.e SIGILL,"SIGILL"
.e SIGTRAP,"SIGTRAP"
.e SIGABRT,"SIGABRT"
.e SIGBUS,"SIGBUS"
.e SIGFPE,"SIGFPE"
.e SIGKILL,"SIGKILL"
.e SIGUSR1,"SIGUSR1"
.e SIGSEGV,"SIGSEGV"
.e SIGUSR2,"SIGUSR2"
.e SIGPIPE,"SIGPIPE"
.e SIGALRM,"SIGALRM"
.e SIGTERM,"SIGTERM"
.e SIGSTKFLT,"SIGSTKFLT"
.e SIGCHLD,"SIGCHLD"
.e SIGCONT,"SIGCONT"
.e SIGSTOP,"SIGSTOP"
.e SIGTSTP,"SIGTSTP"
.e SIGTTIN,"SIGTTIN"
.e SIGTTOU,"SIGTTOU"
.e SIGURG,"SIGURG"
.e SIGXCPU,"SIGXCPU"
.e SIGXFSZ,"SIGXFSZ"
.e SIGVTALRM,"SIGVTALRM"
.e SIGPROF,"SIGPROF"
.e SIGWINCH,"SIGWINCH"
.e SIGIO,"SIGIO"
.e SIGSYS,"SIGSYS"
.e SIGINFO,"SIGINFO"
.e SIGRTMAX,"SIGRTMAX"
.e SIGRTMIN,"SIGRTMIN"
.e SIGEMT,"SIGEMT"
.e SIGPWR,"SIGPWR"
.long MAGNUM_TERMINATOR
.endobj kSignalNames,globl,hidden
.overrun

View file

@ -0,0 +1,52 @@
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/fmt/magnumstrs.internal.h"
#include "libc/macros.internal.h"
.macro .e e s
.long \e - kSockOptnames
.long 1f - kSockOptnames
.rodata.str1.1
1: .string "\s"
.previous
.endm
.section .rodata
.align 4
.underrun
kSockOptnames:
.e SO_DEBUG,"DEBUG" # bool32
.e SO_ACCEPTCONN,"ACCEPTCONN" # bool32
.e SO_BROADCAST,"BROADCAST" # bool32
.e SO_REUSEADDR,"REUSEADDR" # bool32
.e SO_REUSEPORT,"REUSEPORT" # bool32
.e SO_KEEPALIVE,"KEEPALIVE" # bool32
.e SO_DONTROUTE,"DONTROUTE" # bool32
.e SO_RCVTIMEO,"RCVTIMEO" # timeval
.e SO_SNDTIMEO,"SNDTIMEO" # timeval
.e SO_LINGER,"LINGER" # linger
.e SO_TYPE,"TYPE" # int
.e SO_SNDBUF,"SNDBUF" # int
.e SO_RCVBUF,"RCVBUF" # int
.e SO_RCVLOWAT,"RCVLOWAT" # int
.e SO_SNDLOWAT,"SNDLOWAT" # int
.e SO_ERROR,"ERROR" # int
.long MAGNUM_TERMINATOR
.endobj kSockOptnames,globl,hidden
.overrun

View file

@ -0,0 +1,49 @@
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi
Copyright 2021 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/fmt/magnumstrs.internal.h"
#include "libc/macros.internal.h"
.macro .e e s
.long \e - kTcpOptnames
.long 1f - kTcpOptnames
.rodata.str1.1
1: .string "\s"
.previous
.endm
.section .rodata
.align 4
.underrun
kTcpOptnames:
.e TCP_NODELAY,"NODELAY" # bool32
.e TCP_CORK,"CORK" # bool32
.e TCP_QUICKACK,"QUICKACK" # bool32
.e TCP_FASTOPEN_CONNECT,"FASTOPEN_CONNECT" # bool32
.e TCP_DEFER_ACCEPT,"DEFER_ACCEPT" # bool32
.e TCP_KEEPIDLE,"KEEPIDLE" # int (seconds)
.e TCP_KEEPINTVL,"KEEPINTVL" # int (seconds)
.e TCP_FASTOPEN,"FASTOPEN" # int
.e TCP_KEEPCNT,"KEEPCNT" # int
.e TCP_MAXSEG,"MAXSEG" # int
.e TCP_SYNCNT,"SYNCNT" # int
.e TCP_NOTSENT_LOWAT,"NOTSENT_LOWAT" # int
.e TCP_WINDOW_CLAMP,"WINDOW_CLAMP" # int
.long MAGNUM_TERMINATOR
.endobj kTcpOptnames,globl,hidden
.overrun

View file

@ -35,6 +35,6 @@ textwindows bool32 MoveFileEx(const char16_t *lpExistingFileName,
ok = __imp_MoveFileExW(lpExistingFileName, lpNewFileName, dwFlags);
if (!ok) __winerr();
NTTRACE("MoveFileEx(%#hs, %#hs, %s) → %hhhd% m", lpExistingFileName,
lpNewFileName, DescribeNtMoveFileInputFlags(dwFlags), ok);
lpNewFileName, DescribeNtMovFileInpFlags(dwFlags), ok);
return ok;
}

View file

@ -40,7 +40,7 @@ textwindows int64_t OpenProcess(uint32_t dwDesiredAccess, bool32 bInheritHandle,
hHandle = __imp_OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
if (!hHandle) __winerr();
NTTRACE("OpenProcess(%s, %hhhd, %u) → %ld% m",
DescribeNtProcessAccessFlags(dwDesiredAccess), bInheritHandle,
DescribeNtProcAccessFlags(dwDesiredAccess), bInheritHandle,
dwProcessId, hHandle);
return hHandle;
}

View file

@ -126,16 +126,15 @@ void *pthread_getspecific(pthread_key_t);
!atomic_exchange(&(mutex)->lock, 1)) \
? 0 \
: pthread_mutex_lock(mutex))
/*
#define pthread_mutex_unlock(mutex) \
((mutex)->attr == PTHREAD_MUTEX_NORMAL \
? (atomic_store_explicit(&(mutex)->lock, 0, memory_order_relaxed), \
((IsLinux() || IsOpenbsd()) && \
((IsLinux() /* || IsOpenbsd() */) && \
atomic_load_explicit(&(mutex)->waits, memory_order_relaxed) && \
_pthread_mutex_wake(mutex)), \
0) \
: pthread_mutex_unlock(mutex))
*/
#endif
int _pthread_mutex_wake(pthread_mutex_t *) hidden;

View file

@ -16,6 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/assert.h"
#include "libc/errno.h"
#include "libc/intrin/pthread.h"
#include "libc/str/str.h"
@ -29,6 +30,7 @@ int pthread_mutex_destroy(pthread_mutex_t *mutex) {
if (!mutex->lock && !mutex->waits) {
rc = 0;
} else {
assert(!"dead lock");
rc = EDEADLK;
}
bzero(mutex, sizeof(*mutex));

View file

@ -16,6 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/assert.h"
#include "libc/bits/asmflag.h"
#include "libc/bits/atomic.h"
#include "libc/calls/calls.h"
@ -29,15 +30,16 @@
#include "libc/sysv/consts/futex.h"
#include "libc/sysv/consts/nr.h"
static int pthread_mutex_lock_spin(pthread_mutex_t *mutex, int tries) {
static int pthread_mutex_lock_spin(pthread_mutex_t *mutex, int expect,
int tries) {
volatile int i;
if (tries < 7) {
for (i = 0; i != 1 << tries; i++) {
}
tries++;
} else if (IsLinux() || IsOpenbsd()) {
} else if (IsLinux() /* || IsOpenbsd() */) {
atomic_fetch_add(&mutex->waits, 1);
_futex_wait(&mutex->lock, 1, &(struct timespec){1});
_futex_wait(&mutex->lock, expect, &(struct timespec){1});
atomic_fetch_sub(&mutex->waits, 1);
} else {
sched_yield();
@ -64,7 +66,7 @@ int(pthread_mutex_lock)(pthread_mutex_t *mutex) {
!atomic_exchange_explicit(&mutex->lock, 1, memory_order_acquire)) {
break;
}
tries = pthread_mutex_lock_spin(mutex, tries);
tries = pthread_mutex_lock_spin(mutex, 1, tries);
}
return 0;
case PTHREAD_MUTEX_RECURSIVE:
@ -79,14 +81,16 @@ int(pthread_mutex_lock)(pthread_mutex_t *mutex) {
if (mutex->attr != PTHREAD_MUTEX_ERRORCHECK) {
break;
} else {
assert(!"dead lock");
return EDEADLK;
}
}
tries = pthread_mutex_lock_spin(mutex, tries);
tries = pthread_mutex_lock_spin(mutex, owner, tries);
}
++mutex->reent;
return 0;
default:
assert(!"inva lock");
return EINVAL;
}
}

View file

@ -16,6 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/assert.h"
#include "libc/bits/atomic.h"
#include "libc/calls/calls.h"
#include "libc/errno.h"
@ -33,19 +34,23 @@ int(pthread_mutex_unlock)(pthread_mutex_t *mutex) {
case PTHREAD_MUTEX_ERRORCHECK:
me = gettid();
owner = atomic_load_explicit(&mutex->lock, memory_order_relaxed);
if (owner != me) return EPERM;
if (owner != me) {
assert(!"perm lock");
return EPERM;
}
// fallthrough
case PTHREAD_MUTEX_RECURSIVE:
if (--mutex->reent) return 0;
// fallthrough
case PTHREAD_MUTEX_NORMAL:
atomic_store_explicit(&mutex->lock, 0, memory_order_relaxed);
if ((IsLinux() || IsOpenbsd()) &&
if ((IsLinux() /* || IsOpenbsd() */) &&
atomic_load_explicit(&mutex->waits, memory_order_relaxed) > 0) {
_pthread_mutex_wake(mutex);
}
return 0;
default:
assert(!"inva lock");
return EINVAL;
}
}

View file

@ -16,6 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/bits/atomic.h"
#include "libc/intrin/futex.internal.h"
#include "libc/intrin/pthread.h"

View file

@ -39,6 +39,6 @@ int64_t ReOpenFile(int64_t hOriginalFile, uint32_t dwDesiredAccess,
NTTRACE("ReOpenFile(%ld, %s, %s, %s) → %ld% m", hOriginalFile,
DescribeNtFileAccessFlags(dwDesiredAccess),
DescribeNtFileShareFlags(dwShareMode),
DescribeNtFileFlagsAndAttributes(dwFlagsAndAttributes), hHandle);
DescribeNtFileFlagAttr(dwFlagsAndAttributes), hHandle);
return hHandle;
}

37
libc/intrin/sigaddset.c Normal file
View file

@ -0,0 +1,37 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/struct/sigset.h"
#include "libc/sysv/errfuns.h"
/**
* Adds signal to set.
*
* @return 0 on success, or -1 w/ errno
* @raises EINVAL if `1 sig NSIG` isn't the case
* @asyncsignalsafe
*/
int sigaddset(sigset_t *set, int sig) {
_Static_assert(sizeof(set->__bits[0]) * CHAR_BIT == 64, "");
if (1 <= sig && sig <= NSIG) {
set->__bits[(sig - 1) >> 6] |= 1ull << ((sig - 1) & 63);
return 0;
} else {
return einval();
}
}

37
libc/intrin/sigdelset.c Normal file
View file

@ -0,0 +1,37 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/struct/sigset.h"
#include "libc/sysv/errfuns.h"
/**
* Removes signal from set.
*
* @return 0 on success, or -1 w/ errno
* @raises EINVAL if `1 sig NSIG` isn't the case
* @asyncsignalsafe
*/
int sigdelset(sigset_t *set, int sig) {
_Static_assert(sizeof(set->__bits[0]) * CHAR_BIT == 64, "");
if (1 <= sig && sig <= NSIG) {
set->__bits[(sig - 1) >> 6] &= ~(1ull << ((sig - 1) & 63));
return 0;
} else {
return einval();
}
}

31
libc/intrin/sigemptyset.c Normal file
View file

@ -0,0 +1,31 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/struct/sigset.h"
#include "libc/str/str.h"
/**
* Removes all signals from set.
*
* @return 0 on success, or -1 w/ errno
* @asyncsignalsafe
*/
int sigemptyset(sigset_t *set) {
bzero(set->__bits, sizeof(set->__bits));
return 0;
}

32
libc/intrin/sigfillset.c Normal file
View file

@ -0,0 +1,32 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/struct/sigset.h"
#include "libc/str/str.h"
/**
* Adds all signals to set.
*
* @return 0 on success, or -1 w/ errno
* @asyncsignalsafe
* @vforksafe
*/
int sigfillset(sigset_t *set) {
memset(set->__bits, -1, sizeof(set->__bits));
return 0;
}

37
libc/intrin/sigismember.c Normal file
View file

@ -0,0 +1,37 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/struct/sigset.h"
#include "libc/sysv/errfuns.h"
/**
* Returns true if signal is member of set.
*
* @return 1 if set, 0 if not set, or -1 w/ errno
* @raises EINVAL if `1 sig NSIG` isn't the case
* @asyncsignalsafe
* @vforksafe
*/
int sigismember(const sigset_t *set, int sig) {
_Static_assert(sizeof(set->__bits[0]) * CHAR_BIT == 64, "");
if (1 <= sig && sig <= NSIG) {
return !!(set->__bits[(sig - 1) >> 6] & (1ull << ((sig - 1) & 63)));
} else {
return einval();
}
}

67
libc/intrin/strsignal.c Normal file
View file

@ -0,0 +1,67 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/fmt/magnumstrs.internal.h"
#include "libc/str/str.h"
static char g_strsignal[12];
/**
* Returns string describing signal code.
*
* This returns SIGZERO for 0 which is the empty value. Textual names
* should be available for signals 1 through 32. Signals in the range 33
* and 128 are returned as a `SIG%03d` string. Everything else is SIGWUT
*
* This function is thread safe when `sig` is a known signal magnum.
* Otherwise a pointer to static memory is returned which is unsafe.
*
* @param sig is signal number which should be in range 1 through 128
* @return pointer to static memory that mutates on subsequent calls
* @see sigaction()
* @threadsafe
*/
char *strsignal(int sig) {
char *p;
const char *s;
if (!sig) return "0";
if ((s = GetMagnumStr(kSignalNames, sig))) return s;
p = g_strsignal;
p[0] = 'S';
p[1] = 'I';
p[2] = 'G';
p[3] = 0;
if (!sig) {
p[3] = 'Z';
p[4] = 'E';
p[5] = 'R';
p[6] = 'O';
p[7] = 0;
} else if (1 <= sig && sig <= 128) {
p[3] = '0' + sig / 100;
p[4] = '0' + sig / 10 % 10;
p[5] = '0' + sig % 10;
p[6] = 0;
} else {
p[3] = 'W';
p[4] = 'U';
p[5] = 'T';
p[6] = 0;
}
return g_strsignal;
}

View file

@ -0,0 +1,64 @@
/*-*- 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/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/nt/thread.h"
#include "libc/nt/thunk/msabi.h"
#include "libc/runtime/internal.h"
__msabi extern typeof(GetCurrentThreadId) *const __imp_GetCurrentThreadId;
privileged int sys_gettid(void) {
int tid;
int64_t wut;
if (IsWindows()) {
tid = __imp_GetCurrentThreadId();
} else if (IsLinux()) {
asm("syscall"
: "=a"(tid) // man says always succeeds
: "0"(186) // __NR_gettid
: "rcx", "r11", "memory");
} else if (IsXnu()) {
asm("syscall" // xnu/osfmk/kern/ipc_tt.c
: "=a"(tid) // assume success
: "0"(0x1000000 | 27) // Mach thread_self_trap()
: "rcx", "r11", "memory", "cc");
} else if (IsOpenbsd()) {
asm("syscall"
: "=a"(tid) // man says always succeeds
: "0"(299) // getthrid()
: "rcx", "r11", "memory", "cc");
} else if (IsNetbsd()) {
asm("syscall"
: "=a"(tid) // man says always succeeds
: "0"(311) // _lwp_self()
: "rcx", "rdx", "r11", "memory", "cc");
} else if (IsFreebsd()) {
asm("syscall"
: "=a"(tid), // 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");
tid = wut;
} else {
tid = __pid;
}
return tid;
}

View file

@ -49,7 +49,7 @@
*/
privileged void *__initialize_tls(char tib[64]) {
if (tib) {
*(intptr_t *)tib = (intptr_t)tib;
*(intptr_t *)(tib + 0x00) = (intptr_t)tib;
*(intptr_t *)(tib + 0x30) = (intptr_t)tib;
*(int *)(tib + 0x38) = -1; // tid
*(int *)(tib + 0x3c) = 0;

View file

@ -24,11 +24,6 @@
__msabi extern typeof(VirtualProtect) *const __imp_VirtualProtect;
static const char *DescribeVpFlags(uint32_t *x) {
if (!x) return "n/a";
return DescribeNtPageFlags(*x);
}
/**
* Protects memory on the New Technology.
* @note this wrapper takes care of ABI, STRACE(), and __winerr()
@ -42,6 +37,6 @@ textwindows bool32 VirtualProtect(void *lpAddress, uint64_t dwSize,
if (!bOk) __winerr();
NTTRACE("VirtualProtect(%p, %'zu, %s, [%s]) → %hhhd% m", lpAddress, dwSize,
DescribeNtPageFlags(flNewProtect),
DescribeVpFlags(bOk ? lpflOldProtect : 0), bOk);
DescribeNtPageFlags(*lpflOldProtect), bOk);
return bOk;
}

View file

@ -16,6 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/assert.h"
#include "libc/bits/atomic.h"
#include "libc/calls/calls.h"
#include "libc/dce.h"
@ -30,12 +31,12 @@
* by the clone() system call when a thread terminates. The purpose of
* this operation is to know when it's safe to munmap() a thread stack.
*/
void _wait0(int *ptid) {
void _wait0(const int *ptid) {
int x;
for (;;) {
if (!(x = atomic_load_explicit(ptid, memory_order_relaxed))) {
if (!(x = atomic_load_explicit(ptid, memory_order_acquire))) {
break;
} else if (IsLinux() || IsOpenbsd()) {
} else if (IsLinux() /* || IsOpenbsd() */) {
_futex_wait(ptid, x, &(struct timespec){2});
} else {
sched_yield();

View file

@ -3,7 +3,7 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
void _wait0(int *) hidden;
void _wait0(const int *) hidden;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

68
libc/intrin/wsarecv.c Normal file
View file

@ -0,0 +1,68 @@
/*-*- 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/strace.internal.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/nt/thunk/msabi.h"
#include "libc/nt/winsock.h"
__msabi extern typeof(WSARecv) *const __imp_WSARecv;
/**
* Receives data from Windows socket.
*
* @return 0 on success, or -1 on failure
* @note this wrapper takes care of ABI, STRACE(), and __winerr()
*/
textwindows int WSARecv(
uint64_t s, const struct NtIovec *inout_lpBuffers, uint32_t dwBufferCount,
uint32_t *opt_out_lpNumberOfBytesRecvd, uint32_t *inout_lpFlags,
struct NtOverlapped *opt_inout_lpOverlapped,
const NtWsaOverlappedCompletionRoutine opt_lpCompletionRoutine) {
int rc;
#if defined(SYSDEBUG) && _NTTRACE
uint32_t NumberOfBytesRecvd;
if (opt_out_lpNumberOfBytesRecvd) {
NumberOfBytesRecvd = *opt_out_lpNumberOfBytesRecvd;
}
rc = __imp_WSARecv(s, inout_lpBuffers, dwBufferCount, &NumberOfBytesRecvd,
inout_lpFlags, opt_inout_lpOverlapped,
opt_lpCompletionRoutine);
if (opt_out_lpNumberOfBytesRecvd) {
*opt_out_lpNumberOfBytesRecvd = NumberOfBytesRecvd;
}
if (rc == -1) {
__winerr();
}
if (UNLIKELY(__strace > 0)) {
kprintf(STRACE_PROLOGUE "WSARecv(%lu, [", s);
DescribeIovNt(inout_lpBuffers, dwBufferCount,
rc != -1 ? NumberOfBytesRecvd : 0);
kprintf("], %u, [%'u], %p, %p, %p) → %d% lm\n", dwBufferCount,
NumberOfBytesRecvd, inout_lpFlags, opt_inout_lpOverlapped,
opt_lpCompletionRoutine, rc);
}
#else
rc = __imp_WSARecv(s, inout_lpBuffers, dwBufferCount,
opt_out_lpNumberOfBytesRecvd, inout_lpFlags,
opt_inout_lpOverlapped, opt_lpCompletionRoutine);
#endif
return rc;
}

71
libc/intrin/wsarecvfrom.c Normal file
View file

@ -0,0 +1,71 @@
/*-*- 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/strace.internal.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/nt/thunk/msabi.h"
#include "libc/nt/winsock.h"
__msabi extern typeof(WSARecvFrom) *const __imp_WSARecvFrom;
/**
* Receives data from Windows socket.
*
* @return 0 on success, or -1 on failure
* @note this wrapper takes care of ABI, STRACE(), and __winerr()
*/
textwindows int WSARecvFrom(
uint64_t s, const struct NtIovec *inout_lpBuffers, uint32_t dwBufferCount,
uint32_t *opt_out_lpNumberOfBytesRecvd, uint32_t *inout_lpFlags,
void *opt_out_fromsockaddr, uint32_t *opt_inout_fromsockaddrlen,
struct NtOverlapped *opt_inout_lpOverlapped,
const NtWsaOverlappedCompletionRoutine opt_lpCompletionRoutine) {
int rc;
#if defined(SYSDEBUG) && _NTTRACE
uint32_t NumberOfBytesRecvd;
if (opt_out_lpNumberOfBytesRecvd) {
NumberOfBytesRecvd = *opt_out_lpNumberOfBytesRecvd;
}
rc = __imp_WSARecvFrom(s, inout_lpBuffers, dwBufferCount, &NumberOfBytesRecvd,
inout_lpFlags, opt_out_fromsockaddr,
opt_inout_fromsockaddrlen, opt_inout_lpOverlapped,
opt_lpCompletionRoutine);
if (opt_out_lpNumberOfBytesRecvd) {
*opt_out_lpNumberOfBytesRecvd = NumberOfBytesRecvd;
}
if (rc == -1) {
__winerr();
}
if (UNLIKELY(__strace > 0)) {
kprintf(STRACE_PROLOGUE "WSARecvFrom(%lu, [", s);
DescribeIovNt(inout_lpBuffers, dwBufferCount,
rc != -1 ? NumberOfBytesRecvd : 0);
kprintf("], %u, [%'u], %p, %p, %p, %p, %p) → %d% lm\n", dwBufferCount,
NumberOfBytesRecvd, opt_out_fromsockaddr, opt_inout_fromsockaddrlen,
inout_lpFlags, opt_inout_lpOverlapped, opt_lpCompletionRoutine, rc);
}
#else
rc = __imp_WSARecvFrom(s, inout_lpBuffers, dwBufferCount,
opt_out_lpNumberOfBytesRecvd, opt_out_fromsockaddr,
opt_inout_fromsockaddrlen, inout_lpFlags,
opt_inout_lpOverlapped, opt_lpCompletionRoutine);
#endif
return rc;
}

View file

@ -0,0 +1,46 @@
/*-*- 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/strace.internal.h"
#include "libc/calls/syscall_support-nt.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/nt/thunk/msabi.h"
#include "libc/nt/winsock.h"
__msabi extern typeof(WSAWaitForMultipleEvents) *const
__imp_WSAWaitForMultipleEvents;
/**
* Waits for events on Windows sockets.
*
* @return 0 on success, or -1 on failure
* @note this wrapper takes care of ABI, STRACE(), and __winerr()
*/
textwindows uint32_t WSAWaitForMultipleEvents(uint32_t cEvents,
const int64_t *lphEvents,
bool32 fWaitAll,
uint32_t dwTimeout_ms,
bool32 fAlertable) {
uint32_t rc;
rc = __imp_WSAWaitForMultipleEvents(cEvents, lphEvents, fWaitAll,
dwTimeout_ms, fAlertable);
POLLTRACE("WSAWaitForMultipleEvents(%u, %p, %hhhd, %'u, %hhhd) → %u% lm",
cEvents, lphEvents, fWaitAll, dwTimeout_ms, fAlertable, rc);
return rc;
}