mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-04 18:28:30 +00:00
Improve system calls
- Wrap clock_getres() - Wrap sched_setscheduler() - Make sleep() api conformant - Polyfill sleep() using select() - Improve clock_gettime() polyfill - Make nanosleep() POSIX conformant - Slightly improve some DNS functions - Further strengthen pledge() sandboxing - Improve rounding of timeval / timespec - Allow layering of pledge() calls on Linux - Polyfill sched_yield() using select() on XNU - Delete more system constants we probably don't need
This commit is contained in:
parent
5df3e4e7a8
commit
853b6c3864
330 changed files with 1971 additions and 1223 deletions
|
@ -2,11 +2,13 @@
|
|||
#define COSMOPOLITAN_LIBC_INTRIN_DESCRIBEFLAGS_INTERNAL_H_
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/calls/struct/rlimit.h"
|
||||
#include "libc/calls/struct/sched_param.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/sigaltstack.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/mem/alloca.h"
|
||||
#include "libc/nt/struct/iovec.h"
|
||||
#include "libc/nt/struct/securityattributes.h"
|
||||
|
@ -52,6 +54,8 @@ 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[20], int);
|
||||
const char *DescribeSchedParam(char[32], const struct sched_param *);
|
||||
const char *DescribeSchedPolicy(char[48], int);
|
||||
const char *DescribeSeccompOperation(int);
|
||||
const char *DescribeSigaction(char[128], int, const struct sigaction *);
|
||||
const char *DescribeSigaltstk(char[128], int, const struct sigaltstack *);
|
||||
|
@ -64,6 +68,7 @@ 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 *);
|
||||
const char *DescribeTimeval(char[45], int, const struct timeval *);
|
||||
|
||||
void DescribeIov(const struct iovec *, int, ssize_t);
|
||||
void DescribeIovNt(const struct NtIovec *, uint32_t, ssize_t);
|
||||
|
@ -95,6 +100,8 @@ void DescribeIovNt(const struct NtIovec *, uint32_t, ssize_t);
|
|||
#define DescribeRemapFlags(dirfd) DescribeRemapFlags(alloca(48), dirfd)
|
||||
#define DescribeRlimit(rc, rl) DescribeRlimit(alloca(64), rc, rl)
|
||||
#define DescribeRlimitName(rl) DescribeRlimitName(alloca(20), rl)
|
||||
#define DescribeSchedParam(x) DescribeSchedParam(alloca(32), x)
|
||||
#define DescribeSchedPolicy(x) DescribeSchedPolicy(alloca(48), x)
|
||||
#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)
|
||||
|
@ -106,6 +113,7 @@ void DescribeIovNt(const struct NtIovec *, uint32_t, ssize_t);
|
|||
#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)
|
||||
#define DescribeTimeval(rc, ts) DescribeTimeval(alloca(45), rc, ts)
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
36
libc/intrin/describeschedparam.c
Normal file
36
libc/intrin/describeschedparam.c
Normal 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 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/sched_param.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* Describes clock_gettime() clock argument.
|
||||
*/
|
||||
const char *(DescribeSchedParam)(char buf[32], const struct sched_param *x) {
|
||||
char *p;
|
||||
if (!x) return "0";
|
||||
p = buf;
|
||||
*p++ = '{';
|
||||
p = FormatInt32(p, x->sched_priority);
|
||||
*p++ = '}';
|
||||
*p = 0;
|
||||
return buf;
|
||||
}
|
40
libc/intrin/describeschedpolicy.c
Normal file
40
libc/intrin/describeschedpolicy.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*-*- 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/macros.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/sched.h"
|
||||
|
||||
/**
|
||||
* Describes clock_gettime() clock argument.
|
||||
*/
|
||||
const char *(DescribeSchedPolicy)(char buf[48], int x) {
|
||||
struct DescribeFlags flags[] = {
|
||||
{SCHED_RESET_ON_FORK, "RESET_ON_FORK"}, //
|
||||
{SCHED_OTHER, "OTHER"}, //
|
||||
{SCHED_FIFO, "FIFO"}, //
|
||||
{SCHED_RR, "RR"}, //
|
||||
{SCHED_BATCH, "BATCH"}, //
|
||||
{SCHED_IDLE, "IDLE"}, //
|
||||
{SCHED_DEADLINE, "DEADLINE"}, //
|
||||
};
|
||||
return DescribeFlags(buf, 48, flags, ARRAYLEN(flags), "SCHED_", x);
|
||||
}
|
35
libc/intrin/describetimeval.c
Normal file
35
libc/intrin/describetimeval.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 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/timeval.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
|
||||
const char *(DescribeTimeval)(char buf[45], int rc, const struct timeval *tv) {
|
||||
if (rc == -1) return "n/a";
|
||||
if (!tv) return "NULL";
|
||||
if ((!IsAsan() && kisdangerous(tv)) ||
|
||||
(IsAsan() && !__asan_is_valid(tv, sizeof(*tv)))) {
|
||||
ksnprintf(buf, 45, "%p", tv);
|
||||
} else {
|
||||
ksnprintf(buf, 45, "{%ld, %ld}", tv->tv_sec, tv->tv_usec);
|
||||
}
|
||||
return buf;
|
||||
}
|
|
@ -145,10 +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: \
|
||||
o/$(MODE)/libc/intrin/wsawaitformultipleevents.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-Os \
|
||||
-fwrapv \
|
||||
|
|
|
@ -22,17 +22,11 @@
|
|||
.privileged
|
||||
|
||||
// Asks kernel to let other threads be scheduled.
|
||||
//
|
||||
// @return 0 on success, or -1 w/ errno
|
||||
// @return 0 on success, or non-zero on failure
|
||||
// @norestart
|
||||
sched_yield:
|
||||
|
||||
#if SupportsXnu()
|
||||
testb IsXnu()
|
||||
jz 1f
|
||||
pause
|
||||
xor %eax,%eax
|
||||
ret
|
||||
#endif
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
|
||||
#if SupportsWindows()
|
||||
// Windows Support
|
||||
|
@ -46,32 +40,43 @@ sched_yield:
|
|||
// ──Quoth MSDN
|
||||
testb IsWindows()
|
||||
jz 1f
|
||||
push %rbp
|
||||
mov %rsp,%rbp
|
||||
xor %ecx,%ecx
|
||||
xor %edx,%edx
|
||||
ntcall __imp_SleepEx
|
||||
xor %eax,%eax
|
||||
pop %rbp
|
||||
ret
|
||||
jmp 9f
|
||||
1:
|
||||
#endif
|
||||
|
||||
#if SupportsSystemv()
|
||||
// UNIX Support
|
||||
1: mov __NR_sched_yield,%eax
|
||||
#if SupportsBsd() && SupportsLinux()
|
||||
clc
|
||||
#endif
|
||||
// On XNU we polyfill sched_yield() using sleep() which'll
|
||||
// be polyfilled using select() with a zero timeout, which
|
||||
// means to wait zero microseconds and then returns a zero
|
||||
// and this hopefully will give other threads a chance too
|
||||
//
|
||||
// "If the readfds, writefds, and errorfds arguments are
|
||||
// all null pointers and the timeout argument is not a
|
||||
// null pointer, the pselect() or select() function shall
|
||||
// block for the time specified, or until interrupted by
|
||||
// a signal." ──Quoth IEEE 1003.1-2017 §functions/select
|
||||
//
|
||||
// On other platforms, sched_yield() takes no arguments.
|
||||
push $0 # timeout.tv_usec
|
||||
push $0 # timeout.tv_sec
|
||||
xor %edi,%edi # nfds
|
||||
xor %esi,%esi # readfds
|
||||
xor %edx,%edx # writefds
|
||||
xor %r10d,%r10d # exceptfds
|
||||
mov %rsp,%r8 # timeout
|
||||
mov __NR_sched_yield,%eax # ordinal
|
||||
clc # linux
|
||||
syscall
|
||||
#if SupportsBsd()
|
||||
jc systemfive_errno
|
||||
#endif
|
||||
#if SupportsLinux()
|
||||
cmp $-4095,%rax
|
||||
jae systemfive_error
|
||||
#endif
|
||||
// It should not be possible for this to fail so we don't
|
||||
// bother going through the errno ritual. If this somehow
|
||||
// fails a positive or negative errno might get returned.
|
||||
#endif
|
||||
|
||||
2: ret
|
||||
9: leave
|
||||
ret
|
||||
.endfn sched_yield,globl
|
||||
.previous
|
||||
|
|
45
libc/intrin/timespec2timeval.c
Normal file
45
libc/intrin/timespec2timeval.c
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*-*- 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/timespec.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
|
||||
// we don't want instrumentation because:
|
||||
// - nanosleep() depends on this and ftrace can take microsecs
|
||||
|
||||
/**
|
||||
* Converts `struct timespec` to `struct timeval`.
|
||||
*
|
||||
* This divides ts.tv_nsec by 1000 with upward rounding and overflow
|
||||
* handling. Your ts.tv_nsec must be on the interval `[0,1000000000)`
|
||||
* otherwise `{-1, -1}` is returned.
|
||||
*
|
||||
* @return converted timeval whose tv_usec will be -1 on error
|
||||
*/
|
||||
noinstrument struct timeval _timespec2timeval(struct timespec ts) {
|
||||
if (0 <= ts.tv_nsec && ts.tv_nsec < 1000000000) {
|
||||
if (0 <= ts.tv_nsec && ts.tv_nsec < 1000000000 - 999) {
|
||||
return (struct timeval){ts.tv_sec, (ts.tv_nsec + 999) / 1000};
|
||||
} else {
|
||||
return (struct timeval){ts.tv_sec + 1, 0};
|
||||
}
|
||||
} else {
|
||||
return (struct timeval){-1, -1};
|
||||
}
|
||||
}
|
|
@ -92,9 +92,7 @@ privileged void __install_tls(char tib[64]) {
|
|||
assert(!__tls_enabled);
|
||||
assert(*(int *)(tib + 0x38) != -1);
|
||||
if (IsWindows()) {
|
||||
if (!__tls_index) {
|
||||
__tls_index = TlsAlloc();
|
||||
}
|
||||
__tls_index = TlsAlloc();
|
||||
asm("mov\t%1,%%gs:%0" : "=m"(*((long *)0x1480 + __tls_index)) : "r"(tib));
|
||||
} else if (IsFreebsd()) {
|
||||
asm volatile("syscall"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue