mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 15:03:34 +00:00
I wanted a tiny scriptable meltdown proof way to run userspace programs and visualize how program execution impacts memory. It helps to explain how things like Actually Portable Executable works. It can show you how the GCC generated code is going about manipulating matrices and more. I didn't feel fully comfortable with Qemu and Bochs because I'm not smart enough to understand them. I wanted something like gVisor but with much stronger levels of assurances. I wanted a single binary that'll run, on all major operating systems with an embedded GPL barrier ZIP filesystem that is tiny enough to transpile to JavaScript and run in browsers too. https://justine.storage.googleapis.com/emulator625.mp4
99 lines
4.7 KiB
C
99 lines
4.7 KiB
C
#ifndef COSMOPOLITAN_LIBC_LOG_CHECK_H_
|
|
#define COSMOPOLITAN_LIBC_LOG_CHECK_H_
|
|
#include "libc/dce.h"
|
|
#include "libc/macros.h"
|
|
|
|
/**
|
|
* @fileoverview Modern assertions, courtesy of Elgoog.
|
|
*/
|
|
|
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
|
COSMOPOLITAN_C_START_
|
|
|
|
#define CHECK(X, ...) __CHK(eq, ==, true, "true", !!(X), #X, "" __VA_ARGS__)
|
|
#define CHECK_EQ(Y, X, ...) __CHK(eq, ==, Y, #Y, X, #X, "" __VA_ARGS__)
|
|
#define CHECK_NE(Y, X, ...) __CHK(ne, !=, Y, #Y, X, #X, "" __VA_ARGS__)
|
|
#define CHECK_LE(Y, X, ...) __CHK(le, <=, Y, #Y, X, #X, "" __VA_ARGS__)
|
|
#define CHECK_LT(Y, X, ...) __CHK(lt, <, Y, #Y, X, #X, "" __VA_ARGS__)
|
|
#define CHECK_GE(Y, X, ...) __CHK(ge, >=, Y, #Y, X, #X, "" __VA_ARGS__)
|
|
#define CHECK_GT(Y, X, ...) __CHK(gt, >, Y, #Y, X, #X, "" __VA_ARGS__)
|
|
#define CHECK_NOTNULL(X, ...) __CHK(ne, !=, NULL, "NULL", X, #X, "" __VA_ARGS__)
|
|
|
|
#define DCHECK(X, ...) __DCHK(eq, ==, true, "true", !!(X), #X, "" __VA_ARGS__)
|
|
#define DCHECK_EQ(Y, X, ...) __DCHK(eq, ==, Y, #Y, X, #X, "" __VA_ARGS__)
|
|
#define DCHECK_NE(Y, X, ...) __DCHK(ne, !=, Y, #Y, X, #X, "" __VA_ARGS__)
|
|
#define DCHECK_LE(Y, X, ...) __DCHK(le, <=, Y, #Y, X, #X, "" __VA_ARGS__)
|
|
#define DCHECK_LT(Y, X, ...) __DCHK(lt, <, Y, #Y, X, #X, "" __VA_ARGS__)
|
|
#define DCHECK_GE(Y, X, ...) __DCHK(ge, >=, Y, #Y, X, #X, "" __VA_ARGS__)
|
|
#define DCHECK_GT(Y, X, ...) __DCHK(gt, >, Y, #Y, X, #X, "" __VA_ARGS__)
|
|
#define DCHECK_NOTNULL(X, ...) \
|
|
__DCHK(ne, !=, NULL, "NULL", X, #X, "" __VA_ARGS__)
|
|
|
|
#define CHECK_ALIGNED(BYTES, VAR) \
|
|
do { \
|
|
if (((uintptr_t)VAR & ((BYTES)-1u))) { \
|
|
__check_fail_aligned(BYTES, (uintptr_t)VAR); \
|
|
unreachable; \
|
|
} \
|
|
VAR = (typeof(VAR))__builtin_assume_aligned(VAR, BYTES); \
|
|
} while (0)
|
|
|
|
#define DCHECK_ALIGNED(BYTES, VAR) \
|
|
do { \
|
|
if (((uintptr_t)VAR & ((BYTES)-1u))) { \
|
|
__DCHK_ALIGNED(BYTES, (uintptr_t)VAR); \
|
|
unreachable; \
|
|
} \
|
|
VAR = (typeof(VAR))__builtin_assume_aligned(VAR, BYTES); \
|
|
} while (0)
|
|
|
|
#define __CHK(SUFFIX, OP, WANT, WANTSTR, GOT, GOTSTR, ...) \
|
|
do { \
|
|
autotype(GOT) Got = (GOT); \
|
|
autotype(WANT) Want = (WANT); \
|
|
if (!(Want OP Got)) { \
|
|
if (!NoDebug()) { \
|
|
__check_fail(#SUFFIX, #OP, (uint64_t)Want, (WANTSTR), (uint64_t)Got, \
|
|
(GOTSTR), __FILE__, __LINE__, __VA_ARGS__); \
|
|
} else { \
|
|
__check_fail_##SUFFIX((uint64_t)Want, (uint64_t)Got); \
|
|
} \
|
|
unreachable; \
|
|
} \
|
|
} while (0)
|
|
|
|
#ifdef NDEBUG
|
|
#define __DCHK(SUFFIX, OP, WANT, WANTSTR, GOT, ...) \
|
|
do { \
|
|
autotype(GOT) Got = (GOT); \
|
|
autotype(WANT) Want = (WANT); \
|
|
if (!(Want OP Got)) { \
|
|
unreachable; \
|
|
} \
|
|
} while (0)
|
|
#else
|
|
#define __DCHK(SUFFIX, OP, WANT, WANTSTR, GOT, GOTSTR, ...) \
|
|
__CHK(SUFFIX, OP, WANT, WANTSTR, GOT, GOTSTR, __VA_ARGS__)
|
|
#endif
|
|
|
|
#ifdef NDEBUG
|
|
#define __DCHK_ALIGNED(BYTES, VAR)
|
|
#else
|
|
#define __DCHK_ALIGNED(BYTES, VAR) __check_fail_aligned(BYTES, VAR)
|
|
#endif
|
|
|
|
void __check_fail(const char *, const char *, uint64_t, const char *, uint64_t,
|
|
const char *, const char *, int, const char *,
|
|
...) relegated noreturn;
|
|
|
|
void __check_fail_eq(uint64_t, uint64_t) relegated noreturn;
|
|
void __check_fail_ne(uint64_t, uint64_t) relegated noreturn;
|
|
void __check_fail_le(uint64_t, uint64_t) relegated noreturn;
|
|
void __check_fail_lt(uint64_t, uint64_t) relegated noreturn;
|
|
void __check_fail_ge(uint64_t, uint64_t) relegated noreturn;
|
|
void __check_fail_gt(uint64_t, uint64_t) relegated noreturn;
|
|
void __check_fail_aligned(unsigned, uint64_t) relegated noreturn;
|
|
|
|
COSMOPOLITAN_C_END_
|
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
|
#endif /* COSMOPOLITAN_LIBC_LOG_CHECK_H_ */
|