Make more fixes and improvements

- Remove PAGESIZE constant
- Fix realloc() documentation
- Fix ttyname_r() error reporting
- Make forking more reliable on Windows
- Make execvp() a few microseconds faster
- Make system() a few microseconds faster
- Tighten up the socket-related magic numbers
- Loosen restrictions on mmap() offset alignment
- Improve GetProgramExecutableName() with getenv("_")
- Use mkstemp() as basis for mktemp(), tmpfile(), tmpfd()
- Fix flakes in pthread_cancel_test, unix_test, fork_test
- Fix recently introduced futex stack overflow regression
- Let sockets be passed as stdio to subprocesses on Windows
- Improve security of bind() on Windows w/ SO_EXCLUSIVEADDRUSE
This commit is contained in:
Justine Tunney 2023-07-29 18:44:15 -07:00
parent 140a8a52e5
commit 18bb5888e1
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
311 changed files with 1239 additions and 2622 deletions

View file

@ -421,7 +421,7 @@ static struct AsanFault __asan_fault(const signed char *s, signed char dflt) {
struct AsanFault r;
if (s[0] < 0) {
r.kind = s[0];
} else if (((uintptr_t)(s + 1) & (PAGESIZE - 1)) && s[1] < 0) {
} else if (((uintptr_t)(s + 1) & 4095) && s[1] < 0) {
r.kind = s[1];
} else {
r.kind = dflt;
@ -652,6 +652,8 @@ static wint_t __asan_symbolize_access_poison(signed char kind) {
return L'μ';
case kAsanGlobalOverrun:
return L'Ω';
case kAsanMmapSizeOverrun:
return L'Z';
default:
return L'?';
}
@ -963,14 +965,6 @@ __attribute__((__destructor__)) static void __asan_morgue_flush(void) {
}
}
static size_t __asan_user_size(size_t n) {
if (n) {
return n;
} else {
return 1;
}
}
static size_t __asan_heap_size(size_t n) {
if (n < 0x7fffffff0000) {
n = ROUNDUP(n, _Alignof(struct AsanExtra));
@ -1043,7 +1037,6 @@ static void *__asan_allocate(size_t a, size_t n, struct AsanTrace *bt,
char *p;
size_t c;
struct AsanExtra *e;
n = __asan_user_size(n);
if ((p = _weaken(dlmemalign)(a, __asan_heap_size(n)))) {
c = _weaken(dlmalloc_usable_size)(p);
e = (struct AsanExtra *)(p + c - sizeof(*e));
@ -1244,12 +1237,7 @@ void *__asan_calloc(size_t n, size_t m) {
void *__asan_realloc(void *p, size_t n) {
struct AsanTrace bt;
if (p) {
if (n) {
return __asan_realloc_impl(p, n, __asan_realloc_grow);
} else {
__asan_free(p);
return 0;
}
return __asan_realloc_impl(p, n, __asan_realloc_grow);
} else {
__asan_trace(&bt, RBP);
return __asan_allocate_heap(16, n, &bt);

View file

@ -1,28 +1,29 @@
#ifndef COSMOPOLITAN_LIBC_INTRIN_ASANCODES_H_
#define COSMOPOLITAN_LIBC_INTRIN_ASANCODES_H_
#define kAsanScale 3
#define kAsanMagic 0x7fff8000
#define kAsanNullPage -1 /* ∅ 0xff */
#define kAsanProtected -2 /* P 0xfe */
#define kAsanHeapFree -3 /* F 0xfd */
#define kAsanHeapRelocated -4 /* R 0xfc */
#define kAsanAllocaOverrun -5 /* 𝑂 0xfb */
#define kAsanHeapUnderrun -6 /* U 0xfa */
#define kAsanHeapOverrun -7 /* O 0xf9 */
#define kAsanStackUnscoped -8 /* s 0xf8 */
#define kAsanStackOverflow -9 /* ! 0xf7 */
#define kAsanGlobalOrder -10 /* I 0xf6 */
#define kAsanStackFree -11 /* r 0xf5 */
#define kAsanStackPartial -12 /* p 0xf4 */
#define kAsanStackOverrun -13 /* o 0xf3 */
#define kAsanStackMiddle -14 /* m 0xf2 */
#define kAsanStackUnderrun -15 /* u 0xf1 */
#define kAsanAllocaUnderrun -16 /* 𝑈 0xf0 */
#define kAsanUnmapped -17 /* M 0xef */
#define kAsanGlobalRedzone -18 /* G 0xee */
#define kAsanGlobalGone -19 /* 𝐺 0xed */
#define kAsanGlobalUnderrun -20 /* μ 0xec */
#define kAsanGlobalOverrun -21 /* Ω 0xeb */
#define kAsanScale 3
#define kAsanMagic 0x7fff8000
#define kAsanNullPage -1 /* ∅ 0xff */
#define kAsanProtected -2 /* P 0xfe */
#define kAsanHeapFree -3 /* F 0xfd */
#define kAsanHeapRelocated -4 /* R 0xfc */
#define kAsanAllocaOverrun -5 /* 𝑂 0xfb */
#define kAsanHeapUnderrun -6 /* U 0xfa */
#define kAsanHeapOverrun -7 /* O 0xf9 */
#define kAsanStackUnscoped -8 /* s 0xf8 */
#define kAsanStackOverflow -9 /* ! 0xf7 */
#define kAsanGlobalOrder -10 /* I 0xf6 */
#define kAsanStackFree -11 /* r 0xf5 */
#define kAsanStackPartial -12 /* p 0xf4 */
#define kAsanStackOverrun -13 /* o 0xf3 */
#define kAsanStackMiddle -14 /* m 0xf2 */
#define kAsanStackUnderrun -15 /* u 0xf1 */
#define kAsanAllocaUnderrun -16 /* 𝑈 0xf0 */
#define kAsanUnmapped -17 /* M 0xef */
#define kAsanGlobalRedzone -18 /* G 0xee */
#define kAsanGlobalGone -19 /* 𝐺 0xed */
#define kAsanGlobalUnderrun -20 /* μ 0xec */
#define kAsanGlobalOverrun -21 /* Ω 0xeb */
#define kAsanMmapSizeOverrun -22 /* Z 0xea */
#endif /* COSMOPOLITAN_LIBC_INTRIN_ASANCODES_H_ */

View file

@ -8,9 +8,6 @@ int _bitreverse8(int) pureconst;
int _bitreverse16(int) pureconst;
uint32_t _bitreverse32(uint32_t) pureconst;
uint64_t _bitreverse64(uint64_t) pureconst;
unsigned long _roundup2pow(unsigned long) pureconst;
unsigned long _roundup2log(unsigned long) pureconst;
unsigned long _rounddown2pow(unsigned long) pureconst;
#define READ16LE(P) \
(__extension__({ \

View file

@ -1,7 +1,7 @@
/*-*- 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
Copyright 2023 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
@ -16,55 +16,43 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/cosmo.h"
#include "libc/errno.h"
#include "libc/intrin/atomic.h"
#include "libc/intrin/weaken.h"
#include "libc/thread/thread.h"
#include "third_party/nsync/once.h"
#define INIT 0
#define CALLING 1
#define FINISHED 2
/**
* Ensures initialization function is called exactly once, e.g.
* Ensures initialization function is called exactly once.
*
* static void *g_factory;
*
* static void InitFactory(void) {
* g_factory = expensive();
* }
*
* void *GetFactory(void) {
* static pthread_once_t once = PTHREAD_ONCE_INIT;
* pthread_once(&once, InitFactory);
* return g_factory;
* }
* This is the same as `pthread_once` except that it always uses a tiny
* spinlock implementation and won't make any system calls. It's needed
* since this function is an upstream dependency of both pthread_once()
* and nsync_once(). Most code should favor calling those functions.
*
* @return 0 on success, or errno on error
*/
errno_t pthread_once(pthread_once_t *once, void init(void)) {
errno_t cosmo_once(_Atomic(uint32_t) *once, void init(void)) {
uint32_t old;
if (_weaken(nsync_run_once)) {
_weaken(nsync_run_once)((nsync_once *)once, init);
return 0;
}
switch ((old = atomic_load_explicit(&once->_lock, memory_order_relaxed))) {
switch ((old = atomic_load_explicit(once, memory_order_relaxed))) {
case INIT:
if (atomic_compare_exchange_strong_explicit(&once->_lock, &old, CALLING,
if (atomic_compare_exchange_strong_explicit(once, &old, CALLING,
memory_order_acquire,
memory_order_relaxed)) {
init();
atomic_store_explicit(&once->_lock, FINISHED, memory_order_release);
atomic_store_explicit(once, FINISHED, memory_order_release);
return 0;
}
// fallthrough
case CALLING:
do {
pthread_yield();
} while (atomic_load_explicit(&once->_lock, memory_order_acquire) ==
CALLING);
for (;;) {
if (atomic_load_explicit(once, memory_order_acquire) != CALLING) {
break;
}
}
return 0;
case FINISHED:
return 0;

View file

@ -37,8 +37,6 @@ static const char *GetFrameName(int x) {
return "automap";
} else if (IsFixedFrame(x)) {
return "fixed";
} else if (IsArenaFrame(x)) {
return "arena";
} else if (IsStaticStackFrame(x)) {
return "stack";
} else if (IsGfdsFrame(x)) {

View file

@ -25,7 +25,7 @@
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/sol.h"
#define N (PAGESIZE / 2 / sizeof(struct DescribeFlags))
#define N (4096 / 2 / sizeof(struct DescribeFlags))
/**
* Describes clock_gettime() clock argument.

View file

@ -46,6 +46,7 @@ static const char *DescribeSigFlags(char buf[64], int x) {
{SA_RESETHAND, "RESETHAND"}, //
{SA_NOMASK, "NOMASK"}, //
{SA_ONESHOT, "ONESHOT"}, //
{0x04000000, "RESTORER"}, //
};
return DescribeFlags(buf, 64, kSigFlags, ARRAYLEN(kSigFlags), "SA_", x);
}

View file

@ -27,6 +27,7 @@ const char *(DescribeSocketProtocol)(char buf[12], int family) {
if (family == IPPROTO_UDP) return "IPPROTO_UDP";
if (family == IPPROTO_RAW) return "IPPROTO_RAW";
if (family == IPPROTO_IPV6) return "IPPROTO_IPv6";
if (family == IPPROTO_ICMPV6) return "IPPROTO_ICMPV6";
FormatInt32(buf, family);
return buf;
}

View file

@ -24,10 +24,14 @@
* Describes setsockopt() level arguments.
*/
const char *(DescribeSockLevel)(char buf[12], int x) {
if (x == SOL_SOCKET) return "SOL_SOCKET";
if (x == SOL_IP) return "SOL_IP";
if (x == SOL_ICMP) return "SOL_ICMP";
if (x == SOL_TCP) return "SOL_TCP";
if (x == SOL_UDP) return "SOL_UDP";
if (x == SOL_SOCKET) return "SOL_SOCKET";
if (x == SOL_IPV6) return "SOL_IPV6";
if (x == SOL_ICMPV6) return "SOL_ICMPV6";
if (x == SOL_RAW) return "SOL_RAW";
FormatInt32(buf, x);
return buf;
}

View file

@ -79,7 +79,7 @@ const char *(DescribeStat)(char buf[N], int rc, const struct stat *st) {
append(", .st_%s=%'lu", "rdev", st->st_rdev);
}
if (st->st_blksize != PAGESIZE) {
if (st->st_blksize != 4096) {
append(", .st_%s=%'lu", "blksize", st->st_blksize);
}

View file

@ -25,7 +25,7 @@
* @param delta is added to enabled state
* @return enabled state before `delta` was applied
*/
int ftrace_enabled(int delta) {
dontinstrument int ftrace_enabled(int delta) {
int res;
struct CosmoTib *tib;
if (__tls_enabled) {

View file

@ -18,13 +18,17 @@
*/
#include "libc/calls/internal.h"
#include "libc/calls/state.internal.h"
#include "libc/intrin/_getenv.internal.h"
#include "libc/intrin/atomic.h"
#include "libc/intrin/extend.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/pushpop.internal.h"
#include "libc/intrin/weaken.h"
#include "libc/macros.internal.h"
#include "libc/nt/runtime.h"
#include "libc/runtime/memtrack.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/sock/sock.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/o.h"
@ -37,16 +41,26 @@ __static_yoink("_init_g_fds");
struct Fds g_fds;
static struct Fd g_fds_static[OPEN_MAX];
static textwindows dontinline void SetupWinStd(struct Fds *fds, int i, int x) {
static int Atoi(const char *str) {
int i;
for (i = 0; '0' <= *str && *str <= '9'; ++str) {
i *= 10;
i += *str - '0';
}
return i;
}
static textwindows dontinline void SetupWinStd(struct Fds *fds, int i, int x,
int sockset) {
int64_t h;
h = GetStdHandle(x);
if (!h || h == -1) return;
fds->p[i].kind = pushpop(kFdFile);
fds->p[i].kind = ((1 << i) & sockset) ? pushpop(kFdSocket) : pushpop(kFdFile);
fds->p[i].handle = h;
atomic_store_explicit(&fds->f, i + 1, memory_order_relaxed);
}
textstartup void __init_fds(void) {
textstartup void __init_fds(int argc, char **argv, char **envp) {
struct Fds *fds;
__fds_lock_obj._type = PTHREAD_MUTEX_RECURSIVE;
fds = __veil("r", &g_fds);
@ -77,9 +91,29 @@ textstartup void __init_fds(void) {
fds->p[1].handle = __veil("r", 0x3F8ull);
fds->p[2].handle = __veil("r", 0x3F8ull);
} else if (IsWindows()) {
SetupWinStd(fds, 0, kNtStdInputHandle);
SetupWinStd(fds, 1, kNtStdOutputHandle);
SetupWinStd(fds, 2, kNtStdErrorHandle);
int sockset = 0;
struct Env var;
var = _getenv(envp, "__STDIO_SOCKETS");
if (var.s) {
int i = var.i + 1;
do {
envp[i - 1] = envp[i];
} while (envp[i]);
sockset = Atoi(var.s);
}
if (sockset && !_weaken(socket)) {
#ifdef SYSDEBUG
kprintf("%s: parent process passed sockets as stdio, but this program"
" can't use them since it didn't link the socket() function\n",
argv[0]);
_Exit(1);
#else
sockset = 0; // let ReadFile() fail
#endif
}
SetupWinStd(fds, 0, kNtStdInputHandle, sockset);
SetupWinStd(fds, 1, kNtStdOutputHandle, sockset);
SetupWinStd(fds, 2, kNtStdErrorHandle, sockset);
}
fds->p[1].flags = O_WRONLY | O_APPEND;
fds->p[2].flags = O_WRONLY | O_APPEND;

View file

@ -21,6 +21,9 @@
.init.start 305,_init_g_fds
push %rdi
push %rsi
mov %r12d,%edi // argc
mov %r13,%rsi // argv
mov %r14,%rdx // environ
call __init_fds
pop %rsi
pop %rdi

View file

@ -35,7 +35,11 @@ unsigned long getauxval(unsigned long key) {
x = _getauxval(key);
if (key == AT_PAGESZ) {
if (!x.isfound) {
#ifdef __aarch64__
x.value = 16384;
#else
x.value = 4096;
#endif
}
x.isfound = true;
}

View file

@ -26,6 +26,7 @@
* Environment variables can store empty string on Unix but not Windows.
*
* @return pointer to value of `environ` entry, or null if not found
* @threadunsafe
*/
char *getenv(const char *s) {
char **p;

View file

@ -625,7 +625,7 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt,
++p;
}
for (i = j = 0; !pdot || j < prec; ++j) {
if (UNLIKELY(!((intptr_t)s & (PAGESIZE - 1)))) {
if (UNLIKELY(!((intptr_t)s & 4095))) {
if (!dang && kisdangerous(s)) break;
}
if (!type) {
@ -687,7 +687,7 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt,
s += sizeof(char16_t);
if (IsHighSurrogate(t)) {
if (!pdot || j + 1 < prec) {
if (UNLIKELY(!((intptr_t)s & (PAGESIZE - 1)))) {
if (UNLIKELY(!((intptr_t)s & 4095))) {
if (!dang && kisdangerous(s)) break;
}
u = *(const char16_t *)s;

View file

@ -1,38 +0,0 @@
/*-*- 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/intrin/morton.h"
/**
* Interleaves bits.
* @see https://en.wikipedia.org/wiki/Z-order_curve
* @see unmorton()
*/
unsigned long morton(unsigned long y, unsigned long x) {
x = (x | x << 020) & 0x0000FFFF0000FFFF;
x = (x | x << 010) & 0x00FF00FF00FF00FF;
x = (x | x << 004) & 0x0F0F0F0F0F0F0F0F;
x = (x | x << 002) & 0x3333333333333333;
x = (x | x << 001) & 0x5555555555555555;
y = (y | y << 020) & 0x0000FFFF0000FFFF;
y = (y | y << 010) & 0x00FF00FF00FF00FF;
y = (y | y << 004) & 0x0F0F0F0F0F0F0F0F;
y = (y | y << 002) & 0x3333333333333333;
y = (y | y << 001) & 0x5555555555555555;
return x | y << 1;
}

View file

@ -1,16 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_BITS_MORTON_H_
#define COSMOPOLITAN_LIBC_BITS_MORTON_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
#ifdef COSMO
#define morton __morton
#define unmorton __unmorton
unsigned long morton(unsigned long, unsigned long) libcesque;
axdx_t unmorton(unsigned long) libcesque;
#endif /* COSMO */
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_BITS_MORTON_H_ */

View file

@ -27,7 +27,6 @@ static bool IsNoteworthyHole(unsigned i, const struct MemoryIntervals *mm) {
// gaps between shadow frames aren't interesting
// the chasm from heap to stack ruins statistics
return !(
(IsArenaFrame(mm->p[i].y) && !IsArenaFrame(mm->p[i + 1].x)) ||
(IsShadowFrame(mm->p[i].y) || IsShadowFrame(mm->p[i + 1].x)) ||
(!IsStaticStackFrame(mm->p[i].y) && IsStaticStackFrame(mm->p[i + 1].x)));
}

View file

@ -93,6 +93,7 @@ int PutEnvImpl(char *s, bool overwrite) {
* @return 0 on success, or non-zero w/ errno on error
* @raise ENOMEM if we require more vespene gas
* @see setenv(), getenv()
* @threadunsafe
*/
int putenv(char *s) {
int rc;

View file

@ -1,30 +0,0 @@
/*-*- 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/intrin/bits.h"
#include "libc/intrin/bsr.h"
/**
* Returns 𝑥 rounded down to previous two power.
*
* @define (𝑥>02^log𝑥, x=00, 𝑇)
* @see _roundup2pow()
*/
unsigned long _rounddown2pow(unsigned long x) {
return x ? 1ul << _bsrl(x) : 0;
}

View file

@ -1,28 +0,0 @@
/*-*- 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/intrin/bits.h"
#include "libc/intrin/bsr.h"
/**
* Returns 𝑥 rounded up to next two power and log'd.
* @see _roundup2pow()
*/
unsigned long _roundup2log(unsigned long x) {
return x > 1 ? (_bsrl(x - 1) + 1) : x ? 1 : 0;
}

View file

@ -1,30 +0,0 @@
/*-*- 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/intrin/bits.h"
#include "libc/intrin/bsr.h"
/**
* Returns 𝑥 rounded up to next two power.
*
* @define (𝑥>02^logx, x=00, 𝑇)
* @see _rounddown2pow()
*/
unsigned long _roundup2pow(unsigned long x) {
return x > 1 ? 2ul << _bsrl(x - 1) : x ? 1 : 0;
}

View file

@ -30,6 +30,7 @@
* @raise EINVAL if `name` is empty or contains `'='`
* @raise ENOMEM if we require more vespene gas
* @see putenv(), getenv()
* @threadunsafe
*/
int setenv(const char *name, const char *value, int overwrite) {
int rc;

View file

@ -19,7 +19,9 @@ COSMOPOLITAN_C_START_
#define STRACE(FMT, ...) \
do { \
if (UNLIKELY(__strace > 0) && strace_enabled(0) > 0) { \
ftrace_enabled(-1); \
__stracef(STRACE_PROLOGUE FMT "\n", ##__VA_ARGS__); \
ftrace_enabled(+1); \
} \
} while (0)
#else

View file

@ -25,7 +25,7 @@
* @param delta is added to enabled state
* @return enabled state before `delta` was applied
*/
int strace_enabled(int delta) {
dontinstrument int strace_enabled(int delta) {
int res;
struct CosmoTib *tib;
if (__tls_enabled) {

View file

@ -85,7 +85,7 @@ forceinline du_int udiv128by64to64(du_int u1, du_int u0, du_int v, du_int *r) {
* @param b is divisor
* @param rem receives remainder if not NULL
*/
COMPILER_RT_ABI tu_int __udivmodti4(tu_int a, tu_int b, tu_int *rem) {
tu_int __udivmodti4(tu_int a, tu_int b, tu_int *rem) {
const unsigned n_utword_bits = sizeof(tu_int) * CHAR_BIT;
utwords dividend, divisor, quotient, remainder;
si_int shift;
@ -135,3 +135,7 @@ COMPILER_RT_ABI tu_int __udivmodti4(tu_int a, tu_int b, tu_int *rem) {
if (rem) *rem = dividend.all;
return quotient.all;
}
tu_int __udivti3(tu_int a, tu_int b) {
return __udivmodti4(a, b, NULL);
}

View file

@ -1,14 +0,0 @@
#if 0
/*─────────────────────────────────────────────────────────────────╗
To the extent possible under law, Justine Tunney has waived
all copyright and related or neighboring rights to division,
as it is written in the following disclaimers:
http://unlicense.org/ │
http://creativecommons.org/publicdomain/zero/1.0/ │
*/
#endif
#include "third_party/compiler_rt/int_lib.h"
COMPILER_RT_ABI tu_int __udivti3(tu_int a, tu_int b) {
return __udivmodti4(a, b, NULL);
}

View file

@ -1,41 +0,0 @@
/*-*- 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/intrin/morton.h"
static unsigned long GetOddBits(unsigned long x) {
x = (x | x >> 000) & 0x5555555555555555;
x = (x | x >> 001) & 0x3333333333333333;
x = (x | x >> 002) & 0x0F0F0F0F0F0F0F0F;
x = (x | x >> 004) & 0x00FF00FF00FF00FF;
x = (x | x >> 010) & 0x0000FFFF0000FFFF;
x = (x | x >> 020) & 0x00000000FFFFFFFF;
return x;
}
/**
* Deinterleaves bits.
*
* @param 𝑖 is interleaved index
* @return deinterleaved coordinate {ax := 𝑦, dx := 𝑥}
* @see en.wikipedia.org/wiki/Z-order_curve
* @see morton()
*/
axdx_t unmorton(unsigned long i) {
return (axdx_t){GetOddBits(i >> 1), GetOddBits(i)};
}

View file

@ -1,33 +0,0 @@
/*-*- 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/nexgen32e/x86info.h"
#include "tool/decode/lib/x86idnames.h"
const struct IdName kX86GradeNames[] = {
{X86_GRADE_UNKNOWN, "Unknown"}, //
{X86_GRADE_APPLIANCE, "Appliance"}, //
{X86_GRADE_MOBILE, "Mobile"}, //
{X86_GRADE_TABLET, "Tablet"}, //
{X86_GRADE_DESKTOP, "Desktop"}, //
{X86_GRADE_CLIENT, "Client"}, //
{X86_GRADE_DENSITY, "Density"}, //
{X86_GRADE_SERVER, "Server"}, //
{X86_GRADE_SCIENCE, "Science"}, //
{0}, //
};

View file

@ -19,6 +19,19 @@
#include "libc/nexgen32e/x86info.h"
#include "tool/decode/lib/x86idnames.h"
const struct IdName kX86GradeNames[] = {
{X86_GRADE_UNKNOWN, "Unknown"}, //
{X86_GRADE_APPLIANCE, "Appliance"}, //
{X86_GRADE_MOBILE, "Mobile"}, //
{X86_GRADE_TABLET, "Tablet"}, //
{X86_GRADE_DESKTOP, "Desktop"}, //
{X86_GRADE_CLIENT, "Client"}, //
{X86_GRADE_DENSITY, "Density"}, //
{X86_GRADE_SERVER, "Server"}, //
{X86_GRADE_SCIENCE, "Science"}, //
{0}, //
};
const struct IdName kX86MarchNames[] = {
{X86_MARCH_UNKNOWN, "Unknown"}, //
{X86_MARCH_CORE2, "Core 2"}, //