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.
This commit is contained in:
Justine Tunney 2021-02-04 16:37:22 -08:00
parent 888cfa74d7
commit 3384a5a48c
6 changed files with 159 additions and 135 deletions

21
.vscode/vscode.h vendored
View file

@ -11,11 +11,11 @@
#define __INT_MAX__ 0x7FFFFFFF #define __INT_MAX__ 0x7FFFFFFF
#define __LONG_MAX__ 0x7FFFFFFFFFFFFFFF #define __LONG_MAX__ 0x7FFFFFFFFFFFFFFF
#define __LONG_LONG_MAX__ __LONG_MAX__ #define __LONG_LONG_MAX__ __LONG_MAX__
#define __CHAR_MIN__ -((__CHAR_MAX__)+1) #define __CHAR_MIN__ -((__CHAR_MAX__) + 1)
#define __SHRT_MIN__ -((__SHRT_MAX__)+1) #define __SHRT_MIN__ -((__SHRT_MAX__) + 1)
#define __INT_MIN__ -((__INT_MAX__)+1) #define __INT_MIN__ -((__INT_MAX__) + 1)
#define __LONG_MIN__ -((__LONG_MAX__)+1) #define __LONG_MIN__ -((__LONG_MAX__) + 1)
#define __LONG_LONG_MIN__ -((__LONG_LONG_MAX__)+1) #define __LONG_LONG_MIN__ -((__LONG_LONG_MAX__) + 1)
#define __UCHAR_MAX__ 0xFF #define __UCHAR_MAX__ 0xFF
#define __USHRT_MAX__ 0xFFFF #define __USHRT_MAX__ 0xFFFF
#define __UINT_MAX__ 0xFFFFFFFF #define __UINT_MAX__ 0xFFFFFFFF
@ -123,7 +123,7 @@ typedef struct { int ax, dx; } axdx_t;
/* duplicate and replace xmmintrin.internal.h to fix it for IntelliSense /* duplicate and replace xmmintrin.internal.h to fix it for IntelliSense
* SEE: <> */ * SEE: <> */
#define _Vector_size(x) __attribute__(( vector_size( x ) )) #define _Vector_size(x) __attribute__((__vector_size__(x)))
#define IMAGE_BASE_VIRTUAL 0x400000 #define IMAGE_BASE_VIRTUAL 0x400000
#define __SIGACTION(...) (0) #define __SIGACTION(...) (0)
@ -136,9 +136,7 @@ typedef struct { int ax, dx; } axdx_t;
#define CONCAT(a, b, c, d, e) 0 #define CONCAT(a, b, c, d, e) 0
#define shuffle(...) 0 #define shuffle(...) 0
#define reverse(x, y) 0 #define reverse(x, y) 0
#define atomic_load(...) 0 #define autotype(x) intptr_t
#define atomic_store(...) 0
#define autotype(x) int
#define _Generic_(...) (void*)(0) #define _Generic_(...) (void*)(0)
#define _Generic(...) _Generic_ #define _Generic(...) _Generic_
@ -146,11 +144,6 @@ typedef struct { int ax, dx; } axdx_t;
#define _Section(...) #define _Section(...)
#define offsetof(x, y) 0 #define offsetof(x, y) 0
#define cmpxchg(...) 0
#define lockxchg(...) 0
#define lockcmpxchg(...) 0
#define xgetbv(...) 0
#define rdmsr(...) 0
#define INITIALIZER(...) struct _dummy #define INITIALIZER(...) struct _dummy
#define __far #define __far
#define tinystrstr(...) 0 #define tinystrstr(...) 0

View file

@ -17,11 +17,10 @@
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "ape/lib/pc.h" #include "ape/lib/pc.h"
#include "libc/bits/bits.h"
textreal void pageunmap(int64_t vaddr) { textreal void pageunmap(int64_t vaddr) {
uint64_t *entry; uint64_t *entry;
entry = __getpagetableentry(vaddr, 3, &g_pml4t, &g_ptsp_xlm); entry = __getpagetableentry(vaddr, 3, &g_pml4t, &g_ptsp_xlm);
*entry &= ~PAGE_V; *entry &= ~PAGE_V;
invlpg(vaddr); asm volatile("invlpg\t(%0)" : /* no outputs */ : "r"(vaddr) : "memory");
} }

34
libc/bits/atomic_load.c Normal file
View file

@ -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;
}

32
libc/bits/atomic_store.c Normal file
View file

@ -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;
}

View file

@ -24,6 +24,8 @@ unsigned long hamming(unsigned long, unsigned long) pureconst;
intptr_t lockxchg(void *, void *, size_t); intptr_t lockxchg(void *, void *, size_t);
bool cmpxchg(void *, intptr_t, intptr_t, size_t); bool cmpxchg(void *, intptr_t, intptr_t, size_t);
bool lockcmpxchg(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 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 Intel's Six-Thousand Page Manual V.3A §8.2.3.1
* @see atomic_store() * @see atomic_store()
*/ */
#ifndef atomic_load
#define atomic_load(MEM) \ #define atomic_load(MEM) \
({ \ ({ \
autotype(MEM) Mem = (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)); \ asm("mov\t%1,%0" : "=r"(Reg) : "m"(*Mem)); \
Reg; \ Reg; \
}) })
#endif /* atomic_load */
/** /**
* Saves scalar to memory w/ one operation. * 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 Intel Six-Thousand Page Manual Manual V.3A §8.2.3.1
* @see atomic_load() * @see atomic_load()
*/ */
#ifndef atomic_store
#define atomic_store(MEM, VAL) \ #define atomic_store(MEM, VAL) \
({ \ ({ \
autotype(VAL) Val = (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)); \ asm("mov%z1\t%1,%0" : "=m"(*Mem) : "r"(Val)); \
Val; \ Val; \
}) })
#endif /* atomic_store */
#define bts(MEM, BIT) __BitOp("bts", BIT, MEM) /** bit test and set */ #define bts(MEM, BIT) __BitOp("bts", BIT, MEM) /** bit test and set */
#define btr(MEM, BIT) __BitOp("btr", BIT, MEM) /** bit test and reset */ #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] * @return LOCALVAR[0]
* @see xchg() * @see xchg()
*/ */
#ifndef lockxchg
#define lockxchg(MEMORY, LOCALVAR) \ #define lockxchg(MEMORY, LOCALVAR) \
({ \ ({ \
_Static_assert( \ _Static_assert( \
@ -244,7 +241,6 @@ bool lockcmpxchg(void *, intptr_t, intptr_t, size_t);
asm("xchg\t%0,%1" : "+%m"(*(MEMORY)), "+r"(*(LOCALVAR))); \ asm("xchg\t%0,%1" : "+%m"(*(MEMORY)), "+r"(*(LOCALVAR))); \
*(LOCALVAR); \ *(LOCALVAR); \
}) })
#endif /* lockxchg */
/** /**
* Compares and exchanges. * Compares and exchanges.
@ -253,7 +249,6 @@ bool lockcmpxchg(void *, intptr_t, intptr_t, size_t);
* @return true if value was exchanged, otherwise false * @return true if value was exchanged, otherwise false
* @see lockcmpxchg() * @see lockcmpxchg()
*/ */
#ifndef cmpxchg
#define cmpxchg(IFTHING, ISEQUALTOME, REPLACEITWITHME) \ #define cmpxchg(IFTHING, ISEQUALTOME, REPLACEITWITHME) \
({ \ ({ \
bool DidIt; \ bool DidIt; \
@ -266,7 +261,6 @@ bool lockcmpxchg(void *, intptr_t, intptr_t, size_t);
: "cc"); \ : "cc"); \
DidIt; \ DidIt; \
}) })
#endif /* cmpxchg */
/** /**
* Compares and exchanges w/ one operation. * 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 * @return true if value was exchanged, otherwise false
* @see lockcmpxchg() * @see lockcmpxchg()
*/ */
#ifndef lockcmpxchg
#define lockcmpxchg(IFTHING, ISEQUALTOME, REPLACEITWITHME) \ #define lockcmpxchg(IFTHING, ISEQUALTOME, REPLACEITWITHME) \
({ \ ({ \
bool DidIt; \ bool DidIt; \
@ -288,52 +281,6 @@ bool lockcmpxchg(void *, intptr_t, intptr_t, size_t);
: "cc"); \ : "cc"); \
DidIt; \ 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) \ #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))) lockcmpxchg(MEM, (intptr_t)(CMP), (intptr_t)(VAL), sizeof(*(MEM)))
#define lockxchg(MEM, VAR) \ #define lockxchg(MEM, VAR) \
lockxchg(MEM, VAR, sizeof(*(MEM)) / (sizeof(*(MEM)) == sizeof(*(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__ */ #endif /* __GNUC__ && !__STRICT_ANSI__ */
COSMOPOLITAN_C_END_ COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -40,6 +40,22 @@
* operating systems. * 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; int sys_arch_prctl(int, int64_t) hidden;
static inline int arch_prctl_fsgsbase(int code, int64_t addr) { static inline int arch_prctl_fsgsbase(int code, int64_t addr) {