mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-28 13:30:29 +00:00
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:
parent
140a8a52e5
commit
18bb5888e1
311 changed files with 1239 additions and 2622 deletions
|
@ -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);
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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__({ \
|
||||
|
|
|
@ -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;
|
|
@ -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)) {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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_ */
|
|
@ -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)));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 (𝑥>0→2^⌊log₂𝑥⌋, x=0→0, 𝑇→⊥)
|
||||
* @see _roundup2pow()
|
||||
*/
|
||||
unsigned long _rounddown2pow(unsigned long x) {
|
||||
return x ? 1ul << _bsrl(x) : 0;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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 (𝑥>0→2^⌈log₂x⌉, x=0→0, 𝑇→⊥)
|
||||
* @see _rounddown2pow()
|
||||
*/
|
||||
unsigned long _roundup2pow(unsigned long x) {
|
||||
return x > 1 ? 2ul << _bsrl(x - 1) : x ? 1 : 0;
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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)};
|
||||
}
|
|
@ -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}, //
|
||||
};
|
|
@ -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"}, //
|
Loading…
Add table
Add a link
Reference in a new issue