From 2ab9e9f7fdd1b0e6d5f40588dc15f42354c6e922 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Thu, 1 Feb 2024 03:39:46 -0800 Subject: [PATCH] Make improvements - Introduce portable sched_getcpu() api - Support GCC's __target_clones__ feature - Make fma() go faster on x86 in default mode - Remove some asan checks from core libraries - WinMain() now ensures $HOME and $USER are defined --- .vscode/c_cpp_properties.json | 2 +- Makefile | 8 +- ape/ape-m1.c | 38 +- ape/ape.lds | 17 +- ape/loader.c | 73 +- ape/sections.internal.h | 10 +- build/bootstrap/ape.aarch64 | Bin 8296 -> 8296 bytes build/bootstrap/compile.com | Bin 355223 -> 353920 bytes build/bootstrap/fixupobj.com | Bin 192711 -> 210912 bytes build/bootstrap/gcc-only-flags.txt | 58 ++ build/bootstrap/package.com | Bin 250775 -> 250528 bytes build/definitions.mk | 5 +- build/htags | 2 +- build/online.mk | 3 +- build/rules.mk | 1 + examples/BUILD.mk | 2 + examples/system.c | 1 + examples/unbourne.c | 36 +- libc/calls/BUILD.mk | 4 +- libc/calls/calls.h | 2 + libc/calls/clock_gettime-nt.c | 31 +- libc/calls/clock_gettime.c | 25 +- libc/calls/close.c | 2 +- libc/calls/getrandom.c | 4 +- libc/calls/metalfile.c | 4 +- libc/calls/rdrand.c | 2 +- libc/calls/read-nt.c | 2 + libc/calls/sched_getcpu.c | 17 + libc/calls/sig.c | 3 +- libc/calls/syscall_support-nt.internal.h | 2 +- libc/calls/ucontext.h | 2 +- libc/calls/uname.c | 12 + libc/cosmo.h | 1 + libc/integral/c.inc | 37 +- libc/intrin/BUILD.mk | 5 + libc/{runtime => intrin}/fesetround.c | 0 libc/intrin/kprintf.greg.c | 2 +- libc/intrin/memchr.c | 3 +- libc/intrin/memmove.c | 2 +- libc/intrin/memrchr.c | 2 +- libc/intrin/mman.greg.c | 19 +- libc/intrin/reservefd.c | 2 - libc/intrin/segmentation.h | 24 - libc/intrin/stpcpy.c | 2 +- libc/intrin/strchr.c | 2 +- libc/intrin/strchrnul.c | 2 +- libc/intrin/strcpy.c | 2 +- libc/intrin/strlen.c | 3 +- libc/intrin/x86.c | 808 ++++++++++++++++++ libc/log/addr2linepath.c | 2 +- libc/log/cxaprintexits.c | 6 +- libc/log/die.c | 2 + libc/log/gdbexec.c | 2 +- libc/log/oncrash_amd64.c | 13 +- libc/macros.internal.h | 6 +- libc/mem/mergesort.c | 4 +- libc/nexgen32e/rdtscp.h | 5 +- .../ProcessPrng.S} | 8 +- libc/nt/BUILD.mk | 18 + libc/nt/master.sh | 6 +- libc/nt/runtime.h | 4 +- libc/nt/struct/teb.h | 27 +- libc/proc/fork-nt.c | 14 +- libc/runtime/clone.c | 2 +- libc/runtime/cosmo2.c | 2 +- libc/runtime/efimain.greg.c | 10 +- libc/runtime/getargmax.c | 10 +- libc/runtime/memtrack.internal.h | 8 +- libc/runtime/runtime.h | 2 +- libc/runtime/set_tls.c | 8 +- libc/runtime/syslib.internal.h | 14 +- libc/runtime/winargs.internal.h | 17 +- libc/runtime/winmain.greg.c | 41 +- libc/stdbool.h | 17 +- libc/stdio/fmt.c | 4 +- libc/stdio/ftw.c | 2 +- libc/stdio/printargs.c | 4 + libc/stdio/rdseed.c | 2 +- libc/stdio/rngset.c | 3 - libc/stdio/stdio.h | 2 +- libc/stdio/tmpnam.c | 2 - libc/str/BUILD.mk | 2 +- libc/str/djbsort.c | 6 - libc/str/isutf8.c | 2 - libc/str/memmem.c | 7 +- libc/str/memrchr16.c | 8 +- libc/str/rawmemchr.c | 7 +- libc/str/str.h | 2 +- libc/str/strcasecmp.c | 3 - libc/str/strcasestr.c | 5 +- libc/str/strlen16.c | 5 +- libc/str/strnlen_s.c | 2 - libc/str/strstr.c | 5 +- libc/str/wcslen.c | 5 +- libc/str/wmemrchr.c | 14 +- libc/sysv/consts.sh | 29 +- libc/sysv/consts/CLOCK_MONOTONIC.S | 2 +- libc/sysv/consts/CLOCK_MONOTONIC_COARSE.S | 2 +- libc/sysv/consts/CLOCK_MONOTONIC_FAST.S | 2 +- libc/sysv/consts/CLOCK_MONOTONIC_PRECISE.S | 2 +- libc/sysv/consts/CLOCK_MONOTONIC_RAW.S | 2 +- libc/sysv/consts/CLOCK_PROCESS_CPUTIME_ID.S | 2 +- libc/sysv/consts/CLOCK_THREAD_CPUTIME_ID.S | 2 +- libc/sysv/consts/CLOCK_UPTIME.S | 2 +- libc/sysv/consts/MAP_NOCACHE.S | 2 + libc/sysv/consts/MAP_NOEXTEND.S | 2 + libc/sysv/consts/map.h | 3 + libc/testlib/ezbenchcontrol.c | 2 +- libc/testlib/showerror.c | 2 +- libc/testlib/testlib.h | 64 +- libc/thread/makecontext.c | 5 +- libc/thread/tls.h | 2 +- libc/tinymath/fma.c | 29 +- libc/tinymath/fmaf.c | 3 +- libc/tinymath/fmal.c | 287 +++++++ libc/tinymath/ilogb.c | 2 +- libc/tinymath/ilogbf.c | 2 +- libc/tinymath/nearbyint.c | 2 +- libc/tinymath/nearbyintf.c | 2 +- libc/tinymath/nearbyintl.c | 2 +- libc/tinymath/pow.c | 4 +- libc/tinymath/rempio2large.c | 2 + libc/x/x.h | 46 +- libc/x/xasprintf.h | 4 +- test/libc/calls/madvise_test.c | 5 +- test/libc/intrin/kprintf_test.c | 2 +- test/libc/nexgen32e/gclongjmp_test.c | 4 + test/libc/runtime/tls_test.c | 3 + test/libc/runtime/zipos_test.c | 1 - test/libc/x/xstrcat_test.c | 4 + test/libcxx/BUILD.mk | 7 +- test/libcxx/openmp_test.cc | 491 ++++++++--- third_party/awk/run.c | 3 +- third_party/bash/BUILD.mk | 1 + third_party/chibicc/preprocess.c | 3 +- third_party/compiler_rt/cpu_model.h | 33 + third_party/hiredis/sds.c | 2 + third_party/libcxx/BUILD.mk | 1 + third_party/libcxx/__config | 4 +- third_party/libcxx/cassert | 2 +- third_party/libcxx/cfenv | 2 +- third_party/libcxx/cfloat | 3 +- third_party/libcxx/cinttypes | 3 +- third_party/libcxx/ciso646 | 2 + third_party/libcxx/clocale | 3 +- third_party/libcxx/csetjmp | 2 +- third_party/libcxx/csignal | 7 +- third_party/libcxx/cstdarg | 1 + third_party/libcxx/cstdbool | 1 + third_party/libcxx/cstddef | 1 + third_party/libcxx/cstdint | 6 +- third_party/libcxx/cstdlib | 1 + third_party/libcxx/ctime | 10 +- third_party/libcxx/ctype.h | 2 +- third_party/libcxx/errno.h | 2 +- third_party/libcxx/limits.h | 18 +- third_party/libcxx/locale.h | 3 +- third_party/libcxx/math.h | 2 +- third_party/libcxx/stdio.h | 4 +- third_party/libcxx/stdlib.h | 8 +- third_party/libcxx/string | 49 +- third_party/libcxx/string.h | 2 +- third_party/libcxx/wchar.h | 3 +- third_party/libcxx/wctype.h | 3 +- third_party/libcxxabi/test/BUILD.mk | 104 +-- .../libcxxabi/test/incomplete_type.sh.one.cc | 1 - .../libcxxabi/test/incomplete_type.sh.two.cc | 1 - .../test/incomplete_type_test.lib.cc | 1 + ...ype.sh.cc => incomplete_type_test.pass.cc} | 0 third_party/musl/crypt_des.c | 2 + third_party/musl/dn_comp.c | 2 +- third_party/nsync/futex.c | 4 +- third_party/nsync/yield.c | 2 +- third_party/openmp/kmp_os.h | 2 +- third_party/zstd/BUILD.mk | 1 + tool/build/compile.c | 136 ++- .../__clear_cache.c => tool/build/findape.c | 59 +- tool/build/findelf.c | 65 ++ tool/build/findpe.c | 3 + tool/build/fixupobj.c | 212 ++++- tool/build/mkdeps.c | 226 ++--- tool/build/objbincopy.c | 2 +- tool/build/package.c | 3 +- tool/build/runit.c | 10 +- tool/decode/elf.c | 2 +- tool/emacs/c.lang | 2 +- tool/emacs/cosmo-asm-mode.el | 3 +- tool/emacs/cosmo-c-keywords.el | 5 +- tool/emacs/cosmo-platform-constants.el | 3 +- tool/emacs/cosmo-stuff.el | 42 +- tool/emacs/key.py | 4 +- tool/viz/printpeb.c | 4 +- 192 files changed, 2809 insertions(+), 932 deletions(-) create mode 100644 build/bootstrap/gcc-only-flags.txt rename libc/{runtime => intrin}/fesetround.c (100%) delete mode 100644 libc/intrin/segmentation.h create mode 100644 libc/intrin/x86.c rename libc/nt/{advapi32/SystemFunction036.S => BCryptPrimitives/ProcessPrng.S} (57%) create mode 100644 libc/sysv/consts/MAP_NOCACHE.S create mode 100644 libc/sysv/consts/MAP_NOEXTEND.S create mode 100644 libc/tinymath/fmal.c create mode 100644 third_party/compiler_rt/cpu_model.h delete mode 120000 third_party/libcxxabi/test/incomplete_type.sh.one.cc delete mode 120000 third_party/libcxxabi/test/incomplete_type.sh.two.cc create mode 120000 third_party/libcxxabi/test/incomplete_type_test.lib.cc rename third_party/libcxxabi/test/{incomplete_type.sh.cc => incomplete_type_test.pass.cc} (100%) rename libc/intrin/__clear_cache.c => tool/build/findape.c (63%) create mode 100644 tool/build/findelf.c diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 3a7cc4ece..4aad63c52 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -48,7 +48,7 @@ "notpossible=", "thatispacked=", "dontthrow=", - "nocallback=", + "dontcallback=", "relegated=", "hidden=", "textstartup=", diff --git a/Makefile b/Makefile index 46e0b69d9..0f6122670 100644 --- a/Makefile +++ b/Makefile @@ -101,7 +101,6 @@ XARGS ?= xargs -P4 -rs8000 DOT ?= dot CLANG = clang TMPDIR = o/tmp - AR = build/bootstrap/ar.com CP = build/bootstrap/cp.com RM = build/bootstrap/rm.com -f @@ -134,10 +133,10 @@ endif ifneq ($(findstring aarch64,$(MODE)),) ARCH = aarch64 -HOSTS ?= pi studio freebsdarm +HOSTS ?= pi pi5 studio freebsdarm else ARCH = x86_64 -HOSTS ?= freebsd rhel7 xnu win10 openbsd netbsd +HOSTS ?= freebsd rhel7 xnu win10 openbsd netbsd meatball nightmare endif ZIPOBJ_FLAGS += -a$(ARCH) @@ -209,7 +208,7 @@ endif libc/stdbool.h \ libc/disclaimer.inc \ rwc:/dev/shm \ - rx:cosmocc \ + rx:.cosmocc \ rx:build/bootstrap \ r:build/portcosmo.h \ /proc/stat \ @@ -481,6 +480,7 @@ COSMOPOLITAN_OBJECTS = \ LIBC_STR \ LIBC_SYSV \ LIBC_INTRIN \ + LIBC_NT_BCRYPTPRIMITIVES \ LIBC_NT_KERNEL32 \ LIBC_NEXGEN32E diff --git a/ape/ape-m1.c b/ape/ape-m1.c index 82c98feaa..1afd1edb0 100644 --- a/ape/ape-m1.c +++ b/ape/ape-m1.c @@ -39,7 +39,7 @@ /* maximum path size that cosmo can take */ #define PATHSIZE (PATH_MAX < 1024 ? PATH_MAX : 1024) #define SYSLIB_MAGIC ('s' | 'l' << 8 | 'i' << 16 | 'b' << 24) -#define SYSLIB_VERSION 8 +#define SYSLIB_VERSION 9 /* sync with libc/runtime/syslib.internal.h */ struct Syslib { int magic; @@ -96,11 +96,16 @@ struct Syslib { long (*sem_trywait)(int *); long (*getrlimit)(int, struct rlimit *); long (*setrlimit)(int, const struct rlimit *); - // v6 (2023-11-03) + /* v6 (2023-11-03) */ void *(*dlopen)(const char *, int); void *(*dlsym)(void *, const char *); int (*dlclose)(void *); char *(*dlerror)(void); + /* MANDATORY (cosmo runtime won't load if version < 8) + --------------------------------------------------- + OPTIONAL (cosmo lib should check __syslib->version) */ + /* v9 (2024-01-31) */ + int (*pthread_cpu_number_np)(size_t *); }; #define ELFCLASS32 1 @@ -660,9 +665,9 @@ __attribute__((__noreturn__)) static void Spawn(const char *exe, int fd, size = (p[i].p_vaddr & (pagesz - 1)) + p[i].p_filesz; if (prot1 & PROT_EXEC) { #ifdef SIP_DISABLED - // if sip is disabled then we can load the executable segments - // off the binary into memory without needing to copy anything - // which provides considerably better performance for building + /* if sip is disabled then we can load the executable segments + off the binary into memory without needing to copy anything + which provides considerably better performance for building */ rc = sys_mmap(addr, size, prot1, flags, fd, p[i].p_offset & -pagesz); if (rc < 0) { if (rc == -EPERM) { @@ -674,12 +679,12 @@ __attribute__((__noreturn__)) static void Spawn(const char *exe, int fd, } } #else - // the issue is that if sip is enabled then, attempting to map - // it with exec permission will cause xnu to phone home a hash - // of the entire file to apple intelligence as a one time cost - // which is literally minutes for executables holding big data - // since there's no public apple api for detecting sip we read - // as the default strategy which is slow but it works for both + /* the issue is that if sip is enabled then, attempting to map + it with exec permission will cause xnu to phone home a hash + of the entire file to apple intelligence as a one time cost + which is literally minutes for executables holding big data + since there's no public apple api for detecting sip we read + as the default strategy which is slow but it works for both */ rc = sys_mmap(addr, size, (prot1 = PROT_READ | PROT_WRITE), MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0); if (rc < 0) Pexit(exe, rc, "prog mmap anon"); @@ -812,12 +817,10 @@ static const char *TryElf(struct ApeLoader *M, union ElfEhdrBuf *ebuf, } } - /* - * merge adjacent loads that are contiguous with equal protection, - * which prevents our program header overlap check from needlessly - * failing later on; it also shaves away a microsecond of latency, - * since every program header requires invoking at least 1 syscall - */ + /* merge adjacent loads that are contiguous with equal protection, + which prevents our program header overlap check from needlessly + failing later on; it also shaves away a microsecond of latency, + since every program header requires invoking at least 1 syscall */ for (i = 0; i + 1 < e->e_phnum;) { if (p[i].p_type == PT_LOAD && p[i + 1].p_type == PT_LOAD && ((p[i].p_flags & (PF_R | PF_W | PF_X)) == @@ -944,6 +947,7 @@ int main(int argc, char **argv, char **envp) { M->lib.dlsym = dlsym; M->lib.dlclose = dlclose; M->lib.dlerror = dlerror; + M->lib.pthread_cpu_number_np = pthread_cpu_number_np; /* getenv("_") is close enough to at_execfn */ execfn = 0; diff --git a/ape/ape.lds b/ape/ape.lds index 288d798d4..1a39e2dc1 100644 --- a/ape/ape.lds +++ b/ape/ape.lds @@ -282,12 +282,9 @@ SECTIONS { KEEP(*(SORT_BY_NAME(.init.*))) KEEP(*(.init)) KEEP(*(.initepilogue)) - KEEP(*(.pltprologue)) *(.plt) - KEEP(*(.pltepilogue)) - KEEP(*(.pltgotprologue)) *(.plt.got) - KEEP(*(.pltgotepilogue)) + *(.iplt) *(.text.startup .text.startup.*) *(.text.exit .text.exit.*) *(.text.unlikely .text.*_unlikely .text.unlikely.*) @@ -323,7 +320,7 @@ SECTIONS { /*BEGIN: Read Only Data */ - .rodata . : { + .rodata ALIGN(CONSTANT(COMMONPAGESIZE)) : { KEEP(*(.rodata.pytab.0)); KEEP(*(.rodata.pytab.1)); KEEP(*(.rodata.pytab.2)); @@ -398,13 +395,12 @@ SECTIONS { KEEP(*(SORT_BY_NAME(.sort.data.*))) . += . > 0 ? CODE_GRANULE : 0; - KEEP(*(.gotprologue)) + . = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0); + __got_start = .; *(.got) - KEEP(*(.gotepilogue)) + __got_end = .; - KEEP(*(.gotpltprologue)) *(.got.plt) - KEEP(*(.gotpltepilogue)) . = ALIGN(. != 0 ? __SIZEOF_POINTER__ : 0); __init_array_start = .; @@ -430,6 +426,8 @@ SECTIONS { KEEP(*(SORT_BY_NAME(.piro.data.sort.*))) KEEP(*(.piro.pad.data)) KEEP(*(.dataepilogue)) + *(.igot.plt) + . = ALIGN(. != 0 ? CONSTANT(COMMONPAGESIZE) : 0); /*END: NT FORK COPYING */ _edata = .; @@ -528,6 +526,7 @@ SECTIONS { #endif *(__patchable_function_entries) *(__mcount_loc) + *(.rela.dyn) *(.discard) *(.yoink) } diff --git a/ape/loader.c b/ape/loader.c index 87822315e..752d5ef6e 100644 --- a/ape/loader.c +++ b/ape/loader.c @@ -166,13 +166,6 @@ (unsigned long)(255 & (S)[1]) << 010 | \ (unsigned long)(255 & (S)[0]) << 000) -#define DEBUG(VAR) \ - { \ - char ibuf[19] = {0}; \ - Utox(ibuf, VAR); \ - Print(os, 2, ibuf, " " #VAR, "\n", 0l); \ - } - struct ElfEhdr { unsigned char e_ident[16]; unsigned short e_type; @@ -340,23 +333,6 @@ static char *GetEnv(char **p, const char *s) { return 0; } -static char *Utox(char p[19], unsigned long x) { - int i; - if (x) { - *p++ = '0'; - *p++ = 'x'; - i = (__builtin_clzl(x) ^ (sizeof(long) * 8 - 1)) + 1; - i = (i + 3) & -4; - do { - *p++ = "0123456789abcdef"[(x >> (i -= 4)) & 15]; - } while (i); - } else { - *p++ = '0'; - } - *p = 0; - return p; -} - static char *Utoa(char p[20], unsigned long x) { char t; unsigned long i, a, b; @@ -534,6 +510,53 @@ static long Print(int os, int fd, const char *s, ...) { return Write(fd, b, n, os); } +static long Printf(int os, int fd, const char *fmt, ...) { + int i; + char c; + int k = 0; + unsigned u; + char b[512]; + const char *s; + unsigned long d; + __builtin_va_list va; + __builtin_va_start(va, fmt); + for (;;) { + switch ((c = *fmt++)) { + case '\0': + __builtin_va_end(va); + return Write(fd, b, k, os); + case '%': + switch ((c = *fmt++)) { + case 's': + for (s = __builtin_va_arg(va, const char *); s && *s; ++s) { + if (k < 512) b[k++] = *s; + } + break; + case 'd': + d = __builtin_va_arg(va, unsigned long); + for (i = 16; i--;) { + u = (d >> (i * 4)) & 15; + if (u < 10) { + c = '0' + u; + } else { + u -= 10; + c = 'a' + u; + } + if (k < 512) b[k++] = c; + } + break; + default: + if (k < 512) b[k++] = c; + break; + } + break; + default: + if (k < 512) b[k++] = c; + break; + } + } +} + static void Perror(int os, const char *thing, long rc, const char *reason) { char ibuf[21]; ibuf[0] = 0; @@ -901,7 +924,7 @@ EXTERN_C __attribute__((__noreturn__)) void ApeLoader(long di, long *sp, long *auxv, *ap, *endp, *sp2; char *p, *pe, *exe, *prog, **argv, **envp; - (void)Utox; + (void)Printf; /* detect freebsd */ if (SupportsXnu() && dl == XNU) { diff --git a/ape/sections.internal.h b/ape/sections.internal.h index 119c4990e..e99503b7e 100644 --- a/ape/sections.internal.h +++ b/ape/sections.internal.h @@ -18,10 +18,12 @@ extern unsigned char _tbss_end[] __attribute__((__weak__)); extern unsigned char _tls_align[] __attribute__((__weak__)); extern unsigned char __test_start[] __attribute__((__weak__)); extern unsigned char __ro[] __attribute__((__weak__)); -extern uint8_t __data_start[] __attribute__((__weak__)); -extern uint8_t __data_end[] __attribute__((__weak__)); -extern uint8_t __bss_start[] __attribute__((__weak__)); -extern uint8_t __bss_end[] __attribute__((__weak__)); +extern unsigned char __data_start[] __attribute__((__weak__)); +extern unsigned char __data_end[] __attribute__((__weak__)); +extern unsigned char __bss_start[] __attribute__((__weak__)); +extern unsigned char __bss_end[] __attribute__((__weak__)); +extern unsigned long __got_start[] __attribute__((__weak__)); +extern unsigned long __got_end[] __attribute__((__weak__)); extern unsigned char ape_phdrs[] __attribute__((__weak__)); COSMOPOLITAN_C_END_ diff --git a/build/bootstrap/ape.aarch64 b/build/bootstrap/ape.aarch64 index c95c86c7f7697267127499e63aeddc1fb8b495c8..65fe2cc16ca2fe216517087ed66d88fae927096c 100755 GIT binary patch delta 18 XcmaFi@WNq(jvOlk2y8Z#GiL$-Icfxp delta 18 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 KmvTtBivR$F`M!Vv delta 106082 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
`aWk?K{*@Fpa?@&`4(W{htu9-trm(z8Il6 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 delta 44915 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 r$gq?L~W@ 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∋MC@cv;rED^W)ut#n7~{^HTZm% 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 diff --git a/build/bootstrap/gcc-only-flags.txt b/build/bootstrap/gcc-only-flags.txt new file mode 100644 index 000000000..77b816a6b --- /dev/null +++ b/build/bootstrap/gcc-only-flags.txt @@ -0,0 +1,58 @@ +--nocompress-debug-sections +--noexecstack +-Wa,--nocompress-debug-sections +-Wa,--noexecstack +-Wa,-msse2avx +-Werror=maybe-uninitialized +-Wno-literal-suffix +-Wno-unused-but-set-variable +-Wunsafe-loop-optimizations +-fbranch-target-load-optimize +-fcx-limited-range +-fdelete-dead-exceptions +-femit-struct-debug-baseonly +-ffp-int-builtin-inexact +-finline-functions-called-once +-fipa-pta +-fivopts +-flimit-function-alignment +-fmerge-constants +-fmodulo-sched +-fmodulo-sched-allow-regmoves +-fno-align-jumps +-fno-align-labels +-fno-align-loops +-fno-code-hoisting +-fno-cx-limited-range +-fno-fp-int-builtin-inexact +-fno-gnu-unique +-fno-inline-functions-called-once +-fno-instrument-functions +-fno-schedule-insns2 +-fno-whole-program +-fopt-info-vec +-fopt-info-vec-missed +-freg-struct-return +-freschedule-modulo-scheduled-loops +-frounding-math +-fsched2-use-superblocks +-fschedule-insns +-fschedule-insns2 +-fshrink-wrap +-fshrink-wrap-separate +-fsignaling-nans +-fstack-clash-protection +-ftracer +-ftrapv +-ftree-loop-im +-ftree-loop-vectorize +-funsafe-loop-optimizations +-fversion-loops-for-strides +-fwhole-program +-gdescribe-dies +-gstabs +-mcall-ms2sysv-xlogues +-mdispatch-scheduler +-mfpmath=sse+387 +-mmitigate-rop +-mno-fentry diff --git a/build/bootstrap/package.com b/build/bootstrap/package.com index 015964e471ad4657c95615d09fa9f069cb6b3bc2..1c7db41316fdfe0d000b3abe9a8945276c5ecb28 100755 GIT binary patch delta 50641 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 GivR$PVKEp0 delta 51226 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 lim &&*lim == '/') lim++; + if (new > lim && *lim == '/') lim++; } else { USTPUTC('/', new); cdcomppath++; @@ -6565,6 +6564,10 @@ struct job *makejob(union node *node, int nprocs) { return jp; } +#if defined(__GNUC__) && __GNUC__ >= 12 +#pragma GCC diagnostic ignored "-Wuse-after-free" +#endif + static struct job *growjobtab(void) { unsigned len; long offset; @@ -7446,8 +7449,7 @@ static int ulimitcmd(int argc, char **argv) { what = optc; } } - for (l = limits; l->option != what; l++) - ; + for (l = limits; l->option != what; l++); set = *argptr ? 1 : 0; if (set) { char *p = *argptr; @@ -7660,8 +7662,7 @@ static void setparam(char **argv) { char **newparam; char **ap; int nparam; - for (nparam = 0; argv[nparam]; nparam++) - ; + for (nparam = 0; argv[nparam]; nparam++); ap = newparam = ckmalloc((nparam + 1) * sizeof *ap); while (*argv) { *ap++ = savestr(*argv++); @@ -7701,8 +7702,7 @@ static int shiftcmd(int argc, char **argv) { if (shellparam.malloc) ckfree(*ap1); } ap2 = shellparam.p; - while ((*ap2++ = *ap1++) != NULL) - ; + while ((*ap2++ = *ap1++) != NULL); shellparam.optind = 1; shellparam.optoff = -1; INTON; @@ -8308,8 +8308,7 @@ static void parsefname(void) { if (heredoclist == NULL) heredoclist = here; else { - for (p = heredoclist; p->next; p = p->next) - ; + for (p = heredoclist; p->next; p = p->next); p->next = here; } } else if (n->type == NTOFD || n->type == NFROMFD) { @@ -8432,8 +8431,7 @@ static int xxreadtoken(void) { case '\t': continue; case '#': - while ((c = pgetc()) != '\n' && c != PEOF) - ; + while ((c = pgetc()) != '\n' && c != PEOF); pungetc(); continue; case '\n': @@ -8553,7 +8551,7 @@ static int readtoken1(int firstc, char const *syntax, char *eofmark, quotef = 0; bqlist = NULL; STARTSTACKSTR(out); -loop : { /* for each line, until end of word */ +loop: { /* for each line, until end of word */ CHECKEND(); /* set c to PEOF if at end of here document */ for (;;) { /* until end of line or end of word */ CHECKSTRSPACE(4, out); /* permit 4 calls to USTPUTC */ @@ -8701,7 +8699,7 @@ endword: * is called, c is set to the first character of the next input line. If * we are at the end of the here document, this routine sets the c to PEOF. */ -checkend : { +checkend: { if (realeofmark(eofmark)) { int markloc; char *p; @@ -8742,7 +8740,7 @@ checkend : { * specifying the fd to be redirected. The variable "c" contains the * first character of the redirection operator. */ -parseredir : { +parseredir: { char fd = *out; union node *np; np = (union node *)stalloc(sizeof(struct nfile)); @@ -8798,7 +8796,7 @@ parseredir : { * Parse a substitution. At this point, we have read the dollar sign * and nothing else. */ -parsesub : { +parsesub: { int subtype; int typeloc; char *p; @@ -8910,7 +8908,7 @@ parsesub : { * list of commands (passed by reference), and savelen is the number of * characters on the top of the stack which must be preserved. */ -parsebackq : { +parsebackq: { struct nodelist **nlpp; union node *n; char *str; @@ -9002,7 +9000,7 @@ parsebackq : { /* * Parse an arithmetic expansion (indicate start of one and set state) */ -parsearith : { +parsearith: { synstack_push(&synstack, synstack->prev ?: alloca(sizeof(*synstack)), ARISYNTAX); synstack->dblquote = 1; diff --git a/libc/calls/BUILD.mk b/libc/calls/BUILD.mk index bbf134fc4..7f1611f9a 100644 --- a/libc/calls/BUILD.mk +++ b/libc/calls/BUILD.mk @@ -41,6 +41,7 @@ LIBC_CALLS_A_DIRECTDEPS = \ LIBC_INTRIN \ LIBC_NEXGEN32E \ LIBC_NT_ADVAPI32 \ + LIBC_NT_BCRYPTPRIMITIVES \ LIBC_NT_IPHLPAPI \ LIBC_NT_KERNEL32 \ LIBC_NT_NTDLL \ @@ -132,7 +133,8 @@ endif o/$(MODE)/libc/calls/pledge-linux.o: private \ CFLAGS += \ -Os \ - -fPIC + -fPIC \ + -ffreestanding # these assembly files are safe to build on aarch64 o/$(MODE)/libc/calls/getcontext.o: libc/calls/getcontext.S diff --git a/libc/calls/calls.h b/libc/calls/calls.h index 44811fe1d..b9aaa5e3f 100644 --- a/libc/calls/calls.h +++ b/libc/calls/calls.h @@ -247,6 +247,8 @@ ssize_t tinyprint(int, const char *, ...) libcesque nullterminated(); void shm_path_np(const char *, char[hasatleast 78]) libcesque; #endif /* _COSMO_SOURCE */ +int system(const char *) libcesque; + int __wifstopped(int) libcesque pureconst; int __wifcontinued(int) libcesque pureconst; int __wifsignaled(int) libcesque pureconst; diff --git a/libc/calls/clock_gettime-nt.c b/libc/calls/clock_gettime-nt.c index 363da29cc..8ebef10b6 100644 --- a/libc/calls/clock_gettime-nt.c +++ b/libc/calls/clock_gettime-nt.c @@ -21,12 +21,17 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/wintime.internal.h" +#include "libc/nt/accounting.h" +#include "libc/nt/runtime.h" #include "libc/nt/synchronization.h" +#include "libc/nt/thread.h" -#define _CLOCK_REALTIME 0 -#define _CLOCK_MONOTONIC 1 -#define _CLOCK_REALTIME_COARSE 2 -#define _CLOCK_BOOTTIME 3 +#define _CLOCK_REALTIME 0 +#define _CLOCK_MONOTONIC 1 +#define _CLOCK_REALTIME_COARSE 2 +#define _CLOCK_BOOTTIME 3 +#define _CLOCK_PROCESS_CPUTIME_ID 4 +#define _CLOCK_THREAD_CPUTIME_ID 5 static struct { uint64_t base; @@ -35,7 +40,7 @@ static struct { textwindows int sys_clock_gettime_nt(int clock, struct timespec *ts) { uint64_t t; - struct NtFileTime ft; + struct NtFileTime ft, ftExit, ftUser, ftKernel, ftCreation; switch (clock) { case _CLOCK_REALTIME: if (ts) { @@ -61,6 +66,22 @@ textwindows int sys_clock_gettime_nt(int clock, struct timespec *ts) { *ts = timespec_frommillis(GetTickCount64()); } return 0; + case _CLOCK_PROCESS_CPUTIME_ID: + if (ts) { + GetProcessTimes(GetCurrentProcess(), &ftCreation, &ftExit, &ftKernel, + &ftUser); + *ts = WindowsDurationToTimeSpec(ReadFileTime(ftUser) + + ReadFileTime(ftKernel)); + } + return 0; + case _CLOCK_THREAD_CPUTIME_ID: + if (ts) { + GetThreadTimes(GetCurrentThread(), &ftCreation, &ftExit, &ftKernel, + &ftUser); + *ts = WindowsDurationToTimeSpec(ReadFileTime(ftUser) + + ReadFileTime(ftKernel)); + } + return 0; default: return -EINVAL; } diff --git a/libc/calls/clock_gettime.c b/libc/calls/clock_gettime.c index f57b716f3..c5f72fdd9 100644 --- a/libc/calls/clock_gettime.c +++ b/libc/calls/clock_gettime.c @@ -61,24 +61,13 @@ static int __clock_gettime_init(int clockid, struct timespec *ts) { /** * Returns nanosecond time. * - * @param clock can be one of: - * - `CLOCK_REALTIME`: universally supported - * - `CLOCK_REALTIME_FAST`: ditto but faster on freebsd - * - `CLOCK_REALTIME_PRECISE`: ditto but better on freebsd - * - `CLOCK_REALTIME_COARSE`: : like `CLOCK_REALTIME_FAST` w/ Linux 2.6.32+ - * - `CLOCK_MONOTONIC`: universally supported (except on XNU/NT w/o INVTSC) - * - `CLOCK_MONOTONIC_FAST`: ditto but faster on freebsd - * - `CLOCK_MONOTONIC_PRECISE`: ditto but better on freebsd - * - `CLOCK_MONOTONIC_COARSE`: : like `CLOCK_MONOTONIC_FAST` w/ Linux 2.6.32+ - * - `CLOCK_MONOTONIC_RAW`: is actually monotonic but needs Linux 2.6.28+ - * - `CLOCK_PROCESS_CPUTIME_ID`: linux and bsd (NetBSD permits OR'd PID) - * - `CLOCK_THREAD_CPUTIME_ID`: linux and bsd (NetBSD permits OR'd TID) - * - `CLOCK_MONOTONIC_COARSE`: linux, freebsd - * - `CLOCK_PROF`: linux and netbsd - * - `CLOCK_BOOTTIME`: linux and openbsd - * - `CLOCK_REALTIME_ALARM`: linux-only - * - `CLOCK_BOOTTIME_ALARM`: linux-only - * - `CLOCK_TAI`: linux-only + * @param clock supports the following values across OSes: + * - `CLOCK_REALTIME` + * - `CLOCK_MONOTONIC` + * - `CLOCK_REALTIME_COARSE` + * - `CLOCK_MONOTONIC_COARSE` + * - `CLOCK_THREAD_CPUTIME_ID` + * - `CLOCK_PROCESS_CPUTIME_ID` * @param ts is where the result is stored (or null to do clock check) * @return 0 on success, or -1 w/ errno * @raise EFAULT if `ts` points to invalid memory diff --git a/libc/calls/close.c b/libc/calls/close.c index 95068563e..7c8a35f50 100644 --- a/libc/calls/close.c +++ b/libc/calls/close.c @@ -93,7 +93,7 @@ static int close_impl(int fd) { */ int close(int fd) { int rc; - if (__isfdkind(fd, kFdZip)) { // XXX IsWindows()? + if (__isfdkind(fd, kFdZip)) { // XXX IsWindows()? BLOCK_SIGNALS; __fds_lock(); rc = close_impl(fd); diff --git a/libc/calls/getrandom.c b/libc/calls/getrandom.c index 65171f28c..7c9a7e2f2 100644 --- a/libc/calls/getrandom.c +++ b/libc/calls/getrandom.c @@ -103,7 +103,7 @@ static ssize_t GetDevUrandom(char *p, size_t n) { ssize_t __getrandom(void *p, size_t n, unsigned f) { ssize_t rc; if (IsWindows()) { - rc = RtlGenRandom(p, n) ? n : __winerr(); + rc = ProcessPrng(p, n) ? n : __winerr(); } else if (have_getrandom) { if (IsXnu() || IsOpenbsd()) { rc = GetRandomBsd(p, n, GetRandomEntropy); @@ -131,7 +131,7 @@ ssize_t __getrandom(void *p, size_t n, unsigned f) { * * This random number seed generator obtains information from: * - * - RtlGenRandom() on Windows + * - ProcessPrng() on Windows * - getentropy() on XNU and OpenBSD * - getrandom() on Linux, FreeBSD, and NetBSD * - sysctl(KERN_ARND) on older versions of FreeBSD and NetBSD diff --git a/libc/calls/metalfile.c b/libc/calls/metalfile.c index 20d16e56f..0832d52f5 100644 --- a/libc/calls/metalfile.c +++ b/libc/calls/metalfile.c @@ -75,7 +75,9 @@ textstartup void InitializeMetalFile(void) { memcpy(copied_base, (void *)(BANE + IMAGE_BASE_PHYSICAL), size); __ape_com_base = copied_base; __ape_com_size = size; - KINFOF("%s @ %p,+%#zx", APE_COM_NAME, copied_base, size); + // TODO(tkchia): LIBC_CALLS doesn't depend on LIBC_VGA so references + // to its functions need to be weak + // KINFOF("%s @ %p,+%#zx", APE_COM_NAME, copied_base, size); } } diff --git a/libc/calls/rdrand.c b/libc/calls/rdrand.c index 7e5ebfa0c..c499c3752 100644 --- a/libc/calls/rdrand.c +++ b/libc/calls/rdrand.c @@ -52,7 +52,7 @@ static dontinline uint64_t rdrand_failover(void) { * * If RDRAND isn't available (we check CPUID and we also disable it * automatically for microarchitectures where it's slow or buggy) then - * we try getrandom(), RtlGenRandom(), or sysctl(KERN_ARND). If those + * we try getrandom(), ProcessPrng(), or sysctl(KERN_ARND). If those * aren't available then we try /dev/urandom and if that fails, we try * getauxval(AT_RANDOM), and if not we finally use RDTSC and getpid(). * diff --git a/libc/calls/read-nt.c b/libc/calls/read-nt.c index c48b9778c..540855355 100644 --- a/libc/calls/read-nt.c +++ b/libc/calls/read-nt.c @@ -157,6 +157,8 @@ static textwindows struct Keystroke *NewKeystroke(void) { struct Keystroke *k = KEYSTROKE_CONTAINER(e); dll_remove(&__keystroke.free, &k->elem); --__keystroke.freekeys; + // TODO(jart): What's wrong with GCC 12.3? + asm("" : "+r"(k)); k->buflen = 0; return k; } diff --git a/libc/calls/sched_getcpu.c b/libc/calls/sched_getcpu.c index 761bba995..ac80be47a 100644 --- a/libc/calls/sched_getcpu.c +++ b/libc/calls/sched_getcpu.c @@ -19,15 +19,19 @@ #include "libc/calls/calls.h" #include "libc/calls/struct/cpuset.h" #include "libc/dce.h" +#include "libc/errno.h" #include "libc/nexgen32e/rdtscp.h" #include "libc/nexgen32e/x86feature.h" #include "libc/nt/struct/processornumber.h" #include "libc/nt/synchronization.h" +#include "libc/runtime/syslib.internal.h" +#include "libc/sysv/errfuns.h" int sys_getcpu(unsigned *opt_cpu, unsigned *opt_node, void *tcache); /** * Returns ID of CPU on which thread is currently scheduled. + * @return cpu number on success, or -1 w/ errno */ int sched_getcpu(void) { if (X86_HAVE(RDTSCP)) { @@ -38,6 +42,19 @@ int sched_getcpu(void) { struct NtProcessorNumber pn; GetCurrentProcessorNumberEx(&pn); return 64 * pn.Group + pn.Number; + } else if (IsXnuSilicon()) { + if (__syslib->__version >= 9) { + size_t cpu; + errno_t err = __syslib->__pthread_cpu_number_np(&cpu); + if (!err) { + return cpu; + } else { + errno = err; + return -1; + } + } else { + return enosys(); + } } else { unsigned cpu = 0; int rc = sys_getcpu(&cpu, 0, 0); diff --git a/libc/calls/sig.c b/libc/calls/sig.c index 586e74f8a..936ed99d4 100644 --- a/libc/calls/sig.c +++ b/libc/calls/sig.c @@ -441,8 +441,7 @@ textwindows void __sig_generate(int sig, int sic) { // to unblock our sig once the wait operation is completed; when // that's the case we can cancel the thread's i/o to deliver sig if (atomic_load_explicit(&pt->pt_blocker, memory_order_acquire) && - !(atomic_load_explicit(&pt->pt_blkmask, memory_order_relaxed) & - (1ull << (sig - 1)))) { + !(pt->pt_blkmask & (1ull << (sig - 1)))) { _pthread_ref(pt); mark = pt; break; diff --git a/libc/calls/syscall_support-nt.internal.h b/libc/calls/syscall_support-nt.internal.h index 7d7bab43c..a002ef9e3 100644 --- a/libc/calls/syscall_support-nt.internal.h +++ b/libc/calls/syscall_support-nt.internal.h @@ -18,7 +18,7 @@ int sys_fcntl_nt_setfl(int, unsigned); int sys_pause_nt(void); int64_t __fix_enotdir(int64_t, char16_t *); int64_t __fix_enotdir3(int64_t, char16_t *, char16_t *); -int64_t __winerr(void) nocallback privileged; +int64_t __winerr(void) dontcallback privileged; int64_t ntreturn(uint32_t); void *GetProcAddressModule(const char *, const char *); void WinMainForked(void); diff --git a/libc/calls/ucontext.h b/libc/calls/ucontext.h index 4c755f3b0..a869ab0ad 100644 --- a/libc/calls/ucontext.h +++ b/libc/calls/ucontext.h @@ -130,7 +130,7 @@ typedef struct ucontext ucontext_t; int getcontext(ucontext_t *) dontthrow; int setcontext(const ucontext_t *) dontthrow; int swapcontext(ucontext_t *, const ucontext_t *) dontthrow returnstwice; -void makecontext(ucontext_t *, void (*)(), int, ...) dontthrow nocallback; +void makecontext(ucontext_t *, void *, int, ...) dontthrow dontcallback; void __sig_restore(const ucontext_t *) wontreturn; COSMOPOLITAN_C_END_ diff --git a/libc/calls/uname.c b/libc/calls/uname.c index e7d5905bb..2f03c15b4 100644 --- a/libc/calls/uname.c +++ b/libc/calls/uname.c @@ -82,15 +82,27 @@ static textwindows void GetNtName(char *name, int kind) { } static inline textwindows int GetNtMajorVersion(void) { +#ifdef __x86_64__ return NtGetPeb()->OSMajorVersion; +#else + return 0; +#endif } static inline textwindows int GetNtMinorVersion(void) { +#ifdef __x86_64__ return NtGetPeb()->OSMinorVersion; +#else + return 0; +#endif } static inline textwindows int GetNtBuildNumber(void) { +#ifdef __x86_64__ return NtGetPeb()->OSBuildNumber; +#else + return 0; +#endif } static textwindows void GetNtVersion(char *p) { diff --git a/libc/cosmo.h b/libc/cosmo.h index 35c1a47eb..c84b731eb 100644 --- a/libc/cosmo.h +++ b/libc/cosmo.h @@ -4,6 +4,7 @@ COSMOPOLITAN_C_START_ errno_t cosmo_once(_Atomic(uint32_t) *, void (*)(void)); int systemvpe(const char *, char *const[], char *const[]) libcesque; +char *GetProgramExecutableName(void); COSMOPOLITAN_C_END_ #endif /* COSMOPOLITAN_LIBC_COSMO_H_ */ diff --git a/libc/integral/c.inc b/libc/integral/c.inc index 11f6a781d..b5870b7fa 100644 --- a/libc/integral/c.inc +++ b/libc/integral/c.inc @@ -159,7 +159,7 @@ typedef struct { #include "libc/integral/lp64arg.inc" #endif -#define libcesque dontthrow nocallback +#define libcesque dontthrow dontcallback #define memcpyesque libcesque #define strlenesque libcesque nosideeffect paramsnonnull() #define vallocesque \ @@ -364,14 +364,14 @@ typedef struct { #endif #endif -#ifndef nocallback +#ifndef dontcallback #if !defined(__STRICT_ANSI__) && \ (__has_attribute(__leaf__) || \ (!defined(__llvm__) && \ (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 406)) -#define nocallback __attribute__((__leaf__)) +#define dontcallback __attribute__((__leaf__)) #else -#define nocallback +#define dontcallback #endif #endif @@ -645,11 +645,23 @@ void abort(void) wontreturn; #define initarray _Section(".init_array") #endif -#pragma GCC diagnostic ignored "-Wformat" /* todo: patch gcc */ +#ifndef __llvm__ +#pragma GCC diagnostic ignored "-Wformat=0" /* todo: patch gcc */ +#pragma GCC diagnostic ignored "-Wbuiltin-declaration-mismatch" +#pragma GCC diagnostic warning "-Wunknown-pragmas" +#else +#pragma GCC diagnostic ignored "-Wformat" +#pragma GCC diagnostic ignored "-Wconstant-logical-operand" /* what */ +#pragma GCC diagnostic ignored "-Wunknown-warning-option" +#pragma GCC diagnostic ignored "-Wunknown-pragmas" +#pragma GCC diagnostic ignored "-Wstring-plus-int" /* features 4 losers */ +#pragma GCC diagnostic ignored "-Wkeyword-compat" /* c++ upgrade */ +#pragma GCC diagnostic ignored "-Wuser-defined-literals" /* reserved for me */ +#endif + #pragma GCC diagnostic ignored "-Wformat-extra-args" /* todo: patch gcc */ #pragma GCC diagnostic ignored "-Wunused-function" /* contradicts dce */ #pragma GCC diagnostic ignored "-Wunused-const-variable" /* sooo ridiculous */ -#pragma GCC diagnostic ignored "-Wbuiltin-declaration-mismatch" #ifndef __cplusplus #pragma GCC diagnostic ignored "-Wold-style-definition" /* orwellian bullsh */ #endif @@ -745,5 +757,18 @@ void abort(void) wontreturn; #define __funline static inline #endif +#if defined(__x86_64__) && (defined(__GNUC__) || defined(__llvm__)) && \ + !defined(__chibicc__) && 0 /* TODO: enable with toolchain upgrade */ +#define __target_clones(x) __attribute__((__target_clones__(x ",default"))) +#else +#define __target_clones(x) +#endif + +#if !defined(TINY) && !defined(__AVX__) && 0 +#define __vex __target_clones("avx") +#else +#define __vex +#endif + #define MACHINE_CODE_ANALYSIS_BEGIN_ #define MACHINE_CODE_ANALYSIS_END_ diff --git a/libc/intrin/BUILD.mk b/libc/intrin/BUILD.mk index e4ce22629..609e05018 100644 --- a/libc/intrin/BUILD.mk +++ b/libc/intrin/BUILD.mk @@ -86,6 +86,11 @@ o/$(MODE)/libc/intrin/memmove.o: private \ CFLAGS += \ -fpie +o/$(MODE)/libc/intrin/x86.o: private \ + CFLAGS += \ + -ffreestanding \ + -fno-jump-tables + # these assembly files are safe to build on aarch64 o/$(MODE)/libc/intrin/aarch64/%.o: libc/intrin/aarch64/%.S @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $< diff --git a/libc/runtime/fesetround.c b/libc/intrin/fesetround.c similarity index 100% rename from libc/runtime/fesetround.c rename to libc/intrin/fesetround.c diff --git a/libc/intrin/kprintf.greg.c b/libc/intrin/kprintf.greg.c index d281a82c2..cb4c87659 100644 --- a/libc/intrin/kprintf.greg.c +++ b/libc/intrin/kprintf.greg.c @@ -24,7 +24,6 @@ #include "libc/fmt/magnumstrs.internal.h" #include "libc/intrin/asmflag.h" #include "libc/intrin/atomic.h" -#include "libc/serialize.h" #include "libc/intrin/getenv.internal.h" #include "libc/intrin/likely.h" #include "libc/intrin/nomultics.internal.h" @@ -46,6 +45,7 @@ #include "libc/runtime/memtrack.internal.h" #include "libc/runtime/runtime.h" #include "libc/runtime/symbols.internal.h" +#include "libc/serialize.h" #include "libc/stdckdint.h" #include "libc/str/str.h" #include "libc/str/tab.internal.h" diff --git a/libc/intrin/memchr.c b/libc/intrin/memchr.c index aa4adbb0a..b29c6e67a 100644 --- a/libc/intrin/memchr.c +++ b/libc/intrin/memchr.c @@ -67,10 +67,9 @@ static inline const unsigned char *memchr_sse(const unsigned char *s, * @return is pointer to first instance of c or NULL if not found * @asyncsignalsafe */ -void *memchr(const void *s, int c, size_t n) { +__vex void *memchr(const void *s, int c, size_t n) { #if defined(__x86_64__) && !defined(__chibicc__) const void *r; - if (IsAsan()) __asan_verify(s, n); r = memchr_sse(s, c, n); return (void *)r; #else diff --git a/libc/intrin/memmove.c b/libc/intrin/memmove.c index ff2b4ef62..f6687c4b5 100644 --- a/libc/intrin/memmove.c +++ b/libc/intrin/memmove.c @@ -86,7 +86,7 @@ typedef long long xmm_a __attribute__((__vector_size__(16), __aligned__(16))); * @return dst * @asyncsignalsafe */ -void *memmove(void *dst, const void *src, size_t n) { +__vex void *memmove(void *dst, const void *src, size_t n) { char *d; size_t i; const char *s; diff --git a/libc/intrin/memrchr.c b/libc/intrin/memrchr.c index 3a8efe2c0..59f0d6686 100644 --- a/libc/intrin/memrchr.c +++ b/libc/intrin/memrchr.c @@ -67,7 +67,7 @@ static inline const unsigned char *memrchr_sse(const unsigned char *s, * @return is pointer to first instance of c or NULL if not found * @asyncsignalsafe */ -void *memrchr(const void *s, int c, size_t n) { +__vex void *memrchr(const void *s, int c, size_t n) { #if defined(__x86_64__) && !defined(__chibicc__) const void *r; r = memrchr_sse(s, c, n); diff --git a/libc/intrin/mman.greg.c b/libc/intrin/mman.greg.c index 7641a4969..6c886df53 100644 --- a/libc/intrin/mman.greg.c +++ b/libc/intrin/mman.greg.c @@ -44,14 +44,16 @@ #include "libc/runtime/runtime.h" #ifdef __x86_64__ -#define INVERT(x) (BANE + PHYSICAL(x)) -#define NOPAGE ((uint64_t)-1) +#define INVERT(x) (BANE + PHYSICAL((uintptr_t)(x))) +#define NOPAGE ((uint64_t) - 1) -#define ABS64(x) \ - ({ \ - int64_t vAddr; \ - __asm__("movabs\t%1,%0" : "=r"(vAddr) : "i"(x)); \ - vAddr; \ +#define APE_STACK_VADDR \ + ({ \ + int64_t vAddr; \ + __asm__(".weak\tape_stack_vaddr\n\t" \ + "movabs\t$ape_stack_vaddr,%0" \ + : "=r"(vAddr)); \ + vAddr; \ }) struct ReclaimedPage { @@ -305,7 +307,6 @@ textreal void __map_phdrs(struct mman *mm, uint64_t *pml4t, uint64_t b, extern char ape_phdrs_end[] __attribute__((__weak__)); extern char ape_stack_pf[] __attribute__((__weak__)); extern char ape_stack_offset[] __attribute__((__weak__)); - extern char ape_stack_vaddr[] __attribute__((__weak__)); extern char ape_stack_filesz[] __attribute__((__weak__)); extern char ape_stack_memsz[] __attribute__((__weak__)); __setup_mman(mm, pml4t, top); @@ -318,7 +319,7 @@ textreal void __map_phdrs(struct mman *mm, uint64_t *pml4t, uint64_t b, .p_type = PT_LOAD, .p_flags = (uintptr_t)ape_stack_pf, .p_offset = (uintptr_t)ape_stack_offset, - .p_vaddr = ABS64(ape_stack_vaddr), + .p_vaddr = APE_STACK_VADDR, .p_filesz = (uintptr_t)ape_stack_filesz, .p_memsz = (uintptr_t)ape_stack_memsz, }); diff --git a/libc/intrin/reservefd.c b/libc/intrin/reservefd.c index ae96d63d6..447f7ff2e 100644 --- a/libc/intrin/reservefd.c +++ b/libc/intrin/reservefd.c @@ -27,8 +27,6 @@ #include "libc/str/str.h" #include "libc/sysv/consts/map.h" -static volatile size_t mapsize; - /** * Grows file descriptor array memory if needed. * diff --git a/libc/intrin/segmentation.h b/libc/intrin/segmentation.h deleted file mode 100644 index 845b9a41a..000000000 --- a/libc/intrin/segmentation.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef COSMOPOLITAN_LIBC_BITS_SEGMENTATION_H_ -#define COSMOPOLITAN_LIBC_BITS_SEGMENTATION_H_ -#if defined(__GNUC__) && !defined(__STRICT_ANSI__) -#ifdef _COSMO_SOURCE - -/** - * Reads scalar from memory, offset by segment. - * - * @return *(MEM) relative to segment - * @see pushpop() - */ -#define fs(MEM) __peek("fs", MEM) -#define gs(MEM) __peek("gs", MEM) - -#define __peek(SEGMENT, ADDRESS) \ - ({ \ - typeof(*(ADDRESS)) Pk; \ - asm("mov\t%%" SEGMENT ":%1,%0" : "=r"(Pk) : "m"(*(ADDRESS))); \ - Pk; \ - }) - -#endif /* _COSMO_SOURCE */ -#endif /* __GNUC__ && !__STRICT_ANSI__ */ -#endif /* COSMOPOLITAN_LIBC_BITS_SEGMENTATION_H_ */ diff --git a/libc/intrin/stpcpy.c b/libc/intrin/stpcpy.c index b3b7dfed2..c7c15e8e2 100644 --- a/libc/intrin/stpcpy.c +++ b/libc/intrin/stpcpy.c @@ -33,7 +33,7 @@ typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(16))); * @return pointer to nul byte * @asyncsignalsafe */ -char *stpcpy(char *d, const char *s) { +__vex char *stpcpy(char *d, const char *s) { size_t i = 0; #if defined(__x86_64__) && !defined(__chibicc__) for (; (uintptr_t)(s + i) & 15; ++i) { diff --git a/libc/intrin/strchr.c b/libc/intrin/strchr.c index 7eb19a7b1..ab7439239 100644 --- a/libc/intrin/strchr.c +++ b/libc/intrin/strchr.c @@ -94,7 +94,7 @@ static inline const char *strchr_x64(const char *p, uint64_t c) { * @asyncsignalsafe * @vforksafe */ -char *strchr(const char *s, int c) { +__vex char *strchr(const char *s, int c) { #if defined(__x86_64__) && !defined(__chibicc__) const char *r; if (X86_HAVE(SSE)) { diff --git a/libc/intrin/strchrnul.c b/libc/intrin/strchrnul.c index 5c10b129c..b61cebde7 100644 --- a/libc/intrin/strchrnul.c +++ b/libc/intrin/strchrnul.c @@ -92,7 +92,7 @@ static const char *strchrnul_x64(const char *p, uint64_t c) { * @return pointer to first instance of c, or pointer to * NUL terminator if c is not found */ -char *strchrnul(const char *s, int c) { +__vex char *strchrnul(const char *s, int c) { #if defined(__x86_64__) && !defined(__chibicc__) const char *r; if (X86_HAVE(SSE)) { diff --git a/libc/intrin/strcpy.c b/libc/intrin/strcpy.c index fda91111a..b08c271e1 100644 --- a/libc/intrin/strcpy.c +++ b/libc/intrin/strcpy.c @@ -32,7 +32,7 @@ typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(16))); * @return original dest * @asyncsignalsafe */ -char *strcpy(char *d, const char *s) { +__vex char *strcpy(char *d, const char *s) { size_t i = 0; #if defined(__x86_64__) && !defined(__chibicc__) for (; (uintptr_t)(s + i) & 15; ++i) { diff --git a/libc/intrin/strlen.c b/libc/intrin/strlen.c index bc2a95056..89d85e9d2 100644 --- a/libc/intrin/strlen.c +++ b/libc/intrin/strlen.c @@ -37,7 +37,7 @@ size_t strlen(const char *s) { while (!m) m = __builtin_ia32_pmovmskb128(*++p == z); return (const char *)p + __builtin_ctzl(m) - s; #else -#define ONES ((word)-1 / 255) +#define ONES ((word) - 1 / 255) #define BANE (ONES * (255 / 2 + 1)) typedef unsigned long mayalias word; word w; @@ -56,5 +56,4 @@ size_t strlen(const char *s) { return (const char *)p + (__builtin_ctzl(w) >> 3) - s; #endif } - #endif /* __aarch64__ */ diff --git a/libc/intrin/x86.c b/libc/intrin/x86.c new file mode 100644 index 000000000..3a2d21c77 --- /dev/null +++ b/libc/intrin/x86.c @@ -0,0 +1,808 @@ +//===-- cpu_model/x86.c - Support for __cpu_model builtin --------*- C -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is based on LLVM's lib/Support/Host.cpp. +// It implements the operating system Host concept and builtin +// __cpu_model for the compiler_rt library for x86. +// +//===----------------------------------------------------------------------===// +#if defined(__x86_64__) && (defined(__GNUC__) || defined(__clang__)) +#include "libc/intrin/strace.internal.h" +#include "third_party/compiler_rt/cpu_model.h" + +enum VendorSignatures { + SIG_INTEL = 0x756e6547, // Genu + SIG_AMD = 0x68747541, // Auth +}; + +enum ProcessorVendors { + VENDOR_INTEL = 1, + VENDOR_AMD, + VENDOR_OTHER, + VENDOR_MAX +}; + +enum ProcessorTypes { + INTEL_BONNELL = 1, + INTEL_CORE2, + INTEL_COREI7, + AMDFAM10H, + AMDFAM15H, + INTEL_SILVERMONT, + INTEL_KNL, + AMD_BTVER1, + AMD_BTVER2, + AMDFAM17H, + INTEL_KNM, + INTEL_GOLDMONT, + INTEL_GOLDMONT_PLUS, + INTEL_TREMONT, + AMDFAM19H, + ZHAOXIN_FAM7H, + INTEL_SIERRAFOREST, + INTEL_GRANDRIDGE, + INTEL_CLEARWATERFOREST, + CPU_TYPE_MAX +}; + +enum ProcessorSubtypes { + INTEL_COREI7_NEHALEM = 1, + INTEL_COREI7_WESTMERE, + INTEL_COREI7_SANDYBRIDGE, + AMDFAM10H_BARCELONA, + AMDFAM10H_SHANGHAI, + AMDFAM10H_ISTANBUL, + AMDFAM15H_BDVER1, + AMDFAM15H_BDVER2, + AMDFAM15H_BDVER3, + AMDFAM15H_BDVER4, + AMDFAM17H_ZNVER1, + INTEL_COREI7_IVYBRIDGE, + INTEL_COREI7_HASWELL, + INTEL_COREI7_BROADWELL, + INTEL_COREI7_SKYLAKE, + INTEL_COREI7_SKYLAKE_AVX512, + INTEL_COREI7_CANNONLAKE, + INTEL_COREI7_ICELAKE_CLIENT, + INTEL_COREI7_ICELAKE_SERVER, + AMDFAM17H_ZNVER2, + INTEL_COREI7_CASCADELAKE, + INTEL_COREI7_TIGERLAKE, + INTEL_COREI7_COOPERLAKE, + INTEL_COREI7_SAPPHIRERAPIDS, + INTEL_COREI7_ALDERLAKE, + AMDFAM19H_ZNVER3, + INTEL_COREI7_ROCKETLAKE, + ZHAOXIN_FAM7H_LUJIAZUI, + AMDFAM19H_ZNVER4, + INTEL_COREI7_GRANITERAPIDS, + INTEL_COREI7_GRANITERAPIDS_D, + INTEL_COREI7_ARROWLAKE, + INTEL_COREI7_ARROWLAKE_S, + INTEL_COREI7_PANTHERLAKE, + CPU_SUBTYPE_MAX +}; + +enum ProcessorFeatures { + FEATURE_CMOV = 0, + FEATURE_MMX, + FEATURE_POPCNT, + FEATURE_SSE, + FEATURE_SSE2, + FEATURE_SSE3, + FEATURE_SSSE3, + FEATURE_SSE4_1, + FEATURE_SSE4_2, + FEATURE_AVX, + FEATURE_AVX2, + FEATURE_SSE4_A, + FEATURE_FMA4, + FEATURE_XOP, + FEATURE_FMA, + FEATURE_AVX512F, + FEATURE_BMI, + FEATURE_BMI2, + FEATURE_AES, + FEATURE_PCLMUL, + FEATURE_AVX512VL, + FEATURE_AVX512BW, + FEATURE_AVX512DQ, + FEATURE_AVX512CD, + FEATURE_AVX512ER, + FEATURE_AVX512PF, + FEATURE_AVX512VBMI, + FEATURE_AVX512IFMA, + FEATURE_AVX5124VNNIW, + FEATURE_AVX5124FMAPS, + FEATURE_AVX512VPOPCNTDQ, + FEATURE_AVX512VBMI2, + FEATURE_GFNI, + FEATURE_VPCLMULQDQ, + FEATURE_AVX512VNNI, + FEATURE_AVX512BITALG, + FEATURE_AVX512BF16, + FEATURE_AVX512VP2INTERSECT, + + FEATURE_CMPXCHG16B = 46, + FEATURE_F16C = 49, + FEATURE_LAHF_LM = 54, + FEATURE_LM, + FEATURE_WP, + FEATURE_LZCNT, + FEATURE_MOVBE, + + FEATURE_AVX512FP16 = 94, + FEATURE_X86_64_BASELINE, + FEATURE_X86_64_V2, + FEATURE_X86_64_V3, + FEATURE_X86_64_V4, + CPU_FEATURE_MAX +}; + +// The check below for i386 was copied from clang's cpuid.h (__get_cpuid_max). +// Check motivated by bug reports for OpenSSL crashing on CPUs without CPUID +// support. Consequently, for i386, the presence of CPUID is checked first +// via the corresponding eflags bit. +static bool isCpuIdSupported(void) { + return true; +} + +// This code is copied from lib/Support/Host.cpp. +// Changes to either file should be mirrored in the other. + +/// getX86CpuIDAndInfo - Execute the specified cpuid and return the 4 values in +/// the specified arguments. If we can't run cpuid on the host, return true. +static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX, + unsigned *rECX, unsigned *rEDX) { + // gcc doesn't know cpuid would clobber ebx/rbx. Preserve it manually. + // FIXME: should we save this for Clang? + __asm__("movq\t%%rbx, %%rsi\n\t" + "cpuid\n\t" + "xchgq\t%%rbx, %%rsi\n\t" + : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX) + : "a"(value)); + return false; +} + +/// getX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return +/// the 4 values in the specified arguments. If we can't run cpuid on the host, +/// return true. +static bool getX86CpuIDAndInfoEx(unsigned value, unsigned subleaf, + unsigned *rEAX, unsigned *rEBX, unsigned *rECX, + unsigned *rEDX) { + // gcc doesn't know cpuid would clobber ebx/rbx. Preserve it manually. + // FIXME: should we save this for Clang? + __asm__("movq\t%%rbx, %%rsi\n\t" + "cpuid\n\t" + "xchgq\t%%rbx, %%rsi\n\t" + : "=a"(*rEAX), "=S"(*rEBX), "=c"(*rECX), "=d"(*rEDX) + : "a"(value), "c"(subleaf)); + return false; +} + +// Read control register 0 (XCR0). Used to detect features such as AVX. +static bool getX86XCR0(unsigned *rEAX, unsigned *rEDX) { + // Check xgetbv; this uses a .byte sequence instead of the instruction + // directly because older assemblers do not include support for xgetbv and + // there is no easy way to conditionally compile based on the assembler used. + __asm__(".byte 0x0f, 0x01, 0xd0" : "=a"(*rEAX), "=d"(*rEDX) : "c"(0)); + return false; +} + +static void detectX86FamilyModel(unsigned EAX, unsigned *Family, + unsigned *Model) { + *Family = (EAX >> 8) & 0xf; // Bits 8 - 11 + *Model = (EAX >> 4) & 0xf; // Bits 4 - 7 + if (*Family == 6 || *Family == 0xf) { + if (*Family == 0xf) + // Examine extended family ID if family ID is F. + *Family += (EAX >> 20) & 0xff; // Bits 20 - 27 + // Examine extended model ID if family ID is 6 or F. + *Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19 + } +} + +static const char *getIntelProcessorTypeAndSubtype(unsigned Family, + unsigned Model, + const unsigned *Features, + unsigned *Type, + unsigned *Subtype) { +#define testFeature(F) (Features[F / 32] & (1 << (F % 32))) != 0 + + // We select CPU strings to match the code in Host.cpp, but we don't use them + // in compiler-rt. + const char *CPU = 0; + + switch (Family) { + case 6: + switch (Model) { + case 0x0f: // Intel Core 2 Duo processor, Intel Core 2 Duo mobile + // processor, Intel Core 2 Quad processor, Intel Core 2 Quad + // mobile processor, Intel Core 2 Extreme processor, Intel + // Pentium Dual-Core processor, Intel Xeon processor, model + // 0Fh. All processors are manufactured using the 65 nm + // process. + case 0x16: // Intel Celeron processor model 16h. All processors are + // manufactured using the 65 nm process + CPU = "core2"; + *Type = INTEL_CORE2; + break; + case 0x17: // Intel Core 2 Extreme processor, Intel Xeon processor, + // model 17h. All processors are manufactured using the 45 + // nm process. + // + // 45nm: Penryn , Wolfdale, Yorkfield (XE) + case 0x1d: // Intel Xeon processor MP. All processors are manufactured + // using the 45 nm process. + CPU = "penryn"; + *Type = INTEL_CORE2; + break; + case 0x1a: // Intel Core i7 processor and Intel Xeon processor. All + // processors are manufactured using the 45 nm process. + case 0x1e: // Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz. + // As found in a Summer 2010 model iMac. + case 0x1f: + case 0x2e: // Nehalem EX + CPU = "nehalem"; + *Type = INTEL_COREI7; + *Subtype = INTEL_COREI7_NEHALEM; + break; + case 0x25: // Intel Core i7, laptop version. + case 0x2c: // Intel Core i7 processor and Intel Xeon processor. All + // processors are manufactured using the 32 nm process. + case 0x2f: // Westmere EX + CPU = "westmere"; + *Type = INTEL_COREI7; + *Subtype = INTEL_COREI7_WESTMERE; + break; + case 0x2a: // Intel Core i7 processor. All processors are manufactured + // using the 32 nm process. + case 0x2d: + CPU = "sandybridge"; + *Type = INTEL_COREI7; + *Subtype = INTEL_COREI7_SANDYBRIDGE; + break; + case 0x3a: + case 0x3e: // Ivy Bridge EP + CPU = "ivybridge"; + *Type = INTEL_COREI7; + *Subtype = INTEL_COREI7_IVYBRIDGE; + break; + + // Haswell: + case 0x3c: + case 0x3f: + case 0x45: + case 0x46: + CPU = "haswell"; + *Type = INTEL_COREI7; + *Subtype = INTEL_COREI7_HASWELL; + break; + + // Broadwell: + case 0x3d: + case 0x47: + case 0x4f: + case 0x56: + CPU = "broadwell"; + *Type = INTEL_COREI7; + *Subtype = INTEL_COREI7_BROADWELL; + break; + + // Skylake: + case 0x4e: // Skylake mobile + case 0x5e: // Skylake desktop + case 0x8e: // Kaby Lake mobile + case 0x9e: // Kaby Lake desktop + case 0xa5: // Comet Lake-H/S + case 0xa6: // Comet Lake-U + CPU = "skylake"; + *Type = INTEL_COREI7; + *Subtype = INTEL_COREI7_SKYLAKE; + break; + + // Rocketlake: + case 0xa7: + CPU = "rocketlake"; + *Type = INTEL_COREI7; + *Subtype = INTEL_COREI7_ROCKETLAKE; + break; + + // Skylake Xeon: + case 0x55: + *Type = INTEL_COREI7; + if (testFeature(FEATURE_AVX512BF16)) { + CPU = "cooperlake"; + *Subtype = INTEL_COREI7_COOPERLAKE; + } else if (testFeature(FEATURE_AVX512VNNI)) { + CPU = "cascadelake"; + *Subtype = INTEL_COREI7_CASCADELAKE; + } else { + CPU = "skylake-avx512"; + *Subtype = INTEL_COREI7_SKYLAKE_AVX512; + } + break; + + // Cannonlake: + case 0x66: + CPU = "cannonlake"; + *Type = INTEL_COREI7; + *Subtype = INTEL_COREI7_CANNONLAKE; + break; + + // Icelake: + case 0x7d: + case 0x7e: + CPU = "icelake-client"; + *Type = INTEL_COREI7; + *Subtype = INTEL_COREI7_ICELAKE_CLIENT; + break; + + // Tigerlake: + case 0x8c: + case 0x8d: + CPU = "tigerlake"; + *Type = INTEL_COREI7; + *Subtype = INTEL_COREI7_TIGERLAKE; + break; + + // Alderlake: + case 0x97: + case 0x9a: + // Raptorlake: + case 0xb7: + case 0xba: + case 0xbf: + // Meteorlake: + case 0xaa: + case 0xac: + // Gracemont: + case 0xbe: + CPU = "alderlake"; + *Type = INTEL_COREI7; + *Subtype = INTEL_COREI7_ALDERLAKE; + break; + + // Arrowlake: + case 0xc5: + CPU = "arrowlake"; + *Type = INTEL_COREI7; + *Subtype = INTEL_COREI7_ARROWLAKE; + break; + + // Arrowlake S: + case 0xc6: + // Lunarlake: + case 0xbd: + CPU = "arrowlake-s"; + *Type = INTEL_COREI7; + *Subtype = INTEL_COREI7_ARROWLAKE_S; + break; + + // Pantherlake: + case 0xcc: + CPU = "pantherlake"; + *Type = INTEL_COREI7; + *Subtype = INTEL_COREI7_PANTHERLAKE; + break; + + // Icelake Xeon: + case 0x6a: + case 0x6c: + CPU = "icelake-server"; + *Type = INTEL_COREI7; + *Subtype = INTEL_COREI7_ICELAKE_SERVER; + break; + + // Emerald Rapids: + case 0xcf: + // Sapphire Rapids: + case 0x8f: + CPU = "sapphirerapids"; + *Type = INTEL_COREI7; + *Subtype = INTEL_COREI7_SAPPHIRERAPIDS; + break; + + // Granite Rapids: + case 0xad: + CPU = "graniterapids"; + *Type = INTEL_COREI7; + *Subtype = INTEL_COREI7_GRANITERAPIDS; + break; + + // Granite Rapids D: + case 0xae: + CPU = "graniterapids-d"; + *Type = INTEL_COREI7; + *Subtype = INTEL_COREI7_GRANITERAPIDS_D; + break; + + case 0x1c: // Most 45 nm Intel Atom processors + case 0x26: // 45 nm Atom Lincroft + case 0x27: // 32 nm Atom Medfield + case 0x35: // 32 nm Atom Midview + case 0x36: // 32 nm Atom Midview + CPU = "bonnell"; + *Type = INTEL_BONNELL; + break; + + // Atom Silvermont codes from the Intel software optimization guide. + case 0x37: + case 0x4a: + case 0x4d: + case 0x5a: + case 0x5d: + case 0x4c: // really airmont + CPU = "silvermont"; + *Type = INTEL_SILVERMONT; + break; + // Goldmont: + case 0x5c: // Apollo Lake + case 0x5f: // Denverton + CPU = "goldmont"; + *Type = INTEL_GOLDMONT; + break; // "goldmont" + case 0x7a: + CPU = "goldmont-plus"; + *Type = INTEL_GOLDMONT_PLUS; + break; + case 0x86: + case 0x8a: // Lakefield + case 0x96: // Elkhart Lake + case 0x9c: // Jasper Lake + CPU = "tremont"; + *Type = INTEL_TREMONT; + break; + + // Sierraforest: + case 0xaf: + CPU = "sierraforest"; + *Type = INTEL_SIERRAFOREST; + break; + + // Grandridge: + case 0xb6: + CPU = "grandridge"; + *Type = INTEL_GRANDRIDGE; + break; + + // Clearwaterforest: + case 0xdd: + CPU = "clearwaterforest"; + *Type = INTEL_COREI7; + *Subtype = INTEL_CLEARWATERFOREST; + break; + + case 0x57: + CPU = "knl"; + *Type = INTEL_KNL; + break; + + case 0x85: + CPU = "knm"; + *Type = INTEL_KNM; + break; + + default: // Unknown family 6 CPU. + break; + } + break; + default: + break; // Unknown. + } + + return CPU; +} + +static const char *getAMDProcessorTypeAndSubtype(unsigned Family, + unsigned Model, + const unsigned *Features, + unsigned *Type, + unsigned *Subtype) { + // We select CPU strings to match the code in Host.cpp, but we don't use them + // in compiler-rt. + const char *CPU = 0; + + switch (Family) { + case 16: + CPU = "amdfam10"; + *Type = AMDFAM10H; + switch (Model) { + case 2: + *Subtype = AMDFAM10H_BARCELONA; + break; + case 4: + *Subtype = AMDFAM10H_SHANGHAI; + break; + case 8: + *Subtype = AMDFAM10H_ISTANBUL; + break; + } + break; + case 20: + CPU = "btver1"; + *Type = AMD_BTVER1; + break; + case 21: + CPU = "bdver1"; + *Type = AMDFAM15H; + if (Model >= 0x60 && Model <= 0x7f) { + CPU = "bdver4"; + *Subtype = AMDFAM15H_BDVER4; + break; // 60h-7Fh: Excavator + } + if (Model >= 0x30 && Model <= 0x3f) { + CPU = "bdver3"; + *Subtype = AMDFAM15H_BDVER3; + break; // 30h-3Fh: Steamroller + } + if ((Model >= 0x10 && Model <= 0x1f) || Model == 0x02) { + CPU = "bdver2"; + *Subtype = AMDFAM15H_BDVER2; + break; // 02h, 10h-1Fh: Piledriver + } + if (Model <= 0x0f) { + *Subtype = AMDFAM15H_BDVER1; + break; // 00h-0Fh: Bulldozer + } + break; + case 22: + CPU = "btver2"; + *Type = AMD_BTVER2; + break; + case 23: + CPU = "znver1"; + *Type = AMDFAM17H; + if ((Model >= 0x30 && Model <= 0x3f) || (Model == 0x47) || + (Model >= 0x60 && Model <= 0x67) || + (Model >= 0x68 && Model <= 0x6f) || + (Model >= 0x70 && Model <= 0x7f) || + (Model >= 0x84 && Model <= 0x87) || + (Model >= 0x90 && Model <= 0x97) || + (Model >= 0x98 && Model <= 0x9f) || + (Model >= 0xa0 && Model <= 0xaf)) { + // Family 17h Models 30h-3Fh (Starship) Zen 2 + // Family 17h Models 47h (Cardinal) Zen 2 + // Family 17h Models 60h-67h (Renoir) Zen 2 + // Family 17h Models 68h-6Fh (Lucienne) Zen 2 + // Family 17h Models 70h-7Fh (Matisse) Zen 2 + // Family 17h Models 84h-87h (ProjectX) Zen 2 + // Family 17h Models 90h-97h (VanGogh) Zen 2 + // Family 17h Models 98h-9Fh (Mero) Zen 2 + // Family 17h Models A0h-AFh (Mendocino) Zen 2 + CPU = "znver2"; + *Subtype = AMDFAM17H_ZNVER2; + break; + } + if ((Model >= 0x10 && Model <= 0x1f) || + (Model >= 0x20 && Model <= 0x2f)) { + // Family 17h Models 10h-1Fh (Raven1) Zen + // Family 17h Models 10h-1Fh (Picasso) Zen+ + // Family 17h Models 20h-2Fh (Raven2 x86) Zen + *Subtype = AMDFAM17H_ZNVER1; + break; + } + break; + case 25: + CPU = "znver3"; + *Type = AMDFAM19H; + if ((Model <= 0x0f) || (Model >= 0x20 && Model <= 0x2f) || + (Model >= 0x30 && Model <= 0x3f) || + (Model >= 0x40 && Model <= 0x4f) || + (Model >= 0x50 && Model <= 0x5f)) { + // Family 19h Models 00h-0Fh (Genesis, Chagall) Zen 3 + // Family 19h Models 20h-2Fh (Vermeer) Zen 3 + // Family 19h Models 30h-3Fh (Badami) Zen 3 + // Family 19h Models 40h-4Fh (Rembrandt) Zen 3+ + // Family 19h Models 50h-5Fh (Cezanne) Zen 3 + *Subtype = AMDFAM19H_ZNVER3; + break; + } + if ((Model >= 0x10 && Model <= 0x1f) || + (Model >= 0x60 && Model <= 0x6f) || + (Model >= 0x70 && Model <= 0x77) || + (Model >= 0x78 && Model <= 0x7f) || + (Model >= 0xa0 && Model <= 0xaf)) { + // Family 19h Models 10h-1Fh (Stones; Storm Peak) Zen 4 + // Family 19h Models 60h-6Fh (Raphael) Zen 4 + // Family 19h Models 70h-77h (Phoenix, Hawkpoint1) Zen 4 + // Family 19h Models 78h-7Fh (Phoenix 2, Hawkpoint2) Zen 4 + // Family 19h Models A0h-AFh (Stones-Dense) Zen 4 + CPU = "znver4"; + *Subtype = AMDFAM19H_ZNVER4; + break; // "znver4" + } + break; // family 19h + default: + break; // Unknown AMD CPU. + } + + return CPU; +} + +static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf, + unsigned *Features) { + unsigned EAX = 0, EBX = 0; + +#define hasFeature(F) ((Features[F / 32] >> (F % 32)) & 1) +#define setFeature(F) Features[F / 32] |= 1U << (F % 32) + + if ((EDX >> 15) & 1) setFeature(FEATURE_CMOV); + if ((EDX >> 23) & 1) setFeature(FEATURE_MMX); + if ((EDX >> 25) & 1) setFeature(FEATURE_SSE); + if ((EDX >> 26) & 1) setFeature(FEATURE_SSE2); + + if ((ECX >> 0) & 1) setFeature(FEATURE_SSE3); + if ((ECX >> 1) & 1) setFeature(FEATURE_PCLMUL); + if ((ECX >> 9) & 1) setFeature(FEATURE_SSSE3); + if ((ECX >> 12) & 1) setFeature(FEATURE_FMA); + if ((ECX >> 13) & 1) setFeature(FEATURE_CMPXCHG16B); + if ((ECX >> 19) & 1) setFeature(FEATURE_SSE4_1); + if ((ECX >> 20) & 1) setFeature(FEATURE_SSE4_2); + if ((ECX >> 22) & 1) setFeature(FEATURE_MOVBE); + if ((ECX >> 23) & 1) setFeature(FEATURE_POPCNT); + if ((ECX >> 25) & 1) setFeature(FEATURE_AES); + if ((ECX >> 29) & 1) setFeature(FEATURE_F16C); + + // If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV + // indicates that the AVX registers will be saved and restored on context + // switch, then we have full AVX support. + const unsigned AVXBits = (1 << 27) | (1 << 28); + bool HasAVX = ((ECX & AVXBits) == AVXBits) && !getX86XCR0(&EAX, &EDX) && + ((EAX & 0x6) == 0x6); +#if defined(__APPLE__) + // Darwin lazily saves the AVX512 context on first use: trust that the OS will + // save the AVX512 context if we use AVX512 instructions, even the bit is not + // set right now. + bool HasAVX512Save = true; +#else + // AVX512 requires additional context to be saved by the OS. + bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0); +#endif + + if (HasAVX) setFeature(FEATURE_AVX); + + bool HasLeaf7 = + MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX); + + if (HasLeaf7) { + if ((EBX >> 3) & 1) setFeature(FEATURE_BMI); + if (((EBX >> 5) & 1) && HasAVX) setFeature(FEATURE_AVX2); + if ((EBX >> 8) & 1) setFeature(FEATURE_BMI2); + if (HasAVX512Save) { + if ((EBX >> 16) & 1) setFeature(FEATURE_AVX512F); + if ((EBX >> 17) & 1) setFeature(FEATURE_AVX512DQ); + if ((EBX >> 21) & 1) setFeature(FEATURE_AVX512IFMA); + if ((EBX >> 26) & 1) setFeature(FEATURE_AVX512PF); + if ((EBX >> 27) & 1) setFeature(FEATURE_AVX512ER); + if ((EBX >> 28) & 1) setFeature(FEATURE_AVX512CD); + if ((EBX >> 30) & 1) setFeature(FEATURE_AVX512BW); + if ((EBX >> 31) & 1) setFeature(FEATURE_AVX512VL); + if ((ECX >> 1) & 1) setFeature(FEATURE_AVX512VBMI); + if ((ECX >> 6) & 1) setFeature(FEATURE_AVX512VBMI2); + if ((ECX >> 11) & 1) setFeature(FEATURE_AVX512VNNI); + if ((ECX >> 12) & 1) setFeature(FEATURE_AVX512BITALG); + if ((ECX >> 14) & 1) setFeature(FEATURE_AVX512VPOPCNTDQ); + if ((EDX >> 2) & 1) setFeature(FEATURE_AVX5124VNNIW); + if ((EDX >> 3) & 1) setFeature(FEATURE_AVX5124FMAPS); + if ((EDX >> 8) & 1) setFeature(FEATURE_AVX512VP2INTERSECT); + if ((EDX >> 23) & 1) setFeature(FEATURE_AVX512FP16); + } + if ((ECX >> 8) & 1) setFeature(FEATURE_GFNI); + if (((ECX >> 10) & 1) && HasAVX) setFeature(FEATURE_VPCLMULQDQ); + } + + // EAX from subleaf 0 is the maximum subleaf supported. Some CPUs don't + // return all 0s for invalid subleaves so check the limit. + bool HasLeaf7Subleaf1 = + HasLeaf7 && EAX >= 1 && + !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX); + if (HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save) + setFeature(FEATURE_AVX512BF16); + + unsigned MaxExtLevel; + getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX); + + bool HasExtLeaf1 = MaxExtLevel >= 0x80000001 && + !getX86CpuIDAndInfo(0x80000001, &EAX, &EBX, &ECX, &EDX); + if (HasExtLeaf1) { + if (ECX & 1) setFeature(FEATURE_LAHF_LM); + if ((ECX >> 5) & 1) setFeature(FEATURE_LZCNT); + if (((ECX >> 6) & 1)) setFeature(FEATURE_SSE4_A); + if (((ECX >> 11) & 1)) setFeature(FEATURE_XOP); + if (((ECX >> 16) & 1)) setFeature(FEATURE_FMA4); + if (((EDX >> 29) & 1)) setFeature(FEATURE_LM); + } + + if (hasFeature(FEATURE_LM) && hasFeature(FEATURE_SSE2)) { + setFeature(FEATURE_X86_64_BASELINE); + if (hasFeature(FEATURE_CMPXCHG16B) && hasFeature(FEATURE_POPCNT) && + hasFeature(FEATURE_LAHF_LM) && hasFeature(FEATURE_SSE4_2)) { + setFeature(FEATURE_X86_64_V2); + if (hasFeature(FEATURE_AVX2) && hasFeature(FEATURE_BMI) && + hasFeature(FEATURE_BMI2) && hasFeature(FEATURE_F16C) && + hasFeature(FEATURE_FMA) && hasFeature(FEATURE_LZCNT) && + hasFeature(FEATURE_MOVBE)) { + setFeature(FEATURE_X86_64_V3); + if (hasFeature(FEATURE_AVX512BW) && hasFeature(FEATURE_AVX512CD) && + hasFeature(FEATURE_AVX512DQ) && hasFeature(FEATURE_AVX512VL)) + setFeature(FEATURE_X86_64_V4); + } + } + } + +#undef hasFeature +#undef setFeature +} + +int __cpu_indicator_init(void) CONSTRUCTOR_ATTRIBUTE; + +struct __processor_model { + unsigned int __cpu_vendor; + unsigned int __cpu_type; + unsigned int __cpu_subtype; + unsigned int __cpu_features[1]; +} __cpu_model = {0, 0, 0, {0}}; + +unsigned __cpu_features2[(CPU_FEATURE_MAX - 1) / 32]; + +// A constructor function that is sets __cpu_model and __cpu_features2 with +// the right values. This needs to run only once. This constructor is +// given the highest priority and it should run before constructors without +// the priority set. However, it still runs after ifunc initializers and +// needs to be called explicitly there. + +int CONSTRUCTOR_ATTRIBUTE __cpu_indicator_init(void) { + unsigned EAX, EBX, ECX, EDX; + unsigned MaxLeaf = 5; + unsigned Vendor; + unsigned Model, Family; + unsigned Features[(CPU_FEATURE_MAX + 31) / 32] = {0}; + _Static_assert(sizeof(Features) / sizeof(Features[0]) == 4, ""); + _Static_assert(sizeof(__cpu_features2) / sizeof(__cpu_features2[0]) == 3, ""); + + // This function needs to run just once. + if (__cpu_model.__cpu_vendor) return 0; + + if (!isCpuIdSupported() || + getX86CpuIDAndInfo(0, &MaxLeaf, &Vendor, &ECX, &EDX) || MaxLeaf < 1) { + __cpu_model.__cpu_vendor = VENDOR_OTHER; + return -1; + } + + getX86CpuIDAndInfo(1, &EAX, &EBX, &ECX, &EDX); + detectX86FamilyModel(EAX, &Family, &Model); + + // Find available features. + getAvailableFeatures(ECX, EDX, MaxLeaf, &Features[0]); + + __cpu_model.__cpu_features[0] = Features[0]; + __cpu_features2[0] = Features[1]; + __cpu_features2[1] = Features[2]; + __cpu_features2[2] = Features[3]; + + if (Vendor == SIG_INTEL) { + // Get CPU type. + getIntelProcessorTypeAndSubtype(Family, Model, &Features[0], + &(__cpu_model.__cpu_type), + &(__cpu_model.__cpu_subtype)); + __cpu_model.__cpu_vendor = VENDOR_INTEL; + } else if (Vendor == SIG_AMD) { + // Get CPU type. + getAMDProcessorTypeAndSubtype(Family, Model, &Features[0], + &(__cpu_model.__cpu_type), + &(__cpu_model.__cpu_subtype)); + __cpu_model.__cpu_vendor = VENDOR_AMD; + } else { + __cpu_model.__cpu_vendor = VENDOR_OTHER; + } + + return 0; +} + +#endif // __x86_64__ && (gnuc || clang) diff --git a/libc/log/addr2linepath.c b/libc/log/addr2linepath.c index 5493645c2..89c09d18b 100644 --- a/libc/log/addr2linepath.c +++ b/libc/log/addr2linepath.c @@ -36,7 +36,7 @@ static struct { char buf[PATH_MAX]; } g_addr2line; -const void GetAddr2linePathInit(void) { +void GetAddr2linePathInit(void) { int e = errno; const char *path; if (!(path = getenv("ADDR2LINE"))) { diff --git a/libc/log/cxaprintexits.c b/libc/log/cxaprintexits.c index 08e7f2d4a..a9b6354f5 100644 --- a/libc/log/cxaprintexits.c +++ b/libc/log/cxaprintexits.c @@ -48,10 +48,10 @@ void __cxa_printexits(FILE *f, void *pred) { if (symbol) { snprintf(name, sizeof(name), "%s", symbol); } else { - snprintf(name, sizeof(name), "0x%016lx", b->p[i].fp); + snprintf(name, sizeof(name), "0x%016lx", (unsigned long)b->p[i].fp); } - fprintf(f, "%-22s 0x%016lx 0x%016lx\n", name, b->p[i].arg, - b->p[i].pred); + fprintf(f, "%-22s 0x%016lx 0x%016lx\n", name, + (unsigned long)b->p[i].arg, (unsigned long)b->p[i].pred); } } } while ((b = b->next)); diff --git a/libc/log/die.c b/libc/log/die.c index d2fcd7948..30458102c 100644 --- a/libc/log/die.c +++ b/libc/log/die.c @@ -20,6 +20,7 @@ #include "libc/errno.h" #include "libc/intrin/describebacktrace.internal.h" #include "libc/intrin/kprintf.h" +#include "libc/log/backtrace.internal.h" #include "libc/log/internal.h" #include "libc/runtime/runtime.h" #include "libc/runtime/symbols.internal.h" @@ -51,5 +52,6 @@ relegated wontreturn void __die(void) { __nocolor ? "" : "\e[1;31m", program_invocation_short_name, host, getpid(), gettid(), __nocolor ? "" : "\e[0m", FindDebugBinary(), DescribeBacktrace(__builtin_frame_address(0))); + ShowBacktrace(2, __builtin_frame_address(0)); _Exit(77); } diff --git a/libc/log/gdbexec.c b/libc/log/gdbexec.c index 3e0e035ba..f8d47f14e 100644 --- a/libc/log/gdbexec.c +++ b/libc/log/gdbexec.c @@ -41,7 +41,7 @@ relegated int(gdbexec)(const char *cmd) { elf = "-q"; } bp = __builtin_frame_address(0); - sprintf(breakcmd, "%s *%#p", "break", bp->addr); + sprintf(breakcmd, "%s *%#lx", "break", (unsigned long)bp->addr); if (!(pid = vfork())) { execv(gdb, (char *const[]){ "gdb", diff --git a/libc/log/oncrash_amd64.c b/libc/log/oncrash_amd64.c index fe0949c62..06e155a15 100644 --- a/libc/log/oncrash_amd64.c +++ b/libc/log/oncrash_amd64.c @@ -252,16 +252,9 @@ static relegated void ShowCrashReport(int err, int sig, struct siginfo *si, } relegated void __oncrash(int sig, struct siginfo *si, void *arg) { - ucontext_t *ctx = arg; - int gdbpid, err; - err = errno; - if ((gdbpid = IsDebuggerPresent(true))) { - DebugBreak(); - } - if (!(gdbpid > 0 && (sig == SIGTRAP || sig == SIGQUIT))) { - __restore_tty(); - ShowCrashReport(err, sig, si, ctx); - } + int err = errno; + __restore_tty(); + ShowCrashReport(err, sig, si, arg); } #endif /* __x86_64__ */ diff --git a/libc/macros.internal.h b/libc/macros.internal.h index 396f2b749..ae6313384 100644 --- a/libc/macros.internal.h +++ b/libc/macros.internal.h @@ -21,8 +21,8 @@ #define TRUE 1 #define FALSE 0 -#define IS2POW(X) (!((X) & ((X)-1))) -#define ROUNDUP(X, K) (((X) + (K)-1) & -(K)) +#define IS2POW(X) (!((X) & ((X) - 1))) +#define ROUNDUP(X, K) (((X) + (K) - 1) & -(K)) #define ROUNDDOWN(X, K) ((X) & -(K)) #ifndef __ASSEMBLER__ #define ABS(X) ((X) >= 0 ? (X) : -(X)) @@ -40,7 +40,7 @@ #define STRINGIFY(A) __STRINGIFY(A) #define EQUIVALENT(X, Y) (__builtin_constant_p((X) == (Y)) && ((X) == (Y))) #define TYPE_BIT(type) (sizeof(type) * CHAR_BIT) -#define TYPE_SIGNED(type) (((type)-1) < 0) +#define TYPE_SIGNED(type) (((type) - 1) < 0) #define TYPE_INTEGRAL(type) (((type)0.5) != 0.5) #define ARRAYLEN(A) \ diff --git a/libc/mem/mergesort.c b/libc/mem/mergesort.c index 205a20ef4..70344f552 100644 --- a/libc/mem/mergesort.c +++ b/libc/mem/mergesort.c @@ -54,8 +54,8 @@ asm(".include \"libc/disclaimer.inc\""); * (The default is pairwise merging.) */ -static void setup(uint8_t *, uint8_t *, size_t, size_t, int (*)(), void *); -static void insertionsort(uint8_t *, size_t, size_t, int (*)(), void *); +static void setup(uint8_t *, uint8_t *, size_t, size_t, int (*)(const void *, const void *, void *), void *); +static void insertionsort(uint8_t *, size_t, size_t, int (*)(const void *, const void *, void *), void *); #define ISIZE sizeof(int) #define PSIZE sizeof(uint8_t *) diff --git a/libc/nexgen32e/rdtscp.h b/libc/nexgen32e/rdtscp.h index 9c3502faf..5bebc8735 100644 --- a/libc/nexgen32e/rdtscp.h +++ b/libc/nexgen32e/rdtscp.h @@ -5,7 +5,7 @@ #include "libc/nexgen32e/x86feature.h" COSMOPOLITAN_C_START_ -#define TSC_AUX_CORE(MSR) ((MSR)&0xfff) +#define TSC_AUX_CORE(MSR) ((MSR) & 0xfff) #define TSC_AUX_NODE(MSR) (((MSR) >> 12) & 0xfff) /** @@ -41,9 +41,10 @@ COSMOPOLITAN_C_START_ asm volatile("rdpid\t%0" : "=r"(Msr) : /* no inputs */ : "memory"); \ Ok = true; \ } else if (IsLinux()) { \ + char *p = (char *)0x7b; \ asm volatile(ZFLAG_ASM("lsl\t%2,%1") \ : ZFLAG_CONSTRAINT(Ok), "=r"(Msr) \ - : "r"(0x7b) \ + : "r"(p) \ : "memory"); \ } \ if (!Ok && X86_HAVE(RDTSCP)) { \ diff --git a/libc/nt/advapi32/SystemFunction036.S b/libc/nt/BCryptPrimitives/ProcessPrng.S similarity index 57% rename from libc/nt/advapi32/SystemFunction036.S rename to libc/nt/BCryptPrimitives/ProcessPrng.S index 4380c47e3..d7eec4fbb 100644 --- a/libc/nt/advapi32/SystemFunction036.S +++ b/libc/nt/BCryptPrimitives/ProcessPrng.S @@ -1,18 +1,18 @@ #include "libc/nt/codegen.h" -.imp advapi32,__imp_SystemFunction036,SystemFunction036 +.imp BCryptPrimitives,__imp_ProcessPrng,ProcessPrng .text.windows .ftrace1 -RtlGenRandom: +ProcessPrng: .ftrace2 #ifdef __x86_64__ push %rbp mov %rsp,%rbp - mov __imp_SystemFunction036(%rip),%rax + mov __imp_ProcessPrng(%rip),%rax jmp __sysv2nt #elif defined(__aarch64__) mov x0,#0 ret #endif - .endfn RtlGenRandom,globl + .endfn ProcessPrng,globl .previous diff --git a/libc/nt/BUILD.mk b/libc/nt/BUILD.mk index b49f2c41a..feaa79e24 100644 --- a/libc/nt/BUILD.mk +++ b/libc/nt/BUILD.mk @@ -297,6 +297,24 @@ $(LIBC_NT_PSAPI_A).pkg: \ #─────────────────────────────────────────────────────────────────────────────── +LIBC_NT_ARTIFACTS += LIBC_NT_BCRYPTPRIMITIVES_A +LIBC_NT_BCRYPTPRIMITIVES = $(LIBC_NT_BCRYPTPRIMITIVES_A_DEPS) $(LIBC_NT_BCRYPTPRIMITIVES_A) +LIBC_NT_BCRYPTPRIMITIVES_A = o/$(MODE)/libc/nt/BCryptPrimitives.a +LIBC_NT_BCRYPTPRIMITIVES_A_SRCS := $(wildcard libc/nt/BCryptPrimitives/*.S) +LIBC_NT_BCRYPTPRIMITIVES_A_OBJS = $(LIBC_NT_BCRYPTPRIMITIVES_A_SRCS:%.S=o/$(MODE)/%.o) +LIBC_NT_BCRYPTPRIMITIVES_A_CHECKS = $(LIBC_NT_BCRYPTPRIMITIVES_A).pkg +LIBC_NT_BCRYPTPRIMITIVES_A_DIRECTDEPS = LIBC_NT_KERNEL32 +LIBC_NT_BCRYPTPRIMITIVES_A_DEPS := $(call uniq,$(foreach x,$(LIBC_NT_BCRYPTPRIMITIVES_A_DIRECTDEPS),$($(x)))) +$(LIBC_NT_BCRYPTPRIMITIVES_A): \ + libc/nt/BCryptPrimitives/ \ + $(LIBC_NT_BCRYPTPRIMITIVES_A).pkg \ + $(LIBC_NT_BCRYPTPRIMITIVES_A_OBJS) +$(LIBC_NT_BCRYPTPRIMITIVES_A).pkg: \ + $(LIBC_NT_BCRYPTPRIMITIVES_A_OBJS) \ + $(foreach x,$(LIBC_NT_BCRYPTPRIMITIVES_A_DIRECTDEPS),$($(x)_A).pkg) + +#─────────────────────────────────────────────────────────────────────────────── + # let aarch64 compile these o/$(MODE)/libc/nt/%.o: libc/nt/%.S @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) $< diff --git a/libc/nt/master.sh b/libc/nt/master.sh index 11d9e4528..5a76231ed 100755 --- a/libc/nt/master.sh +++ b/libc/nt/master.sh @@ -362,7 +362,6 @@ imp 'RegisterEventSource' RegisterEventSourceW advapi32 2 imp 'ReportEvent' ReportEventW advapi32 9 imp 'ReportEventA' ReportEventA advapi32 9 imp 'RevertToSelf' RevertToSelf advapi32 0 -imp 'RtlGenRandom' SystemFunction036 advapi32 2 imp 'TraceSetInformation' TraceSetInformation advapi32 # Windows 7+ # USER32.DLL @@ -611,6 +610,11 @@ imp 'GetModuleBaseName' GetModuleBaseNameW psapi 4 imp 'GetProcessImageFileName' GetProcessImageFileNameW psapi 3 imp 'GetProcessMemoryInfo' GetProcessMemoryInfo psapi 3 +# BCryptPrimitives.dll +# +# Name Actual DLL Arity +imp 'ProcessPrng' ProcessPrng BCryptPrimitives 2 + # API-MS-Win-Core-Synch-l1-2-0.dll (Windows 8+) # # Name Actual DLL Arity diff --git a/libc/nt/runtime.h b/libc/nt/runtime.h index 5248816a3..953e77692 100644 --- a/libc/nt/runtime.h +++ b/libc/nt/runtime.h @@ -36,11 +36,11 @@ bool32 TerminateProcess(int64_t hProcess, uint32_t uExitCode); void TerminateThisProcess(uint32_t dwWaitStatus) wontreturn; void ExitProcess(uint32_t uExitCode) wontreturn; uint32_t GetLastError(void) nosideeffect; -bool32 CloseHandle(int64_t hObject) dontthrow nocallback; +bool32 CloseHandle(int64_t hObject) dontthrow dontcallback; intptr_t GetStdHandle(uint32_t nStdHandle) nosideeffect; bool32 SetStdHandle(uint32_t nStdHandle, int64_t hHandle); bool32 SetDefaultDllDirectories(unsigned dirflags); -bool32 RtlGenRandom(void *RandomBuffer, uint32_t RandomBufferLength); +bool32 ProcessPrng(void *RandomBuffer, uint32_t RandomBufferLength); uint32_t GetModuleFileName(int64_t hModule, char16_t *lpFilename, uint32_t nSize); diff --git a/libc/nt/struct/teb.h b/libc/nt/struct/teb.h index a232b4f43..ec997a83e 100644 --- a/libc/nt/struct/teb.h +++ b/libc/nt/struct/teb.h @@ -1,6 +1,5 @@ #ifndef COSMOPOLITAN_LIBC_NT_TEB_H_ #define COSMOPOLITAN_LIBC_NT_TEB_H_ -#include "libc/intrin/segmentation.h" #include "libc/nt/struct/peb.h" #if defined(__GNUC__) && !defined(__STRICT_ANSI__) @@ -8,19 +7,19 @@ * These macros address directly into NT's TEB a.k.a. TIB * Any function that does this needs the `dontasan` keyword */ -#define NtGetPeb() gs((struct NtPeb **)(0x60ULL)) -#define NtGetTeb() gs((void **)(0x30)) /* %gs:0 linear address */ -#define NtGetPid() gs((uint32_t *)(0x40)) /* GetCurrentProcessId() */ -#define NtGetTid() gs((uint32_t *)(0x48)) /* GetCurrentThreadId() */ -#define NtGetErr() gs((int *)(0x68)) -#define _NtGetSeh() gs((void **)(0x00)) -#define _NtGetStackHigh() gs((void **)(0x08)) -#define _NtGetStackLow() gs((void **)(0x10)) -#define _NtGetSubsystemTib() gs((void **)(0x18)) -#define _NtGetFib() gs((void **)(0x20)) -#define _NtGetEnv() gs((char16_t **)(0x38)) -#define _NtGetRpc() gs((void **)(0x50)) -#define _NtGetTls() gs((void **)(0x58)) /* cf. gs((long *)0x1480 + i0..64) */ +#define NtGetPeb() ((__seg_gs struct NtPeb *)0x60) +#define NtGetTeb() ((void *)*(__seg_gs uintptr_t *)0x30) +#define NtGetPid() (*(__seg_gs uint32_t *)0x40) +#define NtGetTid() (*(__seg_gs uint32_t *)0x48) +#define NtGetErr() (*(__seg_gs int *)0x68) +#define _NtGetSeh() ((void *)*(__seg_gs uintptr_t *)0x00) +#define _NtGetStackHigh() ((void *)*(__seg_gs uintptr_t *)0x08) +#define _NtGetStackLow() ((void *)*(__seg_gs uintptr_t *)0x10) +#define _NtGetSubsystemTib() ((void *)*(__seg_gs uintptr_t *)0x18) +#define _NtGetFib() ((void *)*(__seg_gs uintptr_t *)0x20) +#define _NtGetEnv() ((char16_t *)*(__seg_gs intptr_t *)0x38) +#define _NtGetRpc() ((void *)*(__seg_gs uintptr_t *)0x50) +#define _NtGetTls() ((void *)*(__seg_gs uintptr_t *)0x58) #endif /* __GNUC__ && !__STRICT_ANSI__ */ #endif /* COSMOPOLITAN_LIBC_NT_TEB_H_ */ diff --git a/libc/proc/fork-nt.c b/libc/proc/fork-nt.c index a59fecaaa..dac6300cb 100644 --- a/libc/proc/fork-nt.c +++ b/libc/proc/fork-nt.c @@ -78,7 +78,9 @@ static textwindows char16_t *ParseInt(char16_t *p, int64_t *x) { } static inline textwindows ssize_t ForkIo(int64_t h, char *p, size_t n, - bool32 (*f)()) { + bool32 (*f)(int64_t, void *, uint32_t, + uint32_t *, + struct NtOverlapped *)) { size_t i; uint32_t x; for (i = 0; i < n; i += x) { @@ -90,8 +92,10 @@ static inline textwindows ssize_t ForkIo(int64_t h, char *p, size_t n, } static dontinline textwindows bool ForkIo2(int64_t h, void *buf, size_t n, - bool32 (*fn)(), const char *sf, - bool ischild) { + bool32 (*fn)(int64_t, void *, + uint32_t, uint32_t *, + struct NtOverlapped *), + const char *sf, bool ischild) { ssize_t rc = ForkIo(h, buf, n, fn); if (ischild) __tls_enabled_set(false); // prevent tls crash in kprintf NTTRACE("%s(%ld, %p, %'zu) → %'zd% m", sf, h, buf, n, rc); @@ -100,9 +104,9 @@ static dontinline textwindows bool ForkIo2(int64_t h, void *buf, size_t n, static dontinline textwindows bool WriteAll(int64_t h, void *buf, size_t n) { bool ok; - ok = ForkIo2(h, buf, n, WriteFile, "WriteFile", false); + ok = ForkIo2(h, buf, n, (void *)WriteFile, "WriteFile", false); #ifndef NDEBUG - if (ok) ok = ForkIo2(h, &n, sizeof(n), WriteFile, "WriteFile", false); + if (ok) ok = ForkIo2(h, &n, sizeof(n), (void *)WriteFile, "WriteFile", false); #endif #if SYSDEBUG if (!ok) { diff --git a/libc/runtime/clone.c b/libc/runtime/clone.c index 85d3db9df..cb1d0733f 100644 --- a/libc/runtime/clone.c +++ b/libc/runtime/clone.c @@ -94,7 +94,7 @@ struct CloneArgs { void *arg; }; -int sys_set_tls(); +int sys_set_tls(uintptr_t, void *); int __stack_call(void *, int, long, long, int (*)(void *, int), void *); static struct CloneArgs *AllocateCloneArgs(char *stk, size_t stksz) { diff --git a/libc/runtime/cosmo2.c b/libc/runtime/cosmo2.c index 841c37d23..f01c63720 100644 --- a/libc/runtime/cosmo2.c +++ b/libc/runtime/cosmo2.c @@ -149,7 +149,7 @@ wontreturn textstartup void cosmo(long *sp, struct Syslib *m1, char *exename, } // check system call abi compatibility - if (IsXnu() && __syslib->__version < SYSLIB_VERSION) { + if (IsXnu() && __syslib->__version < SYSLIB_VERSION_MANDATORY) { sys_write(2, "need newer ape loader\n", 22); _Exit(127); } diff --git a/libc/runtime/efimain.greg.c b/libc/runtime/efimain.greg.c index 50d5dee82..7861ef0bc 100644 --- a/libc/runtime/efimain.greg.c +++ b/libc/runtime/efimain.greg.c @@ -30,6 +30,9 @@ #include "libc/runtime/runtime.h" #include "libc/str/str.h" +#pragma GCC diagnostic ignored "-Warray-bounds" +#pragma GCC diagnostic ignored "-Wstringop-overflow" + #ifdef __x86_64__ /* TODO: Why can't we change CR3? Could it really need PML5T? */ @@ -162,7 +165,7 @@ static void EfiInitAcpi(struct mman *mm, EFI_SYSTEM_TABLE *SystemTable) { * @see libc/dce.h */ __msabi EFI_STATUS EfiMain(EFI_HANDLE ImageHandle, - EFI_SYSTEM_TABLE *SystemTable) { + EFI_SYSTEM_TABLE *SystemTable) { struct mman *mm; uint32_t DescVersion; uintptr_t i, j, MapSize; @@ -215,9 +218,8 @@ __msabi EFI_STATUS EfiMain(EFI_HANDLE ImageHandle, &kEfiLoadedImageProtocol, &ImgInfo); CmdLine = (const char16_t *)ImgInfo->LoadOptions; if (!CmdLine || !CmdLine[0]) CmdLine = u"BOOTX64.EFI"; - Args = GetDosArgv(CmdLine, ArgBlock->ArgBlock, - sizeof(ArgBlock->ArgBlock), ArgBlock->Args, - ARRAYLEN(ArgBlock->Args)); + Args = GetDosArgv(CmdLine, ArgBlock->ArgBlock, sizeof(ArgBlock->ArgBlock), + ArgBlock->Args, ARRAYLEN(ArgBlock->Args)); /* * Gets information about our current video mode. Clears the screen. diff --git a/libc/runtime/getargmax.c b/libc/runtime/getargmax.c index 3a02203d2..37ce64c83 100644 --- a/libc/runtime/getargmax.c +++ b/libc/runtime/getargmax.c @@ -19,6 +19,8 @@ #include "libc/dce.h" #include "libc/macros.internal.h" #include "libc/runtime/runtime.h" +#include "libc/stdio/sysparam.h" +#include "libc/sysv/consts/_posix.h" #include "libc/sysv/consts/limits.h" #include "libc/sysv/consts/rlimit.h" @@ -29,6 +31,7 @@ * Returns expensive but more correct version of `ARG_MAX`. */ int __get_arg_max(void) { + int res; if (IsLinux()) { // You might think that just returning a constant 128KiB (ARG_MAX) // would make sense, as this guy did: @@ -57,10 +60,11 @@ int __get_arg_max(void) { // does. Right now (2019, Linux 5.3) that amounts to: uint64_t stacksz; stacksz = __get_rlimit(RLIMIT_STACK); - return MAX(MIN(stacksz / 4, 3 * (8 * 1024 * 1024) / 4), _ARG_MAX); + res = MAX(MIN(stacksz / 4, 3 * (8 * 1024 * 1024) / 4), _ARG_MAX); } else if (IsBsd()) { - return __get_sysctl(CTL_KERN, KERN_ARGMAX); + res = __get_sysctl(CTL_KERN, KERN_ARGMAX); } else { - return _ARG_MAX; + res = _ARG_MAX; } + return MAX(res, _POSIX_ARG_MAX); } diff --git a/libc/runtime/memtrack.internal.h b/libc/runtime/memtrack.internal.h index 543a16c22..6607a036a 100644 --- a/libc/runtime/memtrack.internal.h +++ b/libc/runtime/memtrack.internal.h @@ -164,9 +164,9 @@ forceinline pureconst bool OverlapsImageSpace(const void *p, size_t n) { const unsigned char *BegA, *EndA, *BegB, *EndB; if (n) { BegA = p; - EndA = BegA + (n - 1); + EndA = BegA + n; BegB = __executable_start; - EndB = _end - 1; + EndB = _end; return MAX(BegA, BegB) < MIN(EndA, EndB); } else { return 0; @@ -177,9 +177,9 @@ forceinline pureconst bool OverlapsShadowSpace(const void *p, size_t n) { intptr_t BegA, EndA, BegB, EndB; if (n) { BegA = (intptr_t)p; - EndA = BegA + (n - 1); + EndA = BegA + n; BegB = 0x7fff0000; - EndB = 0x10007fffffff; + EndB = 0x100080000000; return MAX(BegA, BegB) < MIN(EndA, EndB); } else { return 0; diff --git a/libc/runtime/runtime.h b/libc/runtime/runtime.h index ff26dde66..db0dfb253 100644 --- a/libc/runtime/runtime.h +++ b/libc/runtime/runtime.h @@ -54,7 +54,7 @@ char *getlogin(void); int getlogin_r(char *, size_t); int login_tty(int); int getpagesize(void); -int syncfs(int); +int syncfs(int) dontthrow; int vhangup(void); int getdtablesize(void); int sethostname(const char *, size_t); diff --git a/libc/runtime/set_tls.c b/libc/runtime/set_tls.c index 0dd8049c5..29972f484 100644 --- a/libc/runtime/set_tls.c +++ b/libc/runtime/set_tls.c @@ -29,7 +29,7 @@ #define AMD64_SET_FSBASE 129 #define AMD64_SET_GSBASE 131 -int sys_set_tls(); +int sys_set_tls(uintptr_t, void *); // we can't allow --ftrace here because cosmo_dlopen() calls this // function to fix the tls register, and ftrace needs it unbroken @@ -47,12 +47,12 @@ dontinstrument textstartup void __set_tls(struct CosmoTib *tib) { // netbsd has sysarch(X86_SET_FSBASE) but we can't use that because // signal handlers will cause it to be reset due to not setting the // _mc_tlsbase field in struct mcontext_netbsd. - sys_set_tls(tib); + sys_set_tls((uintptr_t)tib, 0); } else if (IsOpenbsd()) { - sys_set_tls(tib); + sys_set_tls((uintptr_t)tib, 0); } else if (IsXnu()) { // thread_fast_set_cthread_self has a weird ABI - sys_set_tls((intptr_t)tib - 0x30); + sys_set_tls((intptr_t)tib - 0x30, 0); } else { uint64_t val = (uint64_t)tib; asm volatile("wrmsr" diff --git a/libc/runtime/syslib.internal.h b/libc/runtime/syslib.internal.h index 01e129464..ec6d87fe5 100644 --- a/libc/runtime/syslib.internal.h +++ b/libc/runtime/syslib.internal.h @@ -10,8 +10,14 @@ COSMOPOLITAN_C_START_ * `-errno` convention, and hence should be wrapped with `_sysret()`. */ -#define SYSLIB_MAGIC ('s' | 'l' << 8 | 'i' << 16 | 'b' << 24) -#define SYSLIB_VERSION 8 +#define SYSLIB_MAGIC ('s' | 'l' << 8 | 'i' << 16 | 'b' << 24) + +#define SYSLIB_VERSION 9 /* sync with ape/ape-m1.c */ + +/* if this number increases, then everyone on macos arm will need to + reinstall ape loader in order to run newer ape binaries so please + don't do this if it's sufficient to just check __syslib->version. */ +#define SYSLIB_VERSION_MANDATORY 8 typedef uint64_t dispatch_time_t; typedef uint64_t dispatch_semaphore_t; @@ -69,11 +75,13 @@ struct Syslib { long (*__sem_trywait)(int *); long (*__getrlimit)(int, void *); long (*__setrlimit)(int, const void *); - // v6 (2023-11-03) + /* v6 (2023-11-03) */ void *(*__dlopen)(const char *, int); void *(*__dlsym)(void *, const char *); int (*__dlclose)(void *); char *(*__dlerror)(void); + /* v9 (2024-01-31) */ + int (*__pthread_cpu_number_np)(size_t *); }; extern struct Syslib *__syslib; diff --git a/libc/runtime/winargs.internal.h b/libc/runtime/winargs.internal.h index c123cd613..ccf0fc74d 100644 --- a/libc/runtime/winargs.internal.h +++ b/libc/runtime/winargs.internal.h @@ -4,12 +4,17 @@ COSMOPOLITAN_C_START_ struct WinArgs { - char *argv[8192]; - char *envp[512]; - intptr_t auxv[2][2]; - char argv0buf[256]; - char argblock[32767]; - char envblock[32767]; + union { + struct { + char *argv[8192]; + char *envp[512]; + intptr_t auxv[2][2]; + char argv0buf[256]; + char argblock[32767]; + char envblock[32767]; + }; + char16_t tmp16[257]; + }; } forcealign(16); COSMOPOLITAN_C_END_ diff --git a/libc/runtime/winmain.greg.c b/libc/runtime/winmain.greg.c index 118f7fbdf..3c0ae49ed 100644 --- a/libc/runtime/winmain.greg.c +++ b/libc/runtime/winmain.greg.c @@ -24,6 +24,7 @@ #include "libc/limits.h" #include "libc/macros.internal.h" #include "libc/nexgen32e/rdtsc.h" +#include "libc/nt/accounting.h" #include "libc/nt/console.h" #include "libc/nt/enum/consolemodeflags.h" #include "libc/nt/enum/filemapflags.h" @@ -59,6 +60,7 @@ __msabi extern typeof(GetEnvironmentStrings) *const __imp_GetEnvironmentStringsW __msabi extern typeof(GetEnvironmentVariable) *const __imp_GetEnvironmentVariableW; __msabi extern typeof(GetFileAttributes) *const __imp_GetFileAttributesW; __msabi extern typeof(GetStdHandle) *const __imp_GetStdHandle; +__msabi extern typeof(GetUserName) *const __imp_GetUserNameW; __msabi extern typeof(MapViewOfFileEx) *const __imp_MapViewOfFileEx; __msabi extern typeof(SetConsoleCP) *const __imp_SetConsoleCP; __msabi extern typeof(SetConsoleMode) *const __imp_SetConsoleMode; @@ -142,6 +144,11 @@ static abi void DeduplicateStdioHandles(void) { } } +static bool32 HasEnvironmentVariable(const char16_t *name) { + char16_t buf[4]; + return __imp_GetEnvironmentVariableW(name, buf, ARRAYLEN(buf)); +} + // main function of windows init process // i.e. first process spawned that isn't forked static abi wontreturn void WinInit(const char16_t *cmdline) { @@ -168,12 +175,6 @@ static abi wontreturn void WinInit(const char16_t *cmdline) { } } - // avoid programs like emacs nagging the user to define this - char16_t var[8]; - if (!__imp_GetEnvironmentVariableW(u"TERM", var, 8)) { - __imp_SetEnvironmentVariableW(u"TERM", u"xterm-256color"); - } - // allocate memory for stack and argument block _mmi.p = _mmi.s; _mmi.n = ARRAYLEN(_mmi.s); @@ -200,6 +201,34 @@ static abi wontreturn void WinInit(const char16_t *cmdline) { struct WinArgs *wa = (struct WinArgs *)(stackaddr + (stacksize - sizeof(struct WinArgs))); + // define $TERM if it's not already present + // programs like emacs will stop the world and nag if it's not set + if (!HasEnvironmentVariable(u"TERM")) { + __imp_SetEnvironmentVariableW(u"TERM", u"xterm-256color"); + } + + // define $USER as GetUserName() if not set + // Windows doesn't define this environment variable by default + uint32_t vsize = ARRAYLEN(wa->tmp16); + if (!HasEnvironmentVariable(u"USER") && + __imp_GetUserNameW(&wa->tmp16, &vsize)) { + __imp_SetEnvironmentVariableW(u"USER", wa->tmp16); + } + + // define $HOME as $HOMEDRIVE$HOMEPATH if not set + // Windows doesn't define this environment variable by default + uint32_t vlen; + if (!HasEnvironmentVariable(u"HOME") && + (vlen = __imp_GetEnvironmentVariableW(u"HOMEDRIVE", wa->tmp16, + ARRAYLEN(wa->tmp16))) < + ARRAYLEN(wa->tmp16) && + (vlen += __imp_GetEnvironmentVariableW(u"HOMEPATH", wa->tmp16 + vlen, + ARRAYLEN(wa->tmp16) - vlen)) < + ARRAYLEN(wa->tmp16) && + vlen) { + __imp_SetEnvironmentVariableW(u"HOME", wa->tmp16); + } + // parse utf-16 command into utf-8 argv array in argument block int count = GetDosArgv(cmdline, wa->argblock, ARRAYLEN(wa->argblock), wa->argv, ARRAYLEN(wa->argv)); diff --git a/libc/stdbool.h b/libc/stdbool.h index 37173c92c..6e5002ee1 100644 --- a/libc/stdbool.h +++ b/libc/stdbool.h @@ -2,15 +2,22 @@ #define COSMOPOLITAN_LIBC_STDBOOL_H_ #ifndef __cplusplus -#if __STDC_VERSION__ + 0 >= 201112 + #define bool _Bool +#if defined(__STDC_VERSION__) && __STDC_VERSION__ > 201710L +#define true ((_Bool) + 1u) +#define false ((_Bool) + 0u) #else -#define bool unsigned char -#endif -#define true 1 +#define true 1 #define false 0 +#endif + +#else /* __cplusplus */ + +#define _Bool bool + #endif /* __cplusplus */ -#define __bool_true_false_are_defined +#define __bool_true_false_are_defined 1 #endif /* COSMOPOLITAN_LIBC_STDBOOL_H_ */ diff --git a/libc/stdio/fmt.c b/libc/stdio/fmt.c index f35116953..12de10d52 100644 --- a/libc/stdio/fmt.c +++ b/libc/stdio/fmt.c @@ -43,7 +43,6 @@ #include "libc/fmt/conv.h" #include "libc/fmt/divmod10.internal.h" #include "libc/fmt/itoa.h" -#include "libc/serialize.h" #include "libc/intrin/bsr.h" #include "libc/intrin/nomultics.internal.h" #include "libc/intrin/safemacros.internal.h" @@ -53,6 +52,7 @@ #include "libc/mem/mem.h" #include "libc/mem/reverse.internal.h" #include "libc/runtime/internal.h" +#include "libc/serialize.h" #include "libc/str/str.h" #include "libc/str/strwidth.h" #include "libc/str/tab.internal.h" @@ -800,7 +800,7 @@ int __fmt(void *fn, void *arg, const char *format, va_list va) { x = 0; lasterr = errno; - out = fn ? fn : __fmt_noop; + out = fn ? fn : (void *)__fmt_noop; while (*format) { if (*format != '%') { diff --git a/libc/stdio/ftw.c b/libc/stdio/ftw.c index 9be3bb03e..9440b75f8 100644 --- a/libc/stdio/ftw.c +++ b/libc/stdio/ftw.c @@ -50,5 +50,5 @@ int ftw(const char *dirpath, /* The following cast assumes that calling a function with one * argument more than it needs behaves as expected. This is * actually undefined, but works on all real-world machines. */ - return nftw(dirpath, (int (*)())fn, fd_limit, FTW_PHYS); + return nftw(dirpath, (void *)fn, fd_limit, FTW_PHYS); } diff --git a/libc/stdio/printargs.c b/libc/stdio/printargs.c index fa38e6ebf..eb7dbac63 100644 --- a/libc/stdio/printargs.c +++ b/libc/stdio/printargs.c @@ -84,6 +84,7 @@ static const char *FindNameById(const struct IdName *names, unsigned long id) { } static void PrintDependencies(const char *prologue) { +#ifdef __x86_64__ struct NtLinkedList *head = &NtGetPeb()->Ldr->InLoadOrderModuleList; struct NtLinkedList *ldr = head->Next; do { @@ -92,6 +93,7 @@ static void PrintDependencies(const char *prologue) { PRINT(" ☼ %.*!hs (%'zukb @ %p)", dll->FullDllName.Length, dll->FullDllName.Data, dll->SizeOfImage / 1024, dll->DllBase); } while ((ldr = ldr->Next) && ldr != head); +#endif } static void Print(const char *prologue) { @@ -624,6 +626,7 @@ textstartup void __printargs(const char *prologue) { if (GetConsoleMode(GetStdHandle(kNtStdErrorHandle), &cm)) PRINT(" %s", DescribeNtConsoleOutFlags(cm)); +#ifdef __x86_64__ PRINT(""); PRINT("TEB"); PRINT(" ☼ gs:0x%02x %s = %p", 0x00, "NtGetSeh()", _NtGetSeh()); @@ -640,6 +643,7 @@ textstartup void __printargs(const char *prologue) { PRINT(" ☼ gs:0x%02x %s = %p", 0x58, "NtGetTls()", _NtGetTls()); PRINT(" ☼ gs:0x%02x %s = %p", 0x60, "NtGetPeb()", NtGetPeb()); PRINT(" ☼ gs:0x%02x %s = %p", 0x68, "NtGetErr()", NtGetErr()); +#endif PRINT(""); PRINT("DEPENDENCIES"); diff --git a/libc/stdio/rdseed.c b/libc/stdio/rdseed.c index 2b88bb22f..4cde60469 100644 --- a/libc/stdio/rdseed.c +++ b/libc/stdio/rdseed.c @@ -27,7 +27,7 @@ * * If RDSEED isn't available, we'll try RDRAND (which we automatically * disable for microarchitectures where it's known to be slow or buggy). - * If RDRAND isn't available then we try getrandom(), RtlGenRandom(), or + * If RDRAND isn't available then we try getrandom(), ProcessPrng(), or * sysctl(KERN_ARND). If those aren't available then we try /dev/urandom * and if that fails, we use RDTSC and getpid(). * diff --git a/libc/stdio/rngset.c b/libc/stdio/rngset.c index 0c0823172..881eb9fa1 100644 --- a/libc/stdio/rngset.c +++ b/libc/stdio/rngset.c @@ -45,9 +45,6 @@ dontasan void *rngset(void *b, size_t n, uint64_t seed(void), size_t reseed) { size_t m; uint64_t x, t = 0; unsigned char *p = b; - if (IsAsan()) { - __asan_verify(b, n); - } if (!seed) { t = reseed; reseed = -1; diff --git a/libc/stdio/stdio.h b/libc/stdio/stdio.h index e8ec9473e..021aa7c3a 100644 --- a/libc/stdio/stdio.h +++ b/libc/stdio/stdio.h @@ -90,7 +90,7 @@ int fsetpos(FILE *, const fpos_t *) libcesque paramsnonnull(); FILE *tmpfile(void) libcesque __wur; char *tmpnam(char *) libcesque __wur; char *tmpnam_r(char *) libcesque __wur; -int system(const char *) libcesque; + FILE *popen(const char *, const char *) libcesque; /*───────────────────────────────────────────────────────────────────────────│─╗ diff --git a/libc/stdio/tmpnam.c b/libc/stdio/tmpnam.c index b15d42895..b0ab75b92 100644 --- a/libc/stdio/tmpnam.c +++ b/libc/stdio/tmpnam.c @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/dce.h" -#include "libc/intrin/asan.internal.h" #include "libc/stdio/rand.h" #include "libc/stdio/stdio.h" #include "libc/str/str.h" @@ -35,7 +34,6 @@ static char g_tmpnam[L_tmpnam]; * is only mutated on success */ char *tmpnam(char *buf) { - if (IsAsan()) __asan_verify(buf, L_tmpnam); char path[] = P_tmpdir "/tmpnam_XXXXXX"; for (int t = 0; t < 100; ++t) { int w = _rand64(); diff --git a/libc/str/BUILD.mk b/libc/str/BUILD.mk index 8a86f287a..1600b2f3a 100644 --- a/libc/str/BUILD.mk +++ b/libc/str/BUILD.mk @@ -88,7 +88,7 @@ o/$(MODE)/libc/str/windowstimetotimespec.o: private \ -O2 $(LIBC_STR_A_OBJS): private \ - COPTS += \ + CFLAGS += \ -fno-sanitize=all \ -Wframe-larger-than=4096 \ -Walloca-larger-than=4096 diff --git a/libc/str/djbsort.c b/libc/str/djbsort.c index abfc8f3a9..18299e517 100644 --- a/libc/str/djbsort.c +++ b/libc/str/djbsort.c @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/dce.h" -#include "libc/intrin/asan.internal.h" #include "libc/nexgen32e/x86feature.h" #include "libc/runtime/runtime.h" #include "libc/stdckdint.h" @@ -28,11 +27,6 @@ void djbsort_avx2(int32_t *, long); * D.J. Bernstein's outrageously fast integer sorting algorithm. */ void djbsort(int32_t *a, size_t n) { - size_t m; - if (IsAsan()) { - if (ckd_mul(&m, n, 4)) m = -1; - __asan_verify(a, m); - } if (n > 1) { #if defined(__x86_64__) && !defined(__chibicc__) if (X86_HAVE(AVX2)) { diff --git a/libc/str/isutf8.c b/libc/str/isutf8.c index ed0fb918e..ddca5e330 100644 --- a/libc/str/isutf8.c +++ b/libc/str/isutf8.c @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/dce.h" -#include "libc/intrin/asan.internal.h" #include "libc/intrin/likely.h" #include "libc/str/str.h" @@ -53,7 +52,6 @@ bool32 isutf8(const void *data, size_t size) { long c; const char *p, *e; if (size == -1) size = data ? strlen(data) : 0; - if (IsAsan()) __asan_verify(data, size); p = data; e = p + size; while (p < e) { diff --git a/libc/str/memmem.c b/libc/str/memmem.c index c9e43c8f0..51975a3ef 100644 --- a/libc/str/memmem.c +++ b/libc/str/memmem.c @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/dce.h" -#include "libc/intrin/asan.internal.h" #include "libc/intrin/likely.h" #include "libc/str/str.h" @@ -32,16 +31,14 @@ typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(16))); * @param needlelen is its character count * @return pointer to first result or NULL if not found */ -void *memmem(const void *haystack, size_t haystacklen, - const void *needle, size_t needlelen) { +__vex void *memmem(const void *haystack, size_t haystacklen, const void *needle, + size_t needlelen) { #if defined(__x86_64__) && !defined(__chibicc__) char c; xmm_t n; const xmm_t *v; unsigned i, k, m; const char *p, *q, *e; - if (IsAsan()) __asan_verify(needle, needlelen); - if (IsAsan()) __asan_verify(haystack, haystacklen); if (!needlelen) return (void *)haystack; if (UNLIKELY(needlelen > haystacklen)) return 0; q = needle; diff --git a/libc/str/memrchr16.c b/libc/str/memrchr16.c index 517f4a9a0..15c61ba46 100644 --- a/libc/str/memrchr16.c +++ b/libc/str/memrchr16.c @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/dce.h" -#include "libc/intrin/asan.internal.h" #include "libc/limits.h" #include "libc/nexgen32e/x86feature.h" #include "libc/str/str.h" @@ -36,8 +35,8 @@ static inline const char16_t *memrchr16_pure(const char16_t *s, char16_t c, } #if defined(__x86_64__) && !defined(__chibicc__) -static inline const char16_t *memrchr16_sse(const char16_t *s, - char16_t c, size_t n) { +static inline const char16_t *memrchr16_sse(const char16_t *s, char16_t c, + size_t n) { size_t i; unsigned m; xmm_t v, t = {c, c, c, c, c, c, c, c}; @@ -67,11 +66,10 @@ static inline const char16_t *memrchr16_sse(const char16_t *s, * @return is pointer to first instance of c or NULL if not found * @asyncsignalsafe */ -void *memrchr16(const void *s, int c, size_t n) { +__vex void *memrchr16(const void *s, int c, size_t n) { #if defined(__x86_64__) && !defined(__chibicc__) const void *r; if (!IsTiny() && X86_HAVE(SSE)) { - if (IsAsan()) __asan_verify(s, n * 2); r = memrchr16_sse(s, c, n); } else { r = memrchr16_pure(s, c, n); diff --git a/libc/str/rawmemchr.c b/libc/str/rawmemchr.c index a6f089f6b..d3b4a5523 100644 --- a/libc/str/rawmemchr.c +++ b/libc/str/rawmemchr.c @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" #include "libc/dce.h" -#include "libc/intrin/asan.internal.h" #include "libc/nexgen32e/x86feature.h" #include "libc/str/str.h" @@ -33,8 +32,7 @@ static inline const unsigned char *rawmemchr_pure(const unsigned char *s, #if defined(__x86_64__) && !defined(__chibicc__) typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(16))); -static inline const char *rawmemchr_sse(const char *s, - unsigned char c) { +static inline const char *rawmemchr_sse(const char *s, unsigned char c) { unsigned k; unsigned m; const xmm_t *p; @@ -67,11 +65,10 @@ static inline uint64_t UncheckedAlignedRead64(const unsigned char *p) { * @param c is search byte which is masked with 255 * @return is pointer to first instance of c */ -void *rawmemchr(const void *s, int c) { +__vex void *rawmemchr(const void *s, int c) { #if defined(__x86_64__) && !defined(__chibicc__) const void *r; if (X86_HAVE(SSE)) { - if (IsAsan()) __asan_verify(s, 1); r = rawmemchr_sse(s, c); } else { r = rawmemchr_pure(s, c); diff --git a/libc/str/str.h b/libc/str/str.h index 18a91bd20..fdc97b244 100644 --- a/libc/str/str.h +++ b/libc/str/str.h @@ -167,7 +167,7 @@ wint_t towctrans(wint_t, wctrans_t) libcesque; int getsubopt(char **, char *const *, char **) libcesque paramsnonnull(); char *strsignal(int) returnsnonnull libcesque; -char *strerror(int) returnsnonnull dontthrow nocallback; +char *strerror(int) returnsnonnull dontthrow dontcallback; errno_t strerror_r(int, char *, size_t) libcesque; char *__xpg_strerror_r(int, char *, size_t) libcesque; diff --git a/libc/str/strcasecmp.c b/libc/str/strcasecmp.c index acc9d5a7a..edeb633fc 100644 --- a/libc/str/strcasecmp.c +++ b/libc/str/strcasecmp.c @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/dce.h" -#include "libc/intrin/asan.internal.h" #include "libc/str/str.h" #include "libc/str/tab.internal.h" @@ -34,8 +33,6 @@ int strcasecmp(const char *a, const char *b) { size_t i = 0; uint64_t v, w; if (a == b) return 0; - if (IsAsan()) __asan_verify_str(a); - if (IsAsan()) __asan_verify_str(b); if (((uintptr_t)a & 7) == ((uintptr_t)b & 7)) { for (; (uintptr_t)(a + i) & 7; ++i) { CheckEm: diff --git a/libc/str/strcasestr.c b/libc/str/strcasestr.c index 51bdcf138..cf46cb3f1 100644 --- a/libc/str/strcasestr.c +++ b/libc/str/strcasestr.c @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/str/str.h" #include "libc/dce.h" -#include "libc/intrin/asan.internal.h" #include "libc/str/tab.internal.h" typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(16))); @@ -35,15 +34,13 @@ typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(16))); * @asyncsignalsafe * @see strstr() */ -char *strcasestr(const char *haystack, const char *needle) { +__vex char *strcasestr(const char *haystack, const char *needle) { #if defined(__x86_64__) && !defined(__chibicc__) char c; size_t i; unsigned k, m; const xmm_t *p; xmm_t v, n1, n2, z = {0}; - if (IsAsan()) __asan_verify(needle, 1); - if (IsAsan()) __asan_verify(haystack, 1); if (haystack == needle || !*needle) return (char *)haystack; c = *needle; n1 = (xmm_t){c, c, c, c, c, c, c, c, c, c, c, c, c, c, c, c}; diff --git a/libc/str/strlen16.c b/libc/str/strlen16.c index 823d91d4d..cb9fe11c8 100644 --- a/libc/str/strlen16.c +++ b/libc/str/strlen16.c @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/dce.h" -#include "libc/intrin/asan.internal.h" #include "libc/str/str.h" typedef char16_t xmm_t __attribute__((__vector_size__(16), __aligned__(16))); @@ -29,17 +28,15 @@ typedef char16_t xmm_t __attribute__((__vector_size__(16), __aligned__(16))); * @return number of shorts (excluding NUL) * @asyncsignalsafe */ -size_t strlen16(const char16_t *s) { +__vex size_t strlen16(const char16_t *s) { #if defined(__x86_64__) && !defined(__chibicc__) size_t n; xmm_t z = {0}; unsigned m, k = (uintptr_t)s & 15; const xmm_t *p = (const xmm_t *)((uintptr_t)s & -16); - if (IsAsan()) __asan_verify(s, 2); m = __builtin_ia32_pmovmskb128(*p == z) >> k << k; while (!m) m = __builtin_ia32_pmovmskb128(*++p == z); n = (const char16_t *)p + (__builtin_ctzl(m) >> 1) - s; - if (IsAsan()) __asan_verify(s, n * 2); return n; #else size_t n = 0; diff --git a/libc/str/strnlen_s.c b/libc/str/strnlen_s.c index 26595cd4a..c95d88b41 100644 --- a/libc/str/strnlen_s.c +++ b/libc/str/strnlen_s.c @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/assert.h" #include "libc/dce.h" -#include "libc/intrin/asan.internal.h" #include "libc/str/str.h" static size_t strnlen_s_x64(const char *s, size_t n, size_t i) { @@ -48,7 +47,6 @@ static size_t strnlen_s_x64(const char *s, size_t n, size_t i) { size_t strnlen_s(const char *s, size_t n) { size_t i; if (!s) return 0; - if (IsAsan()) __asan_verify(s, n); for (i = 0; (uintptr_t)(s + i) & 7; ++i) { if (i == n || !s[i]) return i; } diff --git a/libc/str/strstr.c b/libc/str/strstr.c index 8cc041d02..b428851b0 100644 --- a/libc/str/strstr.c +++ b/libc/str/strstr.c @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/str/str.h" #include "libc/dce.h" -#include "libc/intrin/asan.internal.h" typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(16))); @@ -35,14 +34,12 @@ typedef char xmm_t __attribute__((__vector_size__(16), __aligned__(16))); * @see strcasestr() * @see memmem() */ -char *strstr(const char *haystack, const char *needle) { +__vex char *strstr(const char *haystack, const char *needle) { #if defined(__x86_64__) && !defined(__chibicc__) size_t i; unsigned k, m; const xmm_t *p; xmm_t v, n, z = {0}; - if (IsAsan()) __asan_verify(needle, 1); - if (IsAsan()) __asan_verify(haystack, 1); if (haystack == needle || !*needle) return (char *)haystack; n = (xmm_t){*needle, *needle, *needle, *needle, *needle, *needle, *needle, *needle, *needle, *needle, *needle, *needle, diff --git a/libc/str/wcslen.c b/libc/str/wcslen.c index 8cbd6ba35..9dbbfcbee 100644 --- a/libc/str/wcslen.c +++ b/libc/str/wcslen.c @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/dce.h" -#include "libc/intrin/asan.internal.h" #include "libc/str/str.h" typedef wchar_t xmm_t __attribute__((__vector_size__(16), __aligned__(16))); @@ -29,17 +28,15 @@ typedef wchar_t xmm_t __attribute__((__vector_size__(16), __aligned__(16))); * @return number of wide characters (excluding NUL) * @asyncsignalsafe */ -size_t wcslen(const wchar_t *s) { +__vex size_t wcslen(const wchar_t *s) { #if defined(__x86_64__) && !defined(__chibicc__) size_t n; xmm_t z = {0}; unsigned m, k = (uintptr_t)s & 15; const xmm_t *p = (const xmm_t *)((uintptr_t)s & -16); - if (IsAsan()) __asan_verify(s, 4); m = __builtin_ia32_pmovmskb128(*p == z) >> k << k; while (!m) m = __builtin_ia32_pmovmskb128(*++p == z); n = (const wchar_t *)p + (__builtin_ctzl(m) >> 2) - s; - if (IsAsan()) __asan_verify(s, n); return n; #else size_t n = 0; diff --git a/libc/str/wmemrchr.c b/libc/str/wmemrchr.c index 848e75ee5..acd2413a6 100644 --- a/libc/str/wmemrchr.c +++ b/libc/str/wmemrchr.c @@ -17,7 +17,6 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/dce.h" -#include "libc/intrin/asan.internal.h" #include "libc/limits.h" #include "libc/nexgen32e/x86feature.h" #include "libc/stdckdint.h" @@ -38,7 +37,7 @@ static inline const wchar_t *wmemrchr_pure(const wchar_t *s, wchar_t c, #if defined(__x86_64__) && !defined(__chibicc__) static inline const wchar_t *wmemrchr_sse(const wchar_t *s, wchar_t c, - size_t n) { + size_t n) { size_t i; unsigned m; xmm_t v, t = {c, c, c, c}; @@ -68,16 +67,9 @@ static inline const wchar_t *wmemrchr_sse(const wchar_t *s, wchar_t c, * @return is pointer to first instance of c or NULL if not found * @asyncsignalsafe */ -void *wmemrchr(const wchar_t *s, wchar_t c, size_t n) { +__vex void *wmemrchr(const wchar_t *s, wchar_t c, size_t n) { #if defined(__x86_64__) && !defined(__chibicc__) - size_t bytes; - const void *r; - if (IsAsan()) { - if (ckd_mul(&bytes, n, sizeof(wchar_t))) bytes = -1; - __asan_verify(s, bytes); - } - r = wmemrchr_sse(s, c, n); - return (void *)r; + return (void *)wmemrchr_sse(s, c, n); #else return (void *)wmemrchr_pure(s, c, n); #endif diff --git a/libc/sysv/consts.sh b/libc/sysv/consts.sh index 2a7a5cf22..1242f1e4a 100755 --- a/libc/sysv/consts.sh +++ b/libc/sysv/consts.sh @@ -234,7 +234,9 @@ syscon mmap MAP_INHERIT -1 -1 -1 -1 -1 -1 0x00000080 -1 # make syscon mmap MAP_HASSEMAPHORE 0 0 0x00000200 0x00000200 0x00000200 0 0x00000200 0 # does it matter on x86? syscon mmap MAP_NOSYNC 0 0 0 0 0x00000800 0 0 0 # flush to physical media only when necessary rather than gratuitously; be sure to use write() rather than ftruncate() with this! syscon mmap MAP_CONCEAL 0 0 0 0 0x00020000 0x00008000 0x00008000 0 # omit from core dumps; MAP_NOCORE on FreeBSD -syscon mmap MAP_JIT 0 0 0 0x00000800 0 0 0 0 # omit from core dumps; MAP_NOCORE on FreeBSD +syscon mmap MAP_JIT 0 0 0 0x00000800 0 0 0 0 # allocate region used for just-in-time compilation +syscon mmap MAP_NOCACHE 0 0 0x00000400 0x00000400 0 0 0 0 # don't cache pages for this mapping +syscon mmap MAP_NOEXTEND 0 0 0x00000100 0x00000100 0 0 0 0 # for MAP_FILE, don't change file size syscon compat MAP_NOCORE 0 0 0 0 0x00020000 0x00008000 0x00008000 0 # use MAP_CONCEAL syscon compat MAP_ANON 0x00000020 0x00000020 0x00001000 0x00001000 0x00001000 0x00001000 0x00001000 0x00000020 # bsd consensus; faked nt syscon compat MAP_EXECUTABLE 0x00001000 0x00001000 0 0 0 0 0 0 # ignored @@ -269,17 +271,18 @@ syscon madv MADV_WIPEONFORK 18 18 127 127 127 127 127 127 # T syscon madv MADV_KEEPONFORK 19 19 127 127 127 127 127 127 # TODO: add support ? syscon madv MADV_COLD 20 20 127 127 127 127 127 127 # TODO: add support ? syscon madv MADV_PAGEOUT 21 21 127 127 127 127 127 127 # TODO: add support ? -syscon madv MADV_POPULATE_READ 22 22 127 127 127 127 127 127 # TODO: add support ? -syscon madv MADV_POPULATE_WRITE 23 23 127 127 127 127 127 127 # TODO: add support ? -syscon madv MADV_DONTNEED_LOCKED 24 24 127 127 127 127 127 127 # TODO: add support ? +syscon madv MADV_POPULATE_READ 22 22 127 127 127 127 127 127 # TODO: add support ? +syscon madv MADV_POPULATE_WRITE 23 23 127 127 127 127 127 127 # TODO: add support ? +syscon madv MADV_DONTNEED_LOCKED 24 24 127 127 127 127 127 127 # TODO: add support ? syscon madv MADV_COLLAPSE 25 25 127 127 127 127 127 127 # TODO: add support ? syscon madv MADV_DOFORK 11 11 127 127 127 127 127 127 # TODO(jart): what is it? syscon madv MADV_DONTDUMP 16 16 127 127 127 127 127 127 # see MAP_CONCEAL in OpenBSD; TODO(jart): what is it? syscon madv MADV_DONTFORK 10 10 127 127 127 127 127 127 # TODO(jart): what is it? syscon madv MADV_HWPOISON 100 100 127 127 127 127 127 127 # TODO(jart): what is it? -syscon madv MADV_SOFT_OFFLINE 101 101 127 127 127 127 127 127 # TODO: add support ? +syscon madv MADV_SOFT_OFFLINE 101 101 127 127 127 127 127 127 # TODO: add support ? syscon madv MADV_REMOVE 9 9 127 127 127 127 127 127 # TODO(jart): what is it? syscon fadv POSIX_FADV_NOREUSE 5 5 127 127 5 127 5 127 # wut +syscon madv MADV_REMOVE 9 9 127 127 127 127 127 127 # TODO(jart): what is it? # mmap(), mprotect(), etc. # digital restrictions management for the people @@ -579,19 +582,19 @@ syscon clock CLOCK_REALTIME 0 0 0 0 0 0 0 0 # consensus syscon clock CLOCK_REALTIME_PRECISE 0 0 0 0 9 0 0 0 # syscon clock CLOCK_REALTIME_FAST 0 0 0 0 10 0 0 0 # syscon clock CLOCK_REALTIME_COARSE 5 5 0 0 10 0 0 2 # Linux 2.6.32+; bsd consensus; not available on RHEL5 -syscon clock CLOCK_MONOTONIC 1 1 1 6 4 3 3 1 # XNU/NT faked; could move backwards if NTP introduces negative leap second -syscon clock CLOCK_MONOTONIC_PRECISE 1 1 1 6 11 3 3 1 # -syscon clock CLOCK_MONOTONIC_FAST 1 1 1 6 12 3 3 1 # -syscon clock CLOCK_MONOTONIC_COARSE 6 6 1 6 12 3 3 1 # Linux 2.6.32+; bsd consensus; not available on RHEL5 -syscon clock CLOCK_MONOTONIC_RAW 4 4 127 4 127 127 127 127 # actually monotonic; not subject to NTP adjustments; Linux 2.6.28+; XNU/NT/FreeBSD/OpenBSD faked; not available on RHEL5 -syscon clock CLOCK_PROCESS_CPUTIME_ID 2 2 127 12 15 2 0x40000000 127 # NetBSD lets you bitwise a PID into clockid_t -syscon clock CLOCK_THREAD_CPUTIME_ID 3 3 127 16 14 4 0x20000000 127 # +syscon clock CLOCK_MONOTONIC 1 1 6 6 4 3 3 1 # XNU/NT faked; could move backwards if NTP introduces negative leap second +syscon clock CLOCK_MONOTONIC_PRECISE 1 1 6 6 11 3 3 1 # +syscon clock CLOCK_MONOTONIC_FAST 1 1 6 6 12 3 3 1 # +syscon clock CLOCK_MONOTONIC_COARSE 6 6 5 5 12 3 3 1 # Linux 2.6.32+; bsd consensus; not available on RHEL5 +syscon clock CLOCK_MONOTONIC_RAW 4 4 4 4 127 127 127 127 # actually monotonic; not subject to NTP adjustments; Linux 2.6.28+; XNU/NT/FreeBSD/OpenBSD faked; not available on RHEL5 +syscon clock CLOCK_PROCESS_CPUTIME_ID 2 2 12 12 15 2 0x40000000 4 # NetBSD lets you bitwise a PID into clockid_t +syscon clock CLOCK_THREAD_CPUTIME_ID 3 3 16 16 14 4 0x20000000 5 # syscon clock CLOCK_PROF 127 127 127 127 2 127 2 127 # syscon clock CLOCK_BOOTTIME 7 7 7 127 127 6 127 3 # syscon clock CLOCK_REALTIME_ALARM 8 8 127 127 127 127 127 127 # syscon clock CLOCK_BOOTTIME_ALARM 9 9 127 127 127 127 127 127 # syscon clock CLOCK_TAI 11 11 127 127 127 127 127 127 # -syscon clock CLOCK_UPTIME 127 127 127 127 5 5 127 127 # +syscon clock CLOCK_UPTIME 127 127 8 8 5 5 127 127 # syscon clock CLOCK_UPTIME_PRECISE 127 127 127 127 7 127 127 127 # syscon clock CLOCK_UPTIME_FAST 127 127 127 127 8 127 127 127 # syscon clock CLOCK_SECOND 127 127 127 127 13 127 127 127 # diff --git a/libc/sysv/consts/CLOCK_MONOTONIC.S b/libc/sysv/consts/CLOCK_MONOTONIC.S index d4cf1ff24..2275c6cf1 100644 --- a/libc/sysv/consts/CLOCK_MONOTONIC.S +++ b/libc/sysv/consts/CLOCK_MONOTONIC.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon clock,CLOCK_MONOTONIC,1,1,1,6,4,3,3,1 +.syscon clock,CLOCK_MONOTONIC,1,1,6,6,4,3,3,1 diff --git a/libc/sysv/consts/CLOCK_MONOTONIC_COARSE.S b/libc/sysv/consts/CLOCK_MONOTONIC_COARSE.S index 27762d022..225972c1d 100644 --- a/libc/sysv/consts/CLOCK_MONOTONIC_COARSE.S +++ b/libc/sysv/consts/CLOCK_MONOTONIC_COARSE.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon clock,CLOCK_MONOTONIC_COARSE,6,6,1,6,12,3,3,1 +.syscon clock,CLOCK_MONOTONIC_COARSE,6,6,5,5,12,3,3,1 diff --git a/libc/sysv/consts/CLOCK_MONOTONIC_FAST.S b/libc/sysv/consts/CLOCK_MONOTONIC_FAST.S index 80bb43b66..0069c82cf 100644 --- a/libc/sysv/consts/CLOCK_MONOTONIC_FAST.S +++ b/libc/sysv/consts/CLOCK_MONOTONIC_FAST.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon clock,CLOCK_MONOTONIC_FAST,1,1,1,6,12,3,3,1 +.syscon clock,CLOCK_MONOTONIC_FAST,1,1,6,6,12,3,3,1 diff --git a/libc/sysv/consts/CLOCK_MONOTONIC_PRECISE.S b/libc/sysv/consts/CLOCK_MONOTONIC_PRECISE.S index fdea24d20..e9e77f345 100644 --- a/libc/sysv/consts/CLOCK_MONOTONIC_PRECISE.S +++ b/libc/sysv/consts/CLOCK_MONOTONIC_PRECISE.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon clock,CLOCK_MONOTONIC_PRECISE,1,1,1,6,11,3,3,1 +.syscon clock,CLOCK_MONOTONIC_PRECISE,1,1,6,6,11,3,3,1 diff --git a/libc/sysv/consts/CLOCK_MONOTONIC_RAW.S b/libc/sysv/consts/CLOCK_MONOTONIC_RAW.S index 5704b2138..1c158565e 100644 --- a/libc/sysv/consts/CLOCK_MONOTONIC_RAW.S +++ b/libc/sysv/consts/CLOCK_MONOTONIC_RAW.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon clock,CLOCK_MONOTONIC_RAW,4,4,127,4,127,127,127,127 +.syscon clock,CLOCK_MONOTONIC_RAW,4,4,4,4,127,127,127,127 diff --git a/libc/sysv/consts/CLOCK_PROCESS_CPUTIME_ID.S b/libc/sysv/consts/CLOCK_PROCESS_CPUTIME_ID.S index 2b8c354db..b4b39f501 100644 --- a/libc/sysv/consts/CLOCK_PROCESS_CPUTIME_ID.S +++ b/libc/sysv/consts/CLOCK_PROCESS_CPUTIME_ID.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon clock,CLOCK_PROCESS_CPUTIME_ID,2,2,127,12,15,2,0x40000000,127 +.syscon clock,CLOCK_PROCESS_CPUTIME_ID,2,2,12,12,15,2,0x40000000,4 diff --git a/libc/sysv/consts/CLOCK_THREAD_CPUTIME_ID.S b/libc/sysv/consts/CLOCK_THREAD_CPUTIME_ID.S index 7d5893688..3f3529ab7 100644 --- a/libc/sysv/consts/CLOCK_THREAD_CPUTIME_ID.S +++ b/libc/sysv/consts/CLOCK_THREAD_CPUTIME_ID.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon clock,CLOCK_THREAD_CPUTIME_ID,3,3,127,16,14,4,0x20000000,127 +.syscon clock,CLOCK_THREAD_CPUTIME_ID,3,3,16,16,14,4,0x20000000,5 diff --git a/libc/sysv/consts/CLOCK_UPTIME.S b/libc/sysv/consts/CLOCK_UPTIME.S index 15a0e414a..281eaa508 100644 --- a/libc/sysv/consts/CLOCK_UPTIME.S +++ b/libc/sysv/consts/CLOCK_UPTIME.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon clock,CLOCK_UPTIME,127,127,127,127,5,5,127,127 +.syscon clock,CLOCK_UPTIME,127,127,8,8,5,5,127,127 diff --git a/libc/sysv/consts/MAP_NOCACHE.S b/libc/sysv/consts/MAP_NOCACHE.S new file mode 100644 index 000000000..23ee0d40c --- /dev/null +++ b/libc/sysv/consts/MAP_NOCACHE.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon mmap,MAP_NOCACHE,0,0,0x00000400,0x00000400,0,0,0,0 diff --git a/libc/sysv/consts/MAP_NOEXTEND.S b/libc/sysv/consts/MAP_NOEXTEND.S new file mode 100644 index 000000000..1d79cf695 --- /dev/null +++ b/libc/sysv/consts/MAP_NOEXTEND.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon mmap,MAP_NOEXTEND,0,0,0x00000100,0x00000100,0,0,0,0 diff --git a/libc/sysv/consts/map.h b/libc/sysv/consts/map.h index 50657c9a8..04008f4cd 100644 --- a/libc/sysv/consts/map.h +++ b/libc/sysv/consts/map.h @@ -16,6 +16,8 @@ extern const int MAP_HASSEMAPHORE; extern const int MAP_INHERIT; extern const int MAP_JIT; extern const int MAP_LOCKED; +extern const int MAP_NOCACHE; +extern const int MAP_NOEXTEND; extern const int MAP_NONBLOCK; extern const int MAP_NORESERVE; extern const int MAP_NOSYNC; @@ -40,6 +42,7 @@ COSMOPOLITAN_C_END_ #define MAP_FIXED_NOREPLACE MAP_FIXED_NOREPLACE #define MAP_HASSEMAPHORE MAP_HASSEMAPHORE #define MAP_POPULATE MAP_POPULATE +#define MAP_NORESERVE MAP_NORESERVE #define MAP_ANON MAP_ANONYMOUS #define MAP_NOCORE MAP_CONCEAL diff --git a/libc/testlib/ezbenchcontrol.c b/libc/testlib/ezbenchcontrol.c index 0763a228f..f64263fe8 100644 --- a/libc/testlib/ezbenchcontrol.c +++ b/libc/testlib/ezbenchcontrol.c @@ -42,7 +42,7 @@ double __testlib_ezbenchcontrol(void) { } while (++Tries < 10 && (__testlib_getcore() != Core && __testlib_getinterrupts() > Interrupts)); if (Tries == 10) { - tinyprint(2, "warning: failed to accurately benchmark control\n"); + tinyprint(2, "warning: failed to accurately benchmark control\n", NULL); } strcpy(host, "unknown"); gethostname(host, 64); diff --git a/libc/testlib/showerror.c b/libc/testlib/showerror.c index 56238317d..713afbb67 100644 --- a/libc/testlib/showerror.c +++ b/libc/testlib/showerror.c @@ -101,7 +101,7 @@ static void testlib_showerror_(int line, // _weaken(kvprintf)(fmt, va); tinyprint(2, "\n", NULL); } else { - tinyprint(2, "\t[missing kvprintf]\n"); + tinyprint(2, "\t[missing kvprintf]\n", NULL); } } tinyprint(2, "\t", SUBTLE, strerror(e), RESET, "\n\t", SUBTLE, diff --git a/libc/testlib/testlib.h b/libc/testlib/testlib.h index e2dedd68f..50a0df919 100644 --- a/libc/testlib/testlib.h +++ b/libc/testlib/testlib.h @@ -167,22 +167,22 @@ void TearDownOnce(void); #define ASSERT_IN(NEEDLE, GOT) \ assertContains(FILIFU sizeof(*(NEEDLE)), NEEDLE, GOT, #GOT, true) -#define ASSERT_BINEQ(WANT, GOT) \ - _Generic((WANT)[0], char \ - : assertBinaryEquals_hex, default \ - : assertBinaryEquals_cp437)(FILIFU WANT, GOT, -1, #GOT, true) -#define ASSERT_BINNE(NOPE, GOT) \ - _Generic((NOPE)[0], char \ - : assertBinaryNotEquals_hex, default \ - : assertBinaryNotEquals_cp437)(FILIFU NOPE, GOT, -1, #GOT, true) -#define ASSERT_BINEQN(WANT, GOT, N) \ - _Generic((WANT)[0], char \ - : assertBinaryEquals_hex, default \ - : assertBinaryEquals_cp437)(FILIFU WANT, GOT, N, #GOT, true) -#define ASSERT_BINNEN(NOPE, GOT, N) \ - _Generic((NOPE)[0], char \ - : assertBinaryNotEquals_hex, default \ - : assertBinaryNotEquals_cp437)(FILIFU NOPE, GOT, -1, #GOT, true) +#define ASSERT_BINEQ(WANT, GOT) \ + _Generic((WANT)[0], \ + char: assertBinaryEquals_hex, \ + default: assertBinaryEquals_cp437)(FILIFU WANT, GOT, -1, #GOT, true) +#define ASSERT_BINNE(NOPE, GOT) \ + _Generic((NOPE)[0], \ + char: assertBinaryNotEquals_hex, \ + default: assertBinaryNotEquals_cp437)(FILIFU NOPE, GOT, -1, #GOT, true) +#define ASSERT_BINEQN(WANT, GOT, N) \ + _Generic((WANT)[0], \ + char: assertBinaryEquals_hex, \ + default: assertBinaryEquals_cp437)(FILIFU WANT, GOT, N, #GOT, true) +#define ASSERT_BINNEN(NOPE, GOT, N) \ + _Generic((NOPE)[0], \ + char: assertBinaryNotEquals_hex, \ + default: assertBinaryNotEquals_cp437)(FILIFU NOPE, GOT, -1, #GOT, true) #define ASSERT_FLOAT_EQ(WANT, GOT) \ assertLongDoubleEquals(FILIFU WANT, GOT, #GOT, true) @@ -243,22 +243,22 @@ void TearDownOnce(void); #define EXPECT_IN(NEEDLE, GOT) \ assertContains(FILIFU sizeof(*(NEEDLE)), NEEDLE, GOT, #GOT, false) -#define EXPECT_BINEQ(WANT, GOT) \ - _Generic((WANT)[0], char \ - : assertBinaryEquals_hex, default \ - : assertBinaryEquals_cp437)(FILIFU WANT, GOT, -1, #GOT, false) -#define EXPECT_BINNE(NOPE, GOT) \ - _Generic((NOPE)[0], char \ - : assertBinaryNotEquals_hex, default \ - : assertBinaryNotEquals_cp437)(FILIFU NOPE, GOT, -1, #GOT, false) -#define EXPECT_BINEQN(WANT, GOT, N) \ - _Generic((WANT)[0], char \ - : assertBinaryEquals_hex, default \ - : assertBinaryEquals_cp437)(FILIFU WANT, GOT, N, #GOT, false) -#define EXPECT_BINNEN(NOPE, GOT, N) \ - _Generic((NOPE)[0], char \ - : assertBinaryNotEquals_hex, default \ - : assertBinaryNotEquals_cp437)(FILIFU NOPE, GOT, -1, #GOT, false) +#define EXPECT_BINEQ(WANT, GOT) \ + _Generic((WANT)[0], \ + char: assertBinaryEquals_hex, \ + default: assertBinaryEquals_cp437)(FILIFU WANT, GOT, -1, #GOT, false) +#define EXPECT_BINNE(NOPE, GOT) \ + _Generic((NOPE)[0], \ + char: assertBinaryNotEquals_hex, \ + default: assertBinaryNotEquals_cp437)(FILIFU NOPE, GOT, -1, #GOT, false) +#define EXPECT_BINEQN(WANT, GOT, N) \ + _Generic((WANT)[0], \ + char: assertBinaryEquals_hex, \ + default: assertBinaryEquals_cp437)(FILIFU WANT, GOT, N, #GOT, false) +#define EXPECT_BINNEN(NOPE, GOT, N) \ + _Generic((NOPE)[0], \ + char: assertBinaryNotEquals_hex, \ + default: assertBinaryNotEquals_cp437)(FILIFU NOPE, GOT, -1, #GOT, false) #define EXPECT_FLOAT_EQ(WANT, GOT) \ assertLongDoubleEquals(FILIFU WANT, GOT, #GOT, false) diff --git a/libc/thread/makecontext.c b/libc/thread/makecontext.c index d3e93a85c..0108979f7 100644 --- a/libc/thread/makecontext.c +++ b/libc/thread/makecontext.c @@ -30,7 +30,8 @@ typedef double vect __attribute__((__vector_size__(16), __aligned__(16))); struct Gadget { - void (*func)(); + void (*func)(long, long, long, long, long, long, // + vect, vect, vect, vect, vect, vect); long longs[6]; vect vects[6]; }; @@ -89,7 +90,7 @@ static void runcontext(struct Gadget *call, ucontext_t *link) { * @param argc is effectively ignored (see notes above) * @see setcontext(), getcontext(), swapcontext() */ -void makecontext(ucontext_t *uc, void func(), int argc, ...) { +void makecontext(ucontext_t *uc, void *func, int argc, ...) { va_list va; long sp, sb; struct Gadget *call; diff --git a/libc/thread/tls.h b/libc/thread/tls.h index a9b689a3f..b5ef8b793 100644 --- a/libc/thread/tls.h +++ b/libc/thread/tls.h @@ -39,7 +39,7 @@ struct CosmoTib { void **tib_keys; void *tib_nsync; void *tib_todo[7]; -}; +} __attribute__((__aligned__(64))); extern int __threaded; extern char __tls_morphed; diff --git a/libc/tinymath/fma.c b/libc/tinymath/fma.c index 2eaf00cb0..72a0ba9a0 100644 --- a/libc/tinymath/fma.c +++ b/libc/tinymath/fma.c @@ -26,6 +26,7 @@ │ │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/math.h" +#include "libc/nexgen32e/x86feature.h" asm(".ident\t\"\\n\\n\ Musl libc (MIT License)\\n\ @@ -92,41 +93,51 @@ static void mul(uint64_t *hi, uint64_t *lo, uint64_t x, uint64_t y) */ double fma(double x, double y, double z) { -#if defined(__x86_64__) && defined(__FMA__) && defined(__FAST_MATH__) +#if defined(__x86_64__) && defined(__FMA__) // Intel Haswell+ (c. 2013) // AMD Piledriver+ (c. 2011) asm("vfmadd132sd\t%1,%2,%0" : "+x"(x) : "x"(y), "x"(z)); return x; -#elif defined(__x86_64__) && defined(__FMA4__) && defined(__FAST_MATH__) +#elif defined(__x86_64__) && defined(__FMA4__) // AMD Bulldozer+ (c. 2011) asm("vfmaddsd\t%3,%2,%1,%0" : "=x"(x) : "x"(x), "x"(y), "x"(z)); return x; -#elif defined(__aarch64__) && defined(__FAST_MATH__) +#elif defined(__aarch64__) asm("fmadd\t%d0,%d1,%d2,%d3" : "=w"(x) : "w"(x), "w"(y), "w"(z)); return x; -#elif defined(__powerpc64__) && defined(__FAST_MATH__) +#elif defined(__powerpc64__) asm("fmadd\t%0,%1,%2,%3" : "=d"(x) : "d"(x), "d"(y), "d"(z)); return x; -#elif defined(__riscv) && __riscv_flen >= 64 && defined(__FAST_MATH__) +#elif defined(__riscv) && __riscv_flen >= 64 asm("fmadd.d\t%0,%1,%2,%3" : "=f"(x) : "f"(x), "f"(y), "f"(z)); return x; -#elif defined(__s390x__) && defined(__FAST_MATH__) +#elif defined(__s390x__) asm("madbr\t%0,\t%1,\t%2" : "+f"(z) : "f"(x), "f"(y)); return z; #else -// #pragma STDC FENV_ACCESS ON +/* #pragma STDC FENV_ACCESS ON */ + +#ifdef __x86_64__ + if (X86_HAVE(FMA)) { + asm("vfmadd132sd\t%1,%2,%0" : "+x"(x) : "x"(y), "x"(z)); + return x; + } else if (X86_HAVE(FMA4)) { + asm("vfmaddsd\t%3,%2,%1,%0" : "=x"(x) : "x"(x), "x"(y), "x"(z)); + return x; + } +#endif /* normalize so top 10bits and last bit are 0 */ struct num nx, ny, nz; @@ -268,3 +279,7 @@ double fma(double x, double y, double z) #endif /* __x86_64__ */ } + +#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024 +__weak_reference(fma, fmal); +#endif diff --git a/libc/tinymath/fmaf.c b/libc/tinymath/fmaf.c index 7d651b650..c65a3d481 100644 --- a/libc/tinymath/fmaf.c +++ b/libc/tinymath/fmaf.c @@ -26,6 +26,7 @@ │ │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/math.h" +#include "libc/nexgen32e/x86feature.h" #include "libc/runtime/fenv.h" asm(".ident\t\"\\n\\n\ @@ -110,7 +111,7 @@ float fmaf(float x, float y, float z) so direct double-precision arithmetic suffices, except where double rounding occurs. */ - /* #pragma STDC FENV_ACCESS ON */ +/* #pragma STDC FENV_ACCESS ON */ double xy, result; union {double f; uint64_t i;} u; int e; diff --git a/libc/tinymath/fmal.c b/libc/tinymath/fmal.c new file mode 100644 index 000000000..cefdca2d6 --- /dev/null +++ b/libc/tinymath/fmal.c @@ -0,0 +1,287 @@ +/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│ +│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │ +╚──────────────────────────────────────────────────────────────────────────────╝ +│ │ +│ Copyright (c) 2004-2005 David Schultz │ +│ All rights reserved. │ +│ │ +│ Redistribution and use in source and binary forms, with or without │ +│ modification, are permitted provided that the following conditions │ +│ are met: │ +│ 1. Redistributions of source code must retain the above copyright │ +│ notice, this list of conditions and the following disclaimer. │ +│ 2. Redistributions in binary form must reproduce the above copyright │ +│ notice, this list of conditions and the following disclaimer in the │ +│ documentation and/or other materials provided with the distribution. │ +│ │ +│ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND │ +│ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE │ +│ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE │ +│ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE │ +│ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL │ +│ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS │ +│ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) │ +│ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT │ +│ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY │ +│ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF │ +│ SUCH DAMAGE. │ +│ │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/math.h" +#include "libc/runtime/fenv.h" +#include "libc/tinymath/freebsd.internal.h" +#include "libc/tinymath/ldshape.internal.h" +#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384 + +asm(".ident\t\"\\n\\n\ +FreeBSD libm (BSD-2 License)\\n\ +Copyright (c) 2005-2011, Bruce D. Evans, Steven G. Kargl, David Schultz.\""); +asm(".include \"libc/disclaimer.inc\""); +// clang-format off + +#if LDBL_MANT_DIG == 64 +#define LASTBIT(u) (u.i.m & 1) +#define SPLIT (0x1p32L + 1) +#elif LDBL_MANT_DIG == 113 +#define LASTBIT(u) (u.i.lo & 1) +#define SPLIT (0x1p57L + 1) +#endif + +/* + * A struct dd represents a floating-point number with twice the precision + * of a long double. We maintain the invariant that "hi" stores the high-order + * bits of the result. + */ +struct dd { + long double hi; + long double lo; +}; + +/* + * Compute a+b exactly, returning the exact result in a struct dd. We assume + * that both a and b are finite, but make no assumptions about their relative + * magnitudes. + */ +static inline struct dd dd_add(long double a, long double b) { + struct dd ret; + long double s; + ret.hi = a + b; + s = ret.hi - a; + ret.lo = (a - (ret.hi - s)) + (b - s); + return (ret); +} + +/* + * Compute a+b, with a small tweak: The least significant bit of the + * result is adjusted into a sticky bit summarizing all the bits that + * were lost to rounding. This adjustment negates the effects of double + * rounding when the result is added to another number with a higher + * exponent. For an explanation of round and sticky bits, see any reference + * on FPU design, e.g., + * + * J. Coonen. An Implementation Guide to a Proposed Standard for + * Floating-Point Arithmetic. Computer, vol. 13, no. 1, Jan 1980. + */ +static inline long double add_adjusted(long double a, long double b) { + struct dd sum; + union ldshape u; + sum = dd_add(a, b); + if (sum.lo != 0) { + u.f = sum.hi; + if (!LASTBIT(u)) sum.hi = nextafterl(sum.hi, INFINITY * sum.lo); + } + return (sum.hi); +} + +/* + * Compute ldexp(a+b, scale) with a single rounding error. It is assumed + * that the result will be subnormal, and care is taken to ensure that + * double rounding does not occur. + */ +static inline long double add_and_denormalize(long double a, long double b, + int scale) { + struct dd sum; + int bits_lost; + union ldshape u; + + sum = dd_add(a, b); + + /* + * If we are losing at least two bits of accuracy to denormalization, + * then the first lost bit becomes a round bit, and we adjust the + * lowest bit of sum.hi to make it a sticky bit summarizing all the + * bits in sum.lo. With the sticky bit adjusted, the hardware will + * break any ties in the correct direction. + * + * If we are losing only one bit to denormalization, however, we must + * break the ties manually. + */ + if (sum.lo != 0) { + u.f = sum.hi; + bits_lost = -u.i.se - scale + 1; + if ((bits_lost != 1) ^ LASTBIT(u)) + sum.hi = nextafterl(sum.hi, INFINITY * sum.lo); + } + return scalbnl(sum.hi, scale); +} + +/* + * Compute a*b exactly, returning the exact result in a struct dd. We assume + * that both a and b are normalized, so no underflow or overflow will occur. + * The current rounding mode must be round-to-nearest. + */ +static inline struct dd dd_mul(long double a, long double b) { + struct dd ret; + long double ha, hb, la, lb, p, q; + + p = a * SPLIT; + ha = a - p; + ha += p; + la = a - ha; + + p = b * SPLIT; + hb = b - p; + hb += p; + lb = b - hb; + + p = ha * hb; + q = ha * lb + la * hb; + + ret.hi = p + q; + ret.lo = p - ret.hi + q + la * lb; + return (ret); +} + +/* + * Fused multiply-add: Compute x * y + z with a single rounding error. + * + * We use scaling to avoid overflow/underflow, along with the + * canonical precision-doubling technique adapted from: + * + * Dekker, T. A Floating-Point Technique for Extending the + * Available Precision. Numer. Math. 18, 224-242 (1971). + */ +long double fmal(long double x, long double y, long double z) { +/* #pragma STDC FENV_ACCESS ON */ + long double xs, ys, zs, adj; + struct dd xy, r; + int oround; + int ex, ey, ez; + int spread; + + /* + * Handle special cases. The order of operations and the particular + * return values here are crucial in handling special cases involving + * infinities, NaNs, overflows, and signed zeroes correctly. + */ + if (!isfinite(x) || !isfinite(y)) return x * y + z; + if (!isfinite(z)) return z; + if (x == 0.0 || y == 0.0) return x * y + z; + if (z == 0.0) return x * y; + + xs = frexpl(x, &ex); + ys = frexpl(y, &ey); + zs = frexpl(z, &ez); + oround = fegetround(); + spread = ex + ey - ez; + + /* + * If x * y and z are many orders of magnitude apart, the scaling + * will overflow, so we handle these cases specially. Rounding + * modes other than FE_TONEAREST are painful. + */ + if (spread < -LDBL_MANT_DIG) { +#ifdef FE_INEXACT + feraiseexcept(FE_INEXACT); +#endif +#ifdef FE_UNDERFLOW + if (!isnormal(z)) feraiseexcept(FE_UNDERFLOW); +#endif + switch (oround) { + default: /* FE_TONEAREST */ + return z; +#ifdef FE_TOWARDZERO + case FE_TOWARDZERO: + if ((x > 0.0) ^ (y < 0.0) ^ (z < 0.0)) + return z; + else + return nextafterl(z, 0); +#endif +#ifdef FE_DOWNWARD + case FE_DOWNWARD: + if ((x > 0.0) ^ (y < 0.0)) + return (z); + else + return nextafterl(z, -INFINITY); +#endif +#ifdef FE_UPWARD + case FE_UPWARD: + if ((x > 0.0) ^ (y < 0.0)) + return nextafterl(z, INFINITY); + else + return (z); +#endif + } + } + if (spread <= LDBL_MANT_DIG * 2) + zs = scalbnl(zs, -spread); + else + zs = copysignl(LDBL_MIN, zs); + + fesetround(FE_TONEAREST); + + /* + * Basic approach for round-to-nearest: + * + * (xy.hi, xy.lo) = x * y (exact) + * (r.hi, r.lo) = xy.hi + z (exact) + * adj = xy.lo + r.lo (inexact; low bit is sticky) + * result = r.hi + adj (correctly rounded) + */ + xy = dd_mul(xs, ys); + r = dd_add(xy.hi, zs); + + spread = ex + ey; + + if (r.hi == 0.0) { + /* + * When the addends cancel to 0, ensure that the result has + * the correct sign. + */ + fesetround(oround); + volatile long double vzs = zs; /* XXX gcc CSE bug workaround */ + return xy.hi + vzs + scalbnl(xy.lo, spread); + } + + if (oround != FE_TONEAREST) { + /* + * There is no need to worry about double rounding in directed + * rounding modes. + * But underflow may not be raised correctly, example in downward rounding: + * fmal(0x1.0000000001p-16000L, 0x1.0000000001p-400L, -0x1p-16440L) + */ + long double ret; +#if defined(FE_INEXACT) && defined(FE_UNDERFLOW) + int e = fetestexcept(FE_INEXACT); + feclearexcept(FE_INEXACT); +#endif + fesetround(oround); + adj = r.lo + xy.lo; + ret = scalbnl(r.hi + adj, spread); +#if defined(FE_INEXACT) && defined(FE_UNDERFLOW) + if (ilogbl(ret) < -16382 && fetestexcept(FE_INEXACT)) + feraiseexcept(FE_UNDERFLOW); + else if (e) + feraiseexcept(FE_INEXACT); +#endif + return ret; + } + + adj = add_adjusted(r.lo, xy.lo); + if (spread + ilogbl(r.hi) > -16383) + return scalbnl(r.hi + adj, spread); + else + return add_and_denormalize(r.hi, adj, spread); +} + +#endif diff --git a/libc/tinymath/ilogb.c b/libc/tinymath/ilogb.c index 429d17a27..fb327610d 100644 --- a/libc/tinymath/ilogb.c +++ b/libc/tinymath/ilogb.c @@ -40,7 +40,7 @@ asm(".include \"libc/disclaimer.inc\""); */ int ilogb(double x) { - // #pragma STDC FENV_ACCESS ON +/* #pragma STDC FENV_ACCESS ON */ union {double f; uint64_t i;} u = {x}; uint64_t i = u.i; int e = i>>52 & 0x7ff; diff --git a/libc/tinymath/ilogbf.c b/libc/tinymath/ilogbf.c index 0d91f0cbc..6e3297604 100644 --- a/libc/tinymath/ilogbf.c +++ b/libc/tinymath/ilogbf.c @@ -40,7 +40,7 @@ asm(".include \"libc/disclaimer.inc\""); */ int ilogbf(float x) { - // #pragma STDC FENV_ACCESS ON +/* #pragma STDC FENV_ACCESS ON */ union {float f; uint32_t i;} u = {x}; uint32_t i = u.i; int e = i>>23 & 0xff; diff --git a/libc/tinymath/nearbyint.c b/libc/tinymath/nearbyint.c index ee8ae70b3..c8b853ce5 100644 --- a/libc/tinymath/nearbyint.c +++ b/libc/tinymath/nearbyint.c @@ -29,7 +29,7 @@ double nearbyint(double x) { asm("fidbra\t%0,0,%1,4" : "=f"(x) : "f"(x)); #else #ifdef FE_INEXACT - // #pragma STDC FENV_ACCESS ON + /* #pragma STDC FENV_ACCESS ON */ int e; e = fetestexcept(FE_INEXACT); #endif diff --git a/libc/tinymath/nearbyintf.c b/libc/tinymath/nearbyintf.c index e9b50cf29..332e15a65 100644 --- a/libc/tinymath/nearbyintf.c +++ b/libc/tinymath/nearbyintf.c @@ -24,7 +24,7 @@ */ float nearbyintf(float x) { #ifdef FE_INEXACT - // #pragma STDC FENV_ACCESS ON + /* #pragma STDC FENV_ACCESS ON */ int e; e = fetestexcept(FE_INEXACT); #endif diff --git a/libc/tinymath/nearbyintl.c b/libc/tinymath/nearbyintl.c index 353b3d905..e020916ae 100644 --- a/libc/tinymath/nearbyintl.c +++ b/libc/tinymath/nearbyintl.c @@ -25,7 +25,7 @@ */ long double nearbyintl(long double x) { #ifdef FE_INEXACT - // #pragma STDC FENV_ACCESS ON + /* #pragma STDC FENV_ACCESS ON */ int e; e = fetestexcept(FE_INEXACT); #endif diff --git a/libc/tinymath/pow.c b/libc/tinymath/pow.c index 94195c97f..4e223fb54 100644 --- a/libc/tinymath/pow.c +++ b/libc/tinymath/pow.c @@ -154,7 +154,7 @@ static inline double_t log_inline(uint64_t ix, double_t *tail) a double. (int32_t)KI is the k used in the argument reduction and exponent adjustment of scale, positive k here means the result may overflow and negative k means the result may underflow. */ -static inline double specialcase(double_t tmp, uint64_t sbits, uint64_t ki) +forceinline double specialcase(double_t tmp, uint64_t sbits, uint64_t ki) { double_t scale, y; @@ -196,7 +196,7 @@ static inline double specialcase(double_t tmp, uint64_t sbits, uint64_t ki) /* Computes sign*exp(x+xtail) where |xtail| < 2^-8/N and |xtail| <= |x|. The sign_bias argument is SIGN_BIAS or 0 and sets the sign to -1 or 1. */ -static inline double exp_inline(double_t x, double_t xtail, uint32_t sign_bias) +forceinline double exp_inline(double_t x, double_t xtail, uint32_t sign_bias) { uint32_t abstop; uint64_t ki, idx, top, sbits; diff --git a/libc/tinymath/rempio2large.c b/libc/tinymath/rempio2large.c index cc6e643f5..4f2b2ad22 100644 --- a/libc/tinymath/rempio2large.c +++ b/libc/tinymath/rempio2large.c @@ -28,6 +28,8 @@ #include "libc/math.h" #include "libc/tinymath/kernel.internal.h" +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" + asm(".ident\t\"\\n\\n\ fdlibm (fdlibm license)\\n\ Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\""); diff --git a/libc/x/x.h b/libc/x/x.h index 1be0a30bf..39335fc91 100644 --- a/libc/x/x.h +++ b/libc/x/x.h @@ -40,39 +40,41 @@ COSMOPOLITAN_C_START_ int xwrite(int, const void *, uint64_t); void xdie(void) wontreturn; char *xdtoa(double) - returnspointerwithnoaliases dontthrow nocallback __wur returnsnonnull; + returnspointerwithnoaliases dontthrow dontcallback __wur returnsnonnull; char *xdtoaf(float) - returnspointerwithnoaliases dontthrow nocallback __wur returnsnonnull; + returnspointerwithnoaliases dontthrow dontcallback __wur returnsnonnull; char *xdtoal(long double) - returnspointerwithnoaliases dontthrow nocallback __wur returnsnonnull; + returnspointerwithnoaliases dontthrow dontcallback __wur returnsnonnull; void *xmalloc(size_t) attributeallocsize((1)) - returnspointerwithnoaliases dontthrow nocallback __wur returnsnonnull; + returnspointerwithnoaliases dontthrow dontcallback __wur returnsnonnull; void *xrealloc(void *, size_t) - attributeallocsize((2)) dontthrow nocallback __wur; + attributeallocsize((2)) dontthrow dontcallback __wur; void *xcalloc(size_t, size_t) attributeallocsize((1, 2)) - returnspointerwithnoaliases dontthrow nocallback __wur returnsnonnull; + returnspointerwithnoaliases dontthrow dontcallback __wur returnsnonnull; void *xvalloc(size_t) attributeallocsize((1)) returnsaligned((65536)) - returnspointerwithnoaliases dontthrow nocallback __wur returnsnonnull; + returnspointerwithnoaliases dontthrow dontcallback __wur returnsnonnull; void *xmemalign(size_t, size_t) attributeallocalign((1)) attributeallocsize((2)) - returnspointerwithnoaliases dontthrow nocallback __wur returnsnonnull; -void *xmemalignzero(size_t, size_t) attributeallocalign((1)) attributeallocsize( - (2)) returnspointerwithnoaliases dontthrow nocallback __wur returnsnonnull; + returnspointerwithnoaliases dontthrow dontcallback __wur returnsnonnull; +void *xmemalignzero(size_t, size_t) attributeallocalign((1)) + attributeallocsize((2)) + returnspointerwithnoaliases dontthrow dontcallback __wur returnsnonnull; char *xstrdup(const char *) paramsnonnull() - returnspointerwithnoaliases dontthrow nocallback __wur returnsnonnull; + returnspointerwithnoaliases dontthrow dontcallback __wur returnsnonnull; char *xstrndup(const char *, size_t) paramsnonnull() - returnspointerwithnoaliases dontthrow nocallback __wur returnsnonnull; + returnspointerwithnoaliases dontthrow dontcallback __wur returnsnonnull; char *xstrcat(const char *, ...) paramsnonnull((1)) nullterminated() - returnspointerwithnoaliases dontthrow nocallback __wur returnsnonnull; + returnspointerwithnoaliases dontthrow dontcallback __wur returnsnonnull; #define xstrcat(...) (xstrcat)(__VA_ARGS__, NULL) char *xstrmul(const char *, size_t) paramsnonnull((1)) - returnspointerwithnoaliases dontthrow nocallback __wur returnsnonnull; + returnspointerwithnoaliases dontthrow dontcallback __wur returnsnonnull; char *xinet_ntop(int, const void *) paramsnonnull() - returnspointerwithnoaliases dontthrow nocallback __wur returnsnonnull; + returnspointerwithnoaliases dontthrow dontcallback __wur returnsnonnull; void *xunbinga(size_t, const char16_t *) - attributeallocalign((1)) returnspointerwithnoaliases dontthrow - nocallback __wur returnsnonnull dontthrow nocallback __wur returnsnonnull; -void *xunbing(const char16_t *) returnspointerwithnoaliases dontthrow - nocallback __wur returnsnonnull dontthrow nocallback __wur returnsnonnull; + attributeallocalign((1)) returnspointerwithnoaliases dontthrow dontcallback + __wur returnsnonnull dontthrow dontcallback __wur returnsnonnull; +void *xunbing(const char16_t *) + returnspointerwithnoaliases dontthrow dontcallback __wur + returnsnonnull dontthrow dontcallback __wur returnsnonnull; char16_t *utf8to16(const char *, size_t, size_t *) __wur; char *utf16to8(const char16_t *, size_t, size_t *) __wur; wchar_t *utf8to32(const char *, size_t, size_t *) __wur; @@ -84,11 +86,11 @@ char *xstripexts(const char *) __wur; void *xload(_Atomic(void *) *, const void *, size_t, size_t); int rmrf(const char *); char *xbasename(const char *) paramsnonnull() - returnspointerwithnoaliases dontthrow nocallback __wur returnsnonnull; + returnspointerwithnoaliases dontthrow dontcallback __wur returnsnonnull; char *xdirname(const char *) paramsnonnull() - returnspointerwithnoaliases dontthrow nocallback __wur returnsnonnull; + returnspointerwithnoaliases dontthrow dontcallback __wur returnsnonnull; char *xjoinpaths(const char *, const char *) paramsnonnull() - returnspointerwithnoaliases dontthrow nocallback __wur returnsnonnull; + returnspointerwithnoaliases dontthrow dontcallback __wur returnsnonnull; void xfixpath(void); void *xslurp(const char *, size_t *) paramsnonnull((1)) returnspointerwithnoaliases returnsaligned((4096)) __wur; diff --git a/libc/x/xasprintf.h b/libc/x/xasprintf.h index 7e4049bae..4d92a3db3 100644 --- a/libc/x/xasprintf.h +++ b/libc/x/xasprintf.h @@ -3,9 +3,9 @@ COSMOPOLITAN_C_START_ char *xasprintf(const char *, ...) paramsnonnull((1)) - returnspointerwithnoaliases dontthrow nocallback __wur returnsnonnull; + returnspointerwithnoaliases dontthrow dontcallback __wur returnsnonnull; char *xvasprintf(const char *, va_list) paramsnonnull() - returnspointerwithnoaliases dontthrow nocallback __wur returnsnonnull; + returnspointerwithnoaliases dontthrow dontcallback __wur returnsnonnull; COSMOPOLITAN_C_END_ #endif /* COSMOPOLITAN_LIBC_X_XASPRINTF_H_ */ diff --git a/test/libc/calls/madvise_test.c b/test/libc/calls/madvise_test.c index a5de04344..d1eb03b5e 100644 --- a/test/libc/calls/madvise_test.c +++ b/test/libc/calls/madvise_test.c @@ -20,6 +20,7 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/runtime/runtime.h" +#include "libc/sysv/consts/auxv.h" #include "libc/sysv/consts/madv.h" #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/o.h" @@ -63,7 +64,9 @@ TEST(madvise, subPages) { char *p; ASSERT_NE(MAP_FAILED, (p = mmap(0, FRAMESIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))); - ASSERT_SYS(0, 0, madvise(p + 4096, FRAMESIZE - 4096, MADV_WILLNEED)); + ASSERT_SYS(0, 0, + madvise(p + getauxval(AT_PAGESZ), FRAMESIZE - getauxval(AT_PAGESZ), + MADV_WILLNEED)); ASSERT_SYS(0, 0, munmap(p, FRAMESIZE)); } diff --git a/test/libc/intrin/kprintf_test.c b/test/libc/intrin/kprintf_test.c index a096c888d..f091d48b0 100644 --- a/test/libc/intrin/kprintf_test.c +++ b/test/libc/intrin/kprintf_test.c @@ -20,13 +20,13 @@ #include "libc/calls/calls.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/serialize.h" #include "libc/limits.h" #include "libc/log/libfatal.internal.h" #include "libc/macros.internal.h" #include "libc/runtime/memtrack.internal.h" #include "libc/runtime/runtime.h" #include "libc/runtime/symbols.internal.h" +#include "libc/serialize.h" #include "libc/stdio/rand.h" #include "libc/stdio/stdio.h" #include "libc/str/str.h" diff --git a/test/libc/nexgen32e/gclongjmp_test.c b/test/libc/nexgen32e/gclongjmp_test.c index a31f4a786..c567dda51 100644 --- a/test/libc/nexgen32e/gclongjmp_test.c +++ b/test/libc/nexgen32e/gclongjmp_test.c @@ -96,6 +96,10 @@ TEST(gc, torture) { for (i = 0; i < n; ++i) EXPECT_SYS(0, 0, pthread_join(t[i], 0)); } +#if defined(__GNUC__) && __GNUC__ >= 12 +#pragma GCC diagnostic ignored "-Winfinite-recursion" +#endif + void crawl2(jmp_buf jb, const char *path) { if (!strcmp(path, "/") || !strcmp(path, ".")) gclongjmp(jb, 1); crawl2(jb, gc(xdirname(path))); diff --git a/test/libc/runtime/tls_test.c b/test/libc/runtime/tls_test.c index 66fbf9679..ef8f086cc 100644 --- a/test/libc/runtime/tls_test.c +++ b/test/libc/runtime/tls_test.c @@ -31,6 +31,8 @@ _Thread_local long y[1] = {40}; _Alignas(A) _Thread_local long a; dontubsan void *Worker(void *arg) { + ASSERT_EQ(A, _Alignof(a)); + ASSERT_EQ(0, (uintptr_t)&a & (_Alignof(a) - 1)); ASSERT_EQ(42, x + y[0] + z); ASSERT_EQ(0, (intptr_t)&a & (A - 1)); if (IsAsan()) { @@ -41,6 +43,7 @@ dontubsan void *Worker(void *arg) { TEST(tls, test) { ASSERT_EQ(A, _Alignof(a)); + ASSERT_EQ(0, (uintptr_t)&a & (_Alignof(a) - 1)); ASSERT_EQ(0, sizeof(struct CosmoTib) % A); ASSERT_EQ(0, (intptr_t)__get_tls() & (A - 1)); EXPECT_EQ(2, z); diff --git a/test/libc/runtime/zipos_test.c b/test/libc/runtime/zipos_test.c index c172a737d..621c3bbea 100644 --- a/test/libc/runtime/zipos_test.c +++ b/test/libc/runtime/zipos_test.c @@ -21,7 +21,6 @@ #include "libc/errno.h" #include "libc/limits.h" #include "libc/mem/gc.h" -#include "libc/mem/gc.h" #include "libc/mem/mem.h" #include "libc/runtime/runtime.h" #include "libc/runtime/zipos.internal.h" diff --git a/test/libc/x/xstrcat_test.c b/test/libc/x/xstrcat_test.c index 3821a60d6..733736de4 100644 --- a/test/libc/x/xstrcat_test.c +++ b/test/libc/x/xstrcat_test.c @@ -35,6 +35,10 @@ TEST(xstrcat, pointerAbuse) { EXPECT_STREQ("hi there\n", gc(xstrcat("hi", ' ', "there", '\n'))); } +#if defined(__GNUC__) && __GNUC__ >= 12 +#pragma GCC diagnostic ignored "-Wuse-after-free" +#endif + int hard_static(void) { char *b, *p; p = b = malloc(16); diff --git a/test/libcxx/BUILD.mk b/test/libcxx/BUILD.mk index c646ddd56..836e6da8c 100644 --- a/test/libcxx/BUILD.mk +++ b/test/libcxx/BUILD.mk @@ -14,9 +14,13 @@ TEST_LIBCXX_TESTS = $(TEST_LIBCXX_COMS:%=%.ok) TEST_LIBCXX_DIRECTDEPS = \ LIBC_CALLS \ LIBC_INTRIN \ + LIBC_LOG \ LIBC_NEXGEN32E \ LIBC_RUNTIME \ LIBC_STDIO \ + LIBC_SYSV \ + LIBC_THREAD \ + LIBC_TINYMATH \ THIRD_PARTY_LIBCXX \ THIRD_PARTY_OPENMP @@ -37,7 +41,8 @@ o/$(MODE)/test/libcxx/%.com.dbg: \ $(TEST_LIBCXX_OBJS): private CCFLAGS += -fexceptions -frtti -o/$(MODE)/test/libcxx/openmp_test.o: private CXXFLAGS += -fopenmp -O3 +o/$(MODE)/test/libcxx/openmp_test.o: private CXXFLAGS += -fopenmp +o/$(MODE)/test/libcxx/openmp_test.com.runs: private QUOTA += -C100 .PHONY: o/$(MODE)/test/libcxx o/$(MODE)/test/libcxx: \ diff --git a/test/libcxx/openmp_test.cc b/test/libcxx/openmp_test.cc index ecf5ef3c2..7a8e7782c 100644 --- a/test/libcxx/openmp_test.cc +++ b/test/libcxx/openmp_test.cc @@ -16,143 +16,330 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/calls.h" -#include "libc/calls/struct/timespec.h" -#include "libc/fmt/itoa.h" -#include "libc/inttypes.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/clock.h" -#include "third_party/double-conversion/double-to-string.h" -#include "third_party/double-conversion/utils.h" -#include "third_party/openmp/omp.h" +#include +#include +#include +#include +#include +#include -#ifndef __FAST_MATH__ -#define FLAWLESS 0 -#else -#define FLAWLESS 1e-05 -#endif +#define PRECISION 2e-6 +#define LV1DCACHE 49152 +#define THRESHOLD 3000000 #if defined(__OPTIMIZE__) && !defined(__SANITIZE_ADDRESS__) -#define ITERATIONS 10 +#define ITERATIONS 5 #else #define ITERATIONS 1 #endif -// m×n → (m×n)ᵀ -template -void transpose(long m, long n, const T *A, long sa, T *B, long sb) { -#pragma omp parallel for collapse(2) - for (long i = 0; i < m; ++i) { +#define OPTIMIZED __attribute__((__optimize__("-O3,-ffast-math"))) +#define PORTABLE \ + __target_clones("arch=znver4," \ + "arch=znver3," \ + "arch=sapphirerapids," \ + "arch=alderlake," \ + "arch=rocketlake," \ + "arch=cooperlake," \ + "arch=tigerlake," \ + "arch=cascadelake," \ + "arch=skylake-avx512," \ + "arch=skylake," \ + "arch=znver1," \ + "arch=tremont," \ + "fma," \ + "avx") + +static bool is_self_testing; + +// m×n → n×m +template +void transpose(long m, long n, const TA *A, long lda, TB *B, long ldb) { +#pragma omp parallel for collapse(2) if (m * n > THRESHOLD) + for (long i = 0; i < m; ++i) for (long j = 0; j < n; ++j) { - B[sb * j + i] = A[sa * i + j]; + B[ldb * j + i] = A[lda * i + j]; } - } } // m×k * k×n → m×n -template -void matmul(long m, long n, long k, const T *A, long sa, const T *B, long sb, - T *C, long sc) { -#pragma omp parallel for collapse(2) - for (long i = 0; i < m; ++i) { +// k×m * k×n → m×n if aT +// m×k * n×k → m×n if bT +// k×m * n×k → m×n if aT and bT +template +void dgemm(bool aT, bool bT, long m, long n, long k, float alpha, const TA *A, + long lda, const TB *B, long ldb, float beta, TC *C, long ldc) { +#pragma omp parallel for collapse(2) if (m * n * k > THRESHOLD) + for (long i = 0; i < m; ++i) for (long j = 0; j < n; ++j) { - T sum = 0; - for (long l = 0; l < k; ++l) { - sum += A[sa * i + l] * B[sb * l + j]; - } - C[sc * i + j] = sum; + double sum = 0; + for (long l = 0; l < k; ++l) + sum = std::fma((aT ? A[lda * l + i] : A[lda * i + l]) * alpha, + (bT ? B[ldb * j + l] : B[ldb * l + j]), sum); + C[ldc * i + j] = beta * C[ldc * i + j] + sum; } - } } -template -void gemmk(long k, const T *A, long sa, const T *B, long sb, T *C, long sc) { - T S[BM][BN] = {0}; - for (long l = 0; l < k; ++l) { - for (long i = 0; i < BM; ++i) { - for (long j = 0; j < BN; ++j) { - S[i][j] += A[sa * l + i] * B[sb * l + j]; +template +struct Gemmlin { + public: + Gemmlin(bool aT, bool bT, float alpha, const TA *A, long lda, const TB *B, + long ldb, float beta, TC *C, long ldc) + : aT(aT), + bT(bT), + alpha(alpha), + A(A), + lda(lda), + B(B), + ldb(ldb), + beta(beta), + C(C), + ldc(ldc) { + } + + void gemm(long m, long n, long k) { + if (!m || !n) return; + for (long i = 0; i < m; ++i) + for (long j = 0; j < n; ++j) { + C[ldc * i + j] *= beta; + } + if (!k) return; + cub = sqrt(LV1DCACHE) / sqrt(sizeof(T) * 3); + mnpack(0, m, 0, n, 0, k); + } + + private: + void mnpack(long m0, long m, // + long n0, long n, // + long k0, long k) { + long mc = rounddown(std::min(m - m0, cub), 4); + long mp = m0 + (m - m0) / mc * mc; + long nc = rounddown(std::min(n - n0, cub), 4); + long np = n0 + (n - n0) / nc * nc; + long kc = rounddown(std::min(k - k0, cub), 4); + long kp = k0 + (k - k0) / kc * kc; + kpack(m0, mc, mp, n0, nc, np, k0, kc, k, kp); + if (m - mp) mnpack(mp, m, n0, np, k0, k); + if (n - np) mnpack(m0, mp, np, n, k0, k); + if (m - mp && n - np) mnpack(mp, m, np, n, k0, k); + } + + void kpack(long m0, long mc, long m, // + long n0, long nc, long n, // + long k0, long kc, long k, // + long kp) { + rpack(m0, mc, m, n0, nc, n, k0, kc, kp); + if (k - kp) rpack(m0, mc, m, n0, nc, n, kp, k - kp, k); + } + + void rpack(long m0, long mc, long m, // + long n0, long nc, long n, // + long k0, long kc, long k) { + if (!(mc % 4) && !(nc % 4)) + bgemm<4, 4>(m0, mc, m, n0, nc, n, k0, kc, k); + else + bgemm<1, 1>(m0, mc, m, n0, nc, n, k0, kc, k); + } + + template + void bgemm(long m0, long mc, long m, // + long n0, long nc, long n, // + long k0, long kc, long k) { + ops = (m - m0) * (n - n0) * (k - k0); + ml = (m - m0) / mc; + nl = (n - n0) / nc; + locks = new lock[ml * nl]; + there_will_be_blocks(m0, mc, m, n0, nc, n, k0, kc, k); + delete[] locks; + } + + template + void there_will_be_blocks(long m0, volatile long mc, long m, long n0, long nc, + long n, long k0, long kc, long k) { +#pragma omp parallel for collapse(2) if (ops > THRESHOLD && mc * kc > 16) + for (long ic = m0; ic < m; ic += mc) + for (long pc = k0; pc < k; pc += kc) + gizmo(m0, mc, ic, n0, nc, k0, kc, pc, n); + } + + template + PORTABLE OPTIMIZED void gizmo(long m0, long mc, long ic, long n0, long nc, + long k0, long kc, long pc, long n) { + T Ac[mc / mr][kc][mr]; + for (long i = 0; i < mc; ++i) + for (long j = 0; j < kc; ++j) + Ac[i / mr][j][i % mr] = alpha * (aT ? A[lda * (pc + j) + (ic + i)] + : A[lda * (ic + i) + (pc + j)]); + for (long jc = n0; jc < n; jc += nc) { + T Bc[nc / nr][nr][kc]; + for (long j = 0; j < nc; ++j) + for (long i = 0; i < kc; ++i) + Bc[j / nr][j % nr][i] = + bT ? B[ldb * (jc + j) + (pc + i)] : B[ldb * (pc + i) + (jc + j)]; + T Cc[nc / nr][mc / mr][nr][mr]; + memset(Cc, 0, nc * mc * sizeof(float)); + for (long jr = 0; jr < nc / nr; ++jr) + for (long ir = 0; ir < mc / mr; ++ir) + for (long pr = 0; pr < kc; ++pr) + for (long j = 0; j < nr; ++j) + for (long i = 0; i < mr; ++i) + Cc[jr][ir][j][i] += Ac[ir][pr][i] * Bc[jr][j][pr]; + const long lk = nl * ((ic - m0) / mc) + ((jc - n0) / nc); + locks[lk].acquire(); + for (long ir = 0; ir < mc; ir += mr) + for (long jr = 0; jr < nc; jr += nr) + for (long i = 0; i < mr; ++i) + for (long j = 0; j < nr; ++j) + C[ldc * (ic + ir + i) + (jc + jr + j)] += + Cc[jr / nr][ir / mr][j][i]; + locks[lk].release(); + } + } + + inline long rounddown(long x, long r) { + if (x < r) + return x; + else + return x & -r; + } + + class lock { + public: + lock() = default; + void acquire() { + while (lock_.exchange(true, std::memory_order_acquire)) { } } - } - for (long i = 0; i < BM; ++i) { - for (long j = 0; j < BN; ++j) { - C[sc * i + j] = S[i][j]; + void release() { + lock_.store(false, std::memory_order_release); } - } + + private: + std::atomic_bool lock_ = false; + }; + + bool aT; + bool bT; + float alpha; + const TA *A; + long lda; + const TB *B; + long ldb; + float beta; + TC *C; + long ldc; + long ops; + long nl; + long ml; + lock *locks; + long cub; +}; + +template +void sgemm(bool aT, bool bT, long m, long n, long k, float alpha, const TA *A, + long lda, const TB *B, long ldb, float beta, TC *C, long ldc) { + Gemmlin g{aT, bT, alpha, A, lda, B, ldb, beta, C, ldc}; + g.gemm(m, n, k); } -// (m×k)ᵀ * k×n → m×n -template -void gemm(long m, long n, long k, const T *A, long sa, const T *B, long sb, - T *C, long sc) { -#pragma omp parallel for collapse(2) - for (long i = 0; i < m; i += BM) { - for (long j = 0; j < n; j += BN) { - gemmk(k, A + i, sa, B + j, sb, C + sc * i + j, sc); - } +template +void show(FILE *f, long max, long m, long n, const TA *A, long lda, const TB *B, + long ldb) { + flockfile(f); + fprintf(f, " "); + for (long j = 0; j < n; ++j) { + fprintf(f, "%13ld", j); } -} - -template -void show(long m, long n, const T *A, long sa) { - long max = 4; - printf("{"); + fprintf(f, "\n"); for (long i = 0; i < m; ++i) { - if (i) { - if (i == max) { - printf(", ..."); + if (i == max) { + fprintf(f, "...\n"); + break; + } + fprintf(f, "%5ld ", i); + for (long j = 0; j < n; ++j) { + if (j == max) { + fprintf(f, " ..."); break; - } else { - printf(", "); + } + char ba[16], bb[16]; + sprintf(ba, "%13.7f", static_cast(A[lda * i + j])); + sprintf(bb, "%13.7f", static_cast(B[ldb * i + j])); + for (long k = 0; ba[k] && bb[k]; ++k) { + if (ba[k] != bb[k]) fputs_unlocked("\33[31m", f); + fputc_unlocked(ba[k], f); + if (ba[k] != bb[k]) fputs_unlocked("\33[0m", f); } } - printf("{"); - for (long j = 0; j < n; ++j) { - if (j) { - if (j == max) { - printf(", ..."); - break; - } else { - printf(", "); - } - } - printf("%g", static_cast(A[j + i * sa])); - } - printf("}"); + fprintf(f, "\n"); } - printf("}"); + funlockfile(f); } -template -double diff(long m, long n, const T *A, long sa, const T *B, long sb) { +inline unsigned long GetDoubleBits(double f) { + union { + double f; + unsigned long i; + } u; + u.f = f; + return u.i; +} + +inline bool IsNan(double x) { + return (GetDoubleBits(x) & (-1ull >> 1)) > (0x7ffull << 52); +} + +template +double diff(long m, long n, const TA *Want, long lda, const TB *Got, long ldb) { double s = 0; - for (long i = 0; i < m; ++i) { - for (long j = 0; j < n; ++j) { - s += fabs(A[sa * i + j] - B[sb * i + j]); - } - } - return s / m / n; + int got_nans = 0; + int want_nans = 0; + for (long i = 0; i < m; ++i) + for (long j = 0; j < n; ++j) + if (IsNan(Want[ldb * i + j])) + ++want_nans; + else if (IsNan(Got[ldb * i + j])) + ++got_nans; + else + s += std::fabs(Want[lda * i + j] - Got[ldb * i + j]); + if (got_nans) printf("WARNING: got %d NaNs!\n", got_nans); + if (want_nans) printf("WARNING: want array has %d NaNs!\n", want_nans); + return s / (m * n); } -template -void check(double tol, long m, long n, const T *A, long sa, const T *B, long sb, - const char *file, long line) { - double sad = diff(m, n, A, sa, B, sb); - if (sad > tol) { - printf("%s:%d: sad %g exceeds %g\n\twant ", file, line, sad, tol); - show(m, n, A, sa); - printf("\n\t got "); - show(m, n, B, sb); - printf("\n"); +template +void show_error(FILE *f, long max, long m, long n, const TA *A, long lda, + const TB *B, long ldb, const char *file, int line, double sad, + double tol) { + fprintf(f, "%s:%d: sad %.17g exceeds %g\nwant\n", file, line, sad, tol); + show(f, max, m, n, A, lda, B, ldb); + fprintf(f, "got\n"); + show(f, max, m, n, B, ldb, A, lda); + fprintf(f, "\n"); +} + +template +void check(double tol, long m, long n, const TA *A, long lda, const TB *B, + long ldb, const char *file, int line) { + double sad = diff(m, n, A, lda, B, ldb); + if (sad <= tol) { + if (!is_self_testing) { + printf(" %g error\n", sad); + } + } else { + show_error(stderr, 16, m, n, A, lda, B, ldb, file, line, sad, tol); + const char *path = "/tmp/openmp_test.log"; + FILE *f = fopen(path, "w"); + if (f) { + show_error(f, 10000, m, n, A, lda, B, ldb, file, line, sad, tol); + printf("see also %s\n", path); + } exit(1); } } -#define check(tol, m, n, A, sa, B, sb) \ - check(tol, m, n, A, sa, B, sb, __FILE__, __LINE__) +#define check(tol, m, n, A, lda, B, ldb) \ + check(tol, m, n, A, lda, B, ldb, __FILE__, __LINE__) long micros(void) { struct timespec ts; @@ -196,41 +383,91 @@ void fill(T *A, long n) { } } -void check_reference_gemm_is_ok(void) { - constexpr long m = 2; - constexpr long n = 2; - constexpr long k = 2; - float A[m][k] = {{1, 2}, {3, 4}}; - float B[k][n] = {{5, 6}, {7, 8}}; - float C[m][n] = {{666, 666}, {666, 666}}; - float G[m][n] = {{19, 22}, {43, 50}}; - bench(matmul(m, n, k, (float *)A, k, (float *)B, n, (float *)C, n)); - check(FLAWLESS, m, n, (float *)G, n, (float *)C, n); -} - -void check_transposed_blocking_gemm_is_ok(void) { - long m = 1024; - long k = 512; - long n = 80; +void test_gemm(long m, long n, long k) { float *A = new float[m * k]; + float *At = new float[k * m]; float *B = new float[k * n]; + float *Bt = new float[n * k]; float *C = new float[m * n]; - float *D = new float[m * n]; + float *GOLD = new float[m * n]; + float alpha = 1; + float beta = 0; fill(A, m * k); fill(B, k * n); - bench(matmul(m, n, k, A, k, B, n, C, n)); - float *At = new float[k * m]; - bench(transpose(m, k, A, k, At, m)); - bench((gemm<8, 4>(m, n, k, At, m, B, n, D, n))); - check(FLAWLESS, m, n, C, n, D, n); - delete[] At; - delete[] D; + dgemm(0, 0, m, n, k, 1, A, k, B, n, 0, GOLD, n); + transpose(m, k, A, k, At, m); + transpose(k, n, B, n, Bt, k); + sgemm(0, 0, m, n, k, alpha, A, k, B, n, beta, C, n); + check(PRECISION, m, n, GOLD, n, C, n); + sgemm(1, 0, m, n, k, alpha, At, m, B, n, beta, C, n); + check(PRECISION, m, n, GOLD, n, C, n); + sgemm(0, 1, m, n, k, alpha, A, k, Bt, k, beta, C, n); + check(PRECISION, m, n, GOLD, n, C, n); + sgemm(1, 1, m, n, k, alpha, At, m, Bt, k, beta, C, n); + check(PRECISION, m, n, GOLD, n, C, n); + delete[] GOLD; delete[] C; + delete[] Bt; delete[] B; + delete[] At; + delete[] A; +} + +void check_gemm_works(void) { + static long kSizes[] = {1, 2, 3, 4, 5, 6, 7, 17, 31, 33, 63, 128, 129}; + is_self_testing = true; + long c = 0; + long N = sizeof(kSizes) / sizeof(kSizes[0]); + for (long i = 0; i < N; ++i) { + long m = kSizes[i]; + for (long j = 0; j < N; ++j) { + long n = kSizes[N - 1 - i]; + for (long k = 0; k < N; ++k) { + long K = kSizes[i]; + if (c++ % 13 == 0) { + printf("testing %2ld %2ld %2ld\r", m, n, K); + } + test_gemm(m, n, K); + } + } + } + printf("\r"); + is_self_testing = false; +} + +long m = 2333 / 3; +long k = 577 / 3; +long n = 713 / 3; + +void check_sgemm(void) { + float *A = new float[m * k]; + float *At = new float[k * m]; + float *B = new float[k * n]; + float *Bt = new float[n * k]; + float *C = new float[m * n]; + double *GOLD = new double[m * n]; + fill(A, m * k); + fill(B, k * n); + transpose(m, k, A, k, At, m); + transpose(k, n, B, n, Bt, k); + bench(dgemm(0, 0, m, n, k, 1, A, k, B, n, 0, GOLD, n)); + bench(sgemm(0, 0, m, n, k, 1, A, k, B, n, 0, C, n)); + check(PRECISION, m, n, GOLD, n, C, n); + bench(sgemm(1, 0, m, n, k, 1, At, m, B, n, 0, C, n)); + check(PRECISION, m, n, GOLD, n, C, n); + bench(sgemm(0, 1, m, n, k, 1, A, k, Bt, k, 0, C, n)); + check(PRECISION, m, n, GOLD, n, C, n); + bench(sgemm(1, 1, m, n, k, 1, At, m, Bt, k, 0, C, n)); + check(PRECISION, m, n, GOLD, n, C, n); + delete[] GOLD; + delete[] C; + delete[] Bt; + delete[] B; + delete[] At; delete[] A; } int main(int argc, char *argv[]) { - check_reference_gemm_is_ok(); - check_transposed_blocking_gemm_is_ok(); + check_gemm_works(); + check_sgemm(); } diff --git a/third_party/awk/run.c b/third_party/awk/run.c index f31259db2..1ee408e4d 100644 --- a/third_party/awk/run.c +++ b/third_party/awk/run.c @@ -103,7 +103,8 @@ int adjbuf(char **pbuf, int *psiz, int minlen, int quantum, char **pbptr, if (rminlen) minlen += quantum - rminlen; tbuf = (char *) realloc(*pbuf, minlen); - DPRINTF("adjbuf %s: %d %d (pbuf=%p, tbuf=%p)\n", whatrtn, *psiz, minlen, (void*)*pbuf, (void*)tbuf); + // [jart] use after free error + // DPRINTF("adjbuf %s: %d %d (pbuf=%p, tbuf=%p)\n", whatrtn, *psiz, minlen, (void*)*pbuf, (void*)tbuf); if (tbuf == NULL) { if (whatrtn) FATAL("out of memory in %s", whatrtn); diff --git a/third_party/bash/BUILD.mk b/third_party/bash/BUILD.mk index df6f7e10a..790dc452d 100644 --- a/third_party/bash/BUILD.mk +++ b/third_party/bash/BUILD.mk @@ -83,6 +83,7 @@ $(THIRD_PARTY_BASH_OBJS): private \ -Wno-nonnull-compare \ -Wno-unused-variable \ -Wno-missing-braces \ + -Wno-use-after-free \ -Wno-unused-label \ -Wno-unused-value \ -Wno-return-type \ diff --git a/third_party/chibicc/preprocess.c b/third_party/chibicc/preprocess.c index dd9780597..ff2dee27e 100644 --- a/third_party/chibicc/preprocess.c +++ b/third_party/chibicc/preprocess.c @@ -789,11 +789,12 @@ static Token *preprocess2(Token *tok) { char *path = xasprintf("%s/%s", dirname(tmp), filename); free(tmp); bool exists = fileexists(path); - free(path); if (exists) { tok = include_file(tok, path, start->next->next); + free(path); continue; } + free(path); } char *path = search_include_paths(filename); tok = include_file(tok, path ? path : filename, start->next->next); diff --git a/third_party/compiler_rt/cpu_model.h b/third_party/compiler_rt/cpu_model.h new file mode 100644 index 000000000..f5d2ba440 --- /dev/null +++ b/third_party/compiler_rt/cpu_model.h @@ -0,0 +1,33 @@ +//===-- cpu_model_common.c - Utilities for cpu model detection ----*- C -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements common utilities for runtime cpu model detection. +// +//===----------------------------------------------------------------------===// + +#ifndef COMPILER_RT_LIB_BUILTINS_CPU_MODEL_COMMON_H +#define COMPILER_RT_LIB_BUILTINS_CPU_MODEL_COMMON_H + +#if __has_attribute(constructor) +#if __GNUC__ >= 9 +// Ordinarily init priorities below 101 are disallowed as they are reserved for +// the implementation. However, we are the implementation, so silence the +// diagnostic, since it doesn't apply to us. +#pragma GCC diagnostic ignored "-Wprio-ctor-dtor" +#endif +// We're choosing init priority 90 to force our constructors to run before any +// constructors in the end user application (starting at priority 101). This +// value matches the libgcc choice for the same functions. +#define CONSTRUCTOR_ATTRIBUTE __attribute__((__constructor__(90))) +#else +// FIXME: For MSVC, we should make a function pointer global in .CRT$X?? so that +// this runs during initialization. +#define CONSTRUCTOR_ATTRIBUTE +#endif + +#endif diff --git a/third_party/hiredis/sds.c b/third_party/hiredis/sds.c index 7f2f5692d..1e7b108e9 100644 --- a/third_party/hiredis/sds.c +++ b/third_party/hiredis/sds.c @@ -64,6 +64,8 @@ #include "third_party/hiredis/sds.h" #include "third_party/hiredis/sdsalloc.h" +#pragma GCC diagnostic ignored "-Wstringop-overflow" + static inline int sdsHdrSize(char type) { switch(type&SDS_TYPE_MASK) { case SDS_TYPE_5: diff --git a/third_party/libcxx/BUILD.mk b/third_party/libcxx/BUILD.mk index b2005f133..b3b29eeb7 100644 --- a/third_party/libcxx/BUILD.mk +++ b/third_party/libcxx/BUILD.mk @@ -223,6 +223,7 @@ $(THIRD_PARTY_LIBCXX_A_OBJS): private \ -fdata-sections \ -fexceptions \ -frtti \ + -Wno-alloc-size-larger-than \ -DLIBCXX_BUILDING_LIBCXXABI THIRD_PARTY_LIBCXX_LIBS = $(foreach x,$(THIRD_PARTY_LIBCXX_ARTIFACTS),$($(x))) diff --git a/third_party/libcxx/__config b/third_party/libcxx/__config index 0194906ef..d0d2c4b0e 100644 --- a/third_party/libcxx/__config +++ b/third_party/libcxx/__config @@ -78,7 +78,7 @@ #if defined(_LIBCPP_ABI_UNSTABLE) || _LIBCPP_ABI_VERSION >= 2 // Change short string representation so that string data starts at offset 0, // improving its alignment in some cases. -# define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT +// # define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT // Fix deque iterator type in order to support incomplete types. # define _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE // Fix undefined behavior in how std::list stores its linked nodes. @@ -332,7 +332,7 @@ #if (defined(__APPLE__) && !defined(__i386__) && !defined(__x86_64__) && \ (!defined(__arm__) || __ARM_ARCH_7K__ >= 2)) || \ defined(_LIBCPP_ALTERNATE_STRING_LAYOUT) -#define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT +// #define _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT #endif #if __has_feature(cxx_alignas) diff --git a/third_party/libcxx/cassert b/third_party/libcxx/cassert index a3daa06a9..582a75434 100644 --- a/third_party/libcxx/cassert +++ b/third_party/libcxx/cassert @@ -17,7 +17,7 @@ Macros: */ #include "third_party/libcxx/__config" -#include "libc/assert.h" +#include "libc/isystem/assert.h" #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/third_party/libcxx/cfenv b/third_party/libcxx/cfenv index bba3dcd31..a66bf926a 100644 --- a/third_party/libcxx/cfenv +++ b/third_party/libcxx/cfenv @@ -53,7 +53,7 @@ int feupdateenv(const fenv_t* envp); */ #include "third_party/libcxx/__config" -#include "libc/runtime/fenv.h" +#include "libc/isystem/fenv.h" #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/third_party/libcxx/cfloat b/third_party/libcxx/cfloat index 9b5e73c3a..1886a4f96 100644 --- a/third_party/libcxx/cfloat +++ b/third_party/libcxx/cfloat @@ -70,8 +70,7 @@ Macros: */ #include "third_party/libcxx/__config" -#include "libc/math.h" -#include "libc/runtime/fenv.h" +#include "libc/isystem/float.h" #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/third_party/libcxx/cinttypes b/third_party/libcxx/cinttypes index 61d1334dd..a57977fae 100644 --- a/third_party/libcxx/cinttypes +++ b/third_party/libcxx/cinttypes @@ -236,8 +236,7 @@ uintmax_t wcstoumax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int #include "third_party/libcxx/__config" #include "third_party/libcxx/cstdint" -#include "libc/inttypes.h" -#include "libc/fmt/conv.h" +#include "libc/isystem/inttypes.h" #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/third_party/libcxx/ciso646 b/third_party/libcxx/ciso646 index 6749b74c0..1b442a032 100644 --- a/third_party/libcxx/ciso646 +++ b/third_party/libcxx/ciso646 @@ -21,4 +21,6 @@ #pragma GCC system_header #endif +#include "libc/isystem/iso646.h" + #endif // _LIBCPP_CISO646 diff --git a/third_party/libcxx/clocale b/third_party/libcxx/clocale index bad5ab57f..126c3521a 100644 --- a/third_party/libcxx/clocale +++ b/third_party/libcxx/clocale @@ -35,8 +35,7 @@ lconv* localeconv(); */ #include "third_party/libcxx/__config" -#include "libc/str/unicode.h" -#include "libc/str/locale.h" +#include "libc/isystem/locale.h" #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/third_party/libcxx/csetjmp b/third_party/libcxx/csetjmp index 9dc5f49bf..d9bfb5305 100644 --- a/third_party/libcxx/csetjmp +++ b/third_party/libcxx/csetjmp @@ -31,7 +31,7 @@ void longjmp(jmp_buf env, int val); */ #include "third_party/libcxx/__config" -#include "libc/runtime/runtime.h" +#include "libc/isystem/setjmp.h" #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/third_party/libcxx/csignal b/third_party/libcxx/csignal index 8530f6248..d6acd9032 100644 --- a/third_party/libcxx/csignal +++ b/third_party/libcxx/csignal @@ -40,12 +40,7 @@ int raise(int sig); */ #include "third_party/libcxx/__config" -#include "libc/calls/calls.h" -#include "libc/calls/struct/sigaction.h" -#include "libc/calls/struct/siginfo.h" -#include "libc/sysv/consts/sa.h" -#include "libc/sysv/consts/sig.h" -#include "libc/sysv/consts/sicode.h" +#include "libc/isystem/signal.h" #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/third_party/libcxx/cstdarg b/third_party/libcxx/cstdarg index d3c9a734a..9564fd3a8 100644 --- a/third_party/libcxx/cstdarg +++ b/third_party/libcxx/cstdarg @@ -11,6 +11,7 @@ #define _LIBCPP_CSTDARG #include "third_party/libcxx/__config" +#include "libc/isystem/stdarg.h" #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/third_party/libcxx/cstdbool b/third_party/libcxx/cstdbool index a32e40195..0ea403fd7 100644 --- a/third_party/libcxx/cstdbool +++ b/third_party/libcxx/cstdbool @@ -20,6 +20,7 @@ Macros: */ #include "third_party/libcxx/__config" +#include "libc/isystem/stdbool.h" #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/third_party/libcxx/cstddef b/third_party/libcxx/cstddef index a20079083..f3672dba6 100644 --- a/third_party/libcxx/cstddef +++ b/third_party/libcxx/cstddef @@ -35,6 +35,7 @@ Types: #include "third_party/libcxx/__config" #include "third_party/libcxx/version" +#include "libc/isystem/stddef.h" #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/third_party/libcxx/cstdint b/third_party/libcxx/cstdint index 8ebad1acb..f1dffe83f 100644 --- a/third_party/libcxx/cstdint +++ b/third_party/libcxx/cstdint @@ -10,11 +10,7 @@ #ifndef _LIBCPP_CSTDINT #define _LIBCPP_CSTDINT -#include "libc/inttypes.h" -#include "libc/fmt/conv.h" -#include "libc/limits.h" -#include "libc/literal.h" -#include "libc/calls/weirdtypes.h" +#include "libc/isystem/stdint.h" #include "third_party/libcxx/__config" #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/third_party/libcxx/cstdlib b/third_party/libcxx/cstdlib index e2c88b522..818ba2ccf 100644 --- a/third_party/libcxx/cstdlib +++ b/third_party/libcxx/cstdlib @@ -13,6 +13,7 @@ #include "third_party/libcxx/__config" #include "libc/str/str.h" #include "third_party/libcxx/stdlib.h" +#include "libc/isystem/stdlib.h" /* cstdlib synopsis diff --git a/third_party/libcxx/ctime b/third_party/libcxx/ctime index 4879de5bb..37f121b7e 100644 --- a/third_party/libcxx/ctime +++ b/third_party/libcxx/ctime @@ -11,15 +11,7 @@ #define _LIBCPP_CTIME #include "third_party/libcxx/__config" -#include "libc/calls/struct/timespec.h" -#include "libc/calls/struct/timeval.h" -#include "libc/sysv/consts/clock.h" -#include "libc/sysv/consts/sched.h" -#include "libc/sysv/consts/timer.h" -#include "libc/calls/weirdtypes.h" -#include "libc/time/struct/tm.h" -#include "libc/calls/calls.h" -#include "libc/time/time.h" +#include "libc/isystem/time.h" #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/third_party/libcxx/ctype.h b/third_party/libcxx/ctype.h index e6a95b2ca..b89d403ec 100644 --- a/third_party/libcxx/ctype.h +++ b/third_party/libcxx/ctype.h @@ -35,7 +35,7 @@ int toupper(int c); #pragma GCC system_header #endif -#include "libc/str/str.h" +#include "libc/isystem/ctype.h" #ifdef __cplusplus diff --git a/third_party/libcxx/errno.h b/third_party/libcxx/errno.h index c1210f888..1dfe334b6 100644 --- a/third_party/libcxx/errno.h +++ b/third_party/libcxx/errno.h @@ -28,7 +28,7 @@ Macros: #pragma GCC system_header #endif -#include "libc/errno.h" +#include "libc/isystem/errno.h" #ifdef __cplusplus diff --git a/third_party/libcxx/limits.h b/third_party/libcxx/limits.h index b78191a71..379e34fcf 100644 --- a/third_party/libcxx/limits.h +++ b/third_party/libcxx/limits.h @@ -43,22 +43,6 @@ Macros: #pragma GCC system_header #endif -#ifndef __GNUC__ -#include "libc/limits.h" -#else -// GCC header limits.h recursively includes itself through another header called -// syslimits.h for some reason. This setup breaks down if we directly -// #include_next GCC's limits.h (reasons not entirely clear to me). Therefore, -// we manually re-create the necessary include sequence below: - -// Get the system limits.h defines (force recurse into the next level) -#define _GCC_LIMITS_H_ -#define _GCC_NEXT_LIMITS_H -#include "libc/limits.h" - -// Get the ISO C defines -#undef _GCC_LIMITS_H_ -#include "libc/limits.h" -#endif // __GNUC__ +#include "libc/isystem/limits.h" #endif // _LIBCPP_LIMITS_H diff --git a/third_party/libcxx/locale.h b/third_party/libcxx/locale.h index bcf7c1a3f..dd61d9df2 100644 --- a/third_party/libcxx/locale.h +++ b/third_party/libcxx/locale.h @@ -39,7 +39,6 @@ Functions: #pragma GCC system_header #endif -#include "libc/str/locale.h" -#include "libc/str/unicode.h" +#include "libc/isystem/locale.h" #endif // _LIBCPP_LOCALE_H diff --git a/third_party/libcxx/math.h b/third_party/libcxx/math.h index 6bb8d562c..9171afc7c 100644 --- a/third_party/libcxx/math.h +++ b/third_party/libcxx/math.h @@ -19,7 +19,7 @@ #define _LIBCPP_STDLIB_INCLUDE_NEXT #include "third_party/libcxx/stdlib.h" -#include "libc/math.h" +#include "libc/isystem/math.h" #ifdef __cplusplus diff --git a/third_party/libcxx/stdio.h b/third_party/libcxx/stdio.h index c16c2d66e..79c965488 100644 --- a/third_party/libcxx/stdio.h +++ b/third_party/libcxx/stdio.h @@ -102,9 +102,7 @@ void perror(const char* s); #pragma GCC system_header #endif -#include "libc/calls/calls.h" -#include "libc/temp.h" -#include "libc/stdio/stdio.h" +#include "libc/isystem/stdio.h" #ifdef __cplusplus diff --git a/third_party/libcxx/stdlib.h b/third_party/libcxx/stdlib.h index a561dc78f..aea595b06 100644 --- a/third_party/libcxx/stdlib.h +++ b/third_party/libcxx/stdlib.h @@ -9,13 +9,7 @@ #if defined(__need_malloc_and_calloc) || defined(_LIBCPP_STDLIB_INCLUDE_NEXT) -#include "libc/stdio/rand.h" -#include "libc/mem/mem.h" -#include "libc/runtime/runtime.h" -#include "libc/runtime/runtime.h" -#include "libc/mem/alg.h" -#include "libc/stdio/stdio.h" -#include "libc/fmt/conv.h" +#include "libc/isystem/stdlib.h" #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/third_party/libcxx/string b/third_party/libcxx/string index ea0b695ef..c8c822545 100644 --- a/third_party/libcxx/string +++ b/third_party/libcxx/string @@ -702,34 +702,41 @@ private: #ifdef _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT - struct __long - { - pointer __data_; + struct __long { + pointer __data_; size_type __size_; - size_type __cap_; + size_type __cap_ : sizeof(size_type) * CHAR_BIT - 1; + size_type __is_long_ : 1; }; -#ifdef _LIBCPP_BIG_ENDIAN - static const size_type __short_mask = 0x01; - static const size_type __long_mask = 0x1ul; -#else // _LIBCPP_BIG_ENDIAN - static const size_type __short_mask = 0x80; - static const size_type __long_mask = ~(size_type(~0) >> 1); -#endif // _LIBCPP_BIG_ENDIAN + enum { __min_cap = (sizeof(__long) - 1) / sizeof(value_type) > 2 ? (sizeof(__long) - 1) / sizeof(value_type) : 2 }; - enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ? - (sizeof(__long) - 1)/sizeof(value_type) : 2}; - - struct __short - { + struct __short { value_type __data_[__min_cap]; - struct - : __padding - { - unsigned char __size_; - }; + unsigned char __padding_[sizeof(value_type) - 1]; + unsigned char __size_ : 7; + unsigned char __is_long_ : 1; }; + // The __endian_factor is required because the field we use to store the size + // has one fewer bit than it would if it were not a bitfield. + // + // If the LSB is used to store the short-flag in the short string representation, + // we have to multiply the size by two when it is stored and divide it by two when + // it is loaded to make sure that we always store an even number. In the long string + // representation, we can ignore this because we can assume that we always allocate + // an even amount of value_types. + // + // If the MSB is used for the short-flag, the max_size() is numeric_limits::max() / 2. + // This does not impact the short string representation, since we never need the MSB + // for representing the size of a short string anyway. + +# ifdef _LIBCPP_BIG_ENDIAN + static const size_type __endian_factor = 2; +# else + static const size_type __endian_factor = 1; +# endif + #else struct __long diff --git a/third_party/libcxx/string.h b/third_party/libcxx/string.h index 5490cbc8d..abd6be931 100644 --- a/third_party/libcxx/string.h +++ b/third_party/libcxx/string.h @@ -16,7 +16,7 @@ #pragma GCC system_header #endif -#include "libc/str/str.h" +#include "libc/isystem/string.h" /* string.h synopsis diff --git a/third_party/libcxx/wchar.h b/third_party/libcxx/wchar.h index c5e80d9bd..17996b194 100644 --- a/third_party/libcxx/wchar.h +++ b/third_party/libcxx/wchar.h @@ -9,8 +9,7 @@ #ifndef _LIBCPP_WCHAR_H #define _LIBCPP_WCHAR_H -#include "libc/str/str.h" -#include "libc/time/time.h" +#include "libc/isystem/wchar.h" #include "third_party/libcxx/__config" #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/third_party/libcxx/wctype.h b/third_party/libcxx/wctype.h index 1ea8f5652..b256d58dd 100644 --- a/third_party/libcxx/wctype.h +++ b/third_party/libcxx/wctype.h @@ -50,8 +50,7 @@ wctrans_t wctrans(const char* property); #pragma GCC system_header #endif -#include "libc/str/str.h" -#include "libc/time/time.h" +#include "libc/isystem/wctype.h" #ifdef __cplusplus diff --git a/third_party/libcxxabi/test/BUILD.mk b/third_party/libcxxabi/test/BUILD.mk index 8bfd39d40..6bc0d5861 100644 --- a/third_party/libcxxabi/test/BUILD.mk +++ b/third_party/libcxxabi/test/BUILD.mk @@ -32,26 +32,27 @@ THIRD_PARTY_LIBCXXABI_TEST_SRCS = \ third_party/libcxxabi/test/cxa_thread_atexit_test.pass.cc \ third_party/libcxxabi/test/cxa_vec_new_overflow_PR41395.pass.cc \ third_party/libcxxabi/test/dynamic_cast.pass.cc \ + third_party/libcxxabi/test/dynamic_cast14.pass.cc \ third_party/libcxxabi/test/dynamic_cast3.pass.cc \ third_party/libcxxabi/test/dynamic_cast5.pass.cc \ - third_party/libcxxabi/test/dynamic_cast14.pass.cc \ third_party/libcxxabi/test/dynamic_cast_stress.pass.cc \ - third_party/libcxxabi/test/exception_object_alignment.pass.cc \ third_party/libcxxabi/test/exception_object_alignment.2.pass.cc \ + third_party/libcxxabi/test/exception_object_alignment.pass.cc \ third_party/libcxxabi/test/guard_test_basic.pass.cc \ - third_party/libcxxabi/test/incomplete_type.sh.cc \ + third_party/libcxxabi/test/incomplete_type_test.pass.cc \ + third_party/libcxxabi/test/incomplete_type_test.lib.cc \ third_party/libcxxabi/test/inherited_exception.pass.cc \ third_party/libcxxabi/test/test_aux_runtime.pass.cc \ third_party/libcxxabi/test/test_aux_runtime_op_array_new.pass.cc\ third_party/libcxxabi/test/test_demangle.pass.cc \ - third_party/libcxxabi/test/test_exception_address_alignment.pass.cc \ + third_party/libcxxabi/test/test_exception_address_alignment.pass.cc \ third_party/libcxxabi/test/test_exception_storage.pass.cc \ third_party/libcxxabi/test/test_fallback_malloc.pass.cc \ third_party/libcxxabi/test/test_guard.pass.cc \ third_party/libcxxabi/test/test_vector1.pass.cc \ third_party/libcxxabi/test/test_vector2.pass.cc \ - third_party/libcxxabi/test/thread_local_destruction_order.pass.cc \ third_party/libcxxabi/test/test_vector3.pass.cc \ + third_party/libcxxabi/test/thread_local_destruction_order.pass.cc \ third_party/libcxxabi/test/uncaught_exception.pass.cc \ third_party/libcxxabi/test/uncaught_exceptions.pass.cc \ third_party/libcxxabi/test/unittest_demangle.pass.cc \ @@ -69,33 +70,21 @@ THIRD_PARTY_LIBCXXABI_TEST_SRCS_TOOSLOW_COSMO = \ THIRD_PARTY_LIBCXXABI_TEST_SRCS_FAILING_GCC = \ third_party/libcxxabi/test/catch_array_01.pass.cc \ third_party/libcxxabi/test/catch_function_01.pass.cc \ - third_party/libcxxabi/test/catch_member_function_pointer_01.pass.cc \ + third_party/libcxxabi/test/catch_member_function_pointer_01.pass.cc \ third_party/libcxxabi/test/catch_member_function_pointer_02.pass.cc +THIRD_PARTY_LIBCXXABI_TEST_OBJS = \ + $(THIRD_PARTY_LIBCXXABI_TEST_SRCS:%.cc=o/$(MODE)/%.o) + +THIRD_PARTY_LIBCXXABI_TEST_COMS_SRCS = \ + $(filter-out %.pass.cc,$(THIRD_PARTY_LIBCXXABI_TEST_SRCS)) + THIRD_PARTY_LIBCXXABI_TEST_COMS = \ - $(THIRD_PARTY_LIBCXXABI_TEST_SRCS:%.cc=o/$(MODE)/%.com) + $(THIRD_PARTY_LIBCXXABI_TEST_COMS_SRCS:%.cc=o/$(MODE)/%.com) THIRD_PARTY_LIBCXXABI_TEST_TESTS = \ $(THIRD_PARTY_LIBCXXABI_TEST_COMS:%=%.ok) -THIRD_PARTY_LIBCXXABI_TEST_OBJS = \ - $(THIRD_PARTY_LIBCXXABI_TEST_SRCS:%.cc=o/$(MODE)/%.o) \ - o/$(MODE)/third_party/libcxxabi/test/incomplete_type.sh.one.o \ - o/$(MODE)/third_party/libcxxabi/test/incomplete_type.sh.two.o - -THIRD_PARTY_LIBCXXABI_TEST_OBJS_WNO_EXCEPTIONS = \ - o/$(MODE)/third_party/libcxxabi/test/catch_class_03.pass.o \ - o/$(MODE)/third_party/libcxxabi/test/catch_class_04.pass.o \ - o/$(MODE)/third_party/libcxxabi/test/catch_ptr.pass.o \ - o/$(MODE)/third_party/libcxxabi/test/catch_ptr_02.pass.o \ - o/$(MODE)/third_party/libcxxabi/test/inherited_exception.pass.o - -THIRD_PARTY_LIBCXXABI_TEST_OBJS_CPP14 = \ - o/$(MODE)/third_party/libcxxabi/test/unwind_02.pass.o \ - o/$(MODE)/third_party/libcxxabi/test/unwind_03.pass.o \ - o/$(MODE)/third_party/libcxxabi/test/unwind_04.pass.o \ - o/$(MODE)/third_party/libcxxabi/test/unwind_05.pass.o - THIRD_PARTY_LIBCXXABI_TEST_BINS = \ $(THIRD_PARTY_LIBCXXABI_TEST_COMS) \ $(THIRD_PARTY_LIBCXXABI_TEST_COMS:%=%.dbg) @@ -105,19 +94,29 @@ THIRD_PARTY_LIBCXXABI_TEST_CHECKS = \ $(THIRD_PARTY_LIBCXXABI_TEST_HDRS:%=o/$(MODE)/%.ok) THIRD_PARTY_LIBCXXABI_TEST_DIRECTDEPS = \ - LIBC_NEXGEN32E \ + LIBC_CALLS \ + LIBC_INTRIN \ LIBC_LOG \ + LIBC_MEM \ + LIBC_NEXGEN32E \ + LIBC_PROC \ + LIBC_RUNTIME \ + LIBC_STDIO \ + LIBC_THREAD \ THIRD_PARTY_LIBCXX \ - THIRD_PARTY_LIBCXXABI + THIRD_PARTY_LIBCXXABI \ + THIRD_PARTY_LIBUNWIND THIRD_PARTY_LIBCXXABI_TEST_DEPS := \ $(call uniq,$(foreach x,$(THIRD_PARTY_LIBCXXABI_TEST_DIRECTDEPS),$($(x)))) $(THIRD_PARTY_LIBCXXABI_TEST_A): \ - $(THIRD_PARTY_LIBCXXABI_TEST_A).pkg + $(THIRD_PARTY_LIBCXXABI_TEST_A).pkg \ + $(THIRD_PARTY_LIBCXXABI_TEST_OBJS) $(THIRD_PARTY_LIBCXXABI_TEST_A).pkg: \ - $(foreach x,$(THIRD_PARTY_LIBCXXABI_TEST_DIRECTDEPS),$($(x)_A).pkg) + $(foreach x,$(THIRD_PARTY_LIBCXXABI_TEST_DIRECTDEPS),$($(x)_A).pkg) \ + $(THIRD_PARTY_LIBCXXABI_TEST_OBJS) o/$(MODE)/third_party/libcxxabi/test/%.com.dbg: \ $(THIRD_PARTY_LIBCXXABI_TEST_DEPS) \ @@ -137,38 +136,27 @@ $(THIRD_PARTY_LIBCXXABI_TEST_OBJS): private \ -D_LIBCPP_BUILDING_LIBRARY \ -D_LIBCPP_CONSTINIT=__constinit -$(THIRD_PARTY_LIBCXXABI_TEST_OBJS_WNO_EXCEPTIONS): private \ - CXXFLAGS += \ - -Wno-exceptions - -$(THIRD_PARTY_LIBCXXABI_TEST_OBJS_CPP14): private \ - CXXFLAGS += \ - -std=gnu++14 - -o/$(MODE)/third_party/libcxxabi/test/guard_test_basic.pass.o: private \ - CXXFLAGS += \ - -Wno-invalid-memory-model - -o/$(MODE)/third_party/libcxxabi/test/incomplete_type.sh.one.o: private \ - CXXFLAGS += \ - -Wno-unreachable-code -o/$(MODE)/third_party/libcxxabi/test/incomplete_type.sh.two.o: private \ - CXXFLAGS += \ - -Wno-unreachable-code \ - -DTU_ONE -o/$(MODE)/third_party/libcxxabi/test/incomplete_type.sh.com.dbg: \ - $(THIRD_PARTY_LIBCXXABI_TEST_DEPS) \ - $(THIRD_PARTY_LIBCXXABI_TEST_A) \ - o/$(MODE)/third_party/libcxxabi/test/incomplete_type.sh.one.o \ - o/$(MODE)/third_party/libcxxabi/test/incomplete_type.sh.two.o \ - $(THIRD_PARTY_LIBCXXABI_TEST_A).pkg \ - $(CRT) \ - $(APE_NO_MODIFY_SELF) - @$(APELINK) - $(THIRD_PARTY_LIBCXXABI_TEST_OBJS): private CONFIG_CPPFLAGS += -UNDEBUG o/$(MODE)/third_party/libcxxabi/test/catch_multi_level_pointer.pass.o: private COPTS += -O0 o/$(MODE)/third_party/libcxxabi/test/catch_multi_level_pointer.pass.o: private QUOTA += -C30 -M4000m +o/$(MODE)/third_party/libcxxabi/test/guard_test_basic.pass.o: private CXXFLAGS += -Wno-invalid-memory-model +o/$(MODE)/third_party/libcxxabi/test/incomplete_type_test.pass.o: private CXXFLAGS += -Wno-unreachable-code +o/$(MODE)/third_party/libcxxabi/test/incomplete_type_test.lib.o: private CXXFLAGS += -Wno-unreachable-code -DTU_ONE + +o/$(MODE)/third_party/libcxxabi/test/catch_class_03.pass.o \ +o/$(MODE)/third_party/libcxxabi/test/catch_class_04.pass.o \ +o/$(MODE)/third_party/libcxxabi/test/catch_ptr.pass.o \ +o/$(MODE)/third_party/libcxxabi/test/catch_ptr_02.pass.o \ +o/$(MODE)/third_party/libcxxabi/test/inherited_exception.pass.o: private \ + CXXFLAGS += \ + -Wno-exceptions + +o/$(MODE)/third_party/libcxxabi/test/unwind_02.pass.o \ +o/$(MODE)/third_party/libcxxabi/test/unwind_03.pass.o \ +o/$(MODE)/third_party/libcxxabi/test/unwind_04.pass.o \ +o/$(MODE)/third_party/libcxxabi/test/unwind_05.pass.o: private \ + CXXFLAGS += \ + -std=gnu++14 .PHONY: o/$(MODE)/third_party/libcxxabi/test o/$(MODE)/third_party/libcxxabi/test: \ diff --git a/third_party/libcxxabi/test/incomplete_type.sh.one.cc b/third_party/libcxxabi/test/incomplete_type.sh.one.cc deleted file mode 120000 index 100e3f363..000000000 --- a/third_party/libcxxabi/test/incomplete_type.sh.one.cc +++ /dev/null @@ -1 +0,0 @@ -incomplete_type.sh.cc \ No newline at end of file diff --git a/third_party/libcxxabi/test/incomplete_type.sh.two.cc b/third_party/libcxxabi/test/incomplete_type.sh.two.cc deleted file mode 120000 index 100e3f363..000000000 --- a/third_party/libcxxabi/test/incomplete_type.sh.two.cc +++ /dev/null @@ -1 +0,0 @@ -incomplete_type.sh.cc \ No newline at end of file diff --git a/third_party/libcxxabi/test/incomplete_type_test.lib.cc b/third_party/libcxxabi/test/incomplete_type_test.lib.cc new file mode 120000 index 000000000..a10bb894c --- /dev/null +++ b/third_party/libcxxabi/test/incomplete_type_test.lib.cc @@ -0,0 +1 @@ +incomplete_type_test.pass.cc \ No newline at end of file diff --git a/third_party/libcxxabi/test/incomplete_type.sh.cc b/third_party/libcxxabi/test/incomplete_type_test.pass.cc similarity index 100% rename from third_party/libcxxabi/test/incomplete_type.sh.cc rename to third_party/libcxxabi/test/incomplete_type_test.pass.cc diff --git a/third_party/musl/crypt_des.c b/third_party/musl/crypt_des.c index 87ae04bff..f301f8b22 100644 --- a/third_party/musl/crypt_des.c +++ b/third_party/musl/crypt_des.c @@ -32,6 +32,8 @@ #include "third_party/musl/crypt.internal.h" #include "third_party/musl/crypt_des.internal.h" +#pragma GCC diagnostic ignored "-Wstringop-overflow" + asm(".ident\t\"\\n\\n\ Musl libc (MIT License)\\n\ Copyright 2005-2014 Rich Felker, et. al.\""); diff --git a/third_party/musl/dn_comp.c b/third_party/musl/dn_comp.c index a6db07072..331d20f18 100644 --- a/third_party/musl/dn_comp.c +++ b/third_party/musl/dn_comp.c @@ -93,7 +93,7 @@ int dn_comp(const char *src, unsigned char **dnptrs, unsigned char **lastdnptr) { - int i, j, n, m=0, offset, bestlen=0, bestoff; + int i, j, n, m=0, offset, bestlen=0, bestoff=0; unsigned char lens[127]; unsigned char **p; const char *end; diff --git a/third_party/nsync/futex.c b/third_party/nsync/futex.c index de9a5889b..feb8c49ef 100644 --- a/third_party/nsync/futex.c +++ b/third_party/nsync/futex.c @@ -143,7 +143,7 @@ static int nsync_futex_polyfill_ (atomic_int *w, int expect, struct timespec *ab if (abstime && timespec_cmp (timespec_real (), *abstime) >= 0) { return -ETIMEDOUT; } - pthread_yield (); + pthread_yield_np (); } } @@ -373,7 +373,7 @@ int nsync_futex_wake_ (atomic_int *w, int count, char pshare) { } } else { Polyfill: - pthread_yield (); + pthread_yield_np (); rc = 0; } diff --git a/third_party/nsync/yield.c b/third_party/nsync/yield.c index 495391fdd..f15b29f6c 100644 --- a/third_party/nsync/yield.c +++ b/third_party/nsync/yield.c @@ -22,6 +22,6 @@ #include "third_party/nsync/common.internal.h" void nsync_yield_ (void) { - pthread_yield (); + pthread_yield_np (); STRACE ("nsync_yield_()"); } diff --git a/third_party/openmp/kmp_os.h b/third_party/openmp/kmp_os.h index 8ef3746ce..6ce5d511a 100644 --- a/third_party/openmp/kmp_os.h +++ b/third_party/openmp/kmp_os.h @@ -75,7 +75,7 @@ #error Unknown compiler #endif -#if (KMP_OS_LINUX || KMP_OS_WINDOWS || KMP_OS_FREEBSD) && !KMP_OS_WASI +#if (KMP_OS_LINUX || KMP_OS_WINDOWS || KMP_OS_FREEBSD) && !KMP_OS_WASI && !defined(__COSMOPOLITAN__) #define KMP_AFFINITY_SUPPORTED 1 #if KMP_OS_WINDOWS && KMP_ARCH_X86_64 #define KMP_GROUP_AFFINITY 1 diff --git a/third_party/zstd/BUILD.mk b/third_party/zstd/BUILD.mk index 27edd513b..5aa69393c 100644 --- a/third_party/zstd/BUILD.mk +++ b/third_party/zstd/BUILD.mk @@ -147,6 +147,7 @@ $(THIRD_PARTY_ZSTD_A_CHECKS): private \ $(THIRD_PARTY_ZSTD_A_OBJS): private \ CFLAGS += \ -Wframe-larger-than=262144 \ + -Wno-array-bounds \ -Wno-comment $(THIRD_PARTY_ZSTD_A_OBJS): private \ diff --git a/tool/build/compile.c b/tool/build/compile.c index aee8f9e30..576177ef5 100644 --- a/tool/build/compile.c +++ b/tool/build/compile.c @@ -226,65 +226,6 @@ const char *const kSafeEnv[] = { "SYSTEMROOT", // needed by socket() }; -const char *const kGccOnlyFlags[] = { - "--nocompress-debug-sections", - "--noexecstack", - "-Wa,--nocompress-debug-sections", - "-Wa,--noexecstack", - "-Wa,-msse2avx", - "-Wno-unused-but-set-variable", - "-Wunsafe-loop-optimizations", - "-fbranch-target-load-optimize", - "-fcx-limited-range", - "-fdelete-dead-exceptions", - "-femit-struct-debug-baseonly", - "-ffp-int-builtin-inexact", - "-finline-functions-called-once", - "-fipa-pta", - "-fivopts", - "-flimit-function-alignment", - "-fmerge-constants", - "-fmodulo-sched", - "-fmodulo-sched-allow-regmoves", - "-fno-align-jumps", - "-fno-align-labels", - "-fno-align-loops", - "-fno-cx-limited-range", - "-fno-fp-int-builtin-inexact", - "-fno-gnu-unique", - "-fno-gnu-unique", - "-fno-inline-functions-called-once", - "-fno-instrument-functions", - "-fno-schedule-insns2", - "-fno-whole-program", - "-fopt-info-vec", - "-fopt-info-vec-missed", - "-freg-struct-return", - "-freschedule-modulo-scheduled-loops", - "-frounding-math", - "-fsched2-use-superblocks", - "-fschedule-insns", - "-fschedule-insns2", - "-fshrink-wrap", - "-fshrink-wrap-separate", - "-fsignaling-nans", - "-fstack-clash-protection", - "-ftracer", - "-ftrapv", - "-ftree-loop-im", - "-ftree-loop-vectorize", - "-funsafe-loop-optimizations", - "-fversion-loops-for-strides", - "-fwhole-program", - "-gdescribe-dies", - "-gstabs", - "-mcall-ms2sysv-xlogues", - "-mdispatch-scheduler", - "-mfpmath=sse+387", - "-mmitigate-rop", - "-mno-fentry", -}; - void OnAlrm(int sig) { ++gotalrm; } @@ -400,21 +341,38 @@ bool IsSafeEnv(const char *s) { return false; } -bool IsGccOnlyFlag(const char *s) { - int m, l, r, x; - l = 0; - r = ARRAYLEN(kGccOnlyFlags) - 1; - while (l <= r) { - m = (l & r) + ((l ^ r) >> 1); // floor((a+b)/2) - x = strcmp(s, kGccOnlyFlags[m]); - if (x < 0) { - r = m - 1; - } else if (x > 0) { - l = m + 1; - } else { - return true; +char *Slurp(const char *path) { + int fd; + char *res = 0; + if ((fd = open(path, O_RDONLY)) != -1) { + ssize_t size; + if ((size = lseek(fd, 0, SEEK_END)) != -1) { + char *buf; + if ((buf = calloc(1, size + 1))) { + if (pread(fd, buf, size, 0) == size) { + res = buf; + } else { + free(buf); + } + } } + close(fd); } + return res; +} + +bool HasFlag(const char *flags, const char *s) { + char buf[256]; + size_t n = strlen(s); + if (!flags) return false; + if (n + 2 > sizeof(buf)) return false; + memcpy(buf, s, n); + buf[n] = '\n'; + buf[n + 1] = 0; + return !!strstr(flags, buf); +} + +bool IsGccOnlyFlag(const char *s) { if (s[0] == '-') { if (s[1] == 'f') { if (startswith(s, "-ffixed-")) return true; @@ -428,8 +386,25 @@ bool IsGccOnlyFlag(const char *s) { if (startswith(s, "-mstringop-strategy=")) return true; if (startswith(s, "-mpreferred-stack-boundary=")) return true; if (startswith(s, "-Wframe-larger-than=")) return true; + if (startswith(s, "-Walloca-larger-than=")) return true; } - return false; + static bool once; + static char *gcc_only_flags; + if (!once) { + gcc_only_flags = Slurp("build/bootstrap/gcc-only-flags.txt"); + once = true; + } + return HasFlag(gcc_only_flags, s); +} + +bool IsClangOnlyFlag(const char *s) { + static bool once; + static char *clang_only_flags; + if (!once) { + clang_only_flags = Slurp("build/bootstrap/clang-only-flags.txt"); + once = true; + } + return HasFlag(clang_only_flags, s); } bool FileExistsAndIsNewerThan(const char *filepath, const char *thanpath) { @@ -926,12 +901,12 @@ int main(int argc, char *argv[]) { } s = basename(strdup(cmd)); - if (strstr(s, "gcc") || strstr(s, "g++")) { - iscc = true; - isgcc = true; - } else if (strstr(s, "clang") || strstr(s, "clang++")) { + if (strstr(s, "clang") || strstr(s, "clang++")) { iscc = true; isclang = true; + } else if (strstr(s, "gcc") || strstr(s, "g++")) { + iscc = true; + isgcc = true; } else if (strstr(s, "ld.bfd")) { isbfd = true; } else if (strstr(s, "ar.com")) { @@ -990,6 +965,9 @@ int main(int argc, char *argv[]) { AddArg(argv[i]); continue; } + if (isgcc && IsClangOnlyFlag(argv[i])) { + continue; + } if (isclang && IsGccOnlyFlag(argv[i])) { continue; } @@ -1188,7 +1166,9 @@ int main(int argc, char *argv[]) { !strcmp(argv[i], "-O3"))) { /* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97623 */ AddArg(argv[i]); - AddArg("-fno-code-hoisting"); + if (!isclang) { + AddArg("-fno-code-hoisting"); + } } else { AddArg(argv[i]); } diff --git a/libc/intrin/__clear_cache.c b/tool/build/findape.c similarity index 63% rename from libc/intrin/__clear_cache.c rename to tool/build/findape.c index 3d93adf45..88373b651 100644 --- a/libc/intrin/__clear_cache.c +++ b/tool/build/findape.c @@ -16,22 +16,49 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/runtime/runtime.h" +#include "libc/serialize.h" +#include "libc/stdio/ftw.h" +#include "libc/stdio/stdio.h" +#include "libc/sysv/consts/o.h" -void __clear_cache2(const void *base, const void *end) { -#ifdef __aarch64__ - int icache, dcache; - const char *p, *pe = end; - static unsigned int ctr_el0 = 0; - if (!ctr_el0) asm volatile("mrs\t%0,ctr_el0" : "=r"(ctr_el0)); - icache = 4 << (ctr_el0 & 15); - dcache = 4 << ((ctr_el0 >> 16) & 15); - for (p = (const char *)((uintptr_t)base & -dcache); p < pe; p += dcache) { - asm volatile("dc\tcvau,%0" : : "r"(p) : "memory"); +// finds ape executables +// usage: findelf PATH... + +static int OnFile(const char *fpath, const struct stat *st, int typeflag, + struct FTW *ftwbuf) { + if (typeflag == FTW_F) { + char buf[8] = {0}; + int fd = open(fpath, O_RDONLY); + if (fd != -1) { + pread(fd, buf, sizeof(buf), 0); + close(fd); + if (READ64LE(buf) == READ64LE("MZqFpD='") || + READ64LE(buf) == READ64LE("jartsr='") || + READ64LE(buf) == READ64LE("APEDBG='")) { + tinyprint(1, fpath, "\n", NULL); + } + } else { + perror(fpath); + } + } + return 0; +} + +static void HandleArg(const char *path) { + if (nftw(path, OnFile, 128, FTW_PHYS | FTW_DEPTH)) { + perror(path); + exit(1); + } +} + +int main(int argc, char *argv[]) { + if (argc <= 1) { + HandleArg("."); + } else { + for (int i = 1; i < argc; ++i) { + HandleArg(argv[i]); + } } - asm volatile("dsb\tish" ::: "memory"); - for (p = (const char *)((uintptr_t)base & -icache); p < pe; p += icache) { - asm volatile("ic\tivau,%0" : : "r"(p) : "memory"); - } - asm volatile("dsb\tish\nisb" ::: "memory"); -#endif } diff --git a/tool/build/findelf.c b/tool/build/findelf.c new file mode 100644 index 000000000..4b781eae4 --- /dev/null +++ b/tool/build/findelf.c @@ -0,0 +1,65 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│ vi: set et 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/calls/calls.h" +#include "libc/elf/def.h" +#include "libc/elf/struct/ehdr.h" +#include "libc/runtime/runtime.h" +#include "libc/serialize.h" +#include "libc/stdio/ftw.h" +#include "libc/stdio/stdio.h" +#include "libc/str/str.h" +#include "libc/sysv/consts/o.h" + +// finds elf executables +// usage: findelf PATH... + +static int OnFile(const char *fpath, const struct stat *st, int typeflag, + struct FTW *ftwbuf) { + if (typeflag == FTW_F && (st->st_mode & 0111)) { + Elf64_Ehdr ehdr = {0}; + int fd = open(fpath, O_RDONLY); + if (fd != -1) { + pread(fd, &ehdr, sizeof(ehdr), 0); + close(fd); + if (READ32LE(ehdr.e_ident) == READ32LE(ELFMAG) && ehdr.e_type != ET_REL) { + tinyprint(1, fpath, "\n", NULL); + } + } else { + perror(fpath); + } + } + return 0; +} + +static void HandleArg(const char *path) { + if (nftw(path, OnFile, 128, FTW_PHYS | FTW_DEPTH)) { + perror(path); + exit(1); + } +} + +int main(int argc, char *argv[]) { + if (argc <= 1) { + HandleArg("."); + } else { + for (int i = 1; i < argc; ++i) { + HandleArg(argv[i]); + } + } +} diff --git a/tool/build/findpe.c b/tool/build/findpe.c index 548ea288a..68e59dc1a 100644 --- a/tool/build/findpe.c +++ b/tool/build/findpe.c @@ -22,6 +22,9 @@ #include "libc/stdio/stdio.h" #include "libc/sysv/consts/o.h" +// finds portable executables (and actually portable executable) +// usage: findelf PATH... + static int OnFile(const char *fpath, const struct stat *st, int typeflag, struct FTW *ftwbuf) { if (typeflag == FTW_F) { diff --git a/tool/build/fixupobj.c b/tool/build/fixupobj.c index f57192c16..7cb391bce 100644 --- a/tool/build/fixupobj.c +++ b/tool/build/fixupobj.c @@ -29,13 +29,16 @@ #include "libc/errno.h" #include "libc/fmt/itoa.h" #include "libc/fmt/magnumstrs.internal.h" +#include "libc/intrin/kprintf.h" #include "libc/limits.h" #include "libc/log/log.h" #include "libc/macros.internal.h" #include "libc/mem/gc.h" #include "libc/runtime/runtime.h" #include "libc/serialize.h" +#include "libc/stdalign.internal.h" #include "libc/stdckdint.h" +#include "libc/stdio/stdio.h" #include "libc/str/str.h" #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/msync.h" @@ -48,8 +51,10 @@ * @fileoverview GCC Codegen Fixer-Upper. */ -#define COSMO_TLS_REG 28 -#define MRS_TPIDR_EL0 0xd53bd040u +#define COSMO_TLS_REG 28 +#define MRS_TPIDR_EL0 0xd53bd040u +#define IFUNC_SECTION ".init.202.ifunc" + #define MOV_REG(DST, SRC) (0xaa0003e0u | (SRC) << 16 | (DST)) static int mode; @@ -365,6 +370,203 @@ static void RelinkZipFiles(void) { eocd = foot; } +// when __attribute__((__target_clones__(...))) is used, the compiler +// will generate multiple implementations of a function for different +// microarchitectures as well as a resolver function that tells which +// function is appropriate to call. however the compiler doesn't make +// code for the actual function. it also doesn't record where resolve +// functions are located in the binary so we've reverse eng'd it here +static void GenerateIfuncInit(void) { + char *name, *s; + long code_i = 0; + long relas_i = 0; + static char code[16384]; + static Elf64_Rela relas[1024]; + Elf64_Shdr *symtab_shdr = GetElfSymbolTable(elf, esize, SHT_SYMTAB, 0); + if (!symtab_shdr) Die("symbol table section header not found"); + Elf64_Word symtab_shdr_index = + ((char *)symtab_shdr - ((char *)elf + elf->e_shoff)) / elf->e_shentsize; + for (Elf64_Xword i = 0; i < symcount; ++i) { + if (syms[i].st_shndx == SHN_UNDEF) continue; + if (syms[i].st_shndx >= SHN_LORESERVE) continue; + if (ELF64_ST_TYPE(syms[i].st_info) != STT_GNU_IFUNC) continue; + if (!(name = GetElfString(elf, esize, symstrs, syms[i].st_name))) + Die("could not get symbol name of ifunc"); + static char resolver_name[65536]; + strlcpy(resolver_name, name, sizeof(resolver_name)); + if (strlcat(resolver_name, ".resolver", sizeof(resolver_name)) >= + sizeof(resolver_name)) + Die("ifunc name too long"); + Elf64_Xword function_sym_index = i; + Elf64_Xword resolver_sym_index = -1; + for (Elf64_Xword i = 0; i < symcount; ++i) { + if (syms[i].st_shndx == SHN_UNDEF) continue; + if (syms[i].st_shndx >= SHN_LORESERVE) continue; + if (ELF64_ST_TYPE(syms[i].st_info) != STT_FUNC) continue; + if (!(s = GetElfString(elf, esize, symstrs, syms[i].st_name))) continue; + if (strcmp(s, resolver_name)) continue; + resolver_sym_index = i; + break; + } + if (resolver_sym_index == -1) + // this can happen if a function with __target_clones() also has a + // __weak_reference() defined, in which case GCC shall only create + // one resolver function for the two of them so we can ignore this + // HOWEVER the GOT will still have an entry for each two functions + continue; + + // call the resolver (using cosmo's special .init abi) + static const char chunk1[] = { + 0x57, // push %rdi + 0x56, // push %rsi + 0xe8, 0x00, 0x00, 0x00, 0x00, // call f.resolver + }; + if (code_i + sizeof(chunk1) > sizeof(code) || relas_i + 1 > ARRAYLEN(relas)) + Die("too many ifuncs"); + memcpy(code + code_i, chunk1, sizeof(chunk1)); + relas[relas_i].r_info = ELF64_R_INFO(resolver_sym_index, R_X86_64_PLT32); + relas[relas_i].r_offset = code_i + 1 + 1 + 1; + relas[relas_i].r_addend = -4; + code_i += sizeof(chunk1); + relas_i += 1; + + // move the resolved function address into the GOT slot. it's very + // important that this happen, because the linker by default makes + // self-referencing PLT functions whose execution falls through oh + // no. we need to repeat this process for any aliases this defines + static const char chunk2[] = { + 0x48, 0x89, 0x05, 0x00, 0x00, 0x00, 0x00, // mov %rax,f@gotpcrel(%rip) + }; + for (Elf64_Xword i = 0; i < symcount; ++i) { + if (i == function_sym_index || + (ELF64_ST_TYPE(syms[i].st_info) == STT_GNU_IFUNC && + syms[i].st_shndx == syms[function_sym_index].st_shndx && + syms[i].st_value == syms[function_sym_index].st_value)) { + if (code_i + sizeof(chunk2) > sizeof(code) || + relas_i + 1 > ARRAYLEN(relas)) + Die("too many ifuncs"); + memcpy(code + code_i, chunk2, sizeof(chunk2)); + relas[relas_i].r_info = ELF64_R_INFO(i, R_X86_64_GOTPCREL); + relas[relas_i].r_offset = code_i + 3; + relas[relas_i].r_addend = -4; + code_i += sizeof(chunk2); + relas_i += 1; + } + } + + static const char chunk3[] = { + 0x5e, // pop %rsi + 0x5f, // pop %rdi + }; + if (code_i + sizeof(chunk3) > sizeof(code)) Die("too many ifuncs"); + memcpy(code + code_i, chunk3, sizeof(chunk3)); + code_i += sizeof(chunk3); + } + if (!code_i) return; + + // prepare to mutate elf + // remap file so it has more space + if (elf->e_shnum + 2 > 65535) Die("too many sections"); + size_t reserve_size = esize + 32 * 1024 * 1024; + if (ftruncate(fildes, reserve_size)) SysExit("ifunc ftruncate #1"); + elf = mmap((char *)elf, reserve_size, PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_SHARED, fildes, 0); + if (elf == MAP_FAILED) SysExit("ifunc mmap"); + + // duplicate section name strings table to end of file + Elf64_Shdr *shdrstr_shdr = (Elf64_Shdr *)((char *)elf + elf->e_shoff + + elf->e_shstrndx * elf->e_shentsize); + memcpy((char *)elf + esize, (char *)elf + shdrstr_shdr->sh_offset, + shdrstr_shdr->sh_size); + shdrstr_shdr->sh_offset = esize; + esize += shdrstr_shdr->sh_size; + + // append strings for the two sections we're creating + const char *code_section_name = IFUNC_SECTION; + Elf64_Word code_section_name_offset = shdrstr_shdr->sh_size; + memcpy((char *)elf + esize, code_section_name, strlen(code_section_name) + 1); + shdrstr_shdr->sh_size += strlen(code_section_name) + 1; + esize += strlen(code_section_name) + 1; + const char *rela_section_name = ".rela" IFUNC_SECTION; + Elf64_Word rela_section_name_offset = shdrstr_shdr->sh_size; + memcpy((char *)elf + esize, rela_section_name, strlen(rela_section_name) + 1); + shdrstr_shdr->sh_size += strlen(rela_section_name) + 1; + esize += strlen(rela_section_name) + 1; + unassert(esize == shdrstr_shdr->sh_offset + shdrstr_shdr->sh_size); + ++esize; + + // duplicate section headers to end of file + esize = (esize + alignof(Elf64_Shdr) - 1) & -alignof(Elf64_Shdr); + memcpy((char *)elf + esize, (char *)elf + elf->e_shoff, + elf->e_shnum * elf->e_shentsize); + elf->e_shoff = esize; + esize += elf->e_shnum * elf->e_shentsize; + unassert(esize == elf->e_shoff + elf->e_shnum * elf->e_shentsize); + + // append code section header + Elf64_Shdr *code_shdr = (Elf64_Shdr *)((char *)elf + esize); + Elf64_Word code_shdr_index = elf->e_shnum++; + esize += elf->e_shentsize; + code_shdr->sh_name = code_section_name_offset; + code_shdr->sh_type = SHT_PROGBITS; + code_shdr->sh_flags = SHF_ALLOC | SHF_EXECINSTR; + code_shdr->sh_addr = 0; + code_shdr->sh_link = 0; + code_shdr->sh_info = 0; + code_shdr->sh_entsize = 1; + code_shdr->sh_addralign = 1; + code_shdr->sh_size = code_i; + + // append code's rela section header + Elf64_Shdr *rela_shdr = (Elf64_Shdr *)((char *)elf + esize); + esize += elf->e_shentsize; + rela_shdr->sh_name = rela_section_name_offset; + rela_shdr->sh_type = SHT_RELA; + rela_shdr->sh_flags = SHF_INFO_LINK; + rela_shdr->sh_addr = 0; + rela_shdr->sh_info = code_shdr_index; + rela_shdr->sh_link = symtab_shdr_index; + rela_shdr->sh_entsize = sizeof(Elf64_Rela); + rela_shdr->sh_addralign = alignof(Elf64_Rela); + rela_shdr->sh_size = relas_i * sizeof(Elf64_Rela); + elf->e_shnum++; + + // append relas + esize = (esize + 63) & -64; + rela_shdr->sh_offset = esize; + memcpy((char *)elf + esize, relas, relas_i * sizeof(Elf64_Rela)); + esize += relas_i * sizeof(Elf64_Rela); + unassert(esize == rela_shdr->sh_offset + rela_shdr->sh_size); + + // append code + esize = (esize + 63) & -64; + code_shdr->sh_offset = esize; + memcpy((char *)elf + esize, code, code_i); + esize += code_i; + unassert(esize == code_shdr->sh_offset + code_shdr->sh_size); + + if (ftruncate(fildes, esize)) SysExit("ifunc ftruncate #1"); +} + +// when __attribute__((__target_clones__(...))) is used, static binaries +// become poisoned with rela IFUNC relocations, which the linker refuses +// to remove. even if we objcopy the ape executable as binary the linker +// preserves its precious ifunc code and puts them before the executable +// header. the good news is that the linker actually does link correctly +// which means we can delete the broken rela sections in the elf binary. +static void PurgeIfuncSections(void) { + Elf64_Shdr *shdrs = (Elf64_Shdr *)((char *)elf + elf->e_shoff); + for (Elf64_Word i = 0; i < elf->e_shnum; ++i) { + char *name; + if (shdrs[i].sh_type == SHT_RELA || + ((name = GetElfSectionName(elf, esize, shdrs + i)) && + !strcmp(name, ".init.202.ifunc"))) { + shdrs[i].sh_type = SHT_NULL; + shdrs[i].sh_flags &= ~SHF_ALLOC; + } + } +} + static void FixupObject(void) { if ((fildes = open(epath, mode)) == -1) { SysExit("open"); @@ -373,8 +575,8 @@ static void FixupObject(void) { SysExit("lseek"); } if (esize) { - if ((elf = mmap(0, esize, PROT_READ | PROT_WRITE, MAP_SHARED, fildes, 0)) == - MAP_FAILED) { + if ((elf = mmap((void *)0x003210000000, esize, PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_SHARED, fildes, 0)) == MAP_FAILED) { SysExit("mmap"); } if (!IsElf64Binary(elf, esize)) { @@ -393,6 +595,7 @@ static void FixupObject(void) { if (mode == O_RDWR) { if (elf->e_machine == EM_NEXGEN32E) { OptimizePatchableFunctionEntries(); + GenerateIfuncInit(); } else if (elf->e_machine == EM_AARCH64) { RewriteTlsCode(); if (elf->e_type != ET_REL) { @@ -400,6 +603,7 @@ static void FixupObject(void) { } } if (elf->e_type != ET_REL) { + PurgeIfuncSections(); RelinkZipFiles(); } if (msync(elf, esize, MS_ASYNC | MS_INVALIDATE)) { diff --git a/tool/build/mkdeps.c b/tool/build/mkdeps.c index 91dd299de..3aa2a2b69 100644 --- a/tool/build/mkdeps.c +++ b/tool/build/mkdeps.c @@ -19,6 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/struct/stat.h" #include "libc/errno.h" +#include "libc/fmt/itoa.h" #include "libc/fmt/libgen.h" #include "libc/fmt/magnumstrs.internal.h" #include "libc/intrin/kprintf.h" @@ -45,48 +46,48 @@ "copyright 2023 justine tunney\n" \ "https://github.com/jart/cosmopolitan\n" -#define MANUAL \ - " -r o// -o OUTPUT INPUT...\n" \ - "\n" \ - "DESCRIPTION\n" \ - "\n" \ - " Generates header file dependencies for your makefile\n" \ - "\n" \ - " This tool computes the transitive closure of included paths\n" \ - " for every source file in your repository. This program does\n" \ - " it orders of a magnitude faster than `gcc -M` on each file.\n" \ - "\n" \ - " Includes look like this:\n" \ - "\n" \ - " - #include \n" \ - " - #include \"samedir.h\"\n" \ - " - #include \"root/of/repository/foo.h\"\n" \ - " - .include \"asm/x86_64/foo.s\"\n" \ - "\n" \ - " Your generated make code looks like this:\n" \ - "\n" \ - " o//package/foo.o: \\\n" \ - " package/foo.c \\\n" \ - " package/foo.h \\\n" \ - " package/bar.h \\\n" \ - " libc/isystem/stdio.h\n" \ - " o//package/bar.o: \\\n" \ - " package/bar.c \\\n" \ - " package/bar.h\n" \ - "\n" \ - "FLAGS\n" \ - "\n" \ - " -h show usage\n" \ - " -o OUTPUT set output path\n" \ - " -g ROOT set generated path [default: o/]\n" \ - " -r ROOT set build output path, e.g. o/$(MODE)/\n" \ - " -S PATH isystem include path [default: libc/isystem/]\n" \ - " -s hermetically sealed mode [repeatable]\n" \ - "\n" \ - "ARGUMENTS\n" \ - "\n" \ - " OUTPUT shall be makefile code\n" \ - " INPUT should be source or @args.txt\n" \ +#define MANUAL \ + " -r o// -o OUTPUT INPUT...\n" \ + "\n" \ + "DESCRIPTION\n" \ + "\n" \ + " Generates header file dependencies for your makefile\n" \ + "\n" \ + " This tool computes the transitive closure of included paths\n" \ + " for every source file in your repository. This program does\n" \ + " it orders of a magnitude faster than `gcc -M` on each file.\n" \ + "\n" \ + " Includes look like this:\n" \ + "\n" \ + " - #include \n" \ + " - #include \"samedir.h\"\n" \ + " - #include \"root/of/repository/foo.h\"\n" \ + " - .include \"asm/x86_64/foo.s\"\n" \ + "\n" \ + " Your generated make code looks like this:\n" \ + "\n" \ + " o//package/foo.o: \\\n" \ + " package/foo.c \\\n" \ + " package/foo.h \\\n" \ + " package/bar.h \\\n" \ + " libc/isystem/stdio.h\n" \ + " o//package/bar.o: \\\n" \ + " package/bar.c \\\n" \ + " package/bar.h\n" \ + "\n" \ + "FLAGS\n" \ + "\n" \ + " -h show usage\n" \ + " -o OUTPUT set output path\n" \ + " -g ROOT set generated path [default: o/]\n" \ + " -r ROOT set build output path, e.g. o/$(MODE)/\n" \ + " -S PATH isystem include path [repeatable; default: libc/isystem/]\n" \ + " -s hermetically sealed mode [repeatable]\n" \ + "\n" \ + "ARGUMENTS\n" \ + "\n" \ + " OUTPUT shall be makefile code\n" \ + " INPUT should be source or @args.txt\n" \ "\n" #define Read32(s) (s[3] << 24 | s[2] << 16 | s[1] << 8 | s[0]) @@ -118,6 +119,11 @@ struct Edges { struct Edge *p; }; +struct Paths { + long n; + const char *p[64]; +}; + static const uint32_t kSourceExts[] = { EXT("s"), // assembly EXT("S"), // assembly with c preprocessor @@ -135,7 +141,7 @@ static const char *prog; static struct Edges edges; static struct Sauce *sauces; static struct Sources sources; -static const char *systempath; +static struct Paths systempaths; static const char *buildroot; static const char *genroot; static const char *outpath; @@ -329,7 +335,7 @@ static const char *FindIncludePath(const char *map, size_t mapsize, // scan backwards for hash character for (;;) { if (q == map) { - return false; + return 0; } if (IsBlank(q[-1])) { --q; @@ -342,7 +348,7 @@ static const char *FindIncludePath(const char *map, size_t mapsize, --q; break; } else { - return false; + return 0; } } @@ -359,7 +365,7 @@ static const char *FindIncludePath(const char *map, size_t mapsize, if (q[-1] == '\n') { break; } else { - return false; + return 0; } } } @@ -378,7 +384,7 @@ static const char *FindIncludePath(const char *map, size_t mapsize, ++q; break; } else { - return false; + return 0; } } @@ -395,7 +401,7 @@ static void LoadRelationships(int argc, char *argv[]) { struct GetArgs ga; int srcid, dependency; static char srcdirbuf[PATH_MAX]; - const char *p, *pe, *src, *path, *pathend, *srcdir; + const char *p, *pe, *src, *path, *pathend, *srcdir, *final; getargs_init(&ga, argv + optind); while ((src = getargs_next(&ga))) { CreateSourceId(src); @@ -433,51 +439,71 @@ static void LoadRelationships(int argc, char *argv[]) { DieSys(src); } for (p = map, pe = map + size; p < pe; ++p) { - char *bp; - char right; - char buf[PATH_MAX]; if (!(p = memmem(p, pe - p, "include ", 8))) break; if (!(path = FindIncludePath(map, size, p, is_assembly))) continue; - bp = buf; + // copy the specified include path + char right; if (path[-1] == '<') { - if (!systempath) continue; - bp = stpcpy(bp, systempath); + if (!systempaths.n) continue; right = '>'; } else { right = '"'; } - if ((pathend = memchr(path, right, pe - path))) { - const char *final; - char juf[PATH_MAX]; - if ((bp - buf) + (pathend - path) >= PATH_MAX) { - tinyprint(2, src, ": include path too long\n", NULL); - exit(1); - } - *(bp = mempcpy(bp, path, pathend - path)) = 0; - // let foo/bar.c say `#include "foo/hdr.h"` - dependency = GetSourceId((final = buf)); - // let foo/bar.c say `#include "hdr.h"` - if (dependency == -1 && right == '"' && !strchr(buf, '/')) { - if (!(final = __join_paths(juf, PATH_MAX, srcdir, buf))) { - DiePathTooLong(buf); + if (!(pathend = memchr(path, right, pe - path))) continue; + if (pathend - path >= PATH_MAX) { + tinyprint(2, src, ": uses really long include path\n", NULL); + exit(1); + } + char juf[PATH_MAX]; + char incpath[PATH_MAX]; + *(char *)mempcpy(incpath, path, pathend - path) = 0; + if (right == '>') { + // handle angle bracket includes + dependency = -1; + for (long i = 0; i < systempaths.n; ++i) { + if (!(final = + __join_paths(juf, PATH_MAX, systempaths.p[i], incpath))) { + DiePathTooLong(incpath); + } + if ((dependency = GetSourceId(final)) != -1) { + break; } - dependency = GetSourceId(final); } - if (dependency == -1) { - if (startswith(buf, genroot)) { - dependency = CreateSourceId(src); - } else if (!hermetic) { - continue; - } else if (hermetic == 1 && right == '>') { + if (dependency != -1) { + AppendEdge(&edges, dependency, srcid); + p = pathend + 1; + } else { + if (hermetic == 1) { // chances are the `#include ` is in some #ifdef // that'll never actually be executed; thus we ignore // since landlock make unveil() shall catch it anyway continue; + } + tinyprint(2, incpath, + ": system header not specified by the HDRS/SRCS/INCS " + "make variables defined by the hermetic mono repo\n", + NULL); + exit(1); + } + } else { + // handle double quote includes + // let foo/bar.c say `#include "foo/hdr.h"` + dependency = GetSourceId((final = incpath)); + // let foo/bar.c say `#include "hdr.h"` + if (dependency == -1 && !strchr(final, '/')) { + if (!(final = __join_paths(juf, PATH_MAX, srcdir, final))) { + DiePathTooLong(incpath); + } + dependency = GetSourceId(final); + } + if (dependency == -1) { + if (startswith(final, genroot)) { + dependency = CreateSourceId(src); } else { - tinyprint( - 2, final, - ": path not specified by HDRS/SRCS/INCS make variables\n", - NULL); + tinyprint(2, incpath, + ": path not specified by HDRS/SRCS/INCS make variables " + "(it was included by ", + src, ")\n", NULL); exit(1); } } @@ -498,6 +524,13 @@ static wontreturn void ShowUsage(int rc, int fd) { exit(rc); } +static void AddPath(struct Paths *paths, const char *path) { + if (paths->n == ARRAYLEN(paths->p)) { + Die("too many path arguments"); + } + paths->p[paths->n++] = path; +} + static void GetOpts(int argc, char *argv[]) { int opt; while ((opt = getopt(argc, argv, "hnsgS:o:r:")) != -1) { @@ -506,10 +539,7 @@ static void GetOpts(int argc, char *argv[]) { ++hermetic; break; case 'S': - if (systempath) { - Die("multiple system paths not supported yet"); - } - systempath = optarg; + AddPath(&systempaths, optarg); break; case 'o': if (outpath) { @@ -555,29 +585,33 @@ static void GetOpts(int argc, char *argv[]) { if (!startswith(buildroot, genroot)) { Die("build output path must start with generated output path"); } - if (!systempath && hermetic) { - systempath = "libc/isystem/"; + if (!systempaths.n && hermetic) { + AddPath(&systempaths, "third_party/libcxx/include/"); + AddPath(&systempaths, "libc/isystem/"); } - if (systempath && !hermetic) { + if (systempaths.n && !hermetic) { Die("system path can only be specified in hermetic mode"); } - if (systempath) { + long j = 0; + for (long i = 0; i < systempaths.n; ++i) { size_t n; struct stat st; - if (stat(systempath, &st)) { - DieSys(systempath); + const char *path = systempaths.p[i]; + if (!stat(path, &st)) { + systempaths.p[j++] = path; + if (!S_ISDIR(st.st_mode)) { + errno = ENOTDIR; + DieSys(path); + } } - if (!S_ISDIR(st.st_mode)) { - errno = ENOTDIR; - DieSys(systempath); + if ((n = strlen(path)) >= PATH_MAX) { + DiePathTooLong(path); } - if ((n = strlen(systempath)) >= PATH_MAX) { - DiePathTooLong(systempath); - } - if (!n || systempath[n - 1] != '/') { + if (!n || path[n - 1] != '/') { Die("system path must end with slash"); } } + systempaths.n = j; } static const char *StripExt(char pathbuf[hasatleast PATH_MAX], const char *s) { diff --git a/tool/build/objbincopy.c b/tool/build/objbincopy.c index a17b3fb63..ab3a906b5 100644 --- a/tool/build/objbincopy.c +++ b/tool/build/objbincopy.c @@ -201,7 +201,7 @@ static void ValidateMachoSection(const char *inpath, // Die(inpath, "don't bother with mach-o sections"); } namelen = strnlen(loadseg->name, sizeof(loadseg->name)); - if (!loadseg->name) { + if (!loadseg->name[0]) { Die(inpath, "mach-o load segment missing name"); } if (filesize || (loadseg->vaddr && loadseg->memsz)) { diff --git a/tool/build/package.c b/tool/build/package.c index df271c788..b52299eff 100644 --- a/tool/build/package.c +++ b/tool/build/package.c @@ -433,7 +433,8 @@ static void LoadSymbols(struct Package *pkg, uint32_t object) { symbol.type = ELF64_ST_TYPE(obj->syms[i].st_info); if (symbol.bind_ != STB_LOCAL && (symbol.type == STT_OBJECT || symbol.type == STT_FUNC || - symbol.type == STT_COMMON || symbol.type == STT_NOTYPE)) { + symbol.type == STT_COMMON || symbol.type == STT_NOTYPE || + symbol.type == STT_GNU_IFUNC)) { if (!(name = GetElfString(obj->elf, obj->size, obj->strs, obj->syms[i].st_name))) { Die("error", "elf overflow"); diff --git a/tool/build/runit.c b/tool/build/runit.c index 9dc1a897e..f94f735ea 100644 --- a/tool/build/runit.c +++ b/tool/build/runit.c @@ -151,17 +151,11 @@ void Connect(void) { struct timespec deadline; if ((rc = getaddrinfo(g_hostname, gc(xasprintf("%hu", g_runitdport)), &kResolvHints, &ai)) != 0) { - FATALF("%s:%hu: EAI_%s %m", g_hostname, g_runitdport, gai_strerror(rc)); + FATALF("%s:%hu: DNS lookup failed: %s", g_hostname, g_runitdport, + gai_strerror(rc)); __builtin_unreachable(); } ip4 = (const char *)&((struct sockaddr_in *)ai->ai_addr)->sin_addr; - if (ispublicip(ai->ai_family, - &((struct sockaddr_in *)ai->ai_addr)->sin_addr)) { - FATALF("%s points to %hhu.%hhu.%hhu.%hhu" - " which isn't part of a local/private/testing subnet", - g_hostname, ip4[0], ip4[1], ip4[2], ip4[3]); - __builtin_unreachable(); - } DEBUGF("connecting to %d.%d.%d.%d port %d", ip4[0], ip4[1], ip4[2], ip4[3], ntohs(((struct sockaddr_in *)ai->ai_addr)->sin_port)); CHECK_NE(-1, diff --git a/tool/decode/elf.c b/tool/decode/elf.c index 314603fb4..2e59203d4 100644 --- a/tool/decode/elf.c +++ b/tool/decode/elf.c @@ -26,7 +26,6 @@ #include "libc/errno.h" #include "libc/fmt/conv.h" #include "libc/fmt/libgen.h" -#include "libc/serialize.h" #include "libc/intrin/safemacros.internal.h" #include "libc/log/check.h" #include "libc/log/log.h" @@ -34,6 +33,7 @@ #include "libc/mem/gc.h" #include "libc/mem/mem.h" #include "libc/runtime/runtime.h" +#include "libc/serialize.h" #include "libc/stdio/stdio.h" #include "libc/str/str.h" #include "libc/sysv/consts/auxv.h" diff --git a/tool/emacs/c.lang b/tool/emacs/c.lang index a2805763a..99f7d7c08 100644 --- a/tool/emacs/c.lang +++ b/tool/emacs/c.lang @@ -125,7 +125,7 @@ Keywords={ "mayalias", "dontinstrument", "interruptfn", -"nocallback", +"dontcallback", "textstartup", "warnifused", "attributeallocsize", diff --git a/tool/emacs/cosmo-asm-mode.el b/tool/emacs/cosmo-asm-mode.el index 580fa0b01..70fd0edd2 100644 --- a/tool/emacs/cosmo-asm-mode.el +++ b/tool/emacs/cosmo-asm-mode.el @@ -67,7 +67,8 @@ "progbits" "nobits" "init_array" - "fini_array")]) + "fini_array" + "gnu_indirect_function")]) "\\>"]) "GNU Assembler section, relocation, macro param qualifiers.") diff --git a/tool/emacs/cosmo-c-keywords.el b/tool/emacs/cosmo-c-keywords.el index f3aa5b349..7fd7cdd30 100644 --- a/tool/emacs/cosmo-c-keywords.el +++ b/tool/emacs/cosmo-c-keywords.el @@ -91,7 +91,7 @@ "mayalias" "dontinstrument" "interruptfn" - "nocallback" + "dontcallback" "textstartup" "warnifused" "attributeallocsize" @@ -206,6 +206,9 @@ "__section__" "__sentinel__" "__simd__" + "__vex" + "__avx2" + "__target_clones" "__target_clones__" "__unused__" "__used__" diff --git a/tool/emacs/cosmo-platform-constants.el b/tool/emacs/cosmo-platform-constants.el index 6ba7d8014..65a84a434 100644 --- a/tool/emacs/cosmo-platform-constants.el +++ b/tool/emacs/cosmo-platform-constants.el @@ -71,7 +71,8 @@ "__SUPPORT_SNAN__" "__GCC_IEC_559_COMPLEX" "__NO_MATH_ERRNO__" - "__gnu__")) + "__gnu__" + "_OPENMP")) (cosmo '("__LINKER__")) diff --git a/tool/emacs/cosmo-stuff.el b/tool/emacs/cosmo-stuff.el index 22cd41d0a..c7ba003a3 100644 --- a/tool/emacs/cosmo-stuff.el +++ b/tool/emacs/cosmo-stuff.el @@ -215,7 +215,7 @@ (runs (format "o/$m/%s.com%s V=5 TESTARGS=-b" name runsuffix)) (buns (format "o/$m/test/%s_test.com%s V=5 TESTARGS=-b" name runsuffix))) (cond ((not (member ext '("c" "cc" "cpp" "s" "S" "rl" "f"))) - (format "m=%s; make -j12 MODE=$m o/$m/%s" + (format "m=%s; make -j32 MODE=$m o/$m/%s" mode (directory-file-name (or (file-name-directory @@ -226,7 +226,7 @@ (cosmo-join " && " `("m=%s; f=o/$m/%s.com" - ,(concat "make -j12 $f MODE=$m") + ,(concat "make -j32 $f MODE=$m") "scp $f $f.dbg win10:; ssh win10 ./%s.com")) mode name (file-name-nondirectory name))) ((eq kind 'run-xnu) @@ -234,19 +234,19 @@ (cosmo-join " && " `("m=%s; f=o/$m/%s.com" - ,(concat "make -j12 $f MODE=$m") + ,(concat "make -j32 $f MODE=$m") "scp $f $f.dbg xnu:" "ssh xnu ./%s.com")) mode name (file-name-nondirectory name))) ((and (equal suffix "") (cosmo-contains "_test." (buffer-file-name))) - (format "m=%s; make -j12 MODE=$m %s" + (format "m=%s; make -j32 MODE=$m %s" mode runs)) ((and (equal suffix "") (file-exists-p (format "%s" buddy))) (format (cosmo-join " && " - '("m=%s; n=%s; make -j12 o/$m/$n%s.o MODE=$m" + '("m=%s; n=%s; make -j32 o/$m/$n%s.o MODE=$m" ;; "bloat o/$m/%s.o | head" ;; "nm -C --size o/$m/%s.o | sort -r" "echo" @@ -258,11 +258,11 @@ (cosmo-join " && " `("m=%s; f=o/$m/%s.com" - ,(concat "make -j12 $f MODE=$m") + ,(concat "make -j32 $f MODE=$m") "build/run ./$f")) mode name)) ((eq kind 'test) - (format `"m=%s; f=o/$m/%s.com.ok && make -j12 $f MODE=$m" mode name)) + (format `"m=%s; f=o/$m/%s.com.ok && make -j32 $f MODE=$m" mode name)) ((and (file-regular-p this) (file-executable-p this)) (format "build/run ./%s" file)) @@ -271,7 +271,7 @@ (cosmo-join " && " `("m=%s; f=o/$m/%s%s.o" - ,(concat "make -j12 $f MODE=$m") + ,(concat "make -j32 $f MODE=$m") ;; "nm -C --size $f | sort -r" "echo" "size -A $f | grep '^[.T]' | grep -v 'debug\\|command.line\\|stack' | sort -rnk2" @@ -481,7 +481,7 @@ (error "don't know how to show assembly for non c/c++ source file")) (let* ((default-directory root) (compile-command - (format "make %s -j12 MODE=%s %s %s" + (format "make %s -j32 MODE=%s %s %s" (or extra-make-flags "") mode asm-gcc asm-clang))) (save-buffer) (set-visited-file-modtime (current-time)) @@ -641,11 +641,11 @@ (compile (format "sh -c %s" file))) ((eq major-mode 'lua-mode) (let* ((mode (cosmo--make-mode arg))) - (compile (format "make -j16 MODE=%s o/%s/tool/net/redbean.com && build/run o/%s/tool/net/redbean.com -i %s" mode mode mode file)))) + (compile (format "make -j32 MODE=%s o/%s/tool/net/redbean.com && build/run o/%s/tool/net/redbean.com -i %s" mode mode mode file)))) ((and (eq major-mode 'python-mode) (cosmo-startswith "third_party/python/Lib/test/" file)) (let ((mode (cosmo--make-mode arg))) - (compile (format "make -j12 MODE=%s PYHARNESSARGS=-vv PYTESTARGS=-v o/%s/%s.py.runs" + (compile (format "make -j32 MODE=%s PYHARNESSARGS=-vv PYTESTARGS=-v o/%s/%s.py.runs" mode mode (file-name-sans-extension file))))) ((eq major-mode 'python-mode) (compile (format "python.com %s" file))) @@ -692,8 +692,10 @@ (define-key lua-mode-map (kbd "C-c C-r") 'cosmo-run) (define-key python-mode-map (kbd "C-c C-r") 'cosmo-run) (define-key c-mode-map (kbd "C-c C-s") 'cosmo-run-test) + (define-key c++-mode-map (kbd "C-c C-s") 'cosmo-run-test) (define-key c-mode-map (kbd "C-c C-_") 'cosmo-run-win7) - (define-key c-mode-map (kbd "C-c C-_") 'cosmo-run-win10)) + (define-key c-mode-map (kbd "C-c C-_") 'cosmo-run-win10) + (define-key c++-mode-map (kbd "C-c C-_") 'cosmo-run-win10)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -939,7 +941,7 @@ "T[0-9][0-9]:[0-9][0-9]:[0-9][0-9]" ;; time "[+.][0-9][0-9][0-9][0-9][0-9][0-9]" ;; micros ":\\([^:]+\\)" ;; file - ":\\([0-9]+\\)")) ;; line + ":\\([0-9]+\\)")) ;; line 1 2)) (eval-after-load 'compile @@ -948,6 +950,20 @@ (cons 'cosmo cosmo-compilation-regexps)) (add-to-list 'compilation-error-regexp-alist 'cosmo))) +(defvar cosmo-gcc123-compilation-regexps + (list (cosmo-join + "" + '("inlined from '[^']*' at " + "\\([^:]+\\)" ;; file + ":\\([0-9]+\\)")) ;; line + 1 2)) + +(eval-after-load 'compile + '(progn + (add-to-list 'compilation-error-regexp-alist-alist + (cons 'cosmo cosmo-gcc123-compilation-regexps)) + (add-to-list 'compilation-error-regexp-alist 'cosmo))) + (provide 'cosmo-stuff) ;;; cosmo-stuff.el ends here diff --git a/tool/emacs/key.py b/tool/emacs/key.py index 6da461954..43a8b7c73 100644 --- a/tool/emacs/key.py +++ b/tool/emacs/key.py @@ -340,7 +340,7 @@ cosmo_kws = frozenset([ "mallocesque", "mayalias", "memcpyesque", - "nocallback", + "dontcallback", "nodebuginfo", "__wur", "dontinline", @@ -399,7 +399,7 @@ cosmo_kws = frozenset([ "mallocesque", "mayalias", "memcpyesque", - "nocallback", + "dontcallback", "nodebuginfo", "__wur", "dontinline", diff --git a/tool/viz/printpeb.c b/tool/viz/printpeb.c index 3d3ee1a61..7d9abbc43 100644 --- a/tool/viz/printpeb.c +++ b/tool/viz/printpeb.c @@ -188,7 +188,7 @@ dontasan void PrintTeb(void) { } void PrintPeb(void) { - struct NtPeb *peb = NtGetPeb(); + __seg_gs struct NtPeb *peb = NtGetPeb(); printf("\n\ ╔──────────────────────────────────────────────────────────────────────────────╗\n\ │ new technology § peb │\n\ @@ -327,8 +327,6 @@ void PrintPeb(void) { "pShimData", peb->pShimData); printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, AppCompatInfo), "AppCompatInfo", peb->AppCompatInfo); - printf("0x%04x: %-40s = \"%s\"\n", offsetof(struct NtPeb, CSDVersion), - "CSDVersion", GetString(&peb->CSDVersion)); printf("0x%04x: %-40s = 0x%lx\n", offsetof(struct NtPeb, ActivationContextData), "ActivationContextData", peb->ActivationContextData);