mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-28 13:30:29 +00:00
Make improvements
This change progresses our AARCH64 support: - The AARCH64 build and tests are now passing - Add 128-bit floating-point support to printf() - Fix clone() so it initializes cosmo's x28 TLS register - Fix TLS memory layout issue with aarch64 _Alignas vars - Revamp microbenchmarking tools so they work on aarch64 - Make some subtle improvements to aarch64 crash reporting - Make kisdangerous() memory checks more accurate on aarch64 - Remove sys_open() since it's not available on Linux AARCH64 This change makes general improvements to Cosmo and Redbean: - Introduce GetHostIsa() function in Redbean - You can now feature check using pledge(0, 0) - You can now feature check using unveil("",0) - Refactor some more x86-specific asm comments - Refactor and write docs for some libm functions - Make the mmap() API behave more similar to Linux - Fix WIFSIGNALED() which wrongly returned true for zero - Rename some obscure cosmo keywords from noFOO to dontFOO
This commit is contained in:
parent
5655c9a4e7
commit
8f522cb702
116 changed files with 1194 additions and 1025 deletions
|
@ -1400,7 +1400,7 @@ 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);
|
||||
addr = (void *)ADDR_32_TO_48(a);
|
||||
prot = PROT_READ | PROT_WRITE;
|
||||
flag = MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS;
|
||||
sm = _weaken(sys_mmap)(addr, size, prot, flag, -1, 0);
|
||||
|
@ -1413,8 +1413,7 @@ void __asan_map_shadow(uintptr_t p, size_t n) {
|
|||
__asan_die()();
|
||||
__asan_unreachable();
|
||||
}
|
||||
__repstosb((void *)(intptr_t)((int64_t)((uint64_t)a << 32) >> 16),
|
||||
kAsanUnmapped, size);
|
||||
__repstosb(addr, kAsanUnmapped, size);
|
||||
}
|
||||
__asan_unpoison((char *)p, n);
|
||||
}
|
||||
|
|
59
libc/intrin/cp.c
Normal file
59
libc/intrin/cp.c
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*-*- 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/blockcancel.internal.h"
|
||||
#include "libc/calls/cp.internal.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/thread/posixthread.internal.h"
|
||||
#include "libc/thread/tls.h"
|
||||
#ifdef MODE_DBG
|
||||
|
||||
int begin_cancellation_point(void) {
|
||||
int state = 0;
|
||||
struct CosmoTib *tib;
|
||||
struct PosixThread *pt;
|
||||
if (__enable_tls) {
|
||||
tib = __get_tls();
|
||||
if ((pt = (struct PosixThread *)tib->tib_pthread)) {
|
||||
state = pt->flags & PT_INCANCEL;
|
||||
pt->flags |= PT_INCANCEL;
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
void end_cancellation_point(int state) {
|
||||
struct CosmoTib *tib;
|
||||
struct PosixThread *pt;
|
||||
if (__enable_tls) {
|
||||
tib = __get_tls();
|
||||
if ((pt = (struct PosixThread *)tib->tib_pthread)) {
|
||||
pt->flags &= ~PT_INCANCEL;
|
||||
pt->flags |= state;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void report_cancellation_point(void) {
|
||||
BLOCK_CANCELLATIONS;
|
||||
_bt("error: need BEGIN/END_CANCELLATION_POINT\n");
|
||||
ALLOW_CANCELLATIONS;
|
||||
}
|
||||
|
||||
#endif /* MODE_DBG */
|
|
@ -26,12 +26,11 @@
|
|||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/winargs.internal.h"
|
||||
|
||||
#define ADDR(x) ((int64_t)((uint64_t)(x) << 32) >> 16)
|
||||
#define UNSHADOW(x) ((int64_t)(MAX(0, (x)-0x7fff8000)) << 3)
|
||||
#define FRAME(x) ((int)((x) >> 16))
|
||||
|
||||
forceinline pureconst bool IsBrkFrame(int x) {
|
||||
unsigned char *p = (unsigned char *)((intptr_t)((uintptr_t)x << 32) >> 16);
|
||||
unsigned char *p = (unsigned char *)ADDR_32_TO_48(x);
|
||||
return _weaken(__brk) && p >= _end && p < _weaken(__brk)->p;
|
||||
}
|
||||
|
||||
|
@ -78,7 +77,8 @@ const char *(DescribeFrame)(char buf[32], int x) {
|
|||
char *p;
|
||||
if (IsShadowFrame(x)) {
|
||||
ksnprintf(buf, 32, "%s %s %.8x", GetFrameName(x),
|
||||
GetFrameName(FRAME(UNSHADOW(ADDR(x)))), FRAME(UNSHADOW(ADDR(x))));
|
||||
GetFrameName(FRAME(UNSHADOW(ADDR_32_TO_48(x)))),
|
||||
FRAME(UNSHADOW(ADDR_32_TO_48(x))));
|
||||
return buf;
|
||||
} else {
|
||||
return GetFrameName(x);
|
||||
|
|
|
@ -39,7 +39,6 @@
|
|||
wontreturn void _Exit(int exitcode) {
|
||||
int i;
|
||||
STRACE("_Exit(%d)", exitcode);
|
||||
#ifdef __x86_64__
|
||||
if (!IsWindows() && !IsMetal()) {
|
||||
// On Linux _Exit1 (exit) must be called in pledge("") mode. If we
|
||||
// call _Exit (exit_group) when we haven't used pledge("stdio") then
|
||||
|
@ -47,34 +46,48 @@ wontreturn void _Exit(int exitcode) {
|
|||
// _Exit1 (__threxit) because only _Exit (exit) is whitelisted when
|
||||
// operating in pledge("") mode.
|
||||
if (!(IsLinux() && !PLEDGED(STDIO))) {
|
||||
#ifdef __x86_64__
|
||||
asm volatile("syscall"
|
||||
: /* no outputs */
|
||||
: "a"(__NR_exit_group), "D"(exitcode)
|
||||
: "rcx", "r11", "memory");
|
||||
#elif defined(__aarch64__)
|
||||
register long x0 asm("x0") = exitcode;
|
||||
asm volatile("mov\tx8,%0\n\t"
|
||||
"mov\tx16,%1\n\t"
|
||||
"svc\t0"
|
||||
: /* no outputs */
|
||||
: "i"(94), "i"(1), "r"(x0)
|
||||
: "x8", "x16", "memory");
|
||||
#else
|
||||
#error "unsupported architecture"
|
||||
#endif
|
||||
}
|
||||
// Inline _Exit1() just in case _Exit() isn't allowed by pledge()
|
||||
#ifdef __x86_64__
|
||||
asm volatile("syscall"
|
||||
: /* no outputs */
|
||||
: "a"(__NR_exit), "D"(exitcode)
|
||||
: "rcx", "r11", "memory");
|
||||
#else
|
||||
register long r0 asm("x0") = exitcode;
|
||||
asm volatile("mov\tx8,%0\n\t"
|
||||
"mov\tx16,%1\n\t"
|
||||
"svc\t0"
|
||||
: /* no outputs */
|
||||
: "i"(93), "i"(0x169), "r"(r0)
|
||||
: "x8", "memory");
|
||||
#endif
|
||||
} else if (IsWindows()) {
|
||||
ExitProcess(exitcode);
|
||||
}
|
||||
#ifdef __x86_64__
|
||||
asm("push\t$0\n\t"
|
||||
"push\t$0\n\t"
|
||||
"cli\n\t"
|
||||
"lidt\t(%rsp)");
|
||||
for (;;) asm("ud2");
|
||||
#elif defined(__aarch64__)
|
||||
register long x0 asm("x0") = exitcode;
|
||||
asm volatile("mov\tx8,%0\n\t"
|
||||
"mov\tx16,%1\n\t"
|
||||
"svc\t0"
|
||||
: /* no outputs */
|
||||
: "i"(94), "i"(1), "r"(x0)
|
||||
: "x8", "x16", "memory");
|
||||
notpossible;
|
||||
#else
|
||||
#error "arch unsupported"
|
||||
unreachable;
|
||||
#endif
|
||||
}
|
||||
|
|
10
libc/intrin/feholdexcept.c
Normal file
10
libc/intrin/feholdexcept.c
Normal file
|
@ -0,0 +1,10 @@
|
|||
#include "libc/runtime/fenv.h"
|
||||
|
||||
/**
|
||||
* Saves floating-point environment and clears current exceptions.
|
||||
*/
|
||||
int feholdexcept(fenv_t *envp) {
|
||||
fegetenv(envp);
|
||||
feclearexcept(FE_ALL_EXCEPT);
|
||||
return 0;
|
||||
}
|
|
@ -27,6 +27,18 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
// Clears floating point exception status, e.g.
|
||||
//
|
||||
// feclearexcept(FE_ALL_EXCEPT);
|
||||
//
|
||||
// @param excepts may bitwise-or the following:
|
||||
// - `FE_INVALID`
|
||||
// - `FE_DIVBYZERO`
|
||||
// - `FE_OVERFLOW`
|
||||
// - `FE_UNDERFLOW`
|
||||
// - `FE_INEXACT`
|
||||
// - `FE_ALL_EXCEPT` (all of the above)
|
||||
// @return 0 on success, or nonzero on error
|
||||
feclearexcept:
|
||||
#ifdef __x86_64__
|
||||
// maintain exceptions in the sse mxcsr, clear x87 exceptions
|
||||
|
@ -53,9 +65,47 @@ feclearexcept:
|
|||
msr fpsr,x1
|
||||
mov w0,#0
|
||||
ret
|
||||
#else
|
||||
#error "unsupported architecture"
|
||||
#endif
|
||||
.endfn feclearexcept,globl
|
||||
|
||||
// Checks for floating point exception.
|
||||
//
|
||||
// This function may be used to check the thread-local
|
||||
// floating-point exception status bits, e.g.
|
||||
//
|
||||
// feclearexcept(FE_ALL_EXCEPT);
|
||||
// volatile double x = 0, y = 1 / x;
|
||||
// assert(fetestexcept(FE_ALL_EXCEPT) == FE_DIVBYZERO);
|
||||
//
|
||||
// @param excepts may bitwise-or the following:
|
||||
// - `FE_INVALID`
|
||||
// - `FE_DIVBYZERO`
|
||||
// - `FE_OVERFLOW`
|
||||
// - `FE_UNDERFLOW`
|
||||
// - `FE_INEXACT`
|
||||
// - `FE_ALL_EXCEPT` (all of the above)
|
||||
// @return mask of which exception status codes are currently set,
|
||||
// or zero if there aren't any floating point exceptions
|
||||
fetestexcept:
|
||||
#ifdef __x86_64__
|
||||
and $0x3f,%edi
|
||||
push %rax
|
||||
stmxcsr (%rsp)
|
||||
pop %rsi
|
||||
fnstsw %ax
|
||||
or %esi,%eax
|
||||
and %edi,%eax
|
||||
ret
|
||||
#elif defined(__aarch64__)
|
||||
and w0,w0,#0x1f
|
||||
mrs x1,fpsr
|
||||
and w0,w0,w1
|
||||
ret
|
||||
#endif
|
||||
.endfn fetestexcept,globl
|
||||
|
||||
feraiseexcept:
|
||||
#ifdef __x86_64__
|
||||
and $0x3f,%edi
|
||||
|
@ -159,21 +209,3 @@ fesetenv:
|
|||
ret
|
||||
#endif
|
||||
.endfn fesetenv,globl
|
||||
|
||||
fetestexcept:
|
||||
#ifdef __x86_64__
|
||||
and $0x3f,%edi
|
||||
push %rax
|
||||
stmxcsr (%rsp)
|
||||
pop %rsi
|
||||
fnstsw %ax
|
||||
or %esi,%eax
|
||||
and %edi,%eax
|
||||
ret
|
||||
#elif defined(__aarch64__)
|
||||
and w0,w0,#0x1f
|
||||
mrs x1,fpsr
|
||||
and w0,w0,w1
|
||||
ret
|
||||
#endif
|
||||
.endfn fetestexcept,globl
|
||||
|
|
29
libc/intrin/feupdateenv.c
Normal file
29
libc/intrin/feupdateenv.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 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 │
|
||||
│ 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/runtime/fenv.h"
|
||||
|
||||
/**
|
||||
* Restores floating point environment and raises exceptions.
|
||||
*/
|
||||
int feupdateenv(const fenv_t *envp) {
|
||||
int ex = fetestexcept(FE_ALL_EXCEPT);
|
||||
fesetenv(envp);
|
||||
feraiseexcept(ex);
|
||||
return 0;
|
||||
}
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/cp.internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
|
@ -50,6 +51,7 @@ int IsDebuggerPresent(bool force) {
|
|||
if (!PLEDGED(RPATH)) return false;
|
||||
res = 0;
|
||||
e = errno;
|
||||
BEGIN_CANCELLATION_POINT;
|
||||
if ((fd = __sys_openat(AT_FDCWD, "/proc/self/status", O_RDONLY, 0)) >= 0) {
|
||||
if ((got = sys_read(fd, buf, sizeof(buf) - 1)) > 0) {
|
||||
buf[got] = '\0';
|
||||
|
@ -60,6 +62,7 @@ int IsDebuggerPresent(bool force) {
|
|||
}
|
||||
sys_close(fd);
|
||||
}
|
||||
END_CANCELLATION_POINT;
|
||||
errno = e;
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/log/internal.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nexgen32e/rdtsc.h"
|
||||
#include "libc/nexgen32e/uart.internal.h"
|
||||
|
@ -174,6 +175,7 @@ privileged static bool kismapped(int x) {
|
|||
|
||||
privileged bool kisdangerous(const void *p) {
|
||||
int frame;
|
||||
if (IsTiny()) return false;
|
||||
if (kisimagepointer(p)) return false;
|
||||
if (kiskernelpointer(p)) return false;
|
||||
if (IsOldStack(p)) return false;
|
||||
|
@ -189,7 +191,7 @@ privileged bool kisdangerous(const void *p) {
|
|||
return true;
|
||||
}
|
||||
|
||||
privileged static void klog(const char *b, size_t n) {
|
||||
privileged dontinline void klog(const char *b, size_t n) {
|
||||
#ifdef __x86_64__
|
||||
int e;
|
||||
bool cf;
|
||||
|
|
|
@ -23,8 +23,6 @@
|
|||
#include "libc/macros.internal.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
|
||||
#define ADDR(x) ((intptr_t)((int64_t)((uint64_t)(x) << 32) >> 16))
|
||||
|
||||
static bool IsNoteworthyHole(unsigned i, const struct MemoryIntervals *mm) {
|
||||
// gaps between shadow frames aren't interesting
|
||||
// the chasm from heap to stack ruins statistics
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue