From 3384a5a48c537de93ce6845b265231aaf5710f81 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Thu, 4 Feb 2021 16:37:22 -0800 Subject: [PATCH] Apply touchups to last PR Compilers like GCC require comments on lines like `#endif rdmsr`. Since the rdmsr macro was only being used in arch_prctl(), I've localized the macro, and I'm considering deleting arch_prctl() too, since there isn't any way to have mem segments unfortunately across operating systems ;_; The remaining changed lines are due to clang-format which runs on auto. --- .vscode/vscode.h | 149 ++++++++++++++++++-------------------- ape/lib/pageunmap.c | 3 +- libc/bits/atomic_load.c | 34 +++++++++ libc/bits/atomic_store.c | 32 ++++++++ libc/bits/bits.h | 60 ++------------- libc/runtime/arch_prctl.c | 16 ++++ 6 files changed, 159 insertions(+), 135 deletions(-) create mode 100644 libc/bits/atomic_load.c create mode 100644 libc/bits/atomic_store.c diff --git a/.vscode/vscode.h b/.vscode/vscode.h index a01ec51d8..570eebc6c 100644 --- a/.vscode/vscode.h +++ b/.vscode/vscode.h @@ -1,82 +1,82 @@ #define __VSCODE_INTELLISENSE__ 1 -#define __LP64__ /* TODO: this is a lazy kludge */ +#define __LP64__ /* TODO: this is a lazy kludge */ #include "libc/integral/normalize.inc" #if 0 #define __VSCODE_INTELLISENSE__ 1 -#define __BIGGEST_ALIGNMENT__ 1 -#define __CHAR_MAX__ 0x7F -#define __SCHAR_MAX__ __CHAR_MAX__ -#define __SHRT_MAX__ 0x7FFF -#define __INT_MAX__ 0x7FFFFFFF -#define __LONG_MAX__ 0x7FFFFFFFFFFFFFFF -#define __LONG_LONG_MAX__ __LONG_MAX__ -#define __CHAR_MIN__ -((__CHAR_MAX__)+1) -#define __SHRT_MIN__ -((__SHRT_MAX__)+1) -#define __INT_MIN__ -((__INT_MAX__)+1) -#define __LONG_MIN__ -((__LONG_MAX__)+1) -#define __LONG_LONG_MIN__ -((__LONG_LONG_MAX__)+1) -#define __UCHAR_MAX__ 0xFF -#define __USHRT_MAX__ 0xFFFF -#define __UINT_MAX__ 0xFFFFFFFF -#define __ULONG_MAX__ 0xFFFFFFFFFFFFFFFF -#define __SIZE_MAX__ __ULONG_MAX__ -#define __SSIZE_MAX__ __LONG_MAX__ -#define __UINTPTR_MAX__ __SIZE_MAX__ -#define __INTPTR_MAX__ __SSIZE_MAX__ -#define __WCHAR_MAX__ __UINT_MAX__ -#define __PTRDIFF_MAX__ __UINTPTR_MAX__ -#define __INTMAX_MAX__ __ULONG_MAX__ -#define __SIZEOF_POINTER__ 8 -#define __SIZEOF_SHORT__ 2 -#define __SIZEOF_INT__ 4 -#define __SIZEOF_LONG__ 8 -#define __SIZEOF_LONG_LONG__ 8 -#define __SIZEOF_PTRDIFF_T__ 8 -#define __SIZEOF_SIZE_T__ 8 -#define __SIZEOF_WCHAR_T__ 4 -#define __SIZEOF_WINT_T__ 4 -#define __SIZEOF_FLOAT__ 4 -#define __SIZEOF_FLOAT128__ 16 -#define __SIZEOF_DOUBLE__ 8 -#define __SIZEOF_FLOAT80__ 10 -#define __SIZEOF_LONG_DOUBLE__ 16 -#define __FLT_MAX__ 1 -#define __DBL_MAX__ 1 +#define __BIGGEST_ALIGNMENT__ 1 +#define __CHAR_MAX__ 0x7F +#define __SCHAR_MAX__ __CHAR_MAX__ +#define __SHRT_MAX__ 0x7FFF +#define __INT_MAX__ 0x7FFFFFFF +#define __LONG_MAX__ 0x7FFFFFFFFFFFFFFF +#define __LONG_LONG_MAX__ __LONG_MAX__ +#define __CHAR_MIN__ -((__CHAR_MAX__) + 1) +#define __SHRT_MIN__ -((__SHRT_MAX__) + 1) +#define __INT_MIN__ -((__INT_MAX__) + 1) +#define __LONG_MIN__ -((__LONG_MAX__) + 1) +#define __LONG_LONG_MIN__ -((__LONG_LONG_MAX__) + 1) +#define __UCHAR_MAX__ 0xFF +#define __USHRT_MAX__ 0xFFFF +#define __UINT_MAX__ 0xFFFFFFFF +#define __ULONG_MAX__ 0xFFFFFFFFFFFFFFFF +#define __SIZE_MAX__ __ULONG_MAX__ +#define __SSIZE_MAX__ __LONG_MAX__ +#define __UINTPTR_MAX__ __SIZE_MAX__ +#define __INTPTR_MAX__ __SSIZE_MAX__ +#define __WCHAR_MAX__ __UINT_MAX__ +#define __PTRDIFF_MAX__ __UINTPTR_MAX__ +#define __INTMAX_MAX__ __ULONG_MAX__ +#define __SIZEOF_POINTER__ 8 +#define __SIZEOF_SHORT__ 2 +#define __SIZEOF_INT__ 4 +#define __SIZEOF_LONG__ 8 +#define __SIZEOF_LONG_LONG__ 8 +#define __SIZEOF_PTRDIFF_T__ 8 +#define __SIZEOF_SIZE_T__ 8 +#define __SIZEOF_WCHAR_T__ 4 +#define __SIZEOF_WINT_T__ 4 +#define __SIZEOF_FLOAT__ 4 +#define __SIZEOF_FLOAT128__ 16 +#define __SIZEOF_DOUBLE__ 8 +#define __SIZEOF_FLOAT80__ 10 +#define __SIZEOF_LONG_DOUBLE__ 16 +#define __FLT_MAX__ 1 +#define __DBL_MAX__ 1 -#define __INT_LEAST8_TYPE__ signed char -#define __INT_LEAST16_TYPE__ signed short -#define __INT_LEAST32_TYPE__ signed int -#define __INT_LEAST64_TYPE__ signed long long -#define __UINT_LEAST8_TYPE__ unsigned char +#define __INT_LEAST8_TYPE__ signed char +#define __INT_LEAST16_TYPE__ signed short +#define __INT_LEAST32_TYPE__ signed int +#define __INT_LEAST64_TYPE__ signed long long +#define __UINT_LEAST8_TYPE__ unsigned char #define __UINT_LEAST16_TYPE__ unsigned short #define __UINT_LEAST32_TYPE__ unsigned int #define __UINT_LEAST64_TYPE__ unsigned long long -#define __UINT8_MAX__ __UCHAR_MAX__ +#define __UINT8_MAX__ __UCHAR_MAX__ #define __UINT16_MAX__ __USHRT_MAX__ #define __UINT32_MAX__ __UINT_MAX__ #define __UINT64_MAX__ __ULONG_MAX__ -#define __INT8_MAX__ __CHAR_MAX__ +#define __INT8_MAX__ __CHAR_MAX__ #define __INT16_MAX__ __SHRT_MAX__ #define __INT32_MAX__ __INT_MAX__ #define __INT64_MAX__ __LONG_MAX__ #define ATEXIT_MAX 1 -#define STACKSIZE 0x10000 -#define ARG_MAX 255 -#define OPEN_MAX 0x7FFF -#define CHAR_BIT 7 -#define NSIG 1 -#define NULL (0) +#define STACKSIZE 0x10000 +#define ARG_MAX 255 +#define OPEN_MAX 0x7FFF +#define CHAR_BIT 7 +#define NSIG 1 +#define NULL (0) #define false 0 #define true (!(false)) #define COSMOPOLITAN_C_START_ #define COSMOPOLITAN_C_END_ -#define PAGESIZE 0x1000 +#define PAGESIZE 0x1000 #define BIGPAGESIZE 0x10000 -#define NAME_MAX 255 +#define NAME_MAX 255 #define SWITCHEROO(...) 0 @@ -85,14 +85,14 @@ extern unsigned g_loglevel; typedef void * va_list; #define va_start(...) 0 -#define va_end(...) 0 -#define va_arg(x, y) (y)(0) +#define va_end(...) 0 +#define va_arg(x, y) (y)(0) typedef signed char int8_t; typedef signed short int16_t; typedef signed int int32_t; -#define int64_t long long -#define int128_t int64_t +#define int64_t long long +#define int128_t int64_t typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; @@ -123,38 +123,31 @@ typedef struct { int ax, dx; } axdx_t; /* duplicate and replace xmmintrin.internal.h to fix it for IntelliSense * SEE: <> */ -#define _Vector_size(x) __attribute__(( vector_size( x ) )) +#define _Vector_size(x) __attribute__((__vector_size__(x))) #define IMAGE_BASE_VIRTUAL 0x400000 -#define __SIGACTION(...) (0) -#define VEIL(x, y) (y) +#define __SIGACTION(...) (0) +#define VEIL(x, y) (y) #define STATIC_YOINK(x) -#define BUFSIZ 1 -#define FRAMESIZE 0x10000 -#define PATH_MAX 252 -#define concat(x, y, z) 0 +#define BUFSIZ 1 +#define FRAMESIZE 0x10000 +#define PATH_MAX 252 +#define concat(x, y, z) 0 #define CONCAT(a, b, c, d, e) 0 -#define shuffle(...) 0 -#define reverse(x, y) 0 -#define atomic_load(...) 0 -#define atomic_store(...) 0 -#define autotype(x) int +#define shuffle(...) 0 +#define reverse(x, y) 0 +#define autotype(x) intptr_t #define _Generic_(...) (void*)(0) #define _Generic(...) _Generic_ #define _Alignas(...) #define _Section(...) -#define offsetof(x, y) 0 -#define cmpxchg(...) 0 -#define lockxchg(...) 0 -#define lockcmpxchg(...) 0 -#define xgetbv(...) 0 -#define rdmsr(...) 0 +#define offsetof(x, y) 0 #define INITIALIZER(...) struct _dummy #define __far #define tinystrstr(...) 0 -#define BENCHLOOP(...) 0 +#define BENCHLOOP(...) 0 #ifdef __hook #undef __hook diff --git a/ape/lib/pageunmap.c b/ape/lib/pageunmap.c index 87981b4a4..9e731b455 100644 --- a/ape/lib/pageunmap.c +++ b/ape/lib/pageunmap.c @@ -17,11 +17,10 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "ape/lib/pc.h" -#include "libc/bits/bits.h" textreal void pageunmap(int64_t vaddr) { uint64_t *entry; entry = __getpagetableentry(vaddr, 3, &g_pml4t, &g_ptsp_xlm); *entry &= ~PAGE_V; - invlpg(vaddr); + asm volatile("invlpg\t(%0)" : /* no outputs */ : "r"(vaddr) : "memory"); } diff --git a/libc/bits/atomic_load.c b/libc/bits/atomic_load.c new file mode 100644 index 000000000..11922c52d --- /dev/null +++ b/libc/bits/atomic_load.c @@ -0,0 +1,34 @@ +/*-*- 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/bits.h" +#include "libc/macros.h" +#include "libc/str/str.h" + +/** + * Atomically loads value. + * + * This macro is intended to prevent things like compiler load tearing + * optimizations. + */ +intptr_t(atomic_load)(void *p, size_t n) { + intptr_t x; + x = 0; + memcpy(&x, p, MAX(n, sizeof(x))); + return x; +} diff --git a/libc/bits/atomic_store.c b/libc/bits/atomic_store.c new file mode 100644 index 000000000..c84821b40 --- /dev/null +++ b/libc/bits/atomic_store.c @@ -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 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/bits.h" +#include "libc/macros.h" +#include "libc/str/str.h" + +/** + * Atomically stores value. + * + * This macro is intended to prevent things like compiler store tearing + * optimizations. + */ +intptr_t(atomic_store)(void *p, intptr_t x, size_t n) { + memcpy(p, &x, MAX(n, sizeof(x))); + return x; +} diff --git a/libc/bits/bits.h b/libc/bits/bits.h index e596f40d1..bd95a28d2 100644 --- a/libc/bits/bits.h +++ b/libc/bits/bits.h @@ -24,6 +24,8 @@ unsigned long hamming(unsigned long, unsigned long) pureconst; intptr_t lockxchg(void *, void *, size_t); bool cmpxchg(void *, intptr_t, intptr_t, size_t); bool lockcmpxchg(void *, intptr_t, intptr_t, size_t); +intptr_t atomic_load(void *, size_t); +intptr_t atomic_store(void *, intptr_t, size_t); /*───────────────────────────────────────────────────────────────────────────│─╗ │ cosmopolitan § bits » no assembly required ─╬─│┼ @@ -174,7 +176,6 @@ bool lockcmpxchg(void *, intptr_t, intptr_t, size_t); * @see Intel's Six-Thousand Page Manual V.3A §8.2.3.1 * @see atomic_store() */ -#ifndef atomic_load #define atomic_load(MEM) \ ({ \ autotype(MEM) Mem = (MEM); \ @@ -182,7 +183,6 @@ bool lockcmpxchg(void *, intptr_t, intptr_t, size_t); asm("mov\t%1,%0" : "=r"(Reg) : "m"(*Mem)); \ Reg; \ }) -#endif /* atomic_load */ /** * Saves scalar to memory w/ one operation. @@ -200,7 +200,6 @@ bool lockcmpxchg(void *, intptr_t, intptr_t, size_t); * @see Intel Six-Thousand Page Manual Manual V.3A §8.2.3.1 * @see atomic_load() */ -#ifndef atomic_store #define atomic_store(MEM, VAL) \ ({ \ autotype(VAL) Val = (VAL); \ @@ -208,7 +207,6 @@ bool lockcmpxchg(void *, intptr_t, intptr_t, size_t); asm("mov%z1\t%1,%0" : "=m"(*Mem) : "r"(Val)); \ Val; \ }) -#endif /* atomic_store */ #define bts(MEM, BIT) __BitOp("bts", BIT, MEM) /** bit test and set */ #define btr(MEM, BIT) __BitOp("btr", BIT, MEM) /** bit test and reset */ @@ -236,7 +234,6 @@ bool lockcmpxchg(void *, intptr_t, intptr_t, size_t); * @return LOCALVAR[0] * @see xchg() */ -#ifndef lockxchg #define lockxchg(MEMORY, LOCALVAR) \ ({ \ _Static_assert( \ @@ -244,7 +241,6 @@ bool lockcmpxchg(void *, intptr_t, intptr_t, size_t); asm("xchg\t%0,%1" : "+%m"(*(MEMORY)), "+r"(*(LOCALVAR))); \ *(LOCALVAR); \ }) -#endif /* lockxchg */ /** * Compares and exchanges. @@ -253,7 +249,6 @@ bool lockcmpxchg(void *, intptr_t, intptr_t, size_t); * @return true if value was exchanged, otherwise false * @see lockcmpxchg() */ -#ifndef cmpxchg #define cmpxchg(IFTHING, ISEQUALTOME, REPLACEITWITHME) \ ({ \ bool DidIt; \ @@ -266,7 +261,6 @@ bool lockcmpxchg(void *, intptr_t, intptr_t, size_t); : "cc"); \ DidIt; \ }) -#endif /* cmpxchg */ /** * Compares and exchanges w/ one operation. @@ -275,7 +269,6 @@ bool lockcmpxchg(void *, intptr_t, intptr_t, size_t); * @return true if value was exchanged, otherwise false * @see lockcmpxchg() */ -#ifndef lockcmpxchg #define lockcmpxchg(IFTHING, ISEQUALTOME, REPLACEITWITHME) \ ({ \ bool DidIt; \ @@ -288,52 +281,6 @@ bool lockcmpxchg(void *, intptr_t, intptr_t, size_t); : "cc"); \ DidIt; \ }) -#endif /* lockcmpxchg */ - -/** - * Gets value of extended control register. - */ -#ifndef xgetbv -#define xgetbv(xcr_register_num) \ - ({ \ - unsigned hi, lo; \ - asm("xgetbv" : "=d"(hi), "=a"(lo) : "c"(cr_register_num)); \ - (uint64_t) hi << 32 | lo; \ - }) -#endif /* xgetbv */ - -/** - * Reads model-specific register. - * @note programs running as guests won't have authorization - */ -#ifndef rdmsr -#define rdmsr(msr) \ - ({ \ - uint32_t lo, hi; \ - asm volatile("rdmsr" : "=a"(lo), "=d"(hi) : "c"(msr)); \ - (uint64_t) hi << 32 | lo; \ - }) -#endif rdmsr - -/** - * Writes model-specific register. - * @note programs running as guests won't have authorization - */ -#define wrmsr(msr, val) \ - do { \ - uint64_t val_ = (val); \ - asm volatile("wrmsr" \ - : /* no outputs */ \ - : "c"(msr), "a"((uint32_t)val_), \ - "d"((uint32_t)(val_ >> 32))); \ - } while (0) - -/** - * Tells CPU page tables changed for virtual address. - * @note programs running as guests won't have authorization - */ -#define invlpg(MEM) \ - asm volatile("invlpg\t(%0)" : /* no outputs */ : "r"(MEM) : "memory") #define IsAddressCanonicalForm(P) \ ({ \ @@ -392,6 +339,9 @@ bool lockcmpxchg(void *, intptr_t, intptr_t, size_t); lockcmpxchg(MEM, (intptr_t)(CMP), (intptr_t)(VAL), sizeof(*(MEM))) #define lockxchg(MEM, VAR) \ lockxchg(MEM, VAR, sizeof(*(MEM)) / (sizeof(*(MEM)) == sizeof(*(VAR)))) +#define atomic_store(MEM, VAL) \ + atomic_store(MEM, VAL, sizeof(*(MEM)) / (sizeof(*(MEM)) == sizeof(*(VAL)))) +#define atomic_load(MEM) atomic_load(MEM, sizeof(*(MEM))) #endif /* __GNUC__ && !__STRICT_ANSI__ */ COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/runtime/arch_prctl.c b/libc/runtime/arch_prctl.c index 59fcc4972..42df89147 100644 --- a/libc/runtime/arch_prctl.c +++ b/libc/runtime/arch_prctl.c @@ -40,6 +40,22 @@ * operating systems. */ +#define rdmsr(msr) \ + ({ \ + uint32_t lo, hi; \ + asm volatile("rdmsr" : "=a"(lo), "=d"(hi) : "c"(msr)); \ + (uint64_t) hi << 32 | lo; \ + }) + +#define wrmsr(msr, val) \ + do { \ + uint64_t val_ = (val); \ + asm volatile("wrmsr" \ + : /* no outputs */ \ + : "c"(msr), "a"((uint32_t)val_), \ + "d"((uint32_t)(val_ >> 32))); \ + } while (0) + int sys_arch_prctl(int, int64_t) hidden; static inline int arch_prctl_fsgsbase(int code, int64_t addr) {