From ff77f2a6afd9bf18d64c7f983bc08aa376683e00 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Mon, 2 Oct 2023 19:25:19 -0700 Subject: [PATCH] Make improvements - This change fixes a bug that allowed unbuffered printf() output (to streams like stderr) to be truncated. This regression was introduced some time between now and the last release. - POSIX specifies all functions as thread safe by default. This change works towards cleaning up our use of the @threadsafe / @threadunsafe documentation annotations to reflect that. The goal is (1) to use @threadunsafe to document functions which POSIX say needn't be thread safe, and (2) use @threadsafe to document functions that we chose to implement as thread safe even though POSIX didn't mandate it. - Tidy up the clock_gettime() implementation. We're now trying out a cleaner approach to system call support that aims to maintain the Linux errno convention as long as possible. This also fixes bugs that existed previously, where the vDSO errno wasn't being translated properly. The gettimeofday() system call is now a wrapper for clock_gettime(), which reduces bloat in apps that use both. - The recently-introduced improvements to the execute bit on Windows has had bugs fixed. access(X_OK) on a directory on Windows now succeeds. fstat() will now perform the MZ/#! ReadFile() operation correctly. - Windows.h is no longer included in libc/isystem/, because it confused PCRE's build system into thinking Cosmopolitan is a WIN32 platform. Cosmo's Windows.h polyfill was never even really that good, since it only defines a subset of the subset of WIN32 APIs that Cosmo defines. - The setlongerjmp() / longerjmp() APIs are removed. While they're nice APIs that are superior to the standardized setjmp / longjmp functions, they weren't superior enough to not be dead code in the monorepo. If you use these APIs, please file an issue and they'll be restored. - The .com appending magic has now been removed from APE Loader. --- ape/ape-m1.c | 57 +- ape/loader.c | 46 +- dsp/mpeg/mpeg1.c | 1 + libc/calls/calls.mk | 2 + libc/calls/clock.c | 2 +- libc/calls/clock_getres.c | 1 - libc/calls/clock_gettime-mono.c | 33 +- libc/calls/clock_gettime-nt.c | 8 +- ...lock_gettime-m1.c => clock_gettime-sysv.c} | 11 +- libc/calls/clock_gettime-xnu.c | 46 +- libc/calls/clock_gettime.c | 167 +- libc/calls/clock_gettime.internal.h | 16 - libc/calls/clock_nanosleep-xnu.c | 36 +- libc/calls/clock_nanosleep.c | 28 +- libc/calls/creat.c | 1 - libc/calls/fstat-nt.c | 2 +- libc/calls/fstatvfs.c | 2 + libc/calls/ftruncate.c | 1 - libc/calls/futimens.c | 1 - libc/calls/futimes.c | 1 - libc/calls/getcontext.S | 1 - libc/calls/getppid.c | 1 - libc/calls/getrusage-nt.c | 2 +- libc/calls/gettimeofday-m1.c | 35 - libc/calls/gettimeofday-metal.c | 25 - libc/calls/gettimeofday-nt.c | 31 - libc/calls/gettimeofday-xnu.c | 31 - libc/calls/gettimeofday.c | 83 +- libc/calls/getuid.c | 2 - libc/calls/lseek.c | 1 - libc/calls/makedirs.c | 1 - libc/calls/mkdir.c | 1 - libc/calls/munmap-sysv.c | 1 - libc/calls/nanosleep-xnu.c | 51 - libc/calls/nanosleep.c | 6 +- libc/calls/ntaccesscheck.c | 7 +- libc/calls/open.c | 1 - libc/calls/openat.c | 1 - libc/calls/pledge-linux.c | 1 - libc/calls/pledge.c | 1 - libc/calls/poll.c | 1 - libc/calls/posix_fadvise.c | 1 - libc/calls/posix_madvise.c | 1 - libc/calls/ppoll.c | 1 - libc/calls/pread.c | 1 - libc/calls/pwrite.c | 1 - libc/calls/read-nt.c | 4 +- libc/calls/reservefd.c | 2 - libc/calls/siginfo2cosmo.c | 8 + libc/calls/state.internal.h | 1 - libc/calls/statvfs.c | 2 + libc/calls/{__clock_gettime.c => stime.c} | 10 +- libc/calls/struct/timespec.internal.h | 6 +- libc/calls/struct/timeval.internal.h | 5 - libc/calls/swapcontext.S | 1 - libc/calls/syscall_support-sysv.internal.h | 5 + libc/calls/timespec_real.c | 2 +- libc/calls/tmpfd.c | 1 - libc/calls/truncate.c | 1 - libc/calls/ttyname.c | 2 +- libc/calls/ttyname_r.c | 1 - libc/calls/ucontext.c | 1 - libc/calls/unveil.c | 1 - libc/calls/utime.c | 1 - libc/calls/utimensat-nt.c | 3 +- libc/calls/utimensat.c | 1 - libc/calls/utimes.c | 1 - libc/calls/vdsofunc.greg.c | 17 +- libc/calls/weirdtypes.h | 2 + libc/calls/winexec.c | 17 +- libc/calls/write-nt.c | 4 +- libc/dns/freeaddrinfo.c | 1 - libc/dns/getaddrinfo.c | 1 - libc/dns/gethoststxt.c | 1 - libc/dns/getresolvconf.c | 1 - libc/dns/lookupservicesbyname.c | 1 - libc/fmt/conv.h | 59 +- libc/fmt/wintime.internal.h | 41 + libc/intrin/bt.c | 68 - libc/intrin/closehandle.c | 37 - libc/intrin/cp.c | 4 +- libc/intrin/directmap.c | 1 - libc/intrin/exit.c | 1 - libc/intrin/exit1.greg.c | 1 - libc/intrin/getmainstack.c | 7 + libc/intrin/getpid.c | 1 - libc/intrin/gettid.c | 1 - libc/intrin/rand64.c | 1 - libc/intrin/strace.internal.h | 13 +- libc/intrin/strsignal.c | 3 +- libc/intrin/strsignal_r.c | 1 - libc/intrin/unsetenv.c | 8 +- libc/isystem/sys/param.h | 2 +- libc/isystem/windows.h | 1507 ----------------- libc/log/die.c | 1 - libc/log/minicrash.c | 1 - libc/log/vflogf.c | 1 - libc/macros.internal.h | 8 + libc/mem/aligned_alloc.c | 1 - libc/mem/calloc.c | 1 - libc/mem/free.c | 1 - libc/mem/gc.c | 2 - libc/mem/get_current_dir_name.c | 1 - libc/mem/hook_realloc_in_place.c | 1 - libc/mem/malloc.c | 1 - libc/mem/malloc_usable_size.c | 1 - libc/mem/memalign.c | 1 - libc/mem/posix_memalign.c | 1 - libc/mem/pvalloc.c | 1 - libc/mem/realloc.c | 1 - libc/mem/reallocarray.c | 1 - libc/mem/strdup.c | 1 - libc/mem/strndup.c | 1 - libc/mem/valloc.c | 1 - libc/mem/wcsdup.c | 1 - libc/nexgen32e/gc.S | 1 - libc/nexgen32e/gclongjmp.S | 1 - libc/nt/kernel32/CloseHandle.S | 18 + libc/nt/master.sh | 2 +- libc/proc/fork.c | 1 - libc/proc/posix_spawn.c | 3 +- libc/proc/systemvpe.c | 1 - libc/proc/vfork.S | 1 - libc/proc/wait4-nt.c | 2 +- libc/runtime/clktck.c | 2 +- libc/runtime/clone.c | 1 - libc/runtime/isheap.c | 3 + libc/runtime/runtime.h | 10 +- libc/runtime/zipos-close.c | 1 - libc/runtime/zipos-get.c | 1 - libc/runtime/zipos-open.c | 1 - libc/sock/pselect.c | 1 - libc/sock/select.c | 1 - libc/stdio/asprintf.c | 1 - libc/stdio/clearerr.c | 1 - libc/stdio/clearerr_unlocked.c | 1 - libc/stdio/dirstream.c | 6 +- libc/stdio/feof.c | 1 - libc/stdio/ferror.c | 1 - libc/stdio/fflush.c | 1 - libc/stdio/fgetc.c | 1 - libc/stdio/fgets.c | 1 - libc/stdio/fgetwc.c | 1 - libc/stdio/fgetws.c | 1 - libc/stdio/fileno.c | 1 - libc/stdio/fputc.c | 1 - libc/stdio/fputs.c | 1 - libc/stdio/fputwc.c | 1 - libc/stdio/fputws.c | 1 - libc/stdio/fread.c | 1 - libc/stdio/fseek.c | 1 - libc/stdio/ftell.c | 1 - libc/stdio/ftw.c | 1 + libc/stdio/fwrite.c | 1 - libc/stdio/getwchar.c | 1 - libc/stdio/nftw.c | 1 + libc/stdio/popen.c | 1 - libc/stdio/putchar.c | 1 - libc/stdio/putwchar.c | 1 - libc/stdio/rand.c | 1 + libc/{calls => stdio}/sysparam.h | 16 +- libc/stdio/tmpfile.c | 1 - libc/stdio/ungetc.c | 1 - libc/stdio/ungetwc.c | 1 - libc/stdio/vasprintf.c | 1 - libc/stdio/vfprintf_unlocked.c | 5 +- libc/str/dosdatetimetounix.c | 2 +- libc/str/getzipcfiletimestamps.c | 2 +- libc/str/str.mk | 1 + libc/str/strtok.c | 2 +- libc/str/timespectowindowstime.c | 2 +- libc/str/timevaltowindowstime.c | 2 +- libc/str/windowsdurationtotimespec.c | 2 +- libc/str/windowsdurationtotimeval.c | 2 +- libc/str/windowstimetotimespec.c | 2 +- libc/str/windowstimetotimeval.c | 2 +- libc/sysv/calls/sys_clock_gettime.S | 2 - libc/sysv/calls/sys_gettimeofday.S | 2 - libc/sysv/consts.sh | 2 +- libc/sysv/consts/ENOBUFS.S | 3 + libc/sysv/syscall.S | 85 - .../setlongerjmp.S => sysv/syscall2.S} | 63 +- .../longerjmp.S => sysv/syscall3.S} | 62 +- libc/sysv/syscalls.sh | 2 - libc/sysv/sysv.mk | 7 +- libc/testlib/ezbenchcontrol.c | 9 +- libc/thread/makecontext.c | 1 - libc/thread/pthread_create.c | 1 - libc/thread/pthread_detach.c | 1 - libc/thread/pthread_exit.c | 1 - libc/thread/pthread_join.c | 1 - libc/thread/pthread_timedjoin_np.c | 1 - libc/thread/pthread_tryjoin_np.c | 1 - libc/thread/sem_open.c | 1 - libc/thread/tls.h | 5 +- libc/time/ctime.c | 4 + libc/time/iso8601.c | 1 - libc/time/iso8601us.c | 1 - libc/time/localtime.c | 7 + libc/time/time.h | 1 + libc/time/times.c | 2 +- libc/x/xload.c | 1 - test/libc/calls/clock_gettime_test.c | 44 +- test/libc/calls/commandv_test.c | 20 +- test/libc/calls/open_test.c | 8 +- test/libc/calls/sigbus_test.c | 108 ++ test/libc/calls/stat_test.c | 13 +- test/libc/fmt/timevaltofiletime_test.c | 4 +- test/libc/proc/posix_spawn_test.c | 25 - test/libc/time/clock_gettime_test.c | 35 - third_party/chibicc/alloc.c | 4 +- third_party/libcxx/filesystem_common.hh | 1 + third_party/libcxx/thread.cc | 2 +- third_party/musl/grp.c | 13 + third_party/musl/pwd.c | 7 +- third_party/nsync/futex.c | 2 - third_party/python/Modules/_threadmodule.c | 2 +- third_party/python/Modules/posixmodule.c | 2 +- third_party/python/Modules/timemodule.c | 2 +- third_party/python/PC/winreg.c | 28 +- third_party/sqlite3/os_unix.c | 2 +- third_party/zip/unix.c | 2 +- third_party/zstd/programs/util.c | 2 +- tool/build/lib/elfwriter_zip.c | 2 +- tool/decode/zip.c | 2 +- tool/net/redbean.c | 1 + 226 files changed, 708 insertions(+), 2657 deletions(-) rename libc/calls/{clock_gettime-m1.c => clock_gettime-sysv.c} (85%) delete mode 100644 libc/calls/clock_gettime.internal.h delete mode 100644 libc/calls/gettimeofday-m1.c delete mode 100644 libc/calls/gettimeofday-metal.c delete mode 100644 libc/calls/gettimeofday-nt.c delete mode 100644 libc/calls/gettimeofday-xnu.c delete mode 100644 libc/calls/nanosleep-xnu.c rename libc/calls/{__clock_gettime.c => stime.c} (90%) create mode 100644 libc/fmt/wintime.internal.h delete mode 100644 libc/intrin/bt.c delete mode 100644 libc/intrin/closehandle.c delete mode 100644 libc/isystem/windows.h rename libc/{calls => stdio}/sysparam.h (75%) delete mode 100644 libc/sysv/calls/sys_clock_gettime.S delete mode 100644 libc/sysv/calls/sys_gettimeofday.S delete mode 100644 libc/sysv/syscall.S rename libc/{nexgen32e/setlongerjmp.S => sysv/syscall2.S} (68%) rename libc/{nexgen32e/longerjmp.S => sysv/syscall3.S} (68%) create mode 100644 test/libc/calls/sigbus_test.c delete mode 100644 test/libc/time/clock_gettime_test.c diff --git a/ape/ape-m1.c b/ape/ape-m1.c index 6db098e53..d77cefd51 100644 --- a/ape/ape-m1.c +++ b/ape/ape-m1.c @@ -76,7 +76,8 @@ struct Syslib { long (*write)(int, const void *, size_t); long (*read)(int, void *, size_t); long (*sigaction)(int, const struct sigaction *, struct sigaction *); - long (*pselect)(int, fd_set *, fd_set *, fd_set *, const struct timespec *, const sigset_t *); + long (*pselect)(int, fd_set *, fd_set *, fd_set *, const struct timespec *, + const sigset_t *); long (*mprotect)(void *, size_t, int); }; @@ -187,10 +188,6 @@ struct ApeLoader { char rando[16]; }; -static int ToLower(int c) { - return 'A' <= c && c <= 'Z' ? c + ('a' - 'A') : c; -} - static unsigned long StrLen(const char *s) { unsigned long n = 0; while (*s++) ++n; @@ -349,38 +346,14 @@ __attribute__((__noreturn__)) static void Pexit(const char *c, int failed, _exit(127); } -static char EndsWithIgnoreCase(const char *p, unsigned long n, const char *s) { - unsigned long i, m; - if (n >= (m = StrLen(s))) { - for (i = n - m; i < n; ++i) { - if (ToLower(p[i]) != *s++) { - return 0; - } - } - return 1; - } else { - return 0; - } -} - -static char IsComPath(struct PathSearcher *ps) { - return EndsWithIgnoreCase(ps->name, ps->namelen, ".com") || - EndsWithIgnoreCase(ps->name, ps->namelen, ".exe") || - EndsWithIgnoreCase(ps->name, ps->namelen, ".com.dbg"); -} - -static char AccessCommand(struct PathSearcher *ps, const char *suffix, - unsigned long pathlen) { - unsigned long suffixlen; - suffixlen = StrLen(suffix); - if (pathlen + 1 + ps->namelen + suffixlen + 1 > sizeof(ps->path)) return 0; +static char AccessCommand(struct PathSearcher *ps, unsigned long pathlen) { + if (pathlen + 1 + ps->namelen + 1 > sizeof(ps->path)) return 0; if (pathlen && ps->path[pathlen - 1] != '/') ps->path[pathlen++] = '/'; MemMove(ps->path + pathlen, ps->name, ps->namelen); - MemMove(ps->path + pathlen + ps->namelen, suffix, suffixlen + 1); return !access(ps->path, X_OK); } -static char SearchPath(struct PathSearcher *ps, const char *suffix) { +static char SearchPath(struct PathSearcher *ps) { const char *p; unsigned long i; for (p = ps->syspath;;) { @@ -389,7 +362,7 @@ static char SearchPath(struct PathSearcher *ps, const char *suffix) { ps->path[i] = p[i]; } } - if (AccessCommand(ps, suffix, i)) { + if (AccessCommand(ps, i)) { return 1; } else if (p[i] == ':') { p += i + 1; @@ -399,13 +372,13 @@ static char SearchPath(struct PathSearcher *ps, const char *suffix) { } } -static char FindCommand(struct PathSearcher *ps, const char *suffix) { +static char FindCommand(struct PathSearcher *ps) { ps->path[0] = 0; /* paths are always 100% taken literally when a slash exists $ ape foo/bar.com arg1 arg2 */ if (MemChr(ps->name, '/', ps->namelen)) { - return AccessCommand(ps, suffix, 0); + return AccessCommand(ps, 0); } /* we don't run files in the current directory @@ -416,12 +389,12 @@ static char FindCommand(struct PathSearcher *ps, const char *suffix) { however we will execute this $ ape - foo.com foo.com arg1 arg2 because cosmo's execve needs it */ - if (ps->literally && AccessCommand(ps, suffix, 0)) { + if (ps->literally && AccessCommand(ps, 0)) { return 1; } /* otherwise search for name on $PATH */ - return SearchPath(ps, suffix); + return SearchPath(ps); } static char *Commandv(struct PathSearcher *ps, const char *name, @@ -429,7 +402,7 @@ static char *Commandv(struct PathSearcher *ps, const char *name, ps->syspath = syspath ? syspath : "/bin:/usr/local/bin:/usr/bin"; if (!(ps->namelen = StrLen((ps->name = name)))) return 0; if (ps->namelen + 1 > sizeof(ps->path)) return 0; - if (FindCommand(ps, "") || (!IsComPath(ps) && FindCommand(ps, ".com"))) { + if (FindCommand(ps)) { return ps->path; } else { return 0; @@ -843,12 +816,14 @@ static long sys_mmap(void *addr, size_t size, int prot, int flags, int fd, return sysret((long)mmap(addr, size, prot, flags, fd, off)); } -static long sys_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { +static long sys_sigaction(int sig, const struct sigaction *act, + struct sigaction *oact) { return sysret(sigaction(sig, act, oact)); } -static long sys_pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds, - const struct timespec *timeout, const sigset_t *sigmask) { +static long sys_pselect(int nfds, fd_set *readfds, fd_set *writefds, + fd_set *errorfds, const struct timespec *timeout, + const sigset_t *sigmask) { return sysret(pselect(nfds, readfds, writefds, errorfds, timeout, sigmask)); } diff --git a/ape/loader.c b/ape/loader.c index d848e1b31..74b2cf6f4 100644 --- a/ape/loader.c +++ b/ape/loader.c @@ -227,10 +227,6 @@ EXTERN_C void Launch(void *, long, void *, int) __attribute__((__noreturn__)); extern char __executable_start[]; extern char _end[]; -static int ToLower(int c) { - return 'A' <= c && c <= 'Z' ? c + ('a' - 'A') : c; -} - static unsigned long StrLen(const char *s) { unsigned long n = 0; while (*s++) ++n; @@ -538,38 +534,14 @@ __attribute__((__noreturn__)) static void Pexit(int os, const char *c, int rc, Exit(127, os); } -static char EndsWithIgnoreCase(const char *p, unsigned long n, const char *s) { - unsigned long i, m; - if (n >= (m = StrLen(s))) { - for (i = n - m; i < n; ++i) { - if (ToLower(p[i]) != *s++) { - return 0; - } - } - return 1; - } else { - return 0; - } -} - -static char IsComPath(struct PathSearcher *ps) { - return EndsWithIgnoreCase(ps->name, ps->namelen, ".com") || - EndsWithIgnoreCase(ps->name, ps->namelen, ".exe") || - EndsWithIgnoreCase(ps->name, ps->namelen, ".com.dbg"); -} - -static char AccessCommand(struct PathSearcher *ps, const char *suffix, - unsigned long pathlen) { - unsigned long suffixlen; - suffixlen = StrLen(suffix); - if (pathlen + 1 + ps->namelen + suffixlen + 1 > sizeof(ps->path)) return 0; +static char AccessCommand(struct PathSearcher *ps, unsigned long pathlen) { + if (pathlen + 1 + ps->namelen + 1 > sizeof(ps->path)) return 0; if (pathlen && ps->path[pathlen - 1] != '/') ps->path[pathlen++] = '/'; MemMove(ps->path + pathlen, ps->name, ps->namelen); - MemMove(ps->path + pathlen + ps->namelen, suffix, suffixlen + 1); return !Access(ps->path, X_OK, ps->os); } -static char SearchPath(struct PathSearcher *ps, const char *suffix) { +static char SearchPath(struct PathSearcher *ps) { const char *p; unsigned long i; for (p = ps->syspath;;) { @@ -578,7 +550,7 @@ static char SearchPath(struct PathSearcher *ps, const char *suffix) { ps->path[i] = p[i]; } } - if (AccessCommand(ps, suffix, i)) { + if (AccessCommand(ps, i)) { return 1; } else if (p[i] == ':') { p += i + 1; @@ -588,13 +560,13 @@ static char SearchPath(struct PathSearcher *ps, const char *suffix) { } } -static char FindCommand(struct PathSearcher *ps, const char *suffix) { +static char FindCommand(struct PathSearcher *ps) { ps->path[0] = 0; /* paths are always 100% taken literally when a slash exists $ ape foo/bar.com arg1 arg2 */ if (MemChr(ps->name, '/', ps->namelen)) { - return AccessCommand(ps, suffix, 0); + return AccessCommand(ps, 0); } /* we don't run files in the current directory @@ -605,12 +577,12 @@ static char FindCommand(struct PathSearcher *ps, const char *suffix) { however we will execute this $ ape - foo.com foo.com arg1 arg2 because cosmo's execve needs it */ - if (ps->literally && AccessCommand(ps, suffix, 0)) { + if (ps->literally && AccessCommand(ps, 0)) { return 1; } /* otherwise search for name on $PATH */ - return SearchPath(ps, suffix); + return SearchPath(ps); } static char *Commandv(struct PathSearcher *ps, int os, const char *name, @@ -619,7 +591,7 @@ static char *Commandv(struct PathSearcher *ps, int os, const char *name, ps->syspath = syspath ? syspath : "/bin:/usr/local/bin:/usr/bin"; if (!(ps->namelen = StrLen((ps->name = name)))) return 0; if (ps->namelen + 1 > sizeof(ps->path)) return 0; - if (FindCommand(ps, "") || (!IsComPath(ps) && FindCommand(ps, ".com"))) { + if (FindCommand(ps)) { return ps->path; } else { return 0; diff --git a/dsp/mpeg/mpeg1.c b/dsp/mpeg/mpeg1.c index ff874c42c..6804255f7 100644 --- a/dsp/mpeg/mpeg1.c +++ b/dsp/mpeg/mpeg1.c @@ -32,6 +32,7 @@ #include "dsp/mpeg/idct.h" #include "dsp/mpeg/mpeg.h" #include "dsp/mpeg/video.h" +#include "libc/calls/struct/timespec.h" #include "libc/fmt/conv.h" #include "libc/log/log.h" #include "libc/macros.internal.h" diff --git a/libc/calls/calls.mk b/libc/calls/calls.mk index 23b558af2..9e15f4abb 100644 --- a/libc/calls/calls.mk +++ b/libc/calls/calls.mk @@ -107,6 +107,8 @@ o//libc/calls/statfs2cosmo.o: private \ # we always want -O2 because: # division is expensive if not optimized o/$(MODE)/libc/calls/clock.o \ +o/$(MODE)/libc/calls/gettimeofday.o \ +o/$(MODE)/libc/calls/clock_gettime-mono.o \ o/$(MODE)/libc/calls/timespec_tomillis.o \ o/$(MODE)/libc/calls/timespec_tomicros.o \ o/$(MODE)/libc/calls/timespec_totimeval.o \ diff --git a/libc/calls/clock.c b/libc/calls/clock.c index 884f74c86..2338a3a10 100644 --- a/libc/calls/clock.c +++ b/libc/calls/clock.c @@ -52,7 +52,7 @@ int64_t clock(void) { struct rusage ru; struct timespec ts; e = errno; - if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts) == -1) { + if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts)) { errno = e; if (getrusage(RUSAGE_SELF, &ru) != -1) { ts = timeval_totimespec(timeval_add(ru.ru_utime, ru.ru_stime)); diff --git a/libc/calls/clock_getres.c b/libc/calls/clock_getres.c index 18fcdfd53..a54bfdb05 100644 --- a/libc/calls/clock_getres.c +++ b/libc/calls/clock_getres.c @@ -54,7 +54,6 @@ static int sys_clock_getres_xnu(int clock, struct timespec *ts) { * @error EPERM if pledge() is in play without stdio promise * @error EINVAL if `clock` isn't supported on this system * @error EFAULT if `ts` points to bad memory - * @threadsafe */ int clock_getres(int clock, struct timespec *ts) { int rc; diff --git a/libc/calls/clock_gettime-mono.c b/libc/calls/clock_gettime-mono.c index b90116387..46474b7dd 100644 --- a/libc/calls/clock_gettime-mono.c +++ b/libc/calls/clock_gettime-mono.c @@ -16,15 +16,19 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/atomic.h" #include "libc/calls/struct/timespec.h" #include "libc/cosmo.h" +#include "libc/errno.h" #include "libc/nexgen32e/rdtsc.h" #include "libc/nexgen32e/x86feature.h" -#include "libc/sysv/consts/clock.h" -#include "libc/sysv/errfuns.h" + +/** + * @fileoverview Fast Monotonic Clock Polyfill for XNU/NT. + */ static struct { - _Atomic(uint32_t) once; + atomic_uint once; struct timespec base_wall; uint64_t base_tick; } g_mono; @@ -37,13 +41,18 @@ static void sys_clock_gettime_mono_init(void) { int sys_clock_gettime_mono(struct timespec *time) { uint64_t nanos; uint64_t cycles; - if (X86_HAVE(INVTSC)) { - cosmo_once(&g_mono.once, sys_clock_gettime_mono_init); - cycles = rdtsc() - g_mono.base_tick; - nanos = cycles / 3; - *time = timespec_add(g_mono.base_wall, timespec_fromnanos(nanos)); - return 0; - } else { - return einval(); - } +#ifdef __x86_64__ + // intel architecture guarantees that a mapping exists between rdtsc & + // nanoseconds only if the cpu advertises invariant timestamps support + if (!X86_HAVE(INVTSC)) return -EINVAL; +#endif + cosmo_once(&g_mono.once, sys_clock_gettime_mono_init); + cycles = rdtsc() - g_mono.base_tick; + // this is a crude approximation, that's worked reasonably well so far + // only the kernel knows the actual mapping between rdtsc and nanosecs + // which we could attempt to measure ourselves using clock_gettime but + // we'd need to impose 100 ms of startup latency for a guess this good + nanos = cycles / 3; + *time = timespec_add(g_mono.base_wall, timespec_fromnanos(nanos)); + return 0; } diff --git a/libc/calls/clock_gettime-nt.c b/libc/calls/clock_gettime-nt.c index 3b6891286..ba334e732 100644 --- a/libc/calls/clock_gettime-nt.c +++ b/libc/calls/clock_gettime-nt.c @@ -16,12 +16,12 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/clock_gettime.internal.h" -#include "libc/fmt/conv.h" +#include "libc/calls/struct/timespec.internal.h" +#include "libc/errno.h" +#include "libc/fmt/wintime.internal.h" #include "libc/nt/struct/filetime.h" #include "libc/nt/synchronization.h" #include "libc/sysv/consts/clock.h" -#include "libc/sysv/errfuns.h" textwindows int sys_clock_gettime_nt(int clock, struct timespec *ts) { struct NtFileTime ft; @@ -32,6 +32,6 @@ textwindows int sys_clock_gettime_nt(int clock, struct timespec *ts) { } else if (clock == CLOCK_MONOTONIC) { return sys_clock_gettime_mono(ts); } else { - return einval(); + return -EINVAL; } } diff --git a/libc/calls/clock_gettime-m1.c b/libc/calls/clock_gettime-sysv.c similarity index 85% rename from libc/calls/clock_gettime-m1.c rename to libc/calls/clock_gettime-sysv.c index 11b0e6568..ae5779a25 100644 --- a/libc/calls/clock_gettime-m1.c +++ b/libc/calls/clock_gettime-sysv.c @@ -1,7 +1,7 @@ /*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ │vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ ╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2022 Justine Alexandra Roberts Tunney │ +│ 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 │ @@ -16,11 +16,10 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timespec.internal.h" -#include "libc/calls/syscall-sysv.internal.h" -#include "libc/runtime/syslib.internal.h" +#include "libc/calls/syscall_support-sysv.internal.h" +#include "libc/sysv/consts/nr.h" -int sys_clock_gettime_m1(int clock, struct timespec *ts) { - return _sysret(__syslib->__clock_gettime(clock, ts)); +int sys_clock_gettime(int clock, struct timespec *ts) { + return __syscall2i(clock, (long)ts, __NR_clock_gettime); } diff --git a/libc/calls/clock_gettime-xnu.c b/libc/calls/clock_gettime-xnu.c index 774fd9382..94726e1a8 100644 --- a/libc/calls/clock_gettime-xnu.c +++ b/libc/calls/clock_gettime-xnu.c @@ -16,28 +16,46 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/clock_gettime.internal.h" +#include "libc/calls/struct/timespec.internal.h" #include "libc/calls/struct/timeval.internal.h" +#include "libc/errno.h" #include "libc/sysv/consts/clock.h" -#include "libc/sysv/errfuns.h" +#ifdef __x86_64__ int sys_clock_gettime_xnu(int clock, struct timespec *ts) { - axdx_t ad; + long ax, dx; if (clock == CLOCK_REALTIME) { - ad = sys_gettimeofday((struct timeval *)ts, 0, 0); - if (ad.ax != -1) { - if (ad.ax) { - ts->tv_sec = ad.ax; - ts->tv_nsec = ad.dx; - } - ts->tv_nsec *= 1000; - return 0; - } else { - return -1; + // invoke the system call + // + // int gettimeofday(struct timeval *tp, + // struct timezone *tzp, + // uint64_t *mach_absolute_time); + // + // as follows + // + // ax, dx = gettimeofday(&ts, 0, 0); + // + // to support multiple calling conventions + // + // 1. new xnu returns *ts in memory via rdi + // 2. old xnu returns *ts in rax:rdx regs + // + // we assume this system call always succeeds + asm volatile("syscall" + : "=a"(ax), "=d"(dx) + : "0"(0x2000000 | 116), "D"(ts), "S"(0), "1"(0) + : "rcx", "r8", "r9", "r10", "r11", "memory"); + if (ax) { + ts->tv_sec = ax; + ts->tv_nsec = dx; } + ts->tv_nsec *= 1000; + return 0; } else if (clock == CLOCK_MONOTONIC) { return sys_clock_gettime_mono(ts); } else { - return einval(); + return -EINVAL; } } + +#endif /* __x86_64__ */ diff --git a/libc/calls/clock_gettime.c b/libc/calls/clock_gettime.c index 5716e7ec8..d28ed5e59 100644 --- a/libc/calls/clock_gettime.c +++ b/libc/calls/clock_gettime.c @@ -16,82 +16,14 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/assert.h" -#include "libc/calls/asan.internal.h" -#include "libc/calls/clock_gettime.internal.h" -#include "libc/calls/state.internal.h" +#include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timespec.internal.h" -#include "libc/calls/struct/timeval.h" #include "libc/calls/syscall_support-sysv.internal.h" #include "libc/dce.h" -#include "libc/fmt/conv.h" -#include "libc/intrin/asan.internal.h" -#include "libc/intrin/asmflag.h" -#include "libc/intrin/bits.h" +#include "libc/errno.h" #include "libc/intrin/describeflags.internal.h" #include "libc/intrin/strace.internal.h" -#include "libc/mem/alloca.h" -#include "libc/nt/synchronization.h" -#include "libc/sysv/errfuns.h" -#include "libc/thread/tls.h" - -/** - * Returns nanosecond time. - * - * This is a high-precision timer that supports multiple definitions of - * time. Among the more popular is CLOCK_MONOTONIC. This function has a - * zero syscall implementation of that on modern x86. - * - * rdtsc l: 13𝑐 4𝑛𝑠 - * gettimeofday l: 44𝑐 14𝑛𝑠 - * clock_gettime l: 40𝑐 13𝑛𝑠 - * __clock_gettime l: 35𝑐 11𝑛𝑠 - * sys_clock_gettime l: 220𝑐 71𝑛𝑠 - * - * @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 - * - `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 - * - `CLOCK_THREAD_CPUTIME_ID`: linux and bsd - * - `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 ts is where the result is stored - * @return 0 on success, or -1 w/ errno - * @error EPERM if pledge() is in play without stdio promise - * @error EINVAL if `clock` isn't supported on this system - * @error EFAULT if `ts` points to bad memory - * @see strftime(), gettimeofday() - * @asyncsignalsafe - * @threadsafe - * @vforksafe - */ -int clock_gettime(int clock, struct timespec *ts) { - // threads on win32 stacks call this so we can't asan check *ts - int rc; - if (clock == 127) { - rc = einval(); // 127 is used by consts.sh to mean unsupported - } else { - rc = __clock_gettime(clock, ts); - } -#if SYSDEBUG - if (__tls_enabled && !(__get_tls()->tib_flags & TIB_FLAG_TIME_CRITICAL)) { - POLLTRACE("clock_gettime(%s, [%s]) → %d% m", DescribeClockName(clock), - DescribeTimespec(rc, ts), rc); - } -#endif - return rc; -} +#include "libc/runtime/syslib.internal.h" #ifdef __aarch64__ #define CGT_VDSO __vdsosym("LINUX_2.6.39", "__kernel_clock_gettime") @@ -99,39 +31,72 @@ int clock_gettime(int clock, struct timespec *ts) { #define CGT_VDSO __vdsosym("LINUX_2.6", "__vdso_clock_gettime") #endif -/** - * Returns pointer to fastest clock_gettime(). - */ -clock_gettime_f *__clock_gettime_get(bool *opt_out_isfast) { - bool isfast; - clock_gettime_f *res; - if (IsLinux() && (res = CGT_VDSO)) { - isfast = true; - } else if (IsXnu()) { -#ifdef __x86_64__ - res = sys_clock_gettime_xnu; - isfast = false; -#elif defined(__aarch64__) - res = sys_clock_gettime_m1; - isfast = true; -#else -#error "unsupported architecture" -#endif +typedef int clock_gettime_f(int, struct timespec *); + +static clock_gettime_f *__clock_gettime_get(void) { + clock_gettime_f *cgt; + if (IsLinux() && (cgt = CGT_VDSO)) { + return cgt; + } else if (__syslib) { + return (void *)__syslib->__clock_gettime; } else if (IsWindows()) { - isfast = true; - res = sys_clock_gettime_nt; + return sys_clock_gettime_nt; +#ifdef __x86_64__ + } else if (IsXnu()) { + return sys_clock_gettime_xnu; +#endif } else { - isfast = false; - res = sys_clock_gettime; + return sys_clock_gettime; } - if (opt_out_isfast) { - *opt_out_isfast = isfast; - } - return res; } -int __clock_gettime_init(int clockid, struct timespec *ts) { - clock_gettime_f *gettime; - __clock_gettime = gettime = __clock_gettime_get(0); - return gettime(clockid, ts); +static int __clock_gettime_init(int, struct timespec *); +static clock_gettime_f *__clock_gettime = __clock_gettime_init; +static int __clock_gettime_init(int clockid, struct timespec *ts) { + clock_gettime_f *cgt; + __clock_gettime = cgt = __clock_gettime_get(); + return cgt(clockid, 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 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 + * @error EINVAL if `clock` isn't supported on this system + * @error EPERM if pledge() is in play without stdio promise + * @error ESRCH on NetBSD if PID/TID OR'd into `clock` wasn't found + * @see strftime(), gettimeofday() + * @asyncsignalsafe + * @vforksafe + */ +int clock_gettime(int clock, struct timespec *ts) { + // threads on win32 stacks call this so we can't asan check *ts + int rc = __clock_gettime(clock, ts); + if (rc) { + errno = -rc; + rc = -1; + } + TIMETRACE("clock_gettime(%s, [%s]) → %d% m", DescribeClockName(clock), + DescribeTimespec(rc, ts), rc); + return rc; } diff --git a/libc/calls/clock_gettime.internal.h b/libc/calls/clock_gettime.internal.h deleted file mode 100644 index a260257fc..000000000 --- a/libc/calls/clock_gettime.internal.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef COSMOPOLITAN_LIBC_CALLS_CLOCK_GETTIME_H_ -#define COSMOPOLITAN_LIBC_CALLS_CLOCK_GETTIME_H_ -#include "libc/calls/struct/timespec.h" -#if !(__ASSEMBLER__ + __LINKER__ + 0) -COSMOPOLITAN_C_START_ - -typedef int clock_gettime_f(int, struct timespec *); - -extern clock_gettime_f *__clock_gettime; -clock_gettime_f *__clock_gettime_get(bool *); -int __clock_gettime_init(int, struct timespec *); -int sys_clock_gettime_mono(struct timespec *); - -COSMOPOLITAN_C_END_ -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ -#endif /* COSMOPOLITAN_LIBC_CALLS_CLOCK_GETTIME_H_ */ diff --git a/libc/calls/clock_nanosleep-xnu.c b/libc/calls/clock_nanosleep-xnu.c index d72adf207..f0502ac00 100644 --- a/libc/calls/clock_nanosleep-xnu.c +++ b/libc/calls/clock_nanosleep-xnu.c @@ -19,40 +19,40 @@ #include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timespec.internal.h" #include "libc/calls/struct/timeval.h" -#include "libc/calls/struct/timeval.internal.h" #include "libc/calls/syscall-sysv.internal.h" #include "libc/errno.h" -#include "libc/fmt/conv.h" -#include "libc/intrin/strace.internal.h" #include "libc/intrin/weaken.h" #include "libc/runtime/syslib.internal.h" #include "libc/sock/internal.h" #include "libc/sysv/consts/clock.h" #include "libc/sysv/consts/timer.h" #include "libc/sysv/errfuns.h" -#include "libc/thread/posixthread.internal.h" #include "libc/thread/thread.h" -#include "libc/thread/tls.h" int sys_clock_nanosleep_xnu(int clock, int flags, const struct timespec *req, struct timespec *rem) { #ifdef __x86_64__ - struct timeval abs, now, rel; - if (clock == CLOCK_REALTIME) { - if (flags & TIMER_ABSTIME) { - abs = timespec_totimeval(*req); - sys_gettimeofday_xnu(&now, 0, 0); - if (timeval_cmp(abs, now) > 0) { - rel = timeval_sub(abs, now); - return sys_select(0, 0, 0, 0, &rel); - } else { - return 0; - } + if (flags & TIMER_ABSTIME) { + struct timespec now; + sys_clock_gettime_xnu(clock, &now); + if (timespec_cmp(*req, now) > 0) { + struct timeval rel = timespec_totimeval(timespec_sub(*req, now)); + return sys_select(0, 0, 0, 0, &rel); } else { - return sys_nanosleep_xnu(req, rem); + return 0; } } else { - return enotsup(); + int rc; + struct timespec beg; + if (rem) sys_clock_gettime_xnu(CLOCK_REALTIME, &beg); + struct timeval rel = timespec_totimeval(*req); // rounds up + rc = sys_select(0, 0, 0, 0, &rel); + if (rc == -1 && rem && errno == EINTR) { + struct timespec end; + sys_clock_gettime_xnu(CLOCK_REALTIME, &end); + *rem = timespec_subz(*req, timespec_sub(end, beg)); + } + return rc; } #else long res; diff --git a/libc/calls/clock_nanosleep.c b/libc/calls/clock_nanosleep.c index d18bf7695..cf4900e8c 100644 --- a/libc/calls/clock_nanosleep.c +++ b/libc/calls/clock_nanosleep.c @@ -21,7 +21,6 @@ #include "libc/calls/blockcancel.internal.h" #include "libc/calls/blocksigs.internal.h" #include "libc/calls/calls.h" -#include "libc/calls/clock_gettime.internal.h" #include "libc/calls/cp.internal.h" #include "libc/calls/state.internal.h" #include "libc/calls/struct/timespec.h" @@ -76,16 +75,15 @@ static errno_t sys_clock_nanosleep(int clock, int flags, static struct timespec GetNanosleepLatency(void) { errno_t rc; int64_t nanos; - clock_gettime_f *cgt; struct timespec x, y, w = {0, 1}; if (!(nanos = g_nanosleep_latency)) { BLOCK_SIGNALS; - for (cgt = __clock_gettime_get(0);;) { - npassert(!cgt(CLOCK_REALTIME_PRECISE, &x)); + for (;;) { + unassert(!clock_gettime(CLOCK_REALTIME_PRECISE, &x)); rc = sys_clock_nanosleep(CLOCK_REALTIME, 0, &w, 0); - npassert(!rc || rc == EINTR); + unassert(!rc || rc == EINTR); if (!rc) { - npassert(!cgt(CLOCK_REALTIME_PRECISE, &y)); + unassert(!clock_gettime(CLOCK_REALTIME_PRECISE, &y)); nanos = timespec_tonanos(timespec_sub(y, x)); g_nanosleep_latency = nanos; break; @@ -107,7 +105,6 @@ static errno_t CheckCancel(void) { static errno_t SpinNanosleep(int clock, int flags, const struct timespec *req, struct timespec *rem) { errno_t rc; - clock_gettime_f *cgt; struct timespec now, start, elapsed; if ((rc = CheckCancel())) { if (rc == EINTR && !flags && rem) { @@ -115,11 +112,10 @@ static errno_t SpinNanosleep(int clock, int flags, const struct timespec *req, } return rc; } - cgt = __clock_gettime_get(0); - npassert(!cgt(CLOCK_REALTIME, &start)); + unassert(!clock_gettime(CLOCK_REALTIME, &start)); for (;;) { pthread_yield(); - npassert(!cgt(CLOCK_REALTIME, &now)); + unassert(!clock_gettime(CLOCK_REALTIME, &now)); if (flags & TIMER_ABSTIME) { if (timespec_cmp(now, *req) >= 0) { return 0; @@ -177,7 +173,7 @@ static bool ShouldUseSpinNanosleep(int clock, int flags, return false; } e = errno; - if (__clock_gettime_get(0)(clock, &now)) { + if (clock_gettime(clock, &now)) { // punt to the nanosleep system call errno = e; return false; @@ -258,12 +254,8 @@ errno_t clock_nanosleep(int clock, int flags, const struct timespec *req, } else { rc = sys_clock_nanosleep(clock, flags, req, rem); } -#if SYSDEBUG - if (__tls_enabled && !(__get_tls()->tib_flags & TIB_FLAG_TIME_CRITICAL)) { - STRACE("clock_nanosleep(%s, %s, %s, [%s]) → %s", DescribeClockName(clock), - DescribeSleepFlags(flags), DescribeTimespec(0, req), - DescribeTimespec(rc, rem), DescribeErrno(rc)); - } -#endif + TIMETRACE("clock_nanosleep(%s, %s, %s, [%s]) → %s", DescribeClockName(clock), + DescribeSleepFlags(flags), DescribeTimespec(0, req), + DescribeTimespec(rc, rem), DescribeErrno(rc)); return rc; } diff --git a/libc/calls/creat.c b/libc/calls/creat.c index 1c1dfe73e..821ae059f 100644 --- a/libc/calls/creat.c +++ b/libc/calls/creat.c @@ -34,7 +34,6 @@ * @cancellationpoint * @asyncsignalsafe * @restartable - * @threadsafe * @vforksafe */ int creat(const char *file, uint32_t mode) { diff --git a/libc/calls/fstat-nt.c b/libc/calls/fstat-nt.c index 7edac781d..bf563c988 100644 --- a/libc/calls/fstat-nt.c +++ b/libc/calls/fstat-nt.c @@ -21,7 +21,7 @@ #include "libc/calls/internal.h" #include "libc/calls/struct/stat.h" #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" #include "libc/intrin/atomic.h" #include "libc/intrin/bsr.h" #include "libc/intrin/strace.internal.h" diff --git a/libc/calls/fstatvfs.c b/libc/calls/fstatvfs.c index 91503ab2a..7e1b98091 100644 --- a/libc/calls/fstatvfs.c +++ b/libc/calls/fstatvfs.c @@ -35,3 +35,5 @@ int fstatvfs(int fd, struct statvfs *sv) { return -1; } } + +__weak_reference(fstatvfs, fstatvfs64); diff --git a/libc/calls/ftruncate.c b/libc/calls/ftruncate.c index 4f7ef83c7..2e8725073 100644 --- a/libc/calls/ftruncate.c +++ b/libc/calls/ftruncate.c @@ -60,7 +60,6 @@ * @raise ENOSYS on bare metal * @cancellationpoint * @asyncsignalsafe - * @threadsafe */ int ftruncate(int fd, int64_t length) { int rc; diff --git a/libc/calls/futimens.c b/libc/calls/futimens.c index 15d7c22df..081bfe96b 100644 --- a/libc/calls/futimens.c +++ b/libc/calls/futimens.c @@ -40,7 +40,6 @@ * @raise EFAULT if `ts` memory was invalid * @raise ENOSYS on RHEL5 or bare metal * @asyncsignalsafe - * @threadsafe */ int futimens(int fd, const struct timespec ts[2]) { int rc; diff --git a/libc/calls/futimes.c b/libc/calls/futimes.c index c8777f3a6..e5bdd0423 100644 --- a/libc/calls/futimes.c +++ b/libc/calls/futimes.c @@ -37,7 +37,6 @@ * @raise ENOSYS on RHEL5 or bare metal * @see futimens() for modern version * @asyncsignalsafe - * @threadsafe */ int futimes(int fd, const struct timeval tv[2]) { int rc; diff --git a/libc/calls/getcontext.S b/libc/calls/getcontext.S index f1f8cc135..cbd7ff9f6 100644 --- a/libc/calls/getcontext.S +++ b/libc/calls/getcontext.S @@ -30,7 +30,6 @@ // @see makecontext() // @see swapcontext() // @see setcontext() -// @threadsafe .ftrace1 getcontext: .ftrace2 diff --git a/libc/calls/getppid.c b/libc/calls/getppid.c index 52df29760..069c69ad1 100644 --- a/libc/calls/getppid.c +++ b/libc/calls/getppid.c @@ -28,7 +28,6 @@ * @return parent process id (always successful) * @note slow on Windows; needs to iterate process tree * @asyncsignalsafe - * @threadsafe * @vforksafe */ int getppid(void) { diff --git a/libc/calls/getrusage-nt.c b/libc/calls/getrusage-nt.c index 563a79b96..a1afb1ae3 100644 --- a/libc/calls/getrusage-nt.c +++ b/libc/calls/getrusage-nt.c @@ -19,7 +19,7 @@ #include "libc/calls/sig.internal.h" #include "libc/calls/struct/rusage.internal.h" #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" #include "libc/nt/accounting.h" #include "libc/nt/process.h" #include "libc/nt/runtime.h" diff --git a/libc/calls/gettimeofday-m1.c b/libc/calls/gettimeofday-m1.c deleted file mode 100644 index 68f1d9122..000000000 --- a/libc/calls/gettimeofday-m1.c +++ /dev/null @@ -1,35 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 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/struct/timespec.h" -#include "libc/calls/struct/timeval.h" -#include "libc/calls/struct/timeval.internal.h" -#include "libc/calls/syscall-sysv.internal.h" -#include "libc/runtime/syslib.internal.h" -#include "libc/sysv/consts/clock.h" - -axdx_t sys_gettimeofday_m1(struct timeval *tv, struct timezone *tz, void *wut) { - axdx_t ad; - struct timespec ts; - ad.ax = _sysret(__syslib->__clock_gettime(CLOCK_REALTIME, &ts)); - ad.dx = 0; - if (!ad.ax && tv) { - *tv = timespec_totimeval(ts); - } - return ad; -} diff --git a/libc/calls/gettimeofday-metal.c b/libc/calls/gettimeofday-metal.c deleted file mode 100644 index f733f0e70..000000000 --- a/libc/calls/gettimeofday-metal.c +++ /dev/null @@ -1,25 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 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/struct/timeval.internal.h" -#include "libc/time/struct/timezone.h" - -axdx_t sys_gettimeofday_metal(struct timeval *tv, struct timezone *tz, - void *wut) { - return (axdx_t){-1, 0}; -} diff --git a/libc/calls/gettimeofday-nt.c b/libc/calls/gettimeofday-nt.c deleted file mode 100644 index 6432e2ba7..000000000 --- a/libc/calls/gettimeofday-nt.c +++ /dev/null @@ -1,31 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 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/fmt/conv.h" -#include "libc/nt/struct/filetime.h" -#include "libc/nt/synchronization.h" -#include "libc/str/str.h" - -textwindows axdx_t sys_gettimeofday_nt(struct timeval *tv, struct timezone *tz, - void *wut) { - struct NtFileTime ft; - GetSystemTimeAsFileTime(&ft); - if (tv) *tv = FileTimeToTimeVal(ft); - if (tz) bzero(tz, sizeof(*tz)); - return (axdx_t){0, 0}; -} diff --git a/libc/calls/gettimeofday-xnu.c b/libc/calls/gettimeofday-xnu.c deleted file mode 100644 index 4a6c138bd..000000000 --- a/libc/calls/gettimeofday-xnu.c +++ /dev/null @@ -1,31 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 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/struct/timeval.internal.h" - -axdx_t sys_gettimeofday_xnu(struct timeval *tv, struct timezone *tz, - void *wut) { - axdx_t ad; - ad = sys_gettimeofday(tv, tz, wut); - if (ad.ax > 0 && tv) { - tv->tv_sec = ad.ax; - tv->tv_usec = ad.dx; - ad.ax = 0; - } - return ad; -} diff --git a/libc/calls/gettimeofday.c b/libc/calls/gettimeofday.c index 12f932d1e..cb1f4763f 100644 --- a/libc/calls/gettimeofday.c +++ b/libc/calls/gettimeofday.c @@ -16,24 +16,11 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/assert.h" -#include "libc/calls/state.internal.h" -#include "libc/calls/struct/itimerval.internal.h" +#include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timeval.h" -#include "libc/calls/struct/timeval.internal.h" -#include "libc/calls/syscall_support-sysv.internal.h" -#include "libc/dce.h" -#include "libc/intrin/asan.internal.h" -#include "libc/intrin/describeflags.internal.h" -#include "libc/intrin/strace.internal.h" -#include "libc/sysv/errfuns.h" -#include "libc/thread/tls.h" +#include "libc/sysv/consts/clock.h" #include "libc/time/struct/timezone.h" -typedef axdx_t gettimeofday_f(struct timeval *, struct timezone *, void *); -static gettimeofday_f __gettimeofday_init; -static gettimeofday_f *__gettimeofday = __gettimeofday_init; - /** * Returns system wall time in microseconds, e.g. * @@ -47,60 +34,26 @@ static gettimeofday_f *__gettimeofday = __gettimeofday_init; * iso8601(p, &tm); * printf("%s\n", p); * - * @param tv points to timeval that receives result if non-NULL - * @param tz receives UTC timezone if non-NULL + * @param tv points to timeval that receives result if non-null + * @param tz is completely ignored + * @return 0 on success, or -1 w/ errno + * @raise EFAULT if `tv` points to invalid memory * @see clock_gettime() for nanosecond precision * @see strftime() for string formatting + * @asyncsignalsafe + * @vforksafe */ int gettimeofday(struct timeval *tv, struct timezone *tz) { - int rc = __gettimeofday(tv, tz, 0).ax; -#if SYSDEBUG - if (__tls_enabled && !(__get_tls()->tib_flags & TIB_FLAG_TIME_CRITICAL)) { - POLLTRACE("gettimeofday([%s], %p) → %d% m", DescribeTimeval(rc, tv), tz, - rc); - } -#endif - return rc; -} - -/** - * Returns pointer to fastest gettimeofday(). - */ -gettimeofday_f *__gettimeofday_get(bool *opt_out_isfast) { - bool isfast; - gettimeofday_f *res; - if (IsLinux() && (res = __vdsosym("LINUX_2.6", "__vdso_gettimeofday"))) { - isfast = true; - } else if (IsWindows()) { - isfast = true; - res = sys_gettimeofday_nt; - } else if (IsXnu()) { -#ifdef __x86_64__ - res = sys_gettimeofday_xnu; - isfast = false; -#elif defined(__aarch64__) - res = sys_gettimeofday_m1; - isfast = true; -#else -#error "unsupported architecture" -#endif - } else if (IsMetal()) { - isfast = false; - res = sys_gettimeofday_metal; + if (tv) { + struct timespec ts; + if (clock_gettime(CLOCK_REALTIME, &ts) != -1) { + tv->tv_sec = ts.tv_sec; + tv->tv_usec = (ts.tv_nsec + 999) / 1000; + return 0; + } else { + return -1; + } } else { - isfast = false; - res = sys_gettimeofday; + return 0; } - if (opt_out_isfast) { - *opt_out_isfast = isfast; - } - return res; -} - -static axdx_t __gettimeofday_init(struct timeval *tv, // - struct timezone *tz, // - void *arg) { - gettimeofday_f *gettime; - __gettimeofday = gettime = __gettimeofday_get(0); - return gettime(tv, tz, 0); } diff --git a/libc/calls/getuid.c b/libc/calls/getuid.c index e63eebd25..fa91a180d 100644 --- a/libc/calls/getuid.c +++ b/libc/calls/getuid.c @@ -37,7 +37,6 @@ * * @return user id (always successful) * @asyncsignalsafe - * @threadsafe * @vforksafe */ uint32_t getuid(void) { @@ -62,7 +61,6 @@ uint32_t getuid(void) { * * @return group id (always successful) * @asyncsignalsafe - * @threadsafe * @vforksafe */ uint32_t getgid(void) { diff --git a/libc/calls/lseek.c b/libc/calls/lseek.c index fff3b7efe..d84b0d948 100644 --- a/libc/calls/lseek.c +++ b/libc/calls/lseek.c @@ -72,7 +72,6 @@ * @raise EINVAL if resulting offset would be negative * @raise EINVAL if `whence` isn't valid * @asyncsignalsafe - * @threadsafe * @vforksafe */ int64_t lseek(int fd, int64_t offset, int whence) { diff --git a/libc/calls/makedirs.c b/libc/calls/makedirs.c index 989e2a42e..e2bf68d6b 100644 --- a/libc/calls/makedirs.c +++ b/libc/calls/makedirs.c @@ -44,7 +44,6 @@ * @raise ENOENT if `path` is an empty string * @raise ELOOP if loop was detected resolving components of `path` * @asyncsignalsafe - * @threadsafe */ int makedirs(const char *path, unsigned mode) { int c, e, i, n; diff --git a/libc/calls/mkdir.c b/libc/calls/mkdir.c index ef25c689e..2ba501cc3 100644 --- a/libc/calls/mkdir.c +++ b/libc/calls/mkdir.c @@ -45,7 +45,6 @@ * @see makedirs() which is higher-level * @see mkdirat() for modern call * @asyncsignalsafe - * @threadsafe */ int mkdir(const char *path, unsigned mode) { return mkdirat(AT_FDCWD, path, mode); diff --git a/libc/calls/munmap-sysv.c b/libc/calls/munmap-sysv.c index 8d847ec52..eeaa8f1da 100644 --- a/libc/calls/munmap-sysv.c +++ b/libc/calls/munmap-sysv.c @@ -29,7 +29,6 @@ * but it works on everything else including bare metal. * * @asyncsignalsafe - * @threadsafe */ int sys_munmap(void *p, size_t n) { int rc; diff --git a/libc/calls/nanosleep-xnu.c b/libc/calls/nanosleep-xnu.c deleted file mode 100644 index 21dad75c5..000000000 --- a/libc/calls/nanosleep-xnu.c +++ /dev/null @@ -1,51 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 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/struct/timespec.h" -#include "libc/calls/struct/timespec.internal.h" -#include "libc/calls/struct/timeval.h" -#include "libc/calls/struct/timeval.internal.h" -#include "libc/calls/syscall-sysv.internal.h" -#include "libc/errno.h" -#include "libc/runtime/syslib.internal.h" -#include "libc/sock/internal.h" - -// nanosleep() on xnu: a bloodbath of a polyfill -// consider using clock_nanosleep(TIMER_ABSTIME) -int sys_nanosleep_xnu(const struct timespec *req, struct timespec *rem) { -#ifdef __x86_64__ - int rc; - struct timeval wt, t1, t2, td; - if (rem) sys_gettimeofday_xnu(&t1, 0, 0); - wt = timespec_totimeval(*req); // rounds up - rc = sys_select(0, 0, 0, 0, &wt); - if (rem && rc == -1 && errno == EINTR) { - sys_gettimeofday_xnu(&t2, 0, 0); - td = timeval_sub(t2, t1); - if (timeval_cmp(td, wt) >= 0) { - rem->tv_sec = 0; - rem->tv_nsec = 0; - } else { - *rem = timeval_totimespec(timeval_sub(wt, td)); - } - } - return rc; -#else - return _sysret(__syslib->__nanosleep(req, rem)); -#endif -} diff --git a/libc/calls/nanosleep.c b/libc/calls/nanosleep.c index 00bce7e1a..22a13fe47 100644 --- a/libc/calls/nanosleep.c +++ b/libc/calls/nanosleep.c @@ -37,11 +37,11 @@ * @norestart */ int nanosleep(const struct timespec *req, struct timespec *rem) { - int rc; - if (!(rc = clock_nanosleep(CLOCK_REALTIME, 0, req, rem))) { + errno_t err; + if (!(err = clock_nanosleep(CLOCK_REALTIME, 0, req, rem))) { return 0; } else { - errno = rc; + errno = err; return -1; } } diff --git a/libc/calls/ntaccesscheck.c b/libc/calls/ntaccesscheck.c index 47d63870f..203bdbad9 100644 --- a/libc/calls/ntaccesscheck.c +++ b/libc/calls/ntaccesscheck.c @@ -16,6 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/calls/syscall_support-nt.internal.h" @@ -35,6 +36,7 @@ #include "libc/nt/errors.h" #include "libc/nt/files.h" #include "libc/nt/runtime.h" +#include "libc/nt/struct/byhandlefileinformation.h" #include "libc/nt/struct/genericmapping.h" #include "libc/nt/struct/privilegeset.h" #include "libc/nt/struct/securitydescriptor.h" @@ -62,6 +64,7 @@ textwindows int ntaccesscheck(const char16_t *pathname, uint32_t flags) { struct NtGenericMapping mapping; struct NtPrivilegeSet privileges; uint32_t secsize, granted, privsize; + struct NtByHandleFileInformation wst; int64_t hToken, hImpersonatedToken, hFile; intptr_t buffer[1024 / sizeof(intptr_t)]; if (flags & X_OK) flags |= R_OK; @@ -100,7 +103,9 @@ textwindows int ntaccesscheck(const char16_t *pathname, uint32_t flags) { 0, kNtOpenExisting, kNtFileAttributeNormal | kNtFileFlagBackupSemantics, 0)) != -1) { - if (IsWindowsExecutable(hFile)) { + unassert(GetFileInformationByHandle(hFile, &wst)); + if ((wst.dwFileAttributes & kNtFileAttributeDirectory) || + IsWindowsExecutable(hFile)) { rc = 0; } else { rc = eacces(); diff --git a/libc/calls/open.c b/libc/calls/open.c index 98889d3ab..883e2d250 100644 --- a/libc/calls/open.c +++ b/libc/calls/open.c @@ -32,7 +32,6 @@ * @cancellationpoint * @asyncsignalsafe * @restartable - * @threadsafe * @vforksafe */ int open(const char *file, int flags, ...) { diff --git a/libc/calls/openat.c b/libc/calls/openat.c index df330efc8..3478a14c0 100644 --- a/libc/calls/openat.c +++ b/libc/calls/openat.c @@ -168,7 +168,6 @@ * @cancellationpoint * @asyncsignalsafe * @restartable - * @threadsafe * @vforksafe */ int openat(int dirfd, const char *path, int flags, ...) { diff --git a/libc/calls/pledge-linux.c b/libc/calls/pledge-linux.c index c8987f639..2a36e362d 100644 --- a/libc/calls/pledge-linux.c +++ b/libc/calls/pledge-linux.c @@ -2297,7 +2297,6 @@ static privileged void AppendPledge(struct Filter *f, // * @param ipromises is inverted integer bitmask of pledge() promises * @return 0 on success, or negative error number on error * @asyncsignalsafe - * @threadsafe * @vforksafe */ privileged int sys_pledge_linux(unsigned long ipromises, int mode) { diff --git a/libc/calls/pledge.c b/libc/calls/pledge.c index bcfd10f8f..3c423c670 100644 --- a/libc/calls/pledge.c +++ b/libc/calls/pledge.c @@ -234,7 +234,6 @@ * @raise ENOSYS if `pledge(0, 0)` was used and security is not possible * @raise EINVAL if `execpromises` on Linux isn't a subset of `promises` * @raise EINVAL if `promises` allows exec and `execpromises` is null - * @threadsafe * @vforksafe */ int pledge(const char *promises, const char *execpromises) { diff --git a/libc/calls/poll.c b/libc/calls/poll.c index c84a40aea..076ba4de6 100644 --- a/libc/calls/poll.c +++ b/libc/calls/poll.c @@ -62,7 +62,6 @@ * @raise EINTR if signal was delivered * @cancellationpoint * @asyncsignalsafe - * @threadsafe * @norestart */ int poll(struct pollfd *fds, size_t nfds, int timeout_ms) { diff --git a/libc/calls/posix_fadvise.c b/libc/calls/posix_fadvise.c index 1582e4280..4955921c6 100644 --- a/libc/calls/posix_fadvise.c +++ b/libc/calls/posix_fadvise.c @@ -46,7 +46,6 @@ int sys_fadvise_netbsd(int, int, int64_t, int64_t, int) asm("sys_fadvise"); * @raise ENOTSUP if `fd` is a /zip file * @raise ENOSYS on XNU and OpenBSD * @returnserrno - * @threadsafe */ errno_t posix_fadvise(int fd, int64_t offset, int64_t len, int advice) { int rc, e = errno; diff --git a/libc/calls/posix_madvise.c b/libc/calls/posix_madvise.c index a4a18b4eb..5c2e2e779 100644 --- a/libc/calls/posix_madvise.c +++ b/libc/calls/posix_madvise.c @@ -24,7 +24,6 @@ * * @return 0 on success, or errno on error * @returnserrno - * @threadsafe */ errno_t posix_madvise(void *addr, uint64_t len, int advice) { int rc, e = errno; diff --git a/libc/calls/ppoll.c b/libc/calls/ppoll.c index b5cebed28..b419b089b 100644 --- a/libc/calls/ppoll.c +++ b/libc/calls/ppoll.c @@ -57,7 +57,6 @@ * @raise EINTR if signal was delivered * @cancellationpoint * @asyncsignalsafe - * @threadsafe * @norestart */ int ppoll(struct pollfd *fds, size_t nfds, const struct timespec *timeout, diff --git a/libc/calls/pread.c b/libc/calls/pread.c index c72c222ea..27bc76f58 100644 --- a/libc/calls/pread.c +++ b/libc/calls/pread.c @@ -52,7 +52,6 @@ * @see pwrite(), write() * @cancellationpoint * @asyncsignalsafe - * @threadsafe * @vforksafe */ ssize_t pread(int fd, void *buf, size_t size, int64_t offset) { diff --git a/libc/calls/pwrite.c b/libc/calls/pwrite.c index b9e5005cd..ac06d28ad 100644 --- a/libc/calls/pwrite.c +++ b/libc/calls/pwrite.c @@ -46,7 +46,6 @@ * @see pread(), write() * @cancellationpoint * @asyncsignalsafe - * @threadsafe * @vforksafe */ ssize_t pwrite(int fd, const void *buf, size_t size, int64_t offset) { diff --git a/libc/calls/read-nt.c b/libc/calls/read-nt.c index 4560cee22..c683cd498 100644 --- a/libc/calls/read-nt.c +++ b/libc/calls/read-nt.c @@ -53,8 +53,6 @@ #include "libc/thread/tls.h" #ifdef __x86_64__ -__msabi extern typeof(CloseHandle) *const __imp_CloseHandle; - static const struct { int vk; int normal_str; @@ -578,7 +576,7 @@ textwindows ssize_t sys_read_nt_impl(int fd, void *data, size_t size, goto BlockingOperation; } } - __imp_CloseHandle(overlap.hEvent); // __imp_ to avoid log noise + CloseHandle(overlap.hEvent); if (!pwriting && seekable) { if (ok) f->pointer = offset + got; diff --git a/libc/calls/reservefd.c b/libc/calls/reservefd.c index 1821dceed..4d3d6bd3c 100644 --- a/libc/calls/reservefd.c +++ b/libc/calls/reservefd.c @@ -51,7 +51,6 @@ int __ensurefds_unlocked(int fd) { /** * Grows file descriptor array memory if needed. * @asyncsignalsafe - * @threadsafe */ int __ensurefds(int fd) { __fds_lock(); @@ -89,7 +88,6 @@ int __reservefd_unlocked(int start) { /** * Finds open file descriptor slot. * @asyncsignalsafe - * @threadsafe */ int __reservefd(int start) { int fd; diff --git a/libc/calls/siginfo2cosmo.c b/libc/calls/siginfo2cosmo.c index 6ca045844..08ec12ce6 100644 --- a/libc/calls/siginfo2cosmo.c +++ b/libc/calls/siginfo2cosmo.c @@ -85,6 +85,14 @@ privileged void __siginfo2cosmo(struct siginfo *si, notpossible; } + // Turn BUS_OBJERR into BUS_ADRERR for consistency with Linux. + // See test/libc/calls/sigbus_test.c + if (IsFreebsd() || IsOpenbsd()) { + if (si_signo == 10 && si_code == 3) { + si_code = 2; + } + } + *si = (struct siginfo){0}; si->si_signo = si_signo; si->si_errno = si_errno; diff --git a/libc/calls/state.internal.h b/libc/calls/state.internal.h index be72f6afb..8c3e266d5 100644 --- a/libc/calls/state.internal.h +++ b/libc/calls/state.internal.h @@ -6,7 +6,6 @@ COSMOPOLITAN_C_START_ extern int __vforked; -extern bool __time_critical; extern pthread_mutex_t __fds_lock_obj; extern unsigned __sighandrvas[NSIG + 1]; extern unsigned __sighandflags[NSIG + 1]; diff --git a/libc/calls/statvfs.c b/libc/calls/statvfs.c index 98f2ea7d5..8f38a8246 100644 --- a/libc/calls/statvfs.c +++ b/libc/calls/statvfs.c @@ -35,3 +35,5 @@ int statvfs(const char *path, struct statvfs *sv) { return -1; } } + +__strong_reference(statvfs, statvfs64); diff --git a/libc/calls/__clock_gettime.c b/libc/calls/stime.c similarity index 90% rename from libc/calls/__clock_gettime.c rename to libc/calls/stime.c index c3b46a6e5..7ab0ef23f 100644 --- a/libc/calls/__clock_gettime.c +++ b/libc/calls/stime.c @@ -16,6 +16,12 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/clock_gettime.internal.h" +#include "libc/calls/struct/timeval.h" +#include "libc/time/time.h" -clock_gettime_f *__clock_gettime = __clock_gettime_init; +/** + * Changes time, the old fashioned way. + */ +int stime(const int64_t *t) { + return settimeofday(&(struct timeval){*t}, 0); +} diff --git a/libc/calls/struct/timespec.internal.h b/libc/calls/struct/timespec.internal.h index 6b2e11b78..3628fff8e 100644 --- a/libc/calls/struct/timespec.internal.h +++ b/libc/calls/struct/timespec.internal.h @@ -10,18 +10,18 @@ int __sys_clock_nanosleep(int, int, const struct timespec *, struct timespec *); int __sys_utimensat(int, const char *, const struct timespec[2], int); int __utimens(int, const char *, const struct timespec[2], int); int sys_clock_getres(int, struct timespec *); -int sys_clock_settime(int, const struct timespec *); int sys_clock_gettime(int, struct timespec *); -int sys_clock_gettime_nt(int, struct timespec *); int sys_clock_gettime_m1(int, struct timespec *); +int sys_clock_gettime_mono(struct timespec *); +int sys_clock_gettime_nt(int, struct timespec *); int sys_clock_gettime_xnu(int, struct timespec *); int sys_clock_nanosleep_nt(int, int, const struct timespec *, struct timespec *); int sys_clock_nanosleep_openbsd(int, int, const struct timespec *, struct timespec *); int sys_clock_nanosleep_xnu(int, int, const struct timespec *, struct timespec *); +int sys_clock_settime(int, const struct timespec *); int sys_futimens(int, const struct timespec[2]); int sys_nanosleep(const struct timespec *, struct timespec *); int sys_nanosleep_nt(const struct timespec *, struct timespec *); -int sys_nanosleep_xnu(const struct timespec *, struct timespec *); int sys_sem_timedwait(int64_t, const struct timespec *); int sys_utimensat(int, const char *, const struct timespec[2], int); int sys_utimensat_nt(int, const char *, const struct timespec[2], int); diff --git a/libc/calls/struct/timeval.internal.h b/libc/calls/struct/timeval.internal.h index aaa2e5fa0..c68b65283 100644 --- a/libc/calls/struct/timeval.internal.h +++ b/libc/calls/struct/timeval.internal.h @@ -6,16 +6,11 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -axdx_t sys_gettimeofday(struct timeval *, struct timezone *, void *); int sys_settimeofday(const struct timeval *, const struct timezone *); int sys_futimes(int, const struct timeval *); int sys_lutimes(const char *, const struct timeval *); int sys_utimes(const char *, const struct timeval *); -axdx_t sys_gettimeofday_m1(struct timeval *, struct timezone *, void *); -axdx_t sys_gettimeofday_xnu(struct timeval *, struct timezone *, void *); -axdx_t sys_gettimeofday_nt(struct timeval *, struct timezone *, void *); int sys_utimes_nt(const char *, const struct timeval[2]); -axdx_t sys_gettimeofday_metal(struct timeval *, struct timezone *, void *); const char *DescribeTimeval(char[45], int, const struct timeval *); #define DescribeTimeval(rc, ts) DescribeTimeval(alloca(45), rc, ts) diff --git a/libc/calls/swapcontext.S b/libc/calls/swapcontext.S index 0fbd1b9c8..8853c2e95 100644 --- a/libc/calls/swapcontext.S +++ b/libc/calls/swapcontext.S @@ -35,7 +35,6 @@ // // @return 0 on success, or -1 w/ errno // @returnstwice -// @threadsafe .ftrace1 swapcontext: .ftrace2 diff --git a/libc/calls/syscall_support-sysv.internal.h b/libc/calls/syscall_support-sysv.internal.h index 3543933ce..1f6be424a 100644 --- a/libc/calls/syscall_support-sysv.internal.h +++ b/libc/calls/syscall_support-sysv.internal.h @@ -6,6 +6,11 @@ COSMOPOLITAN_C_START_ │ cosmopolitan § syscalls » system five » structless support ─╬─│┼ ╚────────────────────────────────────────────────────────────────────────────│*/ +long __syscall2(long, long, int); +int __syscall2i(long, long, int) asm("__syscall2"); +long __syscall3(long, long, long, int); +int __syscall3i(long, long, long, int) asm("__syscall3"); + bool __is_linux_2_6_23(void); bool32 sys_isatty_metal(int); int __fixupnewfd(int, int); diff --git a/libc/calls/timespec_real.c b/libc/calls/timespec_real.c index 37034dcc9..a8a477a1b 100644 --- a/libc/calls/timespec_real.c +++ b/libc/calls/timespec_real.c @@ -31,6 +31,6 @@ */ struct timespec timespec_real(void) { struct timespec ts; - npassert(!clock_gettime(CLOCK_REALTIME, &ts)); + unassert(!clock_gettime(CLOCK_REALTIME, &ts)); return ts; } diff --git a/libc/calls/tmpfd.c b/libc/calls/tmpfd.c index dc7b8620a..7e93b66db 100644 --- a/libc/calls/tmpfd.c +++ b/libc/calls/tmpfd.c @@ -71,7 +71,6 @@ int _mkstemp(char *, int); * @see tmpfile() for stdio version * @cancellationpoint * @asyncsignalsafe - * @threadsafe * @vforksafe */ int tmpfd(void) { diff --git a/libc/calls/truncate.c b/libc/calls/truncate.c index ebd252c2c..cc9772e3b 100644 --- a/libc/calls/truncate.c +++ b/libc/calls/truncate.c @@ -61,7 +61,6 @@ * @raise ENOSYS on bare metal * @cancellationpoint * @see ftruncate() - * @threadsafe */ int truncate(const char *path, int64_t length) { int rc; diff --git a/libc/calls/ttyname.c b/libc/calls/ttyname.c index 5df6e696e..908ccbbde 100644 --- a/libc/calls/ttyname.c +++ b/libc/calls/ttyname.c @@ -17,7 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" -#include "libc/calls/sysparam.h" +#include "libc/stdio/sysparam.h" #include "libc/errno.h" #include "libc/log/log.h" #include "libc/paths.h" diff --git a/libc/calls/ttyname_r.c b/libc/calls/ttyname_r.c index 554255b12..21fbefb72 100644 --- a/libc/calls/ttyname_r.c +++ b/libc/calls/ttyname_r.c @@ -85,7 +85,6 @@ static errno_t ttyname_linux(int fd, char *buf, size_t size) { * @return 0 on success, or error number on error * @raise ERANGE if `size` was too small * @returnserrno - * @threadsafe */ errno_t ttyname_r(int fd, char *buf, size_t size) { errno_t e, res; diff --git a/libc/calls/ucontext.c b/libc/calls/ucontext.c index a5fc2be32..5ff2ceeac 100644 --- a/libc/calls/ucontext.c +++ b/libc/calls/ucontext.c @@ -43,7 +43,6 @@ static int __contextmask(const sigset_t *opt_set, sigset_t *opt_out_oldset) { * @see swapcontext() * @see makecontext() * @see getcontext() - * @threadsafe */ int setcontext(const ucontext_t *uc) { if (__contextmask(&uc->uc_sigmask, 0)) return -1; diff --git a/libc/calls/unveil.c b/libc/calls/unveil.c index 2dd0209d1..00fd47c43 100644 --- a/libc/calls/unveil.c +++ b/libc/calls/unveil.c @@ -460,7 +460,6 @@ int sys_unveil_linux(const char *path, const char *permissions) { * @note on Linux this function requires Linux Kernel 5.13+ and version 6.2+ * to properly support truncation operations * @see [1] https://docs.kernel.org/userspace-api/landlock.html - * @threadsafe */ int unveil(const char *path, const char *permissions) { int e, rc; diff --git a/libc/calls/utime.c b/libc/calls/utime.c index 363f6eff7..f9417ed25 100644 --- a/libc/calls/utime.c +++ b/libc/calls/utime.c @@ -26,7 +26,6 @@ * @return 0 on success, or -1 w/ errno * @see utimensat() for modern version * @asyncsignalsafe - * @threadsafe */ int utime(const char *path, const struct utimbuf *times) { struct timeval tv[2]; diff --git a/libc/calls/utimensat-nt.c b/libc/calls/utimensat-nt.c index e4711a167..46776b3a8 100644 --- a/libc/calls/utimensat-nt.c +++ b/libc/calls/utimensat-nt.c @@ -17,8 +17,9 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/calls/struct/timespec.h" #include "libc/calls/syscall_support-nt.internal.h" -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" #include "libc/nt/createfile.h" #include "libc/nt/enum/accessmask.h" #include "libc/nt/enum/creationdisposition.h" diff --git a/libc/calls/utimensat.c b/libc/calls/utimensat.c index 011950b3f..aa19cf6a2 100644 --- a/libc/calls/utimensat.c +++ b/libc/calls/utimensat.c @@ -51,7 +51,6 @@ * @raise ENOTSUP on XNU or RHEL5 when `dirfd` isn't `AT_FDCWD` * @raise ENOSYS on bare metal * @asyncsignalsafe - * @threadsafe */ int utimensat(int dirfd, const char *path, const struct timespec ts[2], int flags) { diff --git a/libc/calls/utimes.c b/libc/calls/utimes.c index 7297a0663..5e2d3651d 100644 --- a/libc/calls/utimes.c +++ b/libc/calls/utimes.c @@ -32,7 +32,6 @@ * @note truncates to second precision on rhel5 * @see utimensat() for modern version * @asyncsignalsafe - * @threadsafe */ int utimes(const char *path, const struct timeval tv[2]) { int rc; diff --git a/libc/calls/vdsofunc.greg.c b/libc/calls/vdsofunc.greg.c index 861514bab..7f669a962 100644 --- a/libc/calls/vdsofunc.greg.c +++ b/libc/calls/vdsofunc.greg.c @@ -27,6 +27,7 @@ #include "libc/elf/struct/verdaux.h" #include "libc/elf/struct/verdef.h" #include "libc/intrin/bits.h" +#include "libc/intrin/getauxval.internal.h" #include "libc/intrin/strace.internal.h" #include "libc/runtime/runtime.h" #include "libc/str/str.h" @@ -55,7 +56,7 @@ static inline int CheckDsoSymbolVersion(Elf64_Verdef *vd, int sym, } /** - * Returns address of vDSO function. + * Returns address of "Virtual Dynamic Shared Object" function on Linux. */ void *__vdsosym(const char *version, const char *name) { void *p; @@ -64,23 +65,19 @@ void *__vdsosym(const char *version, const char *name) { Elf64_Phdr *phdr; char *strtab = 0; size_t *dyn, base; - unsigned long *ap; Elf64_Sym *symtab = 0; uint16_t *versym = 0; Elf_Symndx *hashtab = 0; Elf64_Verdef *verdef = 0; + struct AuxiliaryValue av; - for (ehdr = 0, ap = __auxv; ap[0]; ap += 2) { - if (ap[0] == AT_SYSINFO_EHDR) { - ehdr = (void *)ap[1]; - break; - } - } - if (!ehdr || READ32LE(ehdr->e_ident) != READ32LE("\177ELF")) { - KERNTRACE("__vdsosym() → AT_SYSINFO_EHDR ELF not found"); + av = __getauxval(AT_SYSINFO_EHDR); + if (!av.isfound) { + KERNTRACE("__vdsosym() → missing AT_SYSINFO_EHDR"); return 0; } + ehdr = (void *)av.value; phdr = (void *)((char *)ehdr + ehdr->e_phoff); for (base = -1, dyn = 0, i = 0; i < ehdr->e_phnum; i++, phdr = (void *)((char *)phdr + ehdr->e_phentsize)) { diff --git a/libc/calls/weirdtypes.h b/libc/calls/weirdtypes.h index 072735dcb..997475a4e 100644 --- a/libc/calls/weirdtypes.h +++ b/libc/calls/weirdtypes.h @@ -64,6 +64,7 @@ typedef uint32_t nlink_t; /* uint16_t on xnu */ #define fstat64 fstat #define fstatat64 fstatat #define fstatfs64 fstatfs +#define fstatvfs64 fstatvfs #define getrlimit64 getrlimit #define ino64_t ino_t #define lockf64 lockf @@ -83,6 +84,7 @@ typedef uint32_t nlink_t; /* uint16_t on xnu */ #define setrlimit64 setrlimit #define stat64 stat #define statfs64 statfs +#define statvfs64 statvfs #define versionsort64 versionsort #endif diff --git a/libc/calls/winexec.c b/libc/calls/winexec.c index 4b5ac6bde..a3daed48e 100644 --- a/libc/calls/winexec.c +++ b/libc/calls/winexec.c @@ -17,12 +17,27 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/nt/errors.h" +#include "libc/nt/events.h" +#include "libc/nt/files.h" #include "libc/nt/runtime.h" +#include "libc/nt/struct/overlapped.h" +// checks if file should be considered an executable on windows textwindows int IsWindowsExecutable(int64_t handle) { + + // read first two bytes of file + // access() and stat() aren't cancelation points char buf[2]; uint32_t got; - return ReadFile(handle, buf, 2, &got, 0) && got == 2 && + struct NtOverlapped overlap = {.hEvent = CreateEvent(0, 0, 0, 0)}; + bool ok = (ReadFile(handle, buf, 2, 0, &overlap) || + GetLastError() == kNtErrorIoPending) && + GetOverlappedResult(handle, &overlap, &got, true); + CloseHandle(overlap.hEvent); + + // it's an executable if it starts with `MZ` or `#!` + return ok && got == 2 && // ((buf[0] == 'M' && buf[1] == 'Z') || // (buf[0] == '#' && buf[1] == '!')); } diff --git a/libc/calls/write-nt.c b/libc/calls/write-nt.c index 83ac291eb..426a2036c 100644 --- a/libc/calls/write-nt.c +++ b/libc/calls/write-nt.c @@ -47,8 +47,6 @@ #include "libc/thread/thread.h" #include "libc/thread/tls.h" -__msabi extern typeof(CloseHandle) *const __imp_CloseHandle; - static bool IsMouseModeCommand(int x) { return x == 1000 || // SET_VT200_MOUSE x == 1002 || // SET_BTN_EVENT_MOUSE @@ -202,7 +200,7 @@ static textwindows ssize_t sys_write_nt_impl(int fd, void *data, size_t size, goto BlockingOperation; } } - __imp_CloseHandle(overlap.hEvent); // __imp_ to avoid log noise + CloseHandle(overlap.hEvent); if (seekable && !pwriting) { if (ok) f->pointer = offset + sent; diff --git a/libc/dns/freeaddrinfo.c b/libc/dns/freeaddrinfo.c index aaa0b67ce..bce7c4933 100644 --- a/libc/dns/freeaddrinfo.c +++ b/libc/dns/freeaddrinfo.c @@ -21,7 +21,6 @@ /** * Frees addresses returned by getaddrinfo(). - * @threadsafe */ void freeaddrinfo(struct addrinfo *ai) { struct addrinfo *next; diff --git a/libc/dns/getaddrinfo.c b/libc/dns/getaddrinfo.c index a799ca4bf..8a03a8089 100644 --- a/libc/dns/getaddrinfo.c +++ b/libc/dns/getaddrinfo.c @@ -41,7 +41,6 @@ * @param res receives a pointer that must be freed with freeaddrinfo(), * and won't be modified if non-zero is returned * @return 0 on success or EAI_xxx value - * @threadsafe */ int getaddrinfo(const char *name, const char *service, const struct addrinfo *hints, struct addrinfo **res) { diff --git a/libc/dns/gethoststxt.c b/libc/dns/gethoststxt.c index dd172d36b..ab63fb370 100644 --- a/libc/dns/gethoststxt.c +++ b/libc/dns/gethoststxt.c @@ -51,7 +51,6 @@ static const char *GetHostsTxtPath(char *path, size_t size) { * Returns hosts.txt map. * * @note yoinking realloc() ensures there's no size limits - * @threadsafe */ const struct HostsTxt *GetHostsTxt(void) { FILE *f; diff --git a/libc/dns/getresolvconf.c b/libc/dns/getresolvconf.c index 09a61be08..f71e97345 100644 --- a/libc/dns/getresolvconf.c +++ b/libc/dns/getresolvconf.c @@ -37,7 +37,6 @@ static struct ResolvConfInitialStaticMemory { /** * Returns singleton with DNS server address. - * @threadsafe */ const struct ResolvConf *GetResolvConf(void) { int rc; diff --git a/libc/dns/lookupservicesbyname.c b/libc/dns/lookupservicesbyname.c index 25924faa0..8a1464923 100644 --- a/libc/dns/lookupservicesbyname.c +++ b/libc/dns/lookupservicesbyname.c @@ -50,7 +50,6 @@ * @return -1 on error, or positive port number * @note aliases are read from file for comparison, but not returned. * @see LookupServicesByPort - * @threadsafe */ int LookupServicesByName(const char *servname, char *servproto, size_t servprotolen, char *buf, size_t bufsize, diff --git a/libc/fmt/conv.h b/libc/fmt/conv.h index 75b0c2a5b..49c4526aa 100644 --- a/libc/fmt/conv.h +++ b/libc/fmt/conv.h @@ -1,16 +1,5 @@ #ifndef COSMOPOLITAN_LIBC_FMT_CONV_H_ #define COSMOPOLITAN_LIBC_FMT_CONV_H_ -#include "libc/calls/struct/timespec.h" -#include "libc/calls/struct/timeval.h" -#include "libc/nt/struct/filetime.h" - -/*───────────────────────────────────────────────────────────────────────────│─╗ -│ cosmopolitan § conversion ─╬─│┼ -╚────────────────────────────────────────────────────────────────────────────│*/ - -#define MODERNITYSECONDS 11644473600ull -#define HECTONANOSECONDS 10000000ull - #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ @@ -48,52 +37,10 @@ float wcstof(const wchar_t *, wchar_t **); double wcstod(const wchar_t *, wchar_t **); long double wcstold(const wchar_t *, wchar_t **); -/*───────────────────────────────────────────────────────────────────────────│─╗ -│ cosmopolitan § conversion » time ─╬─│┼ -╚────────────────────────────────────────────────────────────────────────────│*/ - -int64_t DosDateTimeToUnix(unsigned, unsigned) libcesque nosideeffect; -struct timeval WindowsTimeToTimeVal(int64_t) -libcesque nosideeffect; -struct timespec WindowsTimeToTimeSpec(int64_t) -libcesque nosideeffect; -int64_t TimeSpecToWindowsTime(struct timespec) libcesque nosideeffect; -int64_t TimeValToWindowsTime(struct timeval) libcesque nosideeffect; -struct timeval WindowsDurationToTimeVal(int64_t) -libcesque nosideeffect; -struct timespec WindowsDurationToTimeSpec(int64_t) -libcesque nosideeffect; - -#define MakeFileTime(x) \ - ({ \ - int64_t __x = x; \ - (struct NtFileTime){(uint32_t)__x, (uint32_t)(__x >> 32)}; \ - }) - -#define ReadFileTime(t) \ - ({ \ - struct NtFileTime __t = t; \ - uint64_t x = __t.dwHighDateTime; \ - (int64_t)(x << 32 | __t.dwLowDateTime); \ - }) - -#define FileTimeToTimeSpec(x) WindowsTimeToTimeSpec(ReadFileTime(x)) -#define FileTimeToTimeVal(x) WindowsTimeToTimeVal(ReadFileTime(x)) -#define TimeSpecToFileTime(x) MakeFileTime(TimeSpecToWindowsTime(x)) -#define TimeValToFileTime(x) MakeFileTime(TimeValToWindowsTime(x)) - -/*───────────────────────────────────────────────────────────────────────────│─╗ -│ cosmopolitan § conversion » manipulation ─╬─│┼ -╚────────────────────────────────────────────────────────────────────────────│*/ - #ifdef _COSMO_SOURCE char *stripext(char *); char *stripexts(char *); -#endif - -/*───────────────────────────────────────────────────────────────────────────│─╗ -│ cosmopolitan § conversion » computation ─╬─│┼ -╚────────────────────────────────────────────────────────────────────────────│*/ +#endif /* _COSMO_SOURCE */ typedef struct { int quot; @@ -120,10 +67,6 @@ ldiv_t ldiv(long, long) pureconst; lldiv_t lldiv(long long, long long) pureconst; imaxdiv_t imaxdiv(intmax_t, intmax_t) pureconst; -/*───────────────────────────────────────────────────────────────────────────│─╗ -│ cosmopolitan § conversion » optimizations ─╬─│┼ -╚────────────────────────────────────────────────────────────────────────────│*/ - #if __STDC_VERSION__ + 0 >= 199901L #define div(num, den) ((div_t){(num) / (den), (num) % (den)}) #define ldiv(num, den) ((ldiv_t){(num) / (den), (num) % (den)}) diff --git a/libc/fmt/wintime.internal.h b/libc/fmt/wintime.internal.h new file mode 100644 index 000000000..97d9fce57 --- /dev/null +++ b/libc/fmt/wintime.internal.h @@ -0,0 +1,41 @@ +#ifndef COSMOPOLITAN_LIBC_FMT_WINTIME_H_ +#define COSMOPOLITAN_LIBC_FMT_WINTIME_H_ +#include "libc/calls/struct/timespec.h" +#include "libc/calls/struct/timeval.h" +#include "libc/nt/struct/filetime.h" + +#define MODERNITYSECONDS 11644473600ull +#define HECTONANOSECONDS 10000000ull + +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +int64_t DosDateTimeToUnix(uint32_t, uint32_t) pureconst; +int64_t TimeSpecToWindowsTime(struct timespec) pureconst; +int64_t TimeValToWindowsTime(struct timeval) pureconst; +struct timespec WindowsDurationToTimeSpec(int64_t) pureconst; +struct timespec WindowsTimeToTimeSpec(int64_t) pureconst; +struct timeval WindowsDurationToTimeVal(int64_t) pureconst; +struct timeval WindowsTimeToTimeVal(int64_t) pureconst; + +#define MakeFileTime(x) \ + ({ \ + int64_t __x = x; \ + (struct NtFileTime){(uint32_t)__x, (uint32_t)(__x >> 32)}; \ + }) + +#define ReadFileTime(t) \ + ({ \ + struct NtFileTime __t = t; \ + uint64_t x = __t.dwHighDateTime; \ + (int64_t)(x << 32 | __t.dwLowDateTime); \ + }) + +#define FileTimeToTimeSpec(x) WindowsTimeToTimeSpec(ReadFileTime(x)) +#define FileTimeToTimeVal(x) WindowsTimeToTimeVal(ReadFileTime(x)) +#define TimeSpecToFileTime(x) MakeFileTime(TimeSpecToWindowsTime(x)) +#define TimeValToFileTime(x) MakeFileTime(TimeValToWindowsTime(x)) + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_FMT_WINTIME_H_ */ diff --git a/libc/intrin/bt.c b/libc/intrin/bt.c deleted file mode 100644 index 6d61f0177..000000000 --- a/libc/intrin/bt.c +++ /dev/null @@ -1,68 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2022 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/errno.h" -#include "libc/intrin/kprintf.h" -#include "libc/intrin/weaken.h" -#include "libc/log/backtrace.internal.h" -#include "libc/runtime/symbols.internal.h" - -static _Thread_local bool noreentry; - -/** - * Shows backtrace if crash reporting facilities are linked. - */ -void _bt(const char *fmt, ...) { - int e; - va_list va; - - if (!noreentry) { - noreentry = true; - } else { - return; - } - - if (fmt) { - va_start(va, fmt); - kvprintf(fmt, va); - va_end(va); - } - - if (_weaken(ShowBacktrace) && _weaken(GetSymbolTable)) { - e = errno; - _weaken(ShowBacktrace)(2, __builtin_frame_address(0)); - errno = e; - } else { - kprintf("_bt() can't show backtrace because you need:\n" - "\t__static_yoink(\"ShowBacktrace\");\n" - "to be linked.\n"); - if (_weaken(PrintBacktraceUsingSymbols) && _weaken(GetSymbolTable)) { - e = errno; - _weaken(PrintBacktraceUsingSymbols)(2, __builtin_frame_address(0), - _weaken(GetSymbolTable)()); - errno = e; - } else { - kprintf("_bt() can't show backtrace because you need:\n" - "\t__static_yoink(\"PrintBacktraceUsingSymbols\");\n" - "\t__static_yoink(\"GetSymbolTable\");\n" - "to be linked.\n"); - } - } - - noreentry = false; -} diff --git a/libc/intrin/closehandle.c b/libc/intrin/closehandle.c deleted file mode 100644 index f09b53c03..000000000 --- a/libc/intrin/closehandle.c +++ /dev/null @@ -1,37 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2022 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/syscall_support-nt.internal.h" -#include "libc/intrin/strace.internal.h" -#include "libc/log/log.h" -#include "libc/nt/runtime.h" -#include "libc/nt/thunk/msabi.h" - -__msabi extern typeof(CloseHandle) *const __imp_CloseHandle; - -/** - * Closes an open object handle. - * @note this wrapper takes care of ABI, STRACE(), and __winerr() - */ -textwindows bool32 CloseHandle(int64_t hObject) { - bool32 ok; - ok = __imp_CloseHandle(hObject); - if (!ok) __winerr(); - NTTRACE("CloseHandle(%ld) → %hhhd% m", hObject, ok); - return ok; -} diff --git a/libc/intrin/cp.c b/libc/intrin/cp.c index 7d34f347b..4a9d092db 100644 --- a/libc/intrin/cp.c +++ b/libc/intrin/cp.c @@ -51,9 +51,7 @@ void end_cancellation_point(int state) { } void report_cancellation_point(void) { - BLOCK_CANCELLATIONS; - _bt("error: need BEGIN/END_CANCELLATION_POINT\n"); - ALLOW_CANCELLATIONS; + __builtin_trap(); } #endif /* MODE_DBG */ diff --git a/libc/intrin/directmap.c b/libc/intrin/directmap.c index e224379d9..497b9ba84 100644 --- a/libc/intrin/directmap.c +++ b/libc/intrin/directmap.c @@ -33,7 +33,6 @@ * for passing the magic memory handle on Windows NT to CloseHandle(). * * @asyncsignalsafe - * @threadsafe */ struct DirectMap sys_mmap(void *addr, size_t size, int prot, int flags, int fd, int64_t off) { diff --git a/libc/intrin/exit.c b/libc/intrin/exit.c index bc5a3c79f..255174771 100644 --- a/libc/intrin/exit.c +++ b/libc/intrin/exit.c @@ -40,7 +40,6 @@ * by hosing the interrupt descriptors and triple faulting the system. * * @asyncsignalsafe - * @threadsafe * @vforksafe * @noreturn */ diff --git a/libc/intrin/exit1.greg.c b/libc/intrin/exit1.greg.c index 8c5d300c0..cb90fbbfd 100644 --- a/libc/intrin/exit1.greg.c +++ b/libc/intrin/exit1.greg.c @@ -40,7 +40,6 @@ __msabi extern typeof(ExitThread) *const __imp_ExitThread; * * @param rc only works on Linux and Windows * @see cthread_exit() - * @threadsafe * @noreturn */ privileged wontreturn void _Exit1(int rc) { diff --git a/libc/intrin/getmainstack.c b/libc/intrin/getmainstack.c index 0c955bfb7..498ce2add 100644 --- a/libc/intrin/getmainstack.c +++ b/libc/intrin/getmainstack.c @@ -28,6 +28,8 @@ #include "libc/sysv/consts/rlim.h" #include "libc/sysv/consts/rlimit.h" +// Hack for guessing boundaries of _start()'s stack +// // Every UNIX system in our support vector creates arg blocks like: // // @@ -53,6 +55,11 @@ // up to the microprocessor page size (this computes the top addr) // and the bottom is computed by subtracting RLIMIT_STACK rlim_cur // It's simple but gets tricky if we consider environ can be empty +// +// This code always guesses correctly on Windows because WinMain() +// is written to allocate a stack ourself. Local testing on Linux, +// XNU, FreeBSD, OpenBSD, and NetBSD says that accuracy is ±1 page +// and that error rate applies to both beginning and end addresses static char *__get_last(char **list) { char *res = 0; diff --git a/libc/intrin/getpid.c b/libc/intrin/getpid.c index 94b0fb4f1..fb0860996 100644 --- a/libc/intrin/getpid.c +++ b/libc/intrin/getpid.c @@ -38,7 +38,6 @@ * * @return process id (always successful) * @asyncsignalsafe - * @threadsafe * @vforksafe */ int getpid(void) { diff --git a/libc/intrin/gettid.c b/libc/intrin/gettid.c index f8be087ce..67cb0bfa4 100644 --- a/libc/intrin/gettid.c +++ b/libc/intrin/gettid.c @@ -34,7 +34,6 @@ * * @return thread id greater than zero or -1 w/ errno * @asyncsignalsafe - * @threadsafe * @vforksafe */ int gettid(void) { diff --git a/libc/intrin/rand64.c b/libc/intrin/rand64.c index 88fda8987..aa8e8b5d7 100644 --- a/libc/intrin/rand64.c +++ b/libc/intrin/rand64.c @@ -43,7 +43,6 @@ static struct { * @note this function is not intended for cryptography * @note this function passes bigcrush and practrand * @asyncsignalsafe - * @threadsafe * @vforksafe */ uint64_t _rand64(void) { diff --git a/libc/intrin/strace.internal.h b/libc/intrin/strace.internal.h index 1dce6394d..60b17b3ad 100644 --- a/libc/intrin/strace.internal.h +++ b/libc/intrin/strace.internal.h @@ -3,12 +3,13 @@ #include "libc/intrin/likely.h" #include "libc/runtime/runtime.h" -#define _KERNTRACE 0 /* not configurable w/ flag yet */ +#define _NTTRACE 1 /* not configurable w/ flag yet */ #define _POLLTRACE 0 /* not configurable w/ flag yet */ #define _DATATRACE 1 /* not configurable w/ flag yet */ -#define _STDIOTRACE 0 /* not configurable w/ flag yet */ #define _LOCKTRACE 0 /* not configurable w/ flag yet */ -#define _NTTRACE 0 /* not configurable w/ flag yet */ +#define _STDIOTRACE 0 /* not configurable w/ flag yet */ +#define _KERNTRACE 0 /* not configurable w/ flag yet */ +#define _TIMETRACE 0 /* not configurable w/ flag yet */ #define STRACE_PROLOGUE "%rSYS %6P %'18T " @@ -63,6 +64,12 @@ COSMOPOLITAN_C_START_ #define LOCKTRACE(FMT, ...) (void)0 #endif +#if defined(SYSDEBUG) && _TIMETRACE +#define TIMETRACE(FMT, ...) STRACE(FMT, ##__VA_ARGS__) +#else +#define TIMETRACE(FMT, ...) (void)0 +#endif + void __stracef(const char *, ...); COSMOPOLITAN_C_END_ diff --git a/libc/intrin/strsignal.c b/libc/intrin/strsignal.c index ab70a1c5a..c4d34f21f 100644 --- a/libc/intrin/strsignal.c +++ b/libc/intrin/strsignal.c @@ -33,8 +33,9 @@ static char g_strsignal[21]; * * @param sig is signal number which should be in range 1 through 128 * @return string which is valid code describing signal - * @see strsignal_r() for better thread safety + * @see strsignal_r() * @see sigaction() + * @threadunsafe */ char *strsignal(int sig) { return strsignal_r(sig, g_strsignal); diff --git a/libc/intrin/strsignal_r.c b/libc/intrin/strsignal_r.c index d83206f60..9d8c3ae5f 100644 --- a/libc/intrin/strsignal_r.c +++ b/libc/intrin/strsignal_r.c @@ -34,7 +34,6 @@ * @return pointer to .rodata string, or to `buf` after mutating * @see sigaction() * @asyncsignalsafe - * @threadsafe */ privileged char *strsignal_r(int sig, char buf[21]) { const char *s; diff --git a/libc/intrin/unsetenv.c b/libc/intrin/unsetenv.c index 893d8c577..7499d3c2c 100644 --- a/libc/intrin/unsetenv.c +++ b/libc/intrin/unsetenv.c @@ -19,6 +19,7 @@ #include "libc/dce.h" #include "libc/intrin/getenv.internal.h" #include "libc/runtime/runtime.h" +#include "libc/str/str.h" #include "libc/sysv/errfuns.h" /** @@ -27,15 +28,12 @@ * @param s is non-empty environment key which can't contain `'='` * @return 0 on success, or -1 w/ errno and environment is unchanged * @raise EINVAL if `s` is an empty string or has a `'='` character + * @threadunsafe */ int unsetenv(const char *s) { char **p; struct Env e; - const char *t; - if (!s || !*s) return einval(); - for (t = s; *t; ++t) { - if (*t == '=') return einval(); - } + if (!s || !*s || strchr(s, '=')) return einval(); if ((p = environ)) { e = __getenv(p, s); while (p[e.i]) { diff --git a/libc/isystem/sys/param.h b/libc/isystem/sys/param.h index b23ef87a0..8fbbcc0b8 100644 --- a/libc/isystem/sys/param.h +++ b/libc/isystem/sys/param.h @@ -4,7 +4,7 @@ #include "libc/calls/calls.h" #include "libc/calls/struct/rlimit.h" #include "libc/calls/struct/rusage.h" -#include "libc/calls/sysparam.h" +#include "libc/stdio/sysparam.h" #include "libc/calls/weirdtypes.h" #include "libc/limits.h" #include "libc/sysv/consts/endian.h" diff --git a/libc/isystem/windows.h b/libc/isystem/windows.h deleted file mode 100644 index ee92e29f4..000000000 --- a/libc/isystem/windows.h +++ /dev/null @@ -1,1507 +0,0 @@ -#ifndef COSMOPOLITAN_LIBC_COMPAT_INCLUDE_WINDOWS_H_ -#define COSMOPOLITAN_LIBC_COMPAT_INCLUDE_WINDOWS_H_ -#include "libc/nt/accounting.h" -#include "libc/nt/automation.h" -#include "libc/nt/console.h" -#include "libc/nt/debug.h" -#include "libc/nt/dll.h" -#include "libc/nt/enum/keyaccess.h" -#include "libc/nt/enum/regtype.h" -#include "libc/nt/errors.h" -#include "libc/nt/events.h" -#include "libc/nt/files.h" -#include "libc/nt/ipc.h" -#include "libc/nt/memory.h" -#include "libc/nt/paint.h" -#include "libc/nt/process.h" -#include "libc/nt/registry.h" -#include "libc/nt/synchronization.h" -#include "libc/nt/thread.h" -#include "libc/nt/windows.h" -#include "libc/nt/winsock.h" - -/* #if defined(__GNUC__) */ -/* #pragma GCC diagnostic ignored "-Wint-conversion" */ -/* #endif */ -#undef NULL -#define NULL 0 - -#define ERROR_SUCCESS kNtErrorSuccess - -#define FARPROC wambda -#define NEARPROC wambda -#define PROC wambda - -#define LONG int32_t /* [sic] */ -#define WCHAR char16_t /* [sic] */ -#define BOOL bool32 /* [sic] */ - -#define TRUE true -#define FALSE false - -#define PVOID void* -#define PVOID64 void* -#define LPCVOID const void* -#define CHAR char -#define SHORT short -#define CONST const -#define VOID void -#define INT8 signed char -#define PINT8 signed char* -#define INT16 int16_t -#define PINT16 int16_t* -#define INT32 int32_t -#define PINT32 int32_t* -#define INT64 int64_t -#define PINT64 int64_t* -#define UINT8 unsigned char -#define PUINT8 unsigned char* -#define UINT16 uint16_t -#define PUINT16 uint16_t* -#define UINT32 uint32_t -#define PUINT32 uint32_t* -#define UINT64 uint64_t -#define PUINT64 uint64_t* -#define LONG32 int32_t -#define PLONG32 int32_t* -#define ULONG32 uint32_t -#define PULONG32 uint32_t* -#define DWORD32 uint32_t -#define PDWORD32 uint32_t* - -#define INT_PTR intptr_t -#define PINT_PTR intptr_t* -#define UINT_PTR uintptr_t -#define PUINT_PTR uintptr_t* -#define LONG_PTR intptr_t -#define PLONG_PTR int32_t** -#define ULONG_PTR uintptr_t -#define PULONG_PTR uint32_t** -#define POINTER_64_INT int64_t* -#define __int3264 int64_t - -#define SHANDLE_PTR int64_t -#define HANDLE_PTR uint64_t - -#define UHALF_PTR uint32_t -#define PUHALF_PTR uint32_t* -#define HALF_PTR int32_t -#define PHALF_PTR int32_t* - -#define SIZE_T size_t -#define PSIZE_T size_t* -#define SSIZE_T ssize_t -#define PSSIZE_T ssize_t* -#define DWORD_PTR ULONG_PTR -#define PDWORD_PTR ULONG_PTR* -#define LONG64 int64_t -#define PLONG64 int64_t* -#define ULONG64 uint64_t -#define PULONG64 uint64_t* -#define DWORD64 uint64_t -#define PDWORD64 uint64_t* -#define KAFFINITY ULONG_PTR -#define PKAFFINITY KAFFINITY* -#define KPRIORITY LONG - -#define PWCHAR WCHAR* -#define LPWCH WCHAR* -#define PWCH WCHAR* -#define LPCWCH CONST WCHAR* -#define PCWCH CONST WCHAR* -#define NWPSTR WCHAR* -#define LPWSTR WCHAR* -#define PWSTR WCHAR* -#define PZPWSTR PWSTR* -#define PCZPWSTR CONST PWSTR* -#define LPUWSTR WCHAR forcealign(1)* -#define PUWSTR WCHAR forcealign(1)* -#define LPCWSTR CONST WCHAR* -#define PCWSTR CONST WCHAR* -#define PZPCWSTR PCWSTR* -#define LPCUWSTR CONST WCHAR forcealign(1)* -#define PCUWSTR CONST WCHAR forcealign(1)* -#define PCHAR CHAR* -#define LPCH CHAR* -#define PCH CHAR* -#define LPCCH CONST CHAR* -#define PCCH CONST CHAR* -#define NPSTR CHAR* -#define LPSTR CHAR* -#define PSTR CHAR* -#define PZPSTR PSTR* -#define PCZPSTR CONST PSTR* -#define LPCSTR CONST CHAR* -#define PCSTR CONST CHAR* -#define PZPCSTR PCSTR* -#define TCHAR WCHAR -#define PTCHAR WCHAR* -#define TBYTE WCHAR -#define PTBYTE WCHAR* -#define LPTCH LPWSTR -#define PTCH LPWSTR -#define PTSTR LPWSTR -#define LPTSTR LPWSTR -#define PCTSTR LPCWSTR -#define LPCTSTR LPCWSTR -#define PUTSTR LPUWSTR -#define LPUTSTR LPUWSTR -#define PCUTSTR LPCUWSTR -#define LPCUTSTR LPCUWSTR -#define LP LPWSTR -#define PSHORT int16_t* -#define PLONG int32_t* -#define HANDLE int64_t -#define PHANDLE HANDLE* -#define FCHAR BYTE -#define FSHORT WORD -#define FLONG DWORD -#define HRESULT LONG -#define CCHAR char -#define LCID DWORD -#define PLCID PDWORD -#define LANGID WORD -#define LONGLONG int64_t -#define ULONGLONG uint64_t -#define USN LONGLONG -#define PLONGLONG LONGLONG* -#define PULONGLONG ULONGLONG* -#define DWORDLONG ULONGLONG -#define PDWORDLONG DWORDLONG* -#define LARGE_INTEGER int64_t -#define PLARGE_INTEGER int64_t* - -#define ULONG uint32_t -#define PULONG ULONG* -#define USHORT unsigned short -#define PUSHORT USHORT* -#define UCHAR unsigned char -#define PUCHAR UCHAR* -#define PSZ char* -#define DWORD uint32_t -#define WINBOOL BOOL -#define BOOLEAN BOOL -#define BYTE unsigned char -#define WORD unsigned short -#define FLOAT float -#define PFLOAT FLOAT* -#define PBOOL WINBOOL* -#define PBOOLEAN WINBOOL* -#define LPBOOL WINBOOL* -#define PBYTE BYTE* -#define LPBYTE BYTE* -#define PINT int* -#define LPINT int* -#define PWORD WORD* -#define LPWORD WORD* -#define LPLONG int32_t* -#define PDWORD DWORD* -#define LPDWORD DWORD* -#define LPVOID void* -#define LPCVOID const void* -#define INT int -#define UINT unsigned int -#define PUINT unsigned int* -#define WPARAM UINT_PTR -#define LPARAM LONG_PTR -#define LRESULT LONG_PTR -#define ATOM WORD -#define SPHANDLE HANDLE* -#define LPHANDLE HANDLE* -#define HGLOBAL HANDLE -#define HLOCAL HANDLE -#define GLOBALHANDLE HANDLE -#define LOCALHANDLE HANDLE -#define HGDIOBJ void* -#define PHKEY HKEY* -#define HMODULE HINSTANCE -#define HFILE int -#define HCURSOR HICON -#define COLORREF DWORD -#define LPCOLORREF DWORD* -#define ACCESS_MASK ULONG -#define REGSAM ACCESS_MASK -#define HKEY int64_t - -#define NTSTATUS LONG -#define HACCEL int64_t -#define HBITMAP int64_t -#define HBRUSH int64_t -#define HCOLORSPACE int64_t -#define HDC int64_t -#define HGLRC int64_t -#define HDESK int64_t -#define HENHMETAFILE int64_t -#define HFONT int64_t -#define HICON int64_t -#define HMENU int64_t -#define HMETAFILE int64_t -#define HINSTANCE int64_t -#define HPALETTE int64_t -#define HPEN int64_t -#define HRGN int64_t -#define HRSRC int64_t -#define HSTR int64_t -#define HTASK int64_t -#define HWINSTA int64_t -#define HKL int64_t -#define HMONITOR int64_t -#define HWINEVENTHOOK int64_t -#define HUMPD int64_t -#define HWND int64_t - -#define PDH_FUNCTION LONG - -#define PDH_HCOUNTER HANDLE -#define PDH_HQUERY HANDLE -#define PDH_HLOG HANDLE - -#define ADDRESS_FAMILY uint16_t -#define TUNNEL_TYPE uint32_t -#define NET_IF_CONNECTION_TYPE uint32_t -#define NET_IF_COMPARTMENT_ID uint32_t -#define IFTYPE uint32_t -#define NL_PREFIX_ORIGIN uint32_t -#define NL_SUFFIX_ORIGIN uint32_t -#define NL_DAD_STATE uint32_t -#define NET_IF_NETWORK_GUID struct NtGuid -#define IP_PREFIX_ORIGIN NL_PREFIX_ORIGIN -#define IP_SUFFIX_ORIGIN NL_SUFFIX_ORIGIN -#define IP_DAD_STATE NL_DAD_STATE -#define IP_ADAPTER_ADDRESSES struct NtIpAdapterAddresses -#define PIP_ADAPTER_ADDRESSES struct NtIpAdapterAddresses* -#define IP_ADAPTER_UNICAST_ADDRESS struct NtIpAdapterUnicastAddressLh -#define PIP_ADAPTER_UNICAST_ADDRESS struct NtIpAdapterUnicastAddressLh* -#define IP_ADAPTER_ANYCAST_ADDRESS struct NtIpAdapterAnycastAddressXp -#define PIP_ADAPTER_ANYCAST_ADDRESS struct NtIpAdapterAnycastAddressXp* -#define IP_ADAPTER_MULTICAST_ADDRESS struct NtIpAdapterMulticastAddressXp -#define PIP_ADAPTER_MULTICAST_ADDRESS struct NtIpAdapterMulticastAddressXp* -#define IP_ADAPTER_DNS_SERVER_ADDRESS struct NtIpAdapterDnsServerAddressXp -#define IP_ADAPTER_PREFIX struct NtIpAdapterPrefixXp -#define PIP_ADAPTER_PREFIX struct NtIpAdapterPrefixXp* - -#define _GENERIC_MAPPING NtGenericMapping -#define GENERIC_MAPPING struct NtGenericMapping -#define PGENERIC_MAPPING struct NtGenericMapping* -#define _UNICODE_STRING NtUnicodeString -#define UNICODE_STRING struct NtUnicodeString -#define PUNICODE_STRING struct NtUnicodeString* -#define _IO_COUNTERS NtIoCounters -#define IO_COUNTERS struct NtIoCounters -#define PIO_COUNTERS struct NtIoCounters* -#define _FILE_TIME NtFileTime -#define FILE_TIME struct NtFileTime -#define PFILE_TIME struct NtFileTime* -#define _FILETIME NtFileTime -#define FILETIME struct NtFileTime -#define PFILETIME struct NtFileTime* -#define _CLIENT_ID NtClientId -#define CLIENT_ID struct NtClientId -#define PCLIENT_ID struct NtClientId* -#define _SYSTEM_THREADS NtSystemThreads -#define SYSTEM_THREADS struct NtSystemThreads -#define PSYSTEM_THREADS struct NtSystemThreads* -#define _VM_COUNTERS NtVmCounters -#define VM_COUNTERS struct NtVmCounters -#define PVM_COUNTERS struct NtVmCounters* -#define _SECURITY_DESCRIPTOR NtSecurityDescriptor -#define SECURITY_DESCRIPTOR struct NtSecurityDescriptor -#define PSECURITY_DESCRIPTOR struct NtSecurityDescriptor* - -#define _OBJECT_ALL_INFORMATION NtObjectAllInformation -#define OBJECT_ALL_INFORMATION struct NtObjectAllinformation -#define POBJECT_ALL_INFORMATION struct NtObjectAllInformation* -#define _OBJECT_TYPE_INFORMATION NtObjectTypeInformation -#define OBJECT_TYPE_INFORMATION struct NtObjectTypeInformation -#define POBJECT_TYPE_INFORMATION struct NtObjectTypeInformation* -#define _OBJECT_NAME_INFORMATION NtObjectNameInformation -#define OBJECT_NAME_INFORMATION struct NtObjectNameInformation -#define POBJECT_NAME_INFORMATION struct NtObjectNameInformation* -#define _OBJECT_BASIC_INFORMATION NtObjectBasicInformation -#define OBJECT_BASIC_INFORMATION struct NtObjectBasicInformation -#define POBJECT_BASIC_INFORMATION struct NtObjectBasicInformation* -#define _FILE_ACCESS_INFORMATION NtFileAccessInformation -#define FILE_ACCESS_INFORMATION struct NtFileAccessInformation -#define PFILE_ACCESS_INFORMATION struct NtFileAccessInformation* -#define _FILE_ALIGNMENT_INFORMATION NtFileAlignmentInformation -#define FILE_ALIGNMENT_INFORMATION struct NtFileAlignmentInformation -#define PFILE_ALIGNMENT_INFORMATION struct NtFileAlignmentInformation* -#define _FILE_ALL_INFORMATION NtFileAllInformation -#define FILE_ALL_INFORMATION struct NtFileAllInformation -#define PFILE_ALL_INFORMATION struct NtFileAllInformation* -#define _FILE_ALLOCATION_INFORMATION NtFileAllocationInformation -#define FILE_ALLOCATION_INFORMATION struct NtFileAllocationInformation -#define PFILE_ALLOCATION_INFORMATION struct NtFileAllocationInformation* -#define _FILE_BASIC_INFORMATION NtFileBasicInformation -#define FILE_BASIC_INFORMATION struct NtFileBasicInformation -#define PFILE_BASIC_INFORMATION struct NtFileBasicInformation* -#define _FILE_BOTH_DIR_INFORMATION NtFileBothDirectoryInformation -#define FILE_BOTH_DIR_INFORMATION struct NtFileBothDirectoryInformation -#define PFILE_BOTH_DIR_INFORMATION struct NtFileBothDirectoryInformation* -#define _FILE_BOTH_DIRECTORY_INFORMATION NtFileBothDirectoryInformation -#define FILE_BOTH_DIRECTORY_INFORMATION struct NtFileBothDirectoryInformation -#define PFILE_BOTH_DIRECTORY_INFORMATION struct NtFileBothDirectoryInformation* -#define _FILE_DIRECTORY_INFORMATION NtFileDirectoryInformation -#define FILE_DIRECTORY_INFORMATION struct NtFileDirectoryInformation -#define PFILE_DIRECTORY_INFORMATION struct NtFileDirectoryInformation* -#define _FILE_DISPOSITION_INFORMATION NtFileDispositionInformation -#define FILE_DISPOSITION_INFORMATION struct NtFileDispositionInformation -#define PFILE_DISPOSITION_INFORMATION struct NtFileDispositionInformation* -#define _FILE_EA_INFORMATION NtFileEaInformation -#define FILE_EA_INFORMATION struct NtFileEaInformation -#define PFILE_EA_INFORMATION struct NtFileEaInformation* -#define _FILE_INTERNAL_INFORMATION NtFileInternalInformation -#define FILE_INTERNAL_INFORMATION struct NtFileInternalInformation -#define PFILE_INTERNAL_INFORMATION struct NtFileInternalInformation* -#define _FILE_MODE_INFORMATION NtFileModeInformation -#define FILE_MODE_INFORMATION struct NtFileModeInformation -#define PFILE_MODE_INFORMATION struct NtFileModeInformation* -#define _FILE_NAME_INFORMATION NtFileNameInformation -#define FILE_NAME_INFORMATION struct NtFileNameInformation -#define PFILE_NAME_INFORMATION struct NtFileNameInformation* -#define _FILE_NAMES_INFORMATION NtFileNamesInformation -#define FILE_NAMES_INFORMATION struct NtFileNamesInformation -#define PFILE_NAMES_INFORMATION struct NtFileNamesInformation* -#define _FILE_POSITION_INFORMATION NtFilePositionInformation -#define FILE_POSITION_INFORMATION struct NtFilePositionInformation -#define PFILE_POSITION_INFORMATION struct NtFilePositionInformation* -#define _FILE_RENAME_INFORMATION NtFileRenameInformation -#define FILE_RENAME_INFORMATION struct NtFileRenameInformation -#define PFILE_RENAME_INFORMATION struct NtFileRenameInformation* -#define _FILE_STANDARD_INFORMATION NtFileStandardInformation -#define FILE_STANDARD_INFORMATION struct NtFileStandardInformation -#define PFILE_STANDARD_INFORMATION struct NtFileStandardInformation* -#define _FILE_STREAM_INFORMATION NtFileStreamInformation -#define FILE_STREAM_INFORMATION struct NtFileStreamInformation -#define PFILE_STREAM_INFORMATION struct NtFileStreamInformation* -#define _KERNEL_USER_TIMES NtKernelUserTimes -#define KERNEL_USER_TIMES struct NtKernelUserTimes -#define PKERNEL_USER_TIMES struct NtKernelUserTimes* -#define _PROCESS_BASIC_INFORMATION NtProcessBasicInformation -#define PROCESS_BASIC_INFORMATION struct NtProcessBasicInformation -#define PPROCESS_BASIC_INFORMATION struct NtProcessBasicInformation* -#define _SYSTEM_BASIC_INFORMATION NtSystemBasicInformation -#define SYSTEM_BASIC_INFORMATION struct NtSystemBasicInformation -#define PSYSTEM_BASIC_INFORMATION struct NtSystemBasicInformation* -#define _SYSTEM_EXCEPTION_INFORMATION NtSystemExceptionInformation -#define SYSTEM_EXCEPTION_INFORMATION struct NtSystemExceptionInformation -#define PSYSTEM_EXCEPTION_INFORMATION struct NtSystemExceptionInformation* -#define _SYSTEM_HANDLE_ENTRY NtSystemHandleEntry -#define SYSTEM_HANDLE_ENTRY struct NtSystemHandleEntry -#define PSYSTEM_HANDLE_ENTRY struct NtSystemHandleEntry* -#define _SYSTEM_HANDLE_INFORMATION NtSystemHandleInformation -#define SYSTEM_HANDLE_INFORMATION struct NtSystemHandleInformation -#define PSYSTEM_HANDLE_INFORMATION struct NtSystemHandleInformation* -#define _SYSTEM_INTERRUPT_INFORMATION NtSystemInterruptInformation -#define SYSTEM_INTERRUPT_INFORMATION struct NtSystemInterruptInformation -#define PSYSTEM_INTERRUPT_INFORMATION struct NtSystemInterruptInformation* -#define _SYSTEM_LOOKASIDE_INFORMATION NtSystemLookasideInformation -#define SYSTEM_LOOKASIDE_INFORMATION struct NtSystemLookasideInformation -#define PSYSTEM_LOOKASIDE_INFORMATION struct NtSystemLookasideInformation* -#define _SYSTEM_PERFORMANCE_INFORMATION NtSystemPerformanceInformation -#define SYSTEM_PERFORMANCE_INFORMATION struct NtSystemPerformanceInformation -#define PSYSTEM_PERFORMANCE_INFORMATION struct NtSystemPerformanceInformation* -#define _SYSTEM_PROCESS_INFORMATION NtSystemProcessInformation -#define SYSTEM_PROCESS_INFORMATION struct NtSystemProcessInformation -#define PSYSTEM_PROCESS_INFORMATION struct NtSystemProcessInformation* -#define _SYSTEM_PROCESSOR_INFORMATION NtSystemProcessorInformation -#define SYSTEM_PROCESSOR_INFORMATION struct NtSystemProcessorInformation -#define PSYSTEM_PROCESSOR_INFORMATION struct NtSystemProcessorInformation* -#define _SYSTEM_TIMEOFDAY_INFORMATION NtSystemTimeofdayInformation -#define SYSTEM_TIMEOFDAY_INFORMATION struct NtSystemTimeofdayInformation -#define PSYSTEM_TIMEOFDAY_INFORMATION struct NtSystemTimeofdayInformation* - -#define _SYSTEM_REGISTRY_QUOTA_INFORMATION NtSystemRegistryQuotaInformation -#define SYSTEM_REGISTRY_QUOTA_INFORMATION \ - struct NtSystemRegistryQuotaInformation -#define PSYSTEM_REGISTRY_QUOTA_INFORMATION \ - struct NtSystemRegistryQuotaInformation* -#define _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION \ - NtSystemProcessorPerformanceInformation -#define SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION \ - struct NtSystemProcessorPerformanceInformation -#define PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION \ - struct NtSystemProcessorPerformanceInformation* -#define _FILE_FULL_DIR_INFORMATION NtFileFullDirectoryInformation -#define FILE_FULL_DIR_INFORMATION struct NtFileFullDirectoryInformation -#define PFILE_FULL_DIR_INFORMATION struct NtFileFullDirectoryInformation* -#define _FILE_FULL_DIRECTORY_INFORMATION NtFileFullDirectoryInformation -#define FILE_FULL_DIRECTORY_INFORMATION struct NtFileFullDirectoryInformation -#define PFILE_FULL_DIRECTORY_INFORMATION struct NtFileFullDirectoryInformation* -#define _FILE_ATTRIBUTE_TAG_INFORMATION NtFileAttributeTagInformation -#define FILE_ATTRIBUTE_TAG_INFORMATION struct NtFileAttributeTagInformation -#define PFILE_ATTRIBUTE_TAG_INFORMATION struct NtFileAttributeTagInformation* -#define _FILE_PIPE_LOCAL_INFORMATION NtFilePipeLocalInformation -#define FILE_PIPE_LOCAL_INFORMATION struct NtFilePipeLocalInformation -#define PFILE_PIPE_LOCAL_INFORMATION struct NtFilePipeLocalInformation* -#define _FILE_NETWORK_OPEN_INFORMATION NtFileNetworkOpenInformation -#define FILE_NETWORK_OPEN_INFORMATION struct NtFileNetworkOpenInformation -#define PFILE_NETWORK_OPEN_INFORMATION struct NtFileNetworkOpenInformation* -#define _FILE_MAILSLOT_QUERY_INFORMATION NtFileMailslotQueryInformation -#define FILE_MAILSLOT_QUERY_INFORMATION struct NtFileMailslotQueryInformation -#define PFILE_MAILSLOT_QUERY_INFORMATION struct NtFileMailslotQueryInformation* -#define _FILE_MAILSLOT_SET_INFORMATION NtFileMailslotSetInformation -#define FILE_MAILSLOT_SET_INFORMATION struct NtFileMailslotSetInformation -#define PFILE_MAILSLOT_SET_INFORMATION struct NtFileMailslotSetInformation* -#define _FILE_FULL_EA_INFORMATION NtFileFullEaInformation -#define FILE_FULL_EA_INFORMATION struct NtFileFullEaInformation -#define PFILE_FULL_EA_INFORMATION struct NtFileFullEaInformation* -#define _PDH_FMT_COUNTERVALUE NtPdhFmtCountervalue -#define PDH_FMT_COUNTERVALUE struct NtPdhFmtCountervalue -#define PPDH_FMT_COUNTERVALUE struct NtPdhFmtCountervalue* - -#define _LUID NtLuid -#define LUID struct NtLuid -#define PLUID struct NtLuid* - -#define _LUID_AND_ATTRIBUTES NtLuidAndAttributes -#define LUID_AND_ATTRIBUTES struct NtLuidAndAttributes -#define PLUID_AND_ATTRIBUTES struct NtLuidAndAttributes* - -#define _PRIVILEGE_SET NtPrivilegeSet -#define PRIVILEGE_SET struct NtPrivilegeSet -#define PPRIVILEGE_SET struct NtPrivilegeSet* - -#define _IMAGE_FILE_HEADER NtImageFileHeader -#define IMAGE_FILE_HEADER struct NtImageFileHeader -#define PIMAGE_FILE_HEADER struct NtImageFileHeader* - -#define _IMAGE_DOS_HEADER NtImageDosHeader -#define IMAGE_DOS_HEADER struct NtImageDosHeader -#define PIMAGE_DOS_HEADER struct NtImageDosHeader* - -#define _BY_HANDLE_FILE_INFORMATION NtByHandleFileInformation -#define BY_HANDLE_FILE_INFORMATION struct NtByHandleFileInformation -#define PBY_HANDLE_FILE_INFORMATION struct NtByHandleFileInformation* -#define LPBY_HANDLE_FILE_INFORMATION struct NtByHandleFileInformation* - -#define _WIN32_FILE_ATTRIBUTE_DATA NtWin32FileAttributeData -#define WIN32_FILE_ATTRIBUTE_DATA struct NtWin32FileAttributeData -#define LPWIN32_FILE_ATTRIBUTE_DATA struct NtWin32FileAttributeData* - -#define _FILE_END_OF_FILE_INFORMATION FileEndOfFileInformation -#define FILE_END_OF_FILE_INFORMATION struct FileEndOfFileInformation -#define PFILE_END_OF_FILE_INFORMATION struct FileEndOfFileInformation* - -#define _GET_FILEEX_INFO_LEVELS NtGetFileexInfoLevels -#define GET_FILEEX_INFO_LEVELS int -#define LPGET_FILEEX_INFO_LEVELS int* - -#define _WIN32_FIND_DATA NtWin32FindData -#define WIN32_FIND_DATA struct NtWin32FindData -#define LPWIN32_FIND_DATA struct NtWin32FindData* - -#define _FINDEX_INFO_LEVELS NtFindexInfoLevels -#define FINDEX_INFO_LEVELS int -#define FindExInfoStandard kNtFindExInfoStandard -#define FindExInfoBasic kNtFindExInfoBasic -#define FindExInfoMaxInfoLevel kNtFindExInfoMaxInfoLevel -#define FIND_FIRST_EX_CASE_SENSITIVE kNtFindFirstExCaseSensitive -#define FIND_FIRST_EX_LARGE_FETCH kNtFindFirstExLargeFetch -#define _FINDEX_SEARCH_OPS NtFindexSearchOps -#define FINDEX_SEARCH_OPS int -#define FindExSearchNameMatch kNtFindExSearchNameMatch -#define FindExSearchLimitToDirectories kNtFindExSearchLimitToDirectories -#define FindExSearchLimitToDevices kNtFindExSearchLimitToDevices -#define FindExSearchMaxSearchOp kNtFindExSearchMaxSearchOp - -#define GetFileExInfoStandard kNtGetFileExInfoStandard -#define GetFileExMaxInfoLevel kNtGetFile_MAX - -#define MOVEFILE_REPLACE_EXISTING kNtMovefileReplaceExisting -#define MOVEFILE_COPY_ALLOWED kNtMovefileCopyAllowed -#define MOVEFILE_DELAY_UNTIL_REBOOT kNtMovefileDelayUntilReboot -#define MOVEFILE_CREATE_HARDLINK kNtMovefileCreateHardlink -#define MOVEFILE_FAIL_IF_NOT_TRACKABLE kNtMovefileFailIfNotTrackable -#define MOVEFILE_WRITE_THROUGH kNtMovefileWriteThrough - -#define OFFER_PRIORITY int -#define VmOfferPriorityVeryLow kNtVmOfferPriorityVeryLow -#define VmOfferPriorityLow kNtVmOfferPriorityLow -#define VmOfferPriorityBelowNormal kNtVmOfferPriorityBelowNormal -#define VmOfferPriorityNormal kNtVmOfferPriorityNormal - -#define _KWAIT_REASON uint32_t -#define KWAIT_REASON uint32_t -#define _OBJECT_INFORMATION_CLASS NtObjectInformationClass -#define OBJECT_INFORMATION_CLASS int -#define _PROCESSINFOCLASS NtProcessinfoclass -#define PROCESSINFOCLASS int -#define _THREAD_STATE NtThreadState -#define THREAD_STATE int -#define _TOKEN_TYPE NtTokenType -#define TOKEN_TYPE int - -#define _THREADINFOCLASS Nthreadinfoclass -#define THREADINFOCLASS int - -#define _THREAD_INFORMATION_CLASS NtThreadInformationClass -#define THREAD_INFORMATION_CLASS int -#define PTHREAD_INFORMATION_CLASS int* - -#define OWNER_SECURITY_INFORMATION kNtOwnerSecurityInformation -#define GROUP_SECURITY_INFORMATION kNtGroupSecurityInformation -#define DACL_SECURITY_INFORMATION kNtDaclSecurityInformation -#define SACL_SECURITY_INFORMATION kNtSaclSecurityInformation -#define LABEL_SECURITY_INFORMATION kNtLabelSecurityInformation -#define ATTRIBUTE_SECURITY_INFORMATION kNtAttributeSecurityInformation -#define SCOPE_SECURITY_INFORMATION kNtScopeSecurityInformation -#define PROCESS_TRUST_LABEL_SECURITY_INFORMATION \ - kNtProcessTrustLabelSecurityInformation -#define ACCESS_FILTER_SECURITY_INFORMATION kNtAccessFilterSecurityInformation -#define BACKUP_SECURITY_INFORMATION kNtBackupSecurityInformation -#define PROTECTED_DACL_SECURITY_INFORMATION kNtProtectedDaclSecurityInformation -#define PROTECTED_SACL_SECURITY_INFORMATION kNtProtectedSaclSecurityInformation -#define UNPROTECTED_DACL_SECURITY_INFORMATION \ - kNtUnprotectedDaclSecurityInformation -#define UNPROTECTED_SACL_SECURITY_INFORMATION \ - kNtUnprotectedSaclSecurityInformation - -#define STARTF_USESHOWWINDOW kNtNtStartfUseshowwindow -#define STARTF_USESIZE kNtNtStartfUsesize -#define STARTF_USEPOSITION kNtNtStartfUseposition -#define STARTF_USECOUNTCHARS kNtNtStartfUsecountchars -#define STARTF_USEFILLATTRIBUTE kNtNtStartfUsefillattribute -#define STARTF_RUNFULLSCREEN kNtNtStartfRunfullscreen -#define STARTF_FORCEONFEEDBACK kNtNtStartfForceonfeedback -#define STARTF_FORCEOFFFEEDBACK kNtNtStartfForceofffeedback -#define STARTF_USESTDHANDLES kNtNtStartfUsestdhandles -#define STARTF_USEHOTKEY kNtNtStartfUsehotkey -#define STARTF_TITLEISLINKNAME kNtNtStartfTitleislinkname -#define STARTF_TITLEISAPPID kNtNtStartfTitleisappid -#define STARTF_PREVENTPINNING kNtNtStartfPreventpinning -#define STARTF_UNTRUSTEDSOURCE kNtNtStartfUntrustedsource - -#define MEM_COMMIT kNtMemCommit -#define MEM_RESERVE kNtMemReserve -#define MEM_DECOMMIT kNtMemDecommit -#define MEM_RELEASE kNtMemRelease -#define MEM_FREE kNtMemFree -#define MEM_PRIVATE kNtMemPrivate -#define MEM_MAPPED kNtMemMapped -#define MEM_RESET kNtMemReset -#define MEM_TOP_DOWN kNtMemTopDown -#define MEM_WRITE_WATCH kNtMemWriteWatch -#define MEM_PHYSICAL kNtMemPhysical -#define MEM_LARGE_PAGES kNtMemLargePages -#define MEM_4MB_PAGES kNtMem4mbPages -#define PAGE_NOACCESS kNtPageNoaccess -#define PAGE_READONLY kNtPageReadonly -#define PAGE_READWRITE kNtPageReadwrite -#define PAGE_WRITECOPY kNtPageWritecopy -#define PAGE_EXECUTE kNtPageExecute -#define PAGE_EXECUTE_READ kNtPageExecuteRead -#define PAGE_EXECUTE_READWRITE kNtPageExecuteReadwrite -#define PAGE_EXECUTE_WRITECOPY kNtPageExecuteWritecopy -#define PAGE_GUARD kNtPageGuard -#define PAGE_NOCACHE kNtPageNocache -#define PAGE_WRITECOMBINE kNtPageWritecombine -#define FILE_MAP_COPY kNtFileMapCopy -#define FILE_MAP_WRITE kNtFileMapWrite -#define FILE_MAP_READ kNtFileMapRead -#define FILE_MAP_EXECUTE kNtFileMapExecute -#define FILE_MAP_RESERVE kNtFileMapReserve -#define FILE_MAP_TARGETS_INVALID kNtFileMapTargetsInvalid -#define FILE_MAP_LARGE_PAGES kNtFileMapLargePages - -#define SECTION_QUERY kNtSectionQuery -#define SECTION_MAP_WRITE kNtSectionMapWrite -#define SECTION_MAP_READ kNtSectionMapRead -#define SECTION_MAP_EXECUTE kNtSectionMapExecute -#define SECTION_EXTEND_SIZE kNtSectionExtendSize -#define SECTION_MAP_EXECUTE_EXPLICIT kNtSectionMapExecuteExplicit - -#define CTRL_CEVENT kNtCtrlCEvent -#define CTRL_BREAK_EVENT kNtCtrlBreakEvent -#define CTRL_CLOSE_EVENT kNtCtrlCloseEvent -#define CTRL_LOGOFF_EVENT kNtCtrlLogoffEvent -#define CTRL_SHUTDOWN_EVENT kNtCtrlShutdownEvent - -#define FILE_ATTRIBUTE_NORMAL kNtFileAttributeNormal -#define FILE_ATTRIBUTE_HIDDEN kNtFileAttributeHidden -#define FILE_FLAG_WRITE_THROUGH kNtFileFlagWriteThrough -#define FILE_FLAG_OVERLAPPED kNtFileFlagOverlapped -#define FILE_FLAG_NO_BUFFERING kNtFileFlagNoBuffering -#define FILE_FLAG_RANDOM_ACCESS kNtFileFlagRandomAccess -#define FILE_FLAG_SEQUENTIAL_SCAN kNtFileFlagSequentialScan -#define FILE_FLAG_DELETE_ON_CLOSE kNtFileFlagDeleteOnClose -#define FILE_FLAG_BACKUP_SEMANTICS kNtFileFlagBackupSemantics -#define FILE_FLAG_POSIX_SEMANTICS kNtFileFlagPosixSemantics -#define FILE_FLAG_OPEN_REPARSE_POINT kNtFileFlagOpenReparsePoint -#define FILE_FLAG_OPEN_NO_RECALL kNtFileFlagOpenNoRecall -#define FILE_FLAG_FIRST_PIPE_INSTANCE kNtFileFlagFirstPipeInstance -#define FILE_LIST_DIRECTORY kNtFileListDirectory -#define FILE_ATTRIBUTE_ARCHIVE kNtFileAttributeArchive -#define FILE_ATTRIBUTE_COMPRESSED kNtFileAttributeCompressed -#define FILE_ATTRIBUTE_DEVICE kNtFileAttributeDevice -#define FILE_ATTRIBUTE_DIRECTORY kNtFileAttributeDirectory -#define FILE_ATTRIBUTE_ENCRYPTED kNtFileAttributeEncrypted -#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED kNtFileAttributeNotContentIndexed -#define FILE_ATTRIBUTE_OFFLINE kNtFileAttributeOffline -#define FILE_ATTRIBUTE_READONLY kNtFileAttributeReadonly -#define FILE_ATTRIBUTE_REPARSE_POINT kNtFileAttributeReparsePoint -#define FILE_ATTRIBUTE_SPARSE_FILE kNtFileAttributeSparseFile -#define FILE_ATTRIBUTE_SYSTEM kNtFileAttributeSystem -#define FILE_ATTRIBUTE_TEMPORARY kNtFileAttributeTemporary - -#define CREATE_NEW kNtCreateNew -#define CREATE_ALWAYS kNtCreateAlways -#define OPEN_EXISTING kNtOpenExisting -#define OPEN_ALWAYS kNtOpenAlways -#define TRUNCATE_EXISTING kNtTruncateExisting -#define FILE_SHARE_EXCLUSIVE kNtFileShareExclusive -#define FILE_SHARE_READ kNtFileShareRead -#define FILE_SHARE_WRITE kNtFileShareWrite -#define FILE_SHARE_DELETE kNtFileShareDelete - -#define INVALID_HANDLE_VALUE kNtInvalidHandleValue -#define STD_INPUT_HANDLE kNtStdInputHandle -#define STD_OUTPUT_HANDLE kNtStdOutputHandle -#define STD_ERROR_HANDLE kNtStdErrorHandle - -#define CONSOLE_NO_SELECTION kNtConsoleNoSelection -#define CONSOLE_SELECTION_IN_PROGRESS kNtConsoleSelectionInProgress -#define CONSOLE_SELECTION_NOT_EMPTY kNtConsoleSelectionNotEmpty -#define CONSOLE_MOUSE_SELECTION kNtConsoleMouseSelection -#define CONSOLE_MOUSE_DOWN kNtConsoleMouseDown - -#define MB_OK kNtMbOk -#define MB_OKCANCEL kNtMbOkcancel -#define MB_ABORTRETRYIGNORE kNtMbAbortretryignore -#define MB_YESNOCANCEL kNtMbYesnocancel -#define MB_YESNO kNtMbYesno -#define MB_RETRYCANCEL kNtMbRetrycancel -#define MB_CANCELTRYCONTINUE kNtMbCanceltrycontinue -#define MB_ICONHAND kNtMbIconhand -#define MB_ICONQUESTION kNtMbIconquestion -#define MB_ICONEXCLAMATION kNtMbIconexclamation -#define MB_ICONASTERISK kNtMbIconasterisk -#define MB_USERICON kNtMbUsericon -#define MB_ICONWARNING kNtMbIconwarning -#define MB_ICONERROR kNtMbIconerror -#define MB_ICONINFORMATION kNtMbIconinformation -#define MB_ICONSTOP kNtMbIconstop -#define MB_DEFBUTTON1 kNtMbDefbutton1 -#define MB_DEFBUTTON2 kNtMbDefbutton2 -#define MB_DEFBUTTON3 kNtMbDefbutton3 -#define MB_DEFBUTTON4 kNtMbDefbutton4 -#define MB_APPLMODAL kNtMbApplmodal -#define MB_SYSTEMMODAL kNtMbSystemmodal -#define MB_TASKMODAL kNtMbTaskmodal -#define MB_HELP kNtMbHelp -#define MB_NOFOCUS kNtMbNofocus -#define MB_SETFOREGROUND kNtMbSetforeground -#define MB_DEFAULT_DESKTOP_ONLY kNtMbDefaultDesktopOnly -#define MB_TOPMOST kNtMbTopmost -#define MB_RIGHT kNtMbRight -#define MB_RTLREADING kNtMbRtlreading -#define MB_SERVICE_NOTIFICATION kNtMbServiceNotification -#define MB_SERVICE_NOTIFICATION_NT3X kNtMbServiceNotificationNt3x -#define MB_TYPEMASK kNtMbTypemask -#define MB_ICONMASK kNtMbIconmask -#define MB_DEFMASK kNtMbDefmask -#define MB_MODEMASK kNtMbModemask -#define MB_MISCMASK kNtMbMiscmask - -#define IDOK kNtIdok -#define IDCANCEL kNtIdcancel -#define IDABORT kNtIdabort -#define IDRETRY kNtIdretry -#define IDIGNORE kNtIdignore -#define IDYES kNtIdyes -#define IDNO kNtIdno -#define IDCLOSE kNtIdclose -#define IDHELP kNtIdhelp -#define IDTRYAGAIN kNtIdtryagain -#define IDCONTINUE kNtIdcontinue - -#define PROCESS_TERMINATE kNtProcessTerminate -#define PROCESS_CREATE_THREAD kNtProcessCreateThread -#define PROCESS_SET_SESSIONID kNtProcessSetSessionid -#define PROCESS_VM_OPERATION kNtProcessVmOperation -#define PROCESS_VM_READ kNtProcessVmRead -#define PROCESS_VM_WRITE kNtProcessVmWrite -#define PROCESS_DUP_HANDLE kNtProcessDupHandle -#define PROCESS_CREATE_PROCESS kNtProcessCreateProcess -#define PROCESS_SET_QUOTA kNtProcessSetQuota -#define PROCESS_SET_INFORMATION kNtProcessSetInformation -#define PROCESS_QUERY_INFORMATION kNtProcessQueryInformation -#define PROCESS_SUSPEND_RESUME kNtProcessSuspendResume -#define PROCESS_QUERY_LIMITED_INFORMATION kNtProcessQueryLimitedInformation -#define PROCESS_SET_LIMITED_INFORMATION kNtProcessSetLimitedInformation -#define PROCESS_ALL_ACCESS kNtProcessAllAccess - -#define GENERIC_READ kNtGenericRead -#define GENERIC_WRITE kNtGenericWrite -#define GENERIC_EXECUTE kNtGenericExecute -#define GENERIC_ALL kNtGenericAll -#define DELETE kNtDelete -#define READ_CONTROL kNtReadControl -#define WRITE_DAC kNtWriteDac -#define WRITE_OWNER kNtWriteOwner -#define SYNCHRONIZE kNtSynchronize -#define STANDARD_RIGHTS_REQUIRED kNtStandardRightsRequired -#define STANDARD_RIGHTS_READ kNtStandardRightsRead -#define STANDARD_RIGHTS_WRITE kNtStandardRightsWrite -#define STANDARD_RIGHTS_EXECUTE kNtStandardRightsExecute -#define STANDARD_RIGHTS_ALL kNtStandardRightsAll -#define SPECIFIC_RIGHTS_ALL kNtSpecificRightsAll -#define ACCESS_SYSTEM_SECURITY kNtAccessSystemSecurity -#define MAXIMUM_ALLOWED kNtMaximumAllowed -#define GENERIC_READ kNtGenericRead -#define GENERIC_WRITE kNtGenericWrite -#define GENERIC_EXECUTE kNtGenericExecute -#define GENERIC_ALL kNtGenericAll - -#define FILE_TYPE_UNKNOWN kNtFileTypeUnknown -#define FILE_TYPE_DISK kNtFileTypeDisk -#define FILE_TYPE_CHAR kNtFileTypeChar -#define FILE_TYPE_PIPE kNtFileTypePipe -#define FILE_TYPE_REMOTE kNtFileTypeRemote - -#define NT_DEBUG_PROCESS kNtDebugProcess -#define NT_DEBUG_ONLY_THIS_PROCESS kNtDebugOnlyThisProcess -#define NT_CREATE_SUSPENDED kNtCreateSuspended -#define NT_DETACHED_PROCESS kNtDetachedProcess -#define NT_CREATE_NEW_CONSOLE kNtCreateNewConsole -#define NT_NORMAL_PRIORITY_CLASS kNtNormalPriorityClass -#define NT_IDLE_PRIORITY_CLASS kNtIdlePriorityClass -#define NT_HIGH_PRIORITY_CLASS kNtHighPriorityClass -#define NT_REALTIME_PRIORITY_CLASS kNtRealtimePriorityClass -#define NT_CREATE_NEW_PROCESS_GROUP kNtCreateNewProcessGroup -#define NT_CREATE_UNICODE_ENVIRONMENT kNtCreateUnicodeEnvironment -#define NT_CREATE_SEPARATE_WOW_VDM kNtCreateSeparateWowVdm -#define NT_CREATE_SHARED_WOW_VDM kNtCreateSharedWowVdm -#define NT_CREATE_FORCEDOS kNtCreateForcedos -#define NT_BELOW_NORMAL_PRIORITY_CLASS kNtBelowNormalPriorityClass -#define NT_ABOVE_NORMAL_PRIORITY_CLASS kNtAboveNormalPriorityClass -#define NT_INHERIT_PARENT_AFFINITY kNtInheritParentAffinity -#define NT_CREATE_PROTECTED_PROCESS kNtCreateProtectedProcess -#define NT_EXTENDED_STARTUPINFO_PRESENT kNtExtendedStartupinfoPresent -#define NT_PROCESS_MODE_BACKGROUND_BEGIN kNtProcessModeBackgroundBegin -#define NT_PROCESS_MODE_BACKGROUND_END kNtProcessModeBackgroundEnd -#define NT_CREATE_SECURE_PROCESS kNtCreateSecureProcess -#define NT_CREATE_BREAKAWAY_FROM_JOB kNtCreateBreakawayFromJob -#define NT_CREATE_PRESERVE_CODE_AUTHZ_LEVEL kNtCreatePreserveCodeAuthzLevel -#define NT_CREATE_DEFAULT_ERROR_MODE kNtCreateDefaultErrorMode -#define NT_CREATE_NO_WINDOW kNtCreateNoWindow -#define NT_PROFILE_USER kNtProfileUser -#define NT_PROFILE_KERNEL kNtProfileKernel -#define NT_PROFILE_SERVER kNtProfileServer -#define NT_CREATE_IGNORE_SYSTEM_DEFAULT kNtCreateIgnoreSystemDefault - -#define FILE_READ_DATA kNtFileReadData -#define FILE_WRITE_DATA kNtFileWriteData -#define FILE_ADD_FILE kNtFileAddFile -#define FILE_APPEND_DATA kNtFileAppendData -#define FILE_ADD_SUBDIRECTORY kNtFileAddSubdirectory -#define FILE_CREATE_PIPE_INSTANCE kNtFileCreatePipeInstance -#define FILE_READ_EA kNtFileReadEa -#define FILE_WRITE_EA kNtFileWriteEa -#define FILE_EXECUTE kNtFileExecute -#define FILE_TRAVERSE kNtFileTraverse -#define FILE_DELETE_CHILD kNtFileDeleteChild -#define FILE_READ_ATTRIBUTES kNtFileReadAttributes -#define FILE_WRITE_ATTRIBUTES kNtFileWriteAttributes -#define FILE_ALL_ACCESS kNtFileAllAccess -#define FILE_GENERIC_READ kNtFileGenericRead -#define FILE_GENERIC_WRITE kNtFileGenericWrite -#define FILE_GENERIC_EXECUTE kNtFileGenericExecute - -#define TOKEN_PRIMARY kNtTokenPrimary -#define TOKEN_IMPERSONATION kNtTokenImpersonation - -#define TOKEN_PRIMARY kNtTokenPrimary -#define TOKEN_IMPERSONATION kNtTokenImpersonation -#define SECURITY_ANONYMOUS kNtSecurityAnonymous -#define SECURITY_IDENTIFICATION kNtSecurityIdentification -#define SECURITY_IMPERSONATION kNtSecurityImpersonation -#define SECURITY_DELEGATION kNtSecurityDelegation - -#define TOKEN_DUPLICATE kNtTokenDuplicate -#define TOKEN_IMPERSONATE kNtTokenImpersonate -#define TOKEN_QUERY kNtTokenQuery -#define TOKEN_QUERY_SOURCE kNtTokenQuerySource -#define TOKEN_ADJUST_PRIVILEGES kNtTokenAdjustPrivileges -#define TOKEN_ADJUST_GROUPS kNtTokenAdjustGroups -#define TOKEN_ADJUST_DEFAULT kNtTokenAdjustDefault -#define TOKEN_ADJUST_SESSIONID kNtTokenAdjustSessionid -#define TOKEN_ALL_ACCESS_P kNtTokenAllAccessP -#define TOKEN_ALL_ACCESS kNtTokenAllAccess -#define TOKEN_READ kNtTokenRead -#define TOKEN_WRITE kNtTokenWrite -#define TOKEN_EXECUTE kNtTokenExecute -#define TOKEN_TRUST_CONSTRAINT_MASK kNtTokenTrustConstraintMask -#define TOKEN_ACCESS_PSEUDO_HANDLE_WIN8 kNtTokenAccessPseudoHandleWin8 -#define TOKEN_ACCESS_PSEUDO_HANDLE kNtTokenAccessPseudoHandle - -#define FOREGROUND_BLUE kNtForegroundBlue -#define FOREGROUND_GREEN kNtForegroundGreen -#define FOREGROUND_RED kNtForegroundRed -#define FOREGROUND_INTENSITY kNtForegroundIntensity -#define BACKGROUND_BLUE kNtBackgroundBlue -#define BACKGROUND_GREEN kNtBackgroundGreen -#define BACKGROUND_RED kNtBackgroundRed -#define BACKGROUND_INTENSITY kNtBackgroundIntensity - -#define UNLEN 256 - -#define DUPLICATE_CLOSE_SOURCE kNtDuplicateCloseSource -#define DUPLICATE_SAME_ACCESS kNtDuplicateSameAccess - -#define IMAGE_FILE_MACHINE_UNKNOWN kNtImageFileMachineUnknown -#define IMAGE_FILE_MACHINE_TARGET_HOST kNtImageFileMachineTargetHost -#define IMAGE_FILE_MACHINE_I386 kNtImageFileMachineI386 -#define IMAGE_FILE_MACHINE_R3000 kNtImageFileMachineR3000 -#define IMAGE_FILE_MACHINE_R4000 kNtImageFileMachineR4000 -#define IMAGE_FILE_MACHINE_R10000 kNtImageFileMachineR10000 -#define IMAGE_FILE_MACHINE_WCEMIPSV2 kNtImageFileMachineWcemipsv2 -#define IMAGE_FILE_MACHINE_ALPHA kNtImageFileMachineAlpha -#define IMAGE_FILE_MACHINE_SH3 kNtImageFileMachineSh3 -#define IMAGE_FILE_MACHINE_SH3DSP kNtImageFileMachineSh3dsp -#define IMAGE_FILE_MACHINE_SH3E kNtImageFileMachineSh3e -#define IMAGE_FILE_MACHINE_SH4 kNtImageFileMachineSh4 -#define IMAGE_FILE_MACHINE_SH5 kNtImageFileMachineSh5 -#define IMAGE_FILE_MACHINE_ARM kNtImageFileMachineArm -#define IMAGE_FILE_MACHINE_THUMB kNtImageFileMachineThumb -#define IMAGE_FILE_MACHINE_ARMNT kNtImageFileMachineArmnt -#define IMAGE_FILE_MACHINE_AM33 kNtImageFileMachineAm33 -#define IMAGE_FILE_MACHINE_POWERPC kNtImageFileMachinePowerpc -#define IMAGE_FILE_MACHINE_POWERPCFP kNtImageFileMachinePowerpcfp -#define IMAGE_FILE_MACHINE_IA64 kNtImageFileMachineIa64 -#define IMAGE_FILE_MACHINE_MIPS16 kNtImageFileMachineMips16 -#define IMAGE_FILE_MACHINE_ALPHA64 kNtImageFileMachineAlpha64 -#define IMAGE_FILE_MACHINE_MIPSFPU kNtImageFileMachineMipsfpu -#define IMAGE_FILE_MACHINE_MIPSFPU16 kNtImageFileMachineMipsfpu16 -#define IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64 -#define IMAGE_FILE_MACHINE_TRICORE kNtImageFileMachineTricore -#define IMAGE_FILE_MACHINE_CEF kNtImageFileMachineCef -#define IMAGE_FILE_MACHINE_EBC kNtImageFileMachineEbc -#define IMAGE_FILE_MACHINE_NEXGEN32E kNtImageFileMachineNexgen32e -#define IMAGE_FILE_MACHINE_M32R kNtImageFileMachineM32r -#define IMAGE_FILE_MACHINE_ARM64 kNtImageFileMachineArm64 -#define IMAGE_FILE_MACHINE_CEE kNtImageFileMachineCee - -#define PE_32BIT kNtPe32bit -#define PE_64BIT kNtPe64bit - -#define IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA \ - kNtImageDllcharacteristicsHighEntropyVa -#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE \ - kNtImageDllcharacteristicsDynamicBase -#define IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY \ - kNtImageDllcharacteristicsForceIntegrity -#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT kNtImageDllcharacteristicsNxCompat -#define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION \ - kNtImageDllcharacteristicsNoIsolation -#define IMAGE_DLLCHARACTERISTICS_NO_SEH kNtImageDllcharacteristicsNoSeh -#define IMAGE_DLLCHARACTERISTICS_NO_BIND kNtImageDllcharacteristicsNoBind -#define IMAGE_DLLCHARACTERISTICS_APPCONTAINER \ - kNtImageDllcharacteristicsAppcontainer -#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER kNtImageDllcharacteristicsWdmDriver -#define IMAGE_DLLCHARACTERISTICS_GUARD_CF kNtImageDllcharacteristicsGuardCf -#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE \ - kNtImageDllcharacteristicsTerminalServerAware - -#define IMAGE_SUBSYSTEM_UNKNOWN kNtImageSubsystemUnknown -#define IMAGE_SUBSYSTEM_NATIVE kNtImageSubsystemNative -#define IMAGE_SUBSYSTEM_WINDOWS_GUI kNtImageSubsystemWindowsGui -#define IMAGE_SUBSYSTEM_WINDOWS_CUI kNtImageSubsystemWindowsCui -#define IMAGE_SUBSYSTEM_OS2_CUI kNtImageSubsystemOs2Cui -#define IMAGE_SUBSYSTEM_POSIX_CUI kNtImageSubsystemPosixCui -#define IMAGE_SUBSYSTEM_NATIVE_WINDOWS kNtImageSubsystemNativeWindows -#define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI kNtImageSubsystemWindowsCeGui -#define IMAGE_SUBSYSTEM_EFI_APPLICATION kNtImageSubsystemEfiApplication -#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER \ - kNtImageSubsystemEfiBootServiceDriver -#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER kNtImageSubsystemEfiRuntimeDriver -#define IMAGE_SUBSYSTEM_EFI_ROM kNtImageSubsystemEfiRom -#define IMAGE_SUBSYSTEM_XBOX kNtImageSubsystemXbox -#define IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION \ - kNtImageSubsystemWindowsBootApplication -#define IMAGE_SUBSYSTEM_XBOX_CODE_CATALOG kNtImageSubsystemXboxCodeCatalog - -#define IMAGE_FILE_RELOCS_STRIPPED kNtImageFileRelocsStripped -#define IMAGE_FILE_EXECUTABLE_IMAGE kNtImageFileExecutableImage -#define IMAGE_FILE_LINE_NUMS_STRIPPED kNtImageFileLineNumsStripped -#define IMAGE_FILE_LOCAL_SYMS_STRIPPED kNtImageFileLocalSymsStripped -#define IMAGE_FILE_AGGRESIVE_WS_TRIM kNtImageFileAggresiveWsTrim -#define IMAGE_FILE_LARGE_ADDRESS_AWARE kNtImageFileLargeAddressAware -#define IMAGE_FILE_BYTES_REVERSED_LO kNtImageFileBytesReversedLo -#define IMAGE_FILE_32BIT_MACHINE kNtImageFile_32bitMachine -#define IMAGE_FILE_DEBUG_STRIPPED kNtImageFileDebugStripped -#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP kNtImageFileRemovableRunFromSwap -#define IMAGE_FILE_NET_RUN_FROM_SWAP kNtImageFileNetRunFromSwap -#define IMAGE_FILE_SYSTEM kNtImageFileSystem -#define IMAGE_FILE_DLL kNtImageFileDll -#define IMAGE_FILE_UP_SYSTEM_ONLY kNtImageFileUpSystemOnly -#define IMAGE_FILE_BYTES_REVERSED_HI kNtImageFileBytesReversedHi - -#define IMAGE_DOS_SIGNATURE kNtImageDosSignature -#define IMAGE_OS2_SIGNATURE kNtImageOs2Signature -#define IMAGE_OS2_SIGNATURE_LE kNtImageOs2SignatureLe -#define IMAGE_VXD_SIGNATURE kNtImageVxdSignature -#define IMAGE_NT_SIGNATURE kNtImageNtSignature - -#define RICHKEY kNtRichkey -#define COOKIE_DEFAULT kNtCookieDefault -#define SIZE_OF_80387_REGISTERS kNtSizeOf_80387Registers -#define MAXIMUM_SUPPORTED_EXTENSION kNtMaximumSupportedExtension - -#define PE_SUBSYSTEM_WINDOWS_GUI kNtPeSubsystemWindowsGui -#define PE_SUBSYSTEM_WINDOWS_CUI kNtPeSubsystemWindowsCui - -#define PE_FILE_RELOCS_STRIPPED kNtPeFileRelocsStripped -#define PE_FILE_EXECUTABLE_IMAGE kNtPeFileExecutableImage -#define PE_FILE_LINE_NUMS_STRIPPED kNtPeFileLineNumsStripped -#define PE_FILE_LOCAL_SYMS_STRIPPED kNtPeFileLocalSymsStripped -#define PE_FILE_32BIT_MACHINE kNtPeFile_32bitMachine -#define PE_FILE_DLL kNtPeFileDll - -#define PE_SECTION_CNT_CODE kNtPeSectionCntCode -#define PE_SECTION_CNT_INITIALIZED_DATA kNtPeSectionCntInitializedData -#define PE_SECTION_CNT_UNINITIALIZED_DATA kNtPeSectionCntUninitializedData -#define PE_SECTION_GPREL kNtPeSectionGprel -#define PE_SECTION_MEM_DISCARDABLE kNtPeSectionMemDiscardable -#define PE_SECTION_MEM_NOT_CACHED kNtPeSectionMemNotCached -#define PE_SECTION_MEM_NOT_PAGED kNtPeSectionMemNotPaged -#define PE_SECTION_MEM_SHARED kNtPeSectionMemShared -#define PE_SECTION_MEM_EXECUTE kNtPeSectionMemExecute -#define PE_SECTION_MEM_READ kNtPeSectionMemRead -#define PE_SECTION_MEM_WRITE kNtPeSectionMemWrite - -#define PE_GUARD_CF_INSTRUMENTED kNtPeGuardCfInstrumented -#define PE_GUARD_CFW_INSTRUMENTED kNtPeGuardCfwInstrumented -#define PE_GUARD_CF_FUNCTION_TABLE_PRESENT kNtPeGuardCfFunctionTablePresent -#define PE_GUARD_SECURITY_COOKIE_UNUSED kNtPeGuardSecurityCookieUnused - -#define PE_REL_BASED_ABSOLUTE kNtPeRelBasedAbsolute -#define PE_REL_BASED_HIGH kNtPeRelBasedHigh -#define PE_REL_BASED_LOW kNtPeRelBasedLow -#define PE_REL_BASED_HIGHLOW kNtPeRelBasedHighlow -#define PE_REL_BASED_HIGHADJ kNtPeRelBasedHighadj -#define PE_REL_BASED_MIPS_JMPADDR kNtPeRelBasedMipsJmpaddr -#define PE_REL_BASED_SECTION kNtPeRelBasedSection -#define PE_REL_BASED_REL32 kNtPeRelBasedRel32 -#define PE_REL_BASED_MIPS_JMPADDR16 kNtPeRelBasedMipsJmpaddr16 -#define PE_REL_BASED_IA64_IMM64 kNtPeRelBasedIa64Imm64 -#define PE_REL_BASED_DIR64 kNtPeRelBasedDir64 -#define PE_REL_BASED_HIGH3ADJ kNtPeRelBasedHigh3adj - -#define IMAGE_DIRECTORY_ENTRY_EXPORT kNtImageDirectoryEntryExport -#define IMAGE_DIRECTORY_ENTRY_IMPORT kNtImageDirectoryEntryImport -#define IMAGE_DIRECTORY_ENTRY_RESOURCE kNtImageDirectoryEntryResource -#define IMAGE_DIRECTORY_ENTRY_EXCEPTION kNtImageDirectoryEntryException -#define IMAGE_DIRECTORY_ENTRY_SECURITY kNtImageDirectoryEntrySecurity -#define IMAGE_DIRECTORY_ENTRY_BASERELOC kNtImageDirectoryEntryBasereloc -#define IMAGE_DIRECTORY_ENTRY_DEBUG kNtImageDirectoryEntryDebug -#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE kNtImageDirectoryEntryArchitecture -#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR kNtImageDirectoryEntryGlobalptr -#define IMAGE_DIRECTORY_ENTRY_TLS kNtImageDirectoryEntryTls -#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG kNtImageDirectoryEntryLoadConfig -#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT kNtImageDirectoryEntryBoundImport -#define IMAGE_DIRECTORY_ENTRY_IAT kNtImageDirectoryEntryIat -#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT kNtImageDirectoryEntryDelayImport -#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR kNtImageDirectoryEntryComDescriptor - -#define IMAGE_SCN_TYPE_NO_PAD kNtImageScnTypeNoPad -#define IMAGE_SCN_CNT_CODE kNtImageScnCntCode -#define IMAGE_SCN_CNT_INITIALIZED_DATA kNtImageScnCntInitializedData -#define IMAGE_SCN_CNT_UNINITIALIZED_DATA kNtImageScnCntUninitializedData -#define IMAGE_SCN_LNK_OTHER kNtImageScnLnkOther -#define IMAGE_SCN_LNK_INFO kNtImageScnLnkInfo -#define IMAGE_SCN_LNK_REMOVE kNtImageScnLnkRemove -#define IMAGE_SCN_LNK_COMDAT kNtImageScnLnkComdat -#define IMAGE_SCN_NO_DEFER_SPEC_EXC kNtImageScnNoDeferSpecExc -#define IMAGE_SCN_GPREL kNtImageScnGprel -#define IMAGE_SCN_MEM_FARDATA kNtImageScnMemFardata -#define IMAGE_SCN_MEM_PURGEABLE kNtImageScnMemPurgeable -#define IMAGE_SCN_MEM_16BIT kNtImageScnMem16bit -#define IMAGE_SCN_MEM_LOCKED kNtImageScnMemLocked -#define IMAGE_SCN_MEM_PRELOAD kNtImageScnMemPreload - -#define IMAGE_SCN_ALIGN_1BYTES kNtImageScnAlign1bytes -#define IMAGE_SCN_ALIGN_2BYTES kNtImageScnAlign2bytes -#define IMAGE_SCN_ALIGN_4BYTES kNtImageScnAlign4bytes -#define IMAGE_SCN_ALIGN_8BYTES kNtImageScnAlign8bytes -#define IMAGE_SCN_ALIGN_16BYTES kNtImageScnAlign16bytes -#define IMAGE_SCN_ALIGN_32BYTES kNtImageScnAlign32bytes -#define IMAGE_SCN_ALIGN_64BYTES kNtImageScnAlign64bytes -#define IMAGE_SCN_ALIGN_128BYTES kNtImageScnAlign128bytes -#define IMAGE_SCN_ALIGN_256BYTES kNtImageScnAlign256bytes -#define IMAGE_SCN_ALIGN_512BYTES kNtImageScnAlign512bytes -#define IMAGE_SCN_ALIGN_1024BYTES kNtImageScnAlign1024bytes -#define IMAGE_SCN_ALIGN_2048BYTES kNtImageScnAlign2048bytes -#define IMAGE_SCN_ALIGN_4096BYTES kNtImageScnAlign4096bytes -#define IMAGE_SCN_ALIGN_8192BYTES kNtImageScnAlign8192bytes -#define IMAGE_SCN_ALIGN_MASK kNtImageScnAlignMask - -#define IMAGE_SCN_LNK_NRELOC_OVFL kNtImageScnLnkNrelocOvfl -#define IMAGE_SCN_MEM_DISCARDABLE kNtImageScnMemDiscardable -#define IMAGE_SCN_MEM_NOT_CACHED kNtImageScnMemNotCached -#define IMAGE_SCN_MEM_NOT_PAGED kNtImageScnMemNotPaged -#define IMAGE_SCN_MEM_SHARED kNtImageScnMemShared -#define IMAGE_SCN_MEM_EXECUTE kNtImageScnMemExecute -#define IMAGE_SCN_MEM_READ kNtImageScnMemRead -#define IMAGE_SCN_MEM_WRITE kNtImageScnMemWrite -#define IMAGE_SCN_SCALE_INDEX kNtImageScnScaleIndex - -#define IMAGE_SYM_UNDEFINED kNtImageSymUndefined -#define IMAGE_SYM_ABSOLUTE kNtImageSymAbsolute -#define IMAGE_SYM_DEBUG kNtImageSymDebug -#define IMAGE_SYM_SECTION_MAX kNtImageSymSectionMax -#define IMAGE_SYM_SECTION_MAX_EX kNtImageSymSectionMaxEx -#define IMAGE_SYM_TYPE_NULL kNtImageSymTypeNull -#define IMAGE_SYM_TYPE_VOID kNtImageSymTypeVoid -#define IMAGE_SYM_TYPE_CHAR kNtImageSymTypeChar -#define IMAGE_SYM_TYPE_SHORT kNtImageSymTypeShort -#define IMAGE_SYM_TYPE_INT kNtImageSymTypeInt -#define IMAGE_SYM_TYPE_LONG kNtImageSymTypeLong -#define IMAGE_SYM_TYPE_FLOAT kNtImageSymTypeFloat -#define IMAGE_SYM_TYPE_DOUBLE kNtImageSymTypeDouble -#define IMAGE_SYM_TYPE_STRUCT kNtImageSymTypeStruct -#define IMAGE_SYM_TYPE_UNION kNtImageSymTypeUnion -#define IMAGE_SYM_TYPE_ENUM kNtImageSymTypeEnum -#define IMAGE_SYM_TYPE_MOE kNtImageSymTypeMoe -#define IMAGE_SYM_TYPE_BYTE kNtImageSymTypeByte -#define IMAGE_SYM_TYPE_WORD kNtImageSymTypeWord -#define IMAGE_SYM_TYPE_UINT kNtImageSymTypeUint -#define IMAGE_SYM_TYPE_DWORD kNtImageSymTypeDword -#define IMAGE_SYM_TYPE_PCODE kNtImageSymTypePcode -#define IMAGE_SYM_DTYPE_NULL kNtImageSymDtypeNull -#define IMAGE_SYM_DTYPE_POINTER kNtImageSymDtypePointer -#define IMAGE_SYM_DTYPE_FUNCTION kNtImageSymDtypeFunction -#define IMAGE_SYM_DTYPE_ARRAY kNtImageSymDtypeArray -#define IMAGE_SYM_CLASS_END_OF_FUNCTION kNtImageSymClassEndOfFunction -#define IMAGE_SYM_CLASS_NULL kNtImageSymClassNull -#define IMAGE_SYM_CLASS_AUTOMATIC kNtImageSymClassAutomatic -#define IMAGE_SYM_CLASS_EXTERNAL kNtImageSymClassExternal -#define IMAGE_SYM_CLASS_STATIC kNtImageSymClassStatic -#define IMAGE_SYM_CLASS_REGISTER kNtImageSymClassRegister -#define IMAGE_SYM_CLASS_EXTERNAL_DEF kNtImageSymClassExternalDef -#define IMAGE_SYM_CLASS_LABEL kNtImageSymClassLabel -#define IMAGE_SYM_CLASS_UNDEFINED_LABEL kNtImageSymClassUndefinedLabel -#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT kNtImageSymClassMemberOfStruct -#define IMAGE_SYM_CLASS_ARGUMENT kNtImageSymClassArgument -#define IMAGE_SYM_CLASS_STRUCT_TAG kNtImageSymClassStructTag -#define IMAGE_SYM_CLASS_MEMBER_OF_UNION kNtImageSymClassMemberOfUnion -#define IMAGE_SYM_CLASS_UNION_TAG kNtImageSymClassUnionTag -#define IMAGE_SYM_CLASS_TYPE_DEFINITION kNtImageSymClassTypeDefinition -#define IMAGE_SYM_CLASS_UNDEFINED_STATIC kNtImageSymClassUndefinedStatic -#define IMAGE_SYM_CLASS_ENUM_TAG kNtImageSymClassEnumTag -#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM kNtImageSymClassMemberOfEnum -#define IMAGE_SYM_CLASS_REGISTER_PARAM kNtImageSymClassRegisterParam -#define IMAGE_SYM_CLASS_BIT_FIELD kNtImageSymClassBitField -#define IMAGE_SYM_CLASS_FAR_EXTERNAL kNtImageSymClassFarExternal -#define IMAGE_SYM_CLASS_BLOCK kNtImageSymClassBlock -#define IMAGE_SYM_CLASS_FUNCTION kNtImageSymClassFunction -#define IMAGE_SYM_CLASS_END_OF_STRUCT kNtImageSymClassEndOfStruct -#define IMAGE_SYM_CLASS_FILE kNtImageSymClassFile -#define IMAGE_SYM_CLASS_SECTION kNtImageSymClassSection -#define IMAGE_SYM_CLASS_WEAK_EXTERNAL kNtImageSymClassWeakExternal -#define IMAGE_SYM_CLASS_CLR_TOKEN kNtImageSymClassClrToken - -#define IMAGE_COMDAT_SELECT_NODUPLICATES kNtImageComdatSelectNoduplicates -#define IMAGE_COMDAT_SELECT_ANY kNtImageComdatSelectAny -#define IMAGE_COMDAT_SELECT_SAME_SIZE kNtImageComdatSelectSameSize -#define IMAGE_COMDAT_SELECT_EXACT_MATCH kNtImageComdatSelectExactMatch -#define IMAGE_COMDAT_SELECT_ASSOCIATIVE kNtImageComdatSelectAssociative -#define IMAGE_COMDAT_SELECT_LARGEST kNtImageComdatSelectLargest -#define IMAGE_COMDAT_SELECT_NEWEST kNtImageComdatSelectNewest - -#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY kNtImageWeakExternSearchNolibrary -#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY kNtImageWeakExternSearchLibrary -#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS kNtImageWeakExternSearchAlias -#define IMAGE_WEAK_EXTERN_ANTI_DEPENDENCY kNtImageWeakExternAntiDependency - -#define IMAGE_REL_NEXGEN32E_ABSOLUTE kNtImageRelNexgen32eAbsolute -#define IMAGE_REL_NEXGEN32E_ADDR64 kNtImageRelNexgen32eAddr64 -#define IMAGE_REL_NEXGEN32E_ADDR32 kNtImageRelNexgen32eAddr32 -#define IMAGE_REL_NEXGEN32E_ADDR32NB kNtImageRelNexgen32eAddr32nb -#define IMAGE_REL_NEXGEN32E_REL32 kNtImageRelNexgen32eRel32 -#define IMAGE_REL_NEXGEN32E_REL32_1 kNtImageRelNexgen32eRel321 -#define IMAGE_REL_NEXGEN32E_REL32_2 kNtImageRelNexgen32eRel322 -#define IMAGE_REL_NEXGEN32E_REL32_3 kNtImageRelNexgen32eRel323 -#define IMAGE_REL_NEXGEN32E_REL32_4 kNtImageRelNexgen32eRel324 -#define IMAGE_REL_NEXGEN32E_REL32_5 kNtImageRelNexgen32eRel325 -#define IMAGE_REL_NEXGEN32E_SECTION kNtImageRelNexgen32eSection -#define IMAGE_REL_NEXGEN32E_SECREL kNtImageRelNexgen32eSecrel -#define IMAGE_REL_NEXGEN32E_SECREL7 kNtImageRelNexgen32eSecrel7 -#define IMAGE_REL_NEXGEN32E_TOKEN kNtImageRelNexgen32eToken -#define IMAGE_REL_NEXGEN32E_SREL32 kNtImageRelNexgen32eSrel32 -#define IMAGE_REL_NEXGEN32E_PAIR kNtImageRelNexgen32ePair -#define IMAGE_REL_NEXGEN32E_SSPAN32 kNtImageRelNexgen32eSspan32 - -#define IMAGE_REL_BASED_ABSOLUTE kNtImageRelBasedAbsolute -#define IMAGE_REL_BASED_HIGH kNtImageRelBasedHigh -#define IMAGE_REL_BASED_LOW kNtImageRelBasedLow -#define IMAGE_REL_BASED_HIGHLOW kNtImageRelBasedHighlow -#define IMAGE_REL_BASED_HIGHADJ kNtImageRelBasedHighadj -#define IMAGE_REL_BASED_MACHINE_SPECIFIC_5 kNtImageRelBasedMachineSpecific5 -#define IMAGE_REL_BASED_RESERVED kNtImageRelBasedReserved -#define IMAGE_REL_BASED_MACHINE_SPECIFIC_7 kNtImageRelBasedMachineSpecific7 -#define IMAGE_REL_BASED_MACHINE_SPECIFIC_8 kNtImageRelBasedMachineSpecific8 -#define IMAGE_REL_BASED_MACHINE_SPECIFIC_9 kNtImageRelBasedMachineSpecific9 -#define IMAGE_REL_BASED_DIR64 kNtImageRelBasedDir64 - -#define IMAGE_ARCHIVE_START_SIZE kNtImageArchiveStartSize -#define IMAGE_ARCHIVE_START kNtImageArchiveStart -#define IMAGE_ARCHIVE_END kNtImageArchiveEnd -#define IMAGE_ARCHIVE_PAD kNtImageArchivePad -#define IMAGE_ARCHIVE_LINKER_MEMBER kNtImageArchiveLinkerMember -#define IMAGE_ARCHIVE_LONGNAMES_MEMBER kNtImageArchiveLongnamesMember -#define IMAGE_ARCHIVE_HYBRIDMAP_MEMBER kNtImageArchiveHybridmapMember - -#define IMAGE_ORDINAL_FLAG kNtImageOrdinalFlag -#define IMAGE_ORDINAL(Ordinal) NtImageOrdinal(Ordinal) -#define IMAGE_SNAP_BY_ORDINAL(Ordinal) NtImageSnapByOrdinal(Ordinal) - -#define IMAGE_RESOURCE_NAME_IS_STRING kNtImageResourceNameIsString -#define IMAGE_RESOURCE_DATA_IS_DIRECTORY kNtImageResourceDataIsDirectory - -#define IMAGE_DYNAMIC_RELOCATION_GUARD_RF_PROLOGUE \ - kNtImageDynamicRelocationGuardRfPrologue -#define IMAGE_DYNAMIC_RELOCATION_GUARD_RF_EPILOGUE \ - kNtImageDynamicRelocationGuardRfEpilogue - -#define IMAGE_HOT_PATCH_BASE_OBLIGATORY kNtImageHotPatchBaseObligatory -#define IMAGE_HOT_PATCH_CHUNK_INVERSE kNtImageHotPatchChunkInverse -#define IMAGE_HOT_PATCH_CHUNK_OBLIGATORY kNtImageHotPatchChunkObligatory -#define IMAGE_HOT_PATCH_CHUNK_RESERVED kNtImageHotPatchChunkReserved -#define IMAGE_HOT_PATCH_CHUNK_TYPE kNtImageHotPatchChunkType -#define IMAGE_HOT_PATCH_CHUNK_SOURCE_RVA kNtImageHotPatchChunkSourceRva -#define IMAGE_HOT_PATCH_CHUNK_TARGET_RVA kNtImageHotPatchChunkTargetRva -#define IMAGE_HOT_PATCH_CHUNK_SIZE kNtImageHotPatchChunkSize -#define IMAGE_HOT_PATCH_NONE kNtImageHotPatchNone -#define IMAGE_HOT_PATCH_FUNCTION kNtImageHotPatchFunction -#define IMAGE_HOT_PATCH_ABSOLUTE kNtImageHotPatchAbsolute -#define IMAGE_HOT_PATCH_REL32 kNtImageHotPatchRel32 -#define IMAGE_HOT_PATCH_CALL_TARGET kNtImageHotPatchCallTarget -#define IMAGE_HOT_PATCH_INDIRECT kNtImageHotPatchIndirect -#define IMAGE_HOT_PATCH_NO_CALL_TARGET kNtImageHotPatchNoCallTarget -#define IMAGE_HOT_PATCH_DYNAMIC_VALUE kNtImageHotPatchDynamicValue -#define IMAGE_GUARD_CF_INSTRUMENTED kNtImageGuardCfInstrumented -#define IMAGE_GUARD_CFW_INSTRUMENTED kNtImageGuardCfwInstrumented -#define IMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT \ - kNtImageGuardCfFunctionTablePresent -#define IMAGE_GUARD_SECURITY_COOKIE_UNUSED kNtImageGuardSecurityCookieUnused -#define IMAGE_GUARD_PROTECT_DELAYLOAD_IAT kNtImageGuardProtectDelayloadIat -#define IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION \ - kNtImageGuardDelayloadIatInItsOwnSection -#define IMAGE_GUARD_CF_EXPORT_SUPPRESSION_INFO_PRESENT \ - kNtImageGuardCfExportSuppressionInfoPresent -#define IMAGE_GUARD_CF_ENABLE_EXPORT_SUPPRESSION \ - kNtImageGuardCfEnableExportSuppression -#define IMAGE_GUARD_CF_LONGJUMP_TABLE_PRESENT \ - kNtImageGuardCfLongjumpTablePresent -#define IMAGE_GUARD_RF_INSTRUMENTED kNtImageGuardRfInstrumented -#define IMAGE_GUARD_RF_ENABLE kNtImageGuardRfEnable -#define IMAGE_GUARD_RF_STRICT kNtImageGuardRfStrict -#define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK \ - kNtImageGuardCfFunctionTableSizeMask -#define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT \ - kNtImageGuardCfFunctionTableSizeShift -#define IMAGE_GUARD_FLAG_FID_SUPPRESSED kNtImageGuardFlagFidSuppressed -#define IMAGE_GUARD_FLAG_EXPORT_SUPPRESSED kNtImageGuardFlagExportSuppressed - -#define IMAGE_ENCLAVE_IMPORT_MATCH_NONE kNtImageEnclaveImportMatchNone -#define IMAGE_ENCLAVE_IMPORT_MATCH_UNIQUE_ID kNtImageEnclaveImportMatchUniqueId -#define IMAGE_ENCLAVE_IMPORT_MATCH_AUTHOR_ID kNtImageEnclaveImportMatchAuthorId -#define IMAGE_ENCLAVE_IMPORT_MATCH_FAMILY_ID kNtImageEnclaveImportMatchFamilyId -#define IMAGE_ENCLAVE_IMPORT_MATCH_IMAGE_ID kNtImageEnclaveImportMatchImageId - -#define IMAGE_DEBUG_TYPE_UNKNOWN kNtImageDebugTypeUnknown -#define IMAGE_DEBUG_TYPE_COFF kNtImageDebugTypeCoff -#define IMAGE_DEBUG_TYPE_CODEVIEW kNtImageDebugTypeCodeview -#define IMAGE_DEBUG_TYPE_FPO kNtImageDebugTypeFpo -#define IMAGE_DEBUG_TYPE_MISC kNtImageDebugTypeMisc -#define IMAGE_DEBUG_TYPE_EXCEPTION kNtImageDebugTypeException -#define IMAGE_DEBUG_TYPE_FIXUP kNtImageDebugTypeFixup -#define IMAGE_DEBUG_TYPE_OMAP_TO_SRC kNtImageDebugTypeOmapToSrc -#define IMAGE_DEBUG_TYPE_OMAP_FROM_SRC kNtImageDebugTypeOmapFromSrc -#define IMAGE_DEBUG_TYPE_BORLAND kNtImageDebugTypeBorland -#define IMAGE_DEBUG_TYPE_RESERVED10 kNtImageDebugTypeReserved10 -#define IMAGE_DEBUG_TYPE_CLSID kNtImageDebugTypeClsid -#define IMAGE_DEBUG_TYPE_VC_FEATURE kNtImageDebugTypeVcFeature -#define IMAGE_DEBUG_TYPE_POGO kNtImageDebugTypePogo -#define IMAGE_DEBUG_TYPE_ILTCG kNtImageDebugTypeIltcg -#define IMAGE_DEBUG_TYPE_MPX kNtImageDebugTypeMpx -#define IMAGE_DEBUG_TYPE_REPRO kNtImageDebugTypeRepro - -#define FRAME_FPO kNtFrameFpo -#define FRAME_TRAP kNtFrameTrap -#define FRAME_TSS kNtFrameTss -#define FRAME_NONFPO kNtFrameNonfpo - -#define IMAGE_SIZEOF_SHORT_NAME kNtImageSizeofShortName -#define IMAGE_SIZEOF_SECTION_HEADER kNtImageSizeofSectionHeader -#define IMAGE_SIZEOF_SYMBOL kNtImageSizeofSymbol -#define IMAGE_ENCLAVE_LONG_ID_LENGTH kNtImageEnclaveLongIdLength -#define IMAGE_ENCLAVE_SHORT_ID_LENGTH kNtImageEnclaveShortIdLength -#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES kNtImageNumberofDirectoryEntries - -#define FILE_BEGIN kNtFileBegin -#define FILE_CURRENT kNtFileCurrent -#define FILE_END kNtFileEnd - -#define WSADATA struct NtWsaData -#define LPWSADATA struct NtWsaData* - -#define FD_MAX_EVENTS 10 - -#define CSADDR_INFO struct NtCsAddrInfo -#define PCSADDR_INFO struct NtCsAddrInfo* -#define LPCSADDR_INFO struct NtCsAddrInfo* - -#define AFPROTOCOLS struct NtAfProtocols -#define PAFPROTOCOLS struct NtAfProtocols* -#define LPAFPROTOCOLS struct NtAfProtocols* - -#define WSAECOMPARATOR int -#define PWSAECOMPARATOR int* -#define LPWSAECOMPARATOR int* - -#define WSANETWORKEVENTS struct NtWsaNetworkEvents -#define PWSANETWORKEVENTS struct NtWsaNetworkEvents* -#define LPWSANETWORKEVENTS struct NtWsaNetworkEvents* - -#define WSANSCLASSINFOW struct NtWsansClassInfo -#define PWSANSCLASSINFOW struct NtWsansClassInfo* -#define LPWSANSCLASSINFOW struct NtWsansClassInfo* - -#define WSASERVICECLASSINFOW struct NtWsaServiceClassInfo -#define PWSASERVICECLASSINFOW struct NtWsaServiceClassInfo* -#define LPWSASERVICECLASSINFOW struct NtWsaServiceClassInfo* - -#define WSANAMESPACE_INFOEX struct NtWsaNamespaceInfoEx -#define PWSANAMESPACE_INFOEX struct NtWsaNamespaceInfoEx* -#define LPWSANAMESPACE_INFOEX struct NtWsaNamespaceInfoEx* - -#define WSAQUERYSET struct NtWsaQuerySet -#define PWSAQUERYSET struct NtWsaQuerySet* -#define LPWSAQUERYSET struct NtWsaQuerySet* - -#define WSAVERSION struct NtWsaVersion -#define PWSAVERSION struct NtWsaVersion* -#define LPWSAVERSION struct NtWsaVersion* - -#define SOCKADDR struct sockaddr -#define PSOCKADDR struct sockaddr* -#define LPSOCKADDR struct sockaddr* - -#define SOCKET_ADDRESS struct NtSocketAddress -#define PSOCKET_ADDRESS struct NtSocketAddress* -#define LPSOCKET_ADDRESS struct NtSocketAddress* - -#define REPARSE_DATA_BUFFER struct NtReparseDataBuffer -#define PREPARSE_DATA_BUFFER struct NtReparseDataBuffer* -#define LPREPARSE_DATA_BUFFER struct NtReparseDataBuffer* - -#define SOCKET_ADDRESS_LIST struct NtSocketAddressList -#define PSOCKET_ADDRESS_LIST struct NtSocketAddressList* -#define LPSOCKET_ADDRESS_LIST struct NtSocketAddressList* - -#define FLOWSPEC struct NtFlowSpec -#define LPFLOWSPEC struct NtFlowSpec* - -#define QOS struct NtQos -#define LPQOS struct NtQos* - -#define _WSAPROTOCOLCHAIN NtWsaProtocolChain -#define WSAPROTOCOLCHAIN struct NtWsaProtocolChain -#define LPWSAPROTOCOLCHAIN struct NtWsaProtocolChain* - -#define _WSAPROTOCOL_INFO NtWsaProtocolInfo -#define WSAPROTOCOL_INFO struct NtWsaProtocolInfo -#define LPWSAPROTOCOL_INFO struct NtWsaProtocolInfo* - -#define _WSABUF NtIovec -#define WSABUF struct NtIovec -#define LPWSABUF struct NtIovec* - -#define _GUID NtGuid -#define GUID struct NtGuid -#define LPGUID struct NtGuid* - -#define ADDRINFOEX struct NtAddrInfoEx -#define LPADDRINFOEX struct NtAddrInfoEx* - -#define WSAEVENT HANDLE -#define GROUP uint32_t -#define WSAOVERLAPPED OVERLAPPED -#define INVALID_SOCKET -1ULL -#define SOCKET_ERROR -1 -#define WSA_INVALID_EVENT -1L -#define WAIT_FAILED -1U -#define SOCKET uint64_t -#define WSA_WAIT_IO_COMPLETION 0xc0 -#define WSA_WAIT_TIMEOUT 258 - -#define LPCONDITIONPROC NtConditionProc -#define LPWSAOVERLAPPED_COMPLETION_ROUTINE NtWsaOverlappedCompletionRoutine - -#define WSACOMPLETIONTYPE int -#define PWSACOMPLETIONTYPE int* -#define LPWSACOMPLETIONTYPE int* -#define NSP_NOTIFY_IMMEDIATELY kNtNspNotifyImmediately -#define NSP_NOTIFY_HWND kNtNspNotifyHwnd -#define NSP_NOTIFY_EVENT kNtNspNotifyEvent -#define NSP_NOTIFY_PORT kNtNspNotifyPort -#define NSP_NOTIFY_APC kNtNspNotifyApc - -#define WSACOMPLETION struct NtWsaCompletion -#define PWSACOMPLETION struct NtWsaCompletion* -#define LPWSACOMPLETION struct NtWsaCompletion* - -#define WSAPOLLFD struct pollfd -#define PWSAPOLLFD struct pollfd* -#define LPWSAPOLLFD struct pollfd* - -#define SD_RECEIVE SHUT_RD -#define SD_SEND SHUT_WR -#define SD_BOTH SHUT_RDWR - -#define WSAMSG struct NtMsgHdr -#define PWSAMSG struct NtMsgHdr* -#define LPWSAMSG struct NtMsgHdr* - -#define _MEMORYSTATUSEX NtMemoryStatusEx -#define MEMORYSTATUSEX struct NtMemoryStatusEx -#define LPMEMORYSTATUSEX struct NtMemoryStatusEx* - -#define HKEY_CLASSES_ROOT kNtHkeyClassesRoot -#define HKEY_CURRENT_USER kNtHkeyCurrentUser -#define HKEY_LOCAL_MACHINE kNtHkeyLocalMachine -#define HKEY_USERS kNtHkeyUsers -#define HKEY_PERFORMANCE_DATA kNtHkeyPerformanceData -#define HKEY_PERFORMANCE_TEXT kNtHkeyPerformanceText -#define HKEY_PERFORMANCE_NLSTEXT kNtHkeyPerformanceNlstext -#define HKEY_CURRENT_CONFIG kNtHkeyCurrentConfig -#define HKEY_DYN_DATA kNtHkeyDynData -#define HKEY_CURRENT_USER_LOCAL_SETTINGS kNtHkeyCurrentUserLocalSettings -#define KEY_READ kNtKeyRead -#define KEY_WRITE kNtKeyWrite -#define KEY_EXECUTE kNtKeyExecute -#define KEY_ALL_ACCESS kNtKeyAllAccess -#define REG_NONE kNtRegNone -#define REG_SZ kNtRegSz -#define REG_EXPAND_SZ kNtRegExpandSz -#define REG_BINARY kNtRegBinary -#define REG_DWORD kNtRegDword -#define REG_DWORD_BIG_ENDIAN kNtRegDwordBigEndian -#define REG_LINK kNtRegLink -#define REG_MULTI_SZ kNtRegMultiSz -#define REG_RESOURCE_LIST kNtRegResourceList -#define REG_FULL_RESOURCE_DESCRIPTOR kNtRegFullResourceDescriptor -#define REG_RESOURCE_REQUIREMENTS_LIST kNtRegResourceRequirementsList -#define REG_QWORD kNtRegQword -#define RRF_RT_REG_NONE kNtRrfRtRegNone -#define RRF_RT_REG_SZ kNtRrfRtRegSz -#define RRF_RT_REG_EXPAND_SZ kNtRrfRtRegExpandSz -#define RRF_RT_REG_BINARY kNtRrfRtRegBinary -#define RRF_RT_REG_DWORD kNtRrfRtRegDword -#define RRF_RT_REG_MULTI_SZ kNtRrfRtRegMultiSz -#define RRF_RT_REG_QWORD kNtRrfRtRegQword -#define RRF_RT_DWORD kNtRrfRtDword -#define RRF_RT_QWORD kNtRrfRtQword -#define RRF_RT_ANY kNtRrfRtAny -#define RRF_SUBKEY_WOW6464KEY kNtRrfSubkeyWow6464key -#define RRF_SUBKEY_WOW6432KEY kNtRrfSubkeyWow6432key -#define RRF_WOW64_MASK kNtRrfWow64Mask -#define RRF_NOEXPAND kNtRrfNoexpand -#define RRF_ZEROONFAILURE kNtRrfZeroonfailure - -#define NUMA_NO_PREFERRED_NODE kNtNumaNoPreferredNode - -#define TF_DISCONNECT kNtTfDisconnect -#define TF_REUSE_SOCKET kNtTfReuseSocket -#define TF_WRITE_BEHIND kNtTfWriteBehind -#define TF_USE_DEFAULT_WORKER kNtTfUseDefaultWorker -#define TF_USE_SYSTEM_THREAD kNtTfUseSystemThread -#define TF_USE_KERNEL_APC kNtTfUseKernelApc - -#define SIO_UDP_CONNRESET kNtSioUdpConnreset -#define SIO_SOCKET_CLOSE_NOTIFY kNtSioSocketCloseNotify -#define SIO_UDP_NETRESET kNtSioUdpNetreset - -#define THREAD_TERMINATE kNtThreadTerminate -#define THREAD_SUSPEND_RESUME kNtThreadSuspendResume -#define THREAD_GET_CONTEXT kNtThreadGetContext -#define THREAD_SET_CONTEXT kNtThreadSetContext -#define THREAD_QUERY_INFORMATION kNtThreadQueryInformation -#define THREAD_SET_INFORMATION kNtThreadSetInformation -#define THREAD_SET_THREAD_TOKEN kNtThreadSetThreadToken -#define THREAD_IMPERSONATE kNtThreadImpersonate -#define THREAD_DIRECT_IMPERSONATION kNtThreadDirectImpersonation -#define THREAD_SET_LIMITED_INFORMATION kNtThreadSetLimitedInformation -#define THREAD_QUERY_LIMITED_INFORMATION kNtThreadQueryLimitedInformation -#define THREAD_RESUME kNtThreadResume -#define THREAD_ALL_ACCESS kNtThreadAllAccess - -#define _FILE_SEGMENT_ELEMENT NtFileSegmentElement -#define FILE_SEGMENT_ELEMENT union NtFileSegmentElement -#define PFILE_SEGMENT_ELEMENT union NtFileSegmentElement* - -#define FileBasicInfo kNtFileBasicInfo -#define FileStandardInfo kNtFileStandardInfo -#define FileNameInfo kNtFileNameInfo -#define FileRenameInfo kNtFileRenameInfo -#define FileDispositionInfo kNtFileDispositionInfo -#define FileAllocationInfo kNtFileAllocationInfo -#define FileEndOfFileInfo kNtFileEndOfFileInfo -#define FileStreamInfo kNtFileStreamInfo -#define FileCompressionInfo kNtFileCompressionInfo -#define FileAttributeTagInfo kNtFileAttributeTagInfo -#define FileIdBothDirectoryInfo kNtFileIdBothDirectoryInfo -#define FileIdBothDirectoryRestartInfo kNtFileIdBothDirectoryRestartInfo -#define FileIoPriorityHintInfo kNtFileIoPriorityHintInfo -#define FileRemoteProtocolInfo kNtFileRemoteProtocolInfo -#define FileFullDirectoryInfo kNtFileFullDirectoryInfo -#define FileFullDirectoryRestartInfo kNtFileFullDirectoryRestartInfo -#define FileStorageInfo kNtFileStorageInfo -#define FileAlignmentInfo kNtFileAlignmentInfo -#define FileIdInfo kNtFileIdInfo -#define FileIdExtdDirectoryInfo kNtFileIdExtdDirectoryInfo -#define FileIdExtdDirectoryRestartInfo kNtFileIdExtdDirectoryRestartInfo -#define FileDispositionInfoEx kNtFileDispositionInfoEx -#define FileRenameInfoEx kNtFileRenameInfoEx - -#define _FILE_FULL_DIR_INFO NtFileFullDirectoryInformation -#define FILE_FULL_DIR_INFO struct NtFileFullDirectoryInformation -#define PFILE_FULL_DIR_INFO struct NtFileFullDirectoryInformation* - -#define _FILE_BASIC_INFO NtFileBasicInformation -#define FILE_BASIC_INFO struct NtFileBasicInformation -#define PFILE_BASIC_INFO struct NtFileBasicInformation* - -#define _FILE_STANDARD_INFO NtFileStandardInformation -#define FILE_STANDARD_INFO struct NtFileStandardInformation -#define PFILE_STANDARD_INFO struct NtFileStandardInformation* - -#define HANDLE_FLAG_INHERIT kNtHandleFlagInherit -#define HANDLE_FLAG_PROTECT_FROM_CLOSE kNtHandleFlagProtectFromClose - -#define SYMBOLIC_LINK_FLAG_DIRECTORY kNtSymbolicLinkFlagDirectory - -#define NT_FORMAT_MESSAGE_ALLOCATE_BUFFER kNtFormatMessageAllocateBuffer -#define NT_FORMAT_MESSAGE_IGNORE_INSERTS kNtFormatMessageIgnoreInserts -#define NT_FORMAT_MESSAGE_FROM_STRING kNtFormatMessageFromString -#define NT_FORMAT_MESSAGE_FROM_HMODULE kNtFormatMessageFromHmodule -#define NT_FORMAT_MESSAGE_FROM_SYSTEM kNtFormatMessageFromSystem -#define NT_FORMAT_MESSAGE_ARGUMENT_ARRAY kNtFormatMessageArgumentArray -#define NT_FORMAT_MESSAGE_MAX_WIDTH_MASK kNtFormatMessageMaxWidthMask - -#define THREAD_BASE_PRIORITY_IDLE kNtThreadBasePriorityIdle -#define THREAD_BASE_PRIORITY_MIN kNtThreadBasePriorityMin -#define THREAD_BASE_PRIORITY_MAX kNtThreadBasePriorityMax -#define THREAD_BASE_PRIORITY_LOWRT kNtThreadBasePriorityLowrt - -#define THREAD_PRIORITY_IDLE kNtThreadPriorityIdle -#define THREAD_PRIORITY_LOWEST kNtThreadPriorityLowest -#define THREAD_PRIORITY_BELOW_NORMAL kNtThreadPriorityBelowNormal -#define THREAD_PRIORITY_NORMAL kNtThreadPriorityNormal -#define THREAD_PRIORITY_ABOVE_NORMAL kNtThreadPriorityAboveNormal -#define THREAD_PRIORITY_HIGHEST kNtThreadPriorityHighest -#define THREAD_PRIORITY_TIME_CRITICAL kNtThreadPriorityTimeCritical - -#endif /* COSMOPOLITAN_LIBC_COMPAT_INCLUDE_WINDOWS_H_ */ diff --git a/libc/log/die.c b/libc/log/die.c index a39b427a9..9870c8df9 100644 --- a/libc/log/die.c +++ b/libc/log/die.c @@ -38,7 +38,6 @@ * * @see __minicrash() for signal handlers, e.g. handling abort() * @asyncsignalsafe - * @threadsafe * @vforksafe */ relegated wontreturn void __die(void) { diff --git a/libc/log/minicrash.c b/libc/log/minicrash.c index 6638109f2..3602b2a10 100644 --- a/libc/log/minicrash.c +++ b/libc/log/minicrash.c @@ -49,7 +49,6 @@ * * @see __die() for crashing from normal code without aborting * @asyncsignalsafe - * @threadsafe * @vforksafe */ relegated dontinstrument void __minicrash(int sig, siginfo_t *si, void *arg) { diff --git a/libc/log/vflogf.c b/libc/log/vflogf.c index 56ce1f0aa..31769924c 100644 --- a/libc/log/vflogf.c +++ b/libc/log/vflogf.c @@ -81,7 +81,6 @@ static void vflogf_onfail(FILE *f) { * time that it took to connect. This is great in forking applications. * * @asyncsignalsafe - * @threadsafe */ void(vflogf)(unsigned level, const char *file, int line, FILE *f, const char *fmt, va_list va) { diff --git a/libc/macros.internal.h b/libc/macros.internal.h index e5ba80a60..396f2b749 100644 --- a/libc/macros.internal.h +++ b/libc/macros.internal.h @@ -10,6 +10,14 @@ * @fileoverview Common C preprocessor, assembler, and linker macros. */ +#ifdef MAX +#undef MAX +#endif + +#ifdef MIN +#undef MIN +#endif + #define TRUE 1 #define FALSE 0 diff --git a/libc/mem/aligned_alloc.c b/libc/mem/aligned_alloc.c index 6c734f313..fc2133098 100644 --- a/libc/mem/aligned_alloc.c +++ b/libc/mem/aligned_alloc.c @@ -27,7 +27,6 @@ * @return memory address, or NULL w/ errno * @throw EINVAL if !IS2POW(a) * @see pvalloc() - * @threadsafe */ void *aligned_alloc(size_t a, size_t n) { if (IS2POW(a)) { diff --git a/libc/mem/calloc.c b/libc/mem/calloc.c index c207741b9..ee9f7db65 100644 --- a/libc/mem/calloc.c +++ b/libc/mem/calloc.c @@ -30,7 +30,6 @@ void *(*hook_calloc)(size_t, size_t) = dlcalloc; * @return rax is memory address, or NULL w/ errno * @note overreliance on memalign is a sure way to fragment space * @see dlcalloc() - * @threadsafe */ void *calloc(size_t n, size_t itemsize) { return hook_calloc(n, itemsize); diff --git a/libc/mem/free.c b/libc/mem/free.c index ed9864d6a..7c0c480d0 100644 --- a/libc/mem/free.c +++ b/libc/mem/free.c @@ -31,7 +31,6 @@ void (*hook_free)(void *) = dlfree; * * @param p is allocation address, which may be NULL * @see dlfree() - * @threadsafe */ void free(void *p) { hook_free(p); diff --git a/libc/mem/gc.c b/libc/mem/gc.c index fc3ab1581..d53760a65 100644 --- a/libc/mem/gc.c +++ b/libc/mem/gc.c @@ -115,7 +115,6 @@ void __defer(void *rbp, void *fn, void *arg) { * @warning do not realloc() with gc()'d pointer * @warning be careful about static keyword due to impact of inlining * @note you should use -fno-omit-frame-pointer - * @threadsafe */ void *(_gc)(void *thing) { struct StackFrame *frame; @@ -135,7 +134,6 @@ void *(_gc)(void *thing) { * @warning do not realloc() with gc()'d pointer * @warning be careful about static keyword due to impact of inlining * @note you should use -fno-omit-frame-pointer - * @threadsafe */ void *(_defer)(void *fn, void *arg) { struct StackFrame *frame; diff --git a/libc/mem/get_current_dir_name.c b/libc/mem/get_current_dir_name.c index 505d9d318..0e850f84e 100644 --- a/libc/mem/get_current_dir_name.c +++ b/libc/mem/get_current_dir_name.c @@ -27,7 +27,6 @@ * that'll be returned. * * @return pointer that must be free()'d, or NULL w/ errno - * @threadsafe */ char *get_current_dir_name(void) { const char *p; diff --git a/libc/mem/hook_realloc_in_place.c b/libc/mem/hook_realloc_in_place.c index 191cfcfc3..df85da90f 100644 --- a/libc/mem/hook_realloc_in_place.c +++ b/libc/mem/hook_realloc_in_place.c @@ -36,7 +36,6 @@ void *(*hook_realloc_in_place)(void *, size_t) = dlrealloc_in_place; * @param n is number of bytes needed * @return rax is result, or NULL w/ errno * @see dlrealloc_in_place() - * @threadsafe */ void *realloc_in_place(void *p, size_t n) { return hook_realloc_in_place(p, n); diff --git a/libc/mem/malloc.c b/libc/mem/malloc.c index a527e1361..706f8e3ea 100644 --- a/libc/mem/malloc.c +++ b/libc/mem/malloc.c @@ -41,7 +41,6 @@ void *(*hook_malloc)(size_t) = dlmalloc; * * @param rdi is number of bytes needed, coerced to 1+ * @return new memory, or NULL w/ errno - * @threadsafe */ void *malloc(size_t n) { return hook_malloc(n); diff --git a/libc/mem/malloc_usable_size.c b/libc/mem/malloc_usable_size.c index 2dcda5fe6..d7af246cd 100644 --- a/libc/mem/malloc_usable_size.c +++ b/libc/mem/malloc_usable_size.c @@ -39,7 +39,6 @@ size_t (*hook_malloc_usable_size)(void *) = dlmalloc_usable_size; * @param p is address of allocation * @return total number of bytes * @see dlmalloc_usable_size() - * @threadsafe */ size_t malloc_usable_size(void *p) { return hook_malloc_usable_size(p); diff --git a/libc/mem/memalign.c b/libc/mem/memalign.c index 6d5579f42..e6c33944a 100644 --- a/libc/mem/memalign.c +++ b/libc/mem/memalign.c @@ -34,7 +34,6 @@ void *(*hook_memalign)(size_t, size_t) = dlmemalign; * @param bytes is number of bytes needed, coerced to 1+ * @return rax is memory address, or NULL w/ errno * @see valloc(), pvalloc() - * @threadsafe */ void *memalign(size_t align, size_t bytes) { return hook_memalign(align, bytes); diff --git a/libc/mem/posix_memalign.c b/libc/mem/posix_memalign.c index 149f48d87..b561b4be9 100644 --- a/libc/mem/posix_memalign.c +++ b/libc/mem/posix_memalign.c @@ -36,7 +36,6 @@ * @return return 0 or EINVAL or ENOMEM w/o setting errno * @see memalign() * @returnserrno - * @threadsafe */ errno_t posix_memalign(void **pp, size_t alignment, size_t bytes) { int e; diff --git a/libc/mem/pvalloc.c b/libc/mem/pvalloc.c index 4ee636b4f..899416b1e 100644 --- a/libc/mem/pvalloc.c +++ b/libc/mem/pvalloc.c @@ -29,7 +29,6 @@ * @param n number of bytes needed * @return memory address, or NULL w/ errno * @see valloc() - * @threadsafe */ void *pvalloc(size_t n) { if (ckd_add(&n, n, FRAMESIZE - 1)) { diff --git a/libc/mem/realloc.c b/libc/mem/realloc.c index 9e9609c7b..14c9a8cc5 100644 --- a/libc/mem/realloc.c +++ b/libc/mem/realloc.c @@ -59,7 +59,6 @@ void *(*hook_realloc)(void *, size_t) = dlrealloc; * @param n is number of bytes needed * @return rax is result, or NULL w/ errno w/o free(p) * @see dlrealloc() - * @threadsafe */ void *realloc(void *p, size_t n) { return hook_realloc(p, n); diff --git a/libc/mem/reallocarray.c b/libc/mem/reallocarray.c index 47958a34c..b720b406b 100644 --- a/libc/mem/reallocarray.c +++ b/libc/mem/reallocarray.c @@ -27,7 +27,6 @@ * @param ptr may be NULL for malloc() behavior * @param nmemb may be 0 for free() behavior; shrinking is promised too * @return new address or NULL w/ errno and ptr is NOT free()'d - * @threadsafe */ void *reallocarray(void *ptr, size_t nmemb, size_t itemsize) { size_t n; diff --git a/libc/mem/strdup.c b/libc/mem/strdup.c index 17cb55afb..f3fe00ce3 100644 --- a/libc/mem/strdup.c +++ b/libc/mem/strdup.c @@ -25,7 +25,6 @@ * @param s is a NUL-terminated byte string * @return new string or NULL w/ errno * @error ENOMEM - * @threadsafe */ char *strdup(const char *s) { size_t len = strlen(s); diff --git a/libc/mem/strndup.c b/libc/mem/strndup.c index 39f4bc116..4ef4c7726 100644 --- a/libc/mem/strndup.c +++ b/libc/mem/strndup.c @@ -26,7 +26,6 @@ * @param n if less than strlen(s) will truncate the string * @return new string or NULL w/ errno * @error ENOMEM - * @threadsafe */ char *strndup(const char *s, size_t n) { char *s2; diff --git a/libc/mem/valloc.c b/libc/mem/valloc.c index 401b6f489..81dcec841 100644 --- a/libc/mem/valloc.c +++ b/libc/mem/valloc.c @@ -26,7 +26,6 @@ * @param n number of bytes needed * @return memory address, or NULL w/ errno * @see pvalloc() - * @threadsafe */ void *valloc(size_t n) { return memalign(FRAMESIZE, n); diff --git a/libc/mem/wcsdup.c b/libc/mem/wcsdup.c index b7170cdd4..724bdb2d0 100644 --- a/libc/mem/wcsdup.c +++ b/libc/mem/wcsdup.c @@ -21,7 +21,6 @@ /** * Allocates copy of wide string. - * @threadsafe */ wchar_t *wcsdup(const wchar_t *s) { size_t len = wcslen(s); diff --git a/libc/nexgen32e/gc.S b/libc/nexgen32e/gc.S index f86f5eea3..60b8ce085 100644 --- a/libc/nexgen32e/gc.S +++ b/libc/nexgen32e/gc.S @@ -32,7 +32,6 @@ // // @param rax,rdx,xmm0,xmm1,st0,st1 is return value // @see test/libc/runtime/gc_test.c -// @threadsafe .ftrace1 __gc: .ftrace2 diff --git a/libc/nexgen32e/gclongjmp.S b/libc/nexgen32e/gclongjmp.S index b9e3151a1..2a33decb3 100644 --- a/libc/nexgen32e/gclongjmp.S +++ b/libc/nexgen32e/gclongjmp.S @@ -28,7 +28,6 @@ // @param esi is returned by setjmp() invocation (coerced nonzero) // @assume system five nexgen32e abi conformant // @see examples/ctrlc.c -// @threadsafe // @noreturn .ftrace1 _gclongjmp: diff --git a/libc/nt/kernel32/CloseHandle.S b/libc/nt/kernel32/CloseHandle.S index de7c8b382..d0bf6080e 100644 --- a/libc/nt/kernel32/CloseHandle.S +++ b/libc/nt/kernel32/CloseHandle.S @@ -1,2 +1,20 @@ #include "libc/nt/codegen.h" .imp kernel32,__imp_CloseHandle,CloseHandle + + .text.windows + .ftrace1 +CloseHandle: + .ftrace2 +#ifdef __x86_64__ + push %rbp + mov %rsp,%rbp + mov %rdi,%rcx + sub $32,%rsp + call *__imp_CloseHandle(%rip) + leave +#elif defined(__aarch64__) + mov x0,#0 +#endif + ret + .endfn CloseHandle,globl + .previous diff --git a/libc/nt/master.sh b/libc/nt/master.sh index 4af5999d0..4f7ea3a29 100755 --- a/libc/nt/master.sh +++ b/libc/nt/master.sh @@ -9,7 +9,6 @@ # KERNEL32.DLL # # Name Actual DLL Arity -imp '' CloseHandle kernel32 1 imp '' CreateDirectoryW kernel32 2 imp '' CreateFileA kernel32 7 imp '' CreateFileMappingNumaW kernel32 7 @@ -57,6 +56,7 @@ imp 'CancelIoEx' CancelIoEx kernel32 2 imp 'CancelSynchronousIo' CancelSynchronousIo kernel32 1 imp 'CheckRemoteDebuggerPresent' CheckRemoteDebuggerPresent kernel32 2 imp 'ClearCommBreak' ClearCommBreak kernel32 1 +imp 'CloseHandle' CloseHandle kernel32 1 imp 'ConnectNamedPipe' ConnectNamedPipe kernel32 2 imp 'ContinueDebugEvent' ContinueDebugEvent kernel32 3 imp 'CopyFile' CopyFileW kernel32 3 diff --git a/libc/proc/fork.c b/libc/proc/fork.c index 8ff302ba9..50d21feb3 100644 --- a/libc/proc/fork.c +++ b/libc/proc/fork.c @@ -103,7 +103,6 @@ int _fork(uint32_t dwCreationFlags) { * @raise EAGAIN if `RLIMIT_NPROC` was exceeded or system lacked resources * @raise ENOMEM if we require more vespene gas * @asyncsignalsafe - * @threadsafe */ int fork(void) { return _fork(0); diff --git a/libc/proc/posix_spawn.c b/libc/proc/posix_spawn.c index 7d32b1e14..814f5a42b 100644 --- a/libc/proc/posix_spawn.c +++ b/libc/proc/posix_spawn.c @@ -21,7 +21,6 @@ #include "libc/atomic.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/proc/ntspawn.h" #include "libc/calls/state.internal.h" #include "libc/calls/struct/fd.internal.h" #include "libc/calls/struct/rlimit.h" @@ -51,6 +50,7 @@ #include "libc/nt/runtime.h" #include "libc/nt/struct/processinformation.h" #include "libc/nt/struct/startupinfo.h" +#include "libc/proc/ntspawn.h" #include "libc/proc/posix_spawn.h" #include "libc/proc/posix_spawn.internal.h" #include "libc/proc/proc.internal.h" @@ -305,7 +305,6 @@ static textwindows dontinline errno_t posix_spawn_windows( * @see posix_spawnp() for `$PATH` searching * @returnserrno * @tlsrequired - * @threadsafe */ errno_t posix_spawn(int *pid, const char *path, const posix_spawn_file_actions_t *file_actions, diff --git a/libc/proc/systemvpe.c b/libc/proc/systemvpe.c index 781e9a758..c7143bc4e 100644 --- a/libc/proc/systemvpe.c +++ b/libc/proc/systemvpe.c @@ -46,7 +46,6 @@ * status that can be accessed using macros like WEXITSTATUS(s), * WIFSIGNALED(s), WTERMSIG(s), etc. * @see system() - * @threadsafe */ int systemvpe(const char *prog, char *const argv[], char *const envp[]) { char *exe; diff --git a/libc/proc/vfork.S b/libc/proc/vfork.S index 9bf801b8b..9b9e19a55 100644 --- a/libc/proc/vfork.S +++ b/libc/proc/vfork.S @@ -35,7 +35,6 @@ // // @return pid of child process or 0 if forked process // @returnstwice -// @threadsafe // @vforksafe .ftrace1 vfork: diff --git a/libc/proc/wait4-nt.c b/libc/proc/wait4-nt.c index 6a738f734..2299e9d63 100644 --- a/libc/proc/wait4-nt.c +++ b/libc/proc/wait4-nt.c @@ -25,7 +25,7 @@ #include "libc/calls/struct/timespec.h" #include "libc/cosmo.h" #include "libc/errno.h" -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" #include "libc/intrin/atomic.h" #include "libc/intrin/dll.h" #include "libc/intrin/strace.internal.h" diff --git a/libc/runtime/clktck.c b/libc/runtime/clktck.c index 4283573ba..7f6ca99d7 100644 --- a/libc/runtime/clktck.c +++ b/libc/runtime/clktck.c @@ -19,7 +19,7 @@ #include "libc/runtime/clktck.h" #include "libc/calls/calls.h" #include "libc/dce.h" -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" #include "libc/intrin/getauxval.internal.h" #include "libc/runtime/runtime.h" #include "libc/sysv/consts/auxv.h" diff --git a/libc/runtime/clone.c b/libc/runtime/clone.c index c6ca37d8e..a771817af 100644 --- a/libc/runtime/clone.c +++ b/libc/runtime/clone.c @@ -631,7 +631,6 @@ static int CloneLinux(int (*func)(void *arg, int rc), char *stk, size_t stksz, * @param ctid lets the child receive its thread id without having to * call gettid() and is ignored if `CLONE_CHILD_SETTID` isn't set * @return 0 on success, or errno on errno - * @threadsafe */ errno_t clone(void *func, void *stk, size_t stksz, int flags, void *arg, void *ptid, void *tls, void *ctid) { diff --git a/libc/runtime/isheap.c b/libc/runtime/isheap.c index 1eb5fded0..9651ed6ee 100644 --- a/libc/runtime/isheap.c +++ b/libc/runtime/isheap.c @@ -20,11 +20,14 @@ #include "libc/runtime/memtrack.internal.h" #include "libc/runtime/runtime.h" +// TODO(jart): DELETE + /** * Returns true if address isn't stack and was malloc'd or mmap'd. * * @assume stack addresses are always greater than heap addresses * @assume stack memory isn't stored beneath %rsp (-mno-red-zone) + * @deprecated */ optimizesize bool _isheap(void *p) { intptr_t x, y; diff --git a/libc/runtime/runtime.h b/libc/runtime/runtime.h index 327612989..7a7b1c604 100644 --- a/libc/runtime/runtime.h +++ b/libc/runtime/runtime.h @@ -89,15 +89,13 @@ void _intsort(int *, size_t); void _longsort(long *, size_t); /* diagnostics */ void ShowCrashReports(void); -void __printargs(const char *); int ftrace_install(void); int ftrace_enabled(int); int strace_enabled(int); bool strace_enter(void); -void _bt(const char *, ...); void __print_maps(void); -long _GetMaxFd(void); -/* builtin shell language */ +void __printargs(const char *); +/* builtin sh-like system/popen dsl */ int _cocmd(int, char **, char **); /* executable program */ char *GetProgramExecutableName(void); @@ -105,9 +103,6 @@ char *GetInterpreterExecutableName(char *, size_t); int __open_executable(void); /* execution control */ int verynice(void); -axdx_t setlongerjmp(jmp_buf) -libcesque returnstwice paramsnonnull(); -void longerjmp(jmp_buf, intptr_t) libcesque wontreturn paramsnonnull(); void __warn_if_powersave(void); void _Exit1(int) libcesque wontreturn; void __paginate(int, const char *); @@ -131,7 +126,6 @@ const char *GetCpuidOs(void); const char *GetCpuidEmulator(void); void GetCpuidBrand(char[13], uint32_t); long __get_rlimit(int); -int __set_rlimit(int, int64_t); const char *__describe_os(void); long __get_sysctl(int, int); int __get_arg_max(void) pureconst; diff --git a/libc/runtime/zipos-close.c b/libc/runtime/zipos-close.c index c70ed746a..9a9c038f4 100644 --- a/libc/runtime/zipos-close.c +++ b/libc/runtime/zipos-close.c @@ -27,7 +27,6 @@ * * @param fd is vetted by close() * @asyncsignalsafe - * @threadsafe * @vforksafe */ int __zipos_close(int fd) { diff --git a/libc/runtime/zipos-get.c b/libc/runtime/zipos-get.c index 0565232e5..397fc5e12 100644 --- a/libc/runtime/zipos-get.c +++ b/libc/runtime/zipos-get.c @@ -159,7 +159,6 @@ static void __zipos_init(void) { /** * Returns pointer to zip central directory of current executable. * @asyncsignalsafe - * @threadsafe */ struct Zipos *__zipos_get(void) { cosmo_once(&__zipos_once, __zipos_init); diff --git a/libc/runtime/zipos-open.c b/libc/runtime/zipos-open.c index cb6ec3c6d..d1b2e442d 100644 --- a/libc/runtime/zipos-open.c +++ b/libc/runtime/zipos-open.c @@ -214,7 +214,6 @@ static int __zipos_load(struct Zipos *zipos, size_t cf, int flags, * * @param uri is obtained via __zipos_parseuri() * @asyncsignalsafe - * @threadsafe */ int __zipos_open(struct ZiposUri *name, int flags) { diff --git a/libc/sock/pselect.c b/libc/sock/pselect.c index 0ccdd3a98..b19acd627 100644 --- a/libc/sock/pselect.c +++ b/libc/sock/pselect.c @@ -55,7 +55,6 @@ * @raise EINTR if signal was delivered * @cancellationpoint * @asyncsignalsafe - * @threadsafe * @norestart */ int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, diff --git a/libc/sock/select.c b/libc/sock/select.c index 6c2ba0f0d..d72afa495 100644 --- a/libc/sock/select.c +++ b/libc/sock/select.c @@ -42,7 +42,6 @@ * @raise EINTR if signal was delivered * @cancellationpoint * @asyncsignalsafe - * @threadsafe * @norestart */ int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, diff --git a/libc/stdio/asprintf.c b/libc/stdio/asprintf.c index 6e540a169..549fc191a 100644 --- a/libc/stdio/asprintf.c +++ b/libc/stdio/asprintf.c @@ -26,7 +26,6 @@ * portability, since that's guaranteed to work with all libraries * @return bytes written (excluding NUL) or -1 w/ errno * @see xasprintf() for a better API - * @threadsafe */ int asprintf(char **strp, const char *fmt, ...) { int res; diff --git a/libc/stdio/clearerr.c b/libc/stdio/clearerr.c index bc5fad837..911b94232 100644 --- a/libc/stdio/clearerr.c +++ b/libc/stdio/clearerr.c @@ -23,7 +23,6 @@ * * @param f is file object stream pointer * @see clearerr_unlocked() - * @threadsafe */ void clearerr(FILE *f) { flockfile(f); diff --git a/libc/stdio/clearerr_unlocked.c b/libc/stdio/clearerr_unlocked.c index 55f048a7d..b79524668 100644 --- a/libc/stdio/clearerr_unlocked.c +++ b/libc/stdio/clearerr_unlocked.c @@ -24,7 +24,6 @@ * * @param f is file object stream pointer * @see clearerr() - * @threadsafe */ void clearerr_unlocked(FILE *f) { f->state = 0; diff --git a/libc/stdio/dirstream.c b/libc/stdio/dirstream.c index bead6c70e..6271a2bc1 100644 --- a/libc/stdio/dirstream.c +++ b/libc/stdio/dirstream.c @@ -513,6 +513,7 @@ static struct dirent *readdir_impl(DIR *dir) { * @param dir is the object opendir() or fdopendir() returned * @return next entry or NULL on end or error, which can be * differentiated by setting errno to 0 beforehand + * @threadunsafe */ struct dirent *readdir(DIR *dir) { struct dirent *e; @@ -535,7 +536,6 @@ struct dirent *readdir(DIR *dir) { * @param result will receive `output` pointer, or null on eof * @return 0 on success, or errno on error * @returnserrno - * @threadsafe */ errno_t readdir_r(DIR *dir, struct dirent *output, struct dirent **result) { int err, olderr; @@ -587,7 +587,6 @@ int closedir(DIR *dir) { /** * Returns offset into directory data. - * @threadsafe */ long telldir(DIR *dir) { long rc; @@ -599,7 +598,6 @@ long telldir(DIR *dir) { /** * Returns file descriptor associated with DIR object. - * @threadsafe */ int dirfd(DIR *dir) { return dir->fd; @@ -607,7 +605,6 @@ int dirfd(DIR *dir) { /** * Seeks to beginning of directory stream. - * @threadsafe */ void rewinddir(DIR *dir) { lockdir(dir); @@ -634,7 +631,6 @@ void rewinddir(DIR *dir) { /** * Seeks in directory stream. - * @threadsafe */ void seekdir(DIR *dir, long tell) { lockdir(dir); diff --git a/libc/stdio/feof.c b/libc/stdio/feof.c index eeca17292..2b910c033 100644 --- a/libc/stdio/feof.c +++ b/libc/stdio/feof.c @@ -23,7 +23,6 @@ * * @param f is file object stream pointer * @see feof_unlocked() - * @threadsafe */ int feof(FILE *f) { int rc; diff --git a/libc/stdio/ferror.c b/libc/stdio/ferror.c index d11ef64f7..73b79e8f0 100644 --- a/libc/stdio/ferror.c +++ b/libc/stdio/ferror.c @@ -25,7 +25,6 @@ * @return non-zero if and only if it's an error state * @see ferror_unlocked(), feof() * @note EOF doesn't count - * @threadsafe */ errno_t ferror(FILE *f) { int rc; diff --git a/libc/stdio/fflush.c b/libc/stdio/fflush.c index 5618a8ae4..826dc484e 100644 --- a/libc/stdio/fflush.c +++ b/libc/stdio/fflush.c @@ -23,7 +23,6 @@ * * @param f is the stream handle, or 0 for all streams * @return is 0 on success or -1 on error - * @threadsafe */ int fflush(FILE *f) { int rc; diff --git a/libc/stdio/fgetc.c b/libc/stdio/fgetc.c index 05b4e05dd..478e3e0e1 100644 --- a/libc/stdio/fgetc.c +++ b/libc/stdio/fgetc.c @@ -24,7 +24,6 @@ * @param f is non-null file object stream pointer * @return byte in range 0..255, or -1 w/ errno * @see fgetc_unlocked() - * @threadsafe */ int fgetc(FILE *f) { int rc; diff --git a/libc/stdio/fgets.c b/libc/stdio/fgets.c index 360896f66..437c2c556 100644 --- a/libc/stdio/fgets.c +++ b/libc/stdio/fgets.c @@ -34,7 +34,6 @@ * @return s on success, NULL on error, or NULL if EOF happens when * zero characters have been read * @see fgets_unlocked() - * @threadsafe */ char *fgets(char *s, int size, FILE *f) { char *res; diff --git a/libc/stdio/fgetwc.c b/libc/stdio/fgetwc.c index ddc471ea3..28b43cb3f 100644 --- a/libc/stdio/fgetwc.c +++ b/libc/stdio/fgetwc.c @@ -24,7 +24,6 @@ * @param f is non-null file object stream pointer * @return wide character or -1 on EOF or error * @see fgetwc_unlocked() - * @threadsafe */ wint_t fgetwc(FILE *f) { wint_t wc; diff --git a/libc/stdio/fgetws.c b/libc/stdio/fgetws.c index 4ac3f156a..2c8f2854f 100644 --- a/libc/stdio/fgetws.c +++ b/libc/stdio/fgetws.c @@ -29,7 +29,6 @@ * @param size is byte length of `s` * @param f is file stream object pointer * @see fgetws() - * @threadsafe */ wchar_t *fgetws(wchar_t *s, int size, FILE *f) { wchar_t *rc; diff --git a/libc/stdio/fileno.c b/libc/stdio/fileno.c index 294becdbf..b81ebcb4c 100644 --- a/libc/stdio/fileno.c +++ b/libc/stdio/fileno.c @@ -24,7 +24,6 @@ * * @param f is file stream object pointer * @return fd on success or -1 w/ errno; - * @threadsafe */ int fileno(FILE *f) { int rc; diff --git a/libc/stdio/fputc.c b/libc/stdio/fputc.c index f0bdac9ad..cd15f84c7 100644 --- a/libc/stdio/fputc.c +++ b/libc/stdio/fputc.c @@ -23,7 +23,6 @@ * * @param c is byte to buffer or write, which is masked * @return c as unsigned char if written or -1 w/ errno - * @threadsafe */ int fputc(int c, FILE *f) { int rc; diff --git a/libc/stdio/fputs.c b/libc/stdio/fputs.c index aef211a86..8bba14dda 100644 --- a/libc/stdio/fputs.c +++ b/libc/stdio/fputs.c @@ -28,7 +28,6 @@ * @param s is a NUL-terminated string that's non-NULL * @param f is an open stream * @return bytes written, or -1 w/ errno - * @threadsafe */ int fputs(const char *s, FILE *f) { int rc; diff --git a/libc/stdio/fputwc.c b/libc/stdio/fputwc.c index 4ecced63f..692e56cc9 100644 --- a/libc/stdio/fputwc.c +++ b/libc/stdio/fputwc.c @@ -24,7 +24,6 @@ * @param wc has wide character * @param f is file object stream pointer * @return wide character if written or -1 w/ errno - * @threadsafe */ wint_t fputwc(wchar_t wc, FILE *f) { wint_t rc; diff --git a/libc/stdio/fputws.c b/libc/stdio/fputws.c index c9b533f8b..096d112d4 100644 --- a/libc/stdio/fputws.c +++ b/libc/stdio/fputws.c @@ -28,7 +28,6 @@ * @param s is a NUL-terminated string that's non-NULL * @param f is an open stream * @return strlen(s), or -1 w/ errno - * @threadsafe */ int fputws(const wchar_t *s, FILE *f) { int rc; diff --git a/libc/stdio/fread.c b/libc/stdio/fread.c index 24f2cc446..ee82f8275 100644 --- a/libc/stdio/fread.c +++ b/libc/stdio/fread.c @@ -27,7 +27,6 @@ * @param stride specifies the size of individual items * @param count is the number of strides to fetch * @return count on success, [0,count) on eof, or 0 on error or count==0 - * @threadsafe */ size_t fread(void *buf, size_t stride, size_t count, FILE *f) { size_t rc; diff --git a/libc/stdio/fseek.c b/libc/stdio/fseek.c index e78db477e..0da8e521b 100644 --- a/libc/stdio/fseek.c +++ b/libc/stdio/fseek.c @@ -32,7 +32,6 @@ * @param offset is the byte delta * @param whence can be SEET_SET, SEEK_CUR, or SEEK_END * @returns 0 on success or -1 on error - * @threadsafe */ int fseek(FILE *f, int64_t offset, int whence) { int rc; diff --git a/libc/stdio/ftell.c b/libc/stdio/ftell.c index 5210815a1..ce23fbd7e 100644 --- a/libc/stdio/ftell.c +++ b/libc/stdio/ftell.c @@ -44,7 +44,6 @@ static inline int64_t ftell_unlocked(FILE *f) { * * @param stream is a non-null stream handle * @returns current byte offset from beginning, or -1 w/ errno - * @threadsafe */ int64_t ftell(FILE *f) { int64_t rc; diff --git a/libc/stdio/ftw.c b/libc/stdio/ftw.c index 23034f973..e66ddba98 100644 --- a/libc/stdio/ftw.c +++ b/libc/stdio/ftw.c @@ -39,6 +39,7 @@ asm(".include \"libc/disclaimer.inc\""); * @return 0 on success, -1 on error, or non-zero `fn` result * @see examples/walk.c for example * @see nftw() + * @threadsafe */ int ftw(const char *dirpath, int fn(const char *fpath, diff --git a/libc/stdio/fwrite.c b/libc/stdio/fwrite.c index 9fddb9921..7888be1b7 100644 --- a/libc/stdio/fwrite.c +++ b/libc/stdio/fwrite.c @@ -26,7 +26,6 @@ * @param stride specifies the size of individual items * @param count is the number of strides to write * @return count on success, [0,count) on EOF, 0 on error or count==0 - * @threadsafe */ size_t fwrite(const void *data, size_t stride, size_t count, FILE *f) { size_t rc; diff --git a/libc/stdio/getwchar.c b/libc/stdio/getwchar.c index 2bae268ed..a455dbc11 100644 --- a/libc/stdio/getwchar.c +++ b/libc/stdio/getwchar.c @@ -21,7 +21,6 @@ /** * Reads UTF-8 character from stream. * @return wide character or -1 on EOF or error - * @threadsafe */ wint_t getwchar(void) { return fgetwc(stdin); diff --git a/libc/stdio/nftw.c b/libc/stdio/nftw.c index 59ea2d31a..7e61243f1 100644 --- a/libc/stdio/nftw.c +++ b/libc/stdio/nftw.c @@ -160,6 +160,7 @@ static int do_nftw(char *path, * * @return 0 on success, -1 on error, or non-zero `fn` result * @see examples/walk.c for example + * @threadsafe */ int nftw(const char *dirpath, int fn(const char *fpath, diff --git a/libc/stdio/popen.c b/libc/stdio/popen.c index b408fb15c..7f3265873 100644 --- a/libc/stdio/popen.c +++ b/libc/stdio/popen.c @@ -52,7 +52,6 @@ * @raise EAGAIN if `RLIMIT_NPROC` was exceeded * @raise EINTR if signal was delivered * @cancellationpoint - * @threadsafe */ FILE *popen(const char *cmdline, const char *mode) { FILE *f, *f2; diff --git a/libc/stdio/putchar.c b/libc/stdio/putchar.c index 4cbf20297..1739c34ea 100644 --- a/libc/stdio/putchar.c +++ b/libc/stdio/putchar.c @@ -22,7 +22,6 @@ * Writes byte to stdout. * * @return c (as unsigned char) if written or -1 w/ errno - * @threadsafe */ int putchar(int c) { return fputc(c, stdout); diff --git a/libc/stdio/putwchar.c b/libc/stdio/putwchar.c index fe0c20b51..8fe5cf01c 100644 --- a/libc/stdio/putwchar.c +++ b/libc/stdio/putwchar.c @@ -21,7 +21,6 @@ /** * Writes wide character to stdout. * @return wc if written or -1 w/ errno - * @threadsafe */ wint_t putwchar(wchar_t wc) { return fputwc(wc, stdout); diff --git a/libc/stdio/rand.c b/libc/stdio/rand.c index 1c5524213..6ff04b99e 100644 --- a/libc/stdio/rand.c +++ b/libc/stdio/rand.c @@ -36,6 +36,7 @@ * @note this function does well on bigcrush and practrand * @note this function is not intended for cryptography * @see lemur64(), _rand64(), rdrand() + * @threadunsafe */ int rand(void) { return KnuthLinearCongruentialGenerator(&g_rando) >> 33; diff --git a/libc/calls/sysparam.h b/libc/stdio/sysparam.h similarity index 75% rename from libc/calls/sysparam.h rename to libc/stdio/sysparam.h index 865a53bf5..1cdcb44fc 100644 --- a/libc/calls/sysparam.h +++ b/libc/stdio/sysparam.h @@ -1,5 +1,5 @@ -#ifndef COSMOPOLITAN_LIBC_CALLS_SYSPARAM_H_ -#define COSMOPOLITAN_LIBC_CALLS_SYSPARAM_H_ +#ifndef COSMOPOLITAN_LIBC_SYSPARAM_H_ +#define COSMOPOLITAN_LIBC_SYSPARAM_H_ #define MAXSYMLINKS 20 #define MAXHOSTNAMELEN 64 @@ -27,6 +27,16 @@ COSMOPOLITAN_C_START_ #define powerof2(n) !(((n)-1) & (n)) #define howmany(n, d) (((n) + ((d)-1)) / (d)) +#ifdef MIN +#undef MIN +#endif +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +#ifdef MAX +#undef MAX +#endif +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ -#endif /* COSMOPOLITAN_LIBC_CALLS_SYSPARAM_H_ */ +#endif /* COSMOPOLITAN_LIBC_SYSPARAM_H_ */ diff --git a/libc/stdio/tmpfile.c b/libc/stdio/tmpfile.c index 6211f1cc8..ee0c2b88a 100644 --- a/libc/stdio/tmpfile.c +++ b/libc/stdio/tmpfile.c @@ -57,7 +57,6 @@ * @raise EINTR if signal was delivered * @cancellationpoint * @asyncsignalsafe - * @threadsafe * @vforksafe */ FILE *tmpfile(void) { diff --git a/libc/stdio/ungetc.c b/libc/stdio/ungetc.c index 672e9dade..3e3bc3825 100644 --- a/libc/stdio/ungetc.c +++ b/libc/stdio/ungetc.c @@ -20,7 +20,6 @@ /** * Pushes byte back to stream. - * @threadsafe */ int ungetc(int c, FILE *f) { int rc; diff --git a/libc/stdio/ungetwc.c b/libc/stdio/ungetwc.c index 3ec9f03df..5f39cacad 100644 --- a/libc/stdio/ungetwc.c +++ b/libc/stdio/ungetwc.c @@ -20,7 +20,6 @@ /** * Pushes wide character back to stream. - * @threadsafe */ wint_t ungetwc(wint_t c, FILE *f) { wint_t rc; diff --git a/libc/stdio/vasprintf.c b/libc/stdio/vasprintf.c index 5e8a7035a..6a7c10ec8 100644 --- a/libc/stdio/vasprintf.c +++ b/libc/stdio/vasprintf.c @@ -23,7 +23,6 @@ /** * Formats string w/ dynamic memory allocation. * @see xasprintf() for a better API - * @threadsafe */ int vasprintf(char **strp, const char *fmt, va_list va) { va_list vb; diff --git a/libc/stdio/vfprintf_unlocked.c b/libc/stdio/vfprintf_unlocked.c index 9e28a5201..2dce1045e 100644 --- a/libc/stdio/vfprintf_unlocked.c +++ b/libc/stdio/vfprintf_unlocked.c @@ -59,12 +59,11 @@ static int __vfprintf_nbuf(const char *s, struct state *t, size_t n) { for (i = 0; i < n; ++i) { t->b.p[t->b.n++] = s[i]; if (t->b.n == sizeof(t->b.p)) { - if (!fwrite_unlocked(s, 1, t->b.n, t->f)) { + if (!fwrite_unlocked(t->b.p, 1, t->b.n, t->f)) { return -1; } t->b.n = 0; - } - if (ckd_add(&t->n, t->n, 1)) { + } else if (ckd_add(&t->n, t->n, 1)) { return eoverflow(); } } diff --git a/libc/str/dosdatetimetounix.c b/libc/str/dosdatetimetounix.c index 158b65a10..b6fb7fc48 100644 --- a/libc/str/dosdatetimetounix.c +++ b/libc/str/dosdatetimetounix.c @@ -26,7 +26,7 @@ * @note type signature supports dates greater than 2100 * @see PKZIP, FAT */ -int64_t DosDateTimeToUnix(unsigned date, unsigned time) { +int64_t DosDateTimeToUnix(uint32_t date, uint32_t time) { unsigned year, month, day, hour, minute, second, yday, leap; year = ((date & 0xfffffe00) >> 9) + 1980 - 1900; month = MAX(1, MIN(12, (date & 0x01e0) >> 5)); diff --git a/libc/str/getzipcfiletimestamps.c b/libc/str/getzipcfiletimestamps.c index 12640aa8f..44d0c0a3b 100644 --- a/libc/str/getzipcfiletimestamps.c +++ b/libc/str/getzipcfiletimestamps.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" #include "libc/zip.internal.h" static inline int pop(int x) { diff --git a/libc/str/str.mk b/libc/str/str.mk index da938328b..e9b5f4166 100644 --- a/libc/str/str.mk +++ b/libc/str/str.mk @@ -75,6 +75,7 @@ o/$(MODE)/libc/str/iswseparator.o: private \ CFLAGS += \ -fno-jump-tables +# ensure that division is optimized o/$(MODE)/libc/str/bcmp.o \ o/$(MODE)/libc/str/strcmp.o \ o/$(MODE)/libc/str/windowsdurationtotimeval.o \ diff --git a/libc/str/strtok.c b/libc/str/strtok.c index 941029a3d..740d8e801 100644 --- a/libc/str/strtok.c +++ b/libc/str/strtok.c @@ -25,7 +25,7 @@ * @param sep is a NUL-terminated set of bytes to consider separators * @return pointer to next token or NULL for end * @see strtok_r() and strsep() for superior functions - * @notasyncsignalsafe + * @threadunsafe */ char *strtok(char *s, const char *sep) { static char *state; diff --git a/libc/str/timespectowindowstime.c b/libc/str/timespectowindowstime.c index 5e118e3d8..439cd0dc1 100644 --- a/libc/str/timespectowindowstime.c +++ b/libc/str/timespectowindowstime.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" int64_t TimeSpecToWindowsTime(struct timespec t) { return t.tv_nsec / 100 + (t.tv_sec + MODERNITYSECONDS) * HECTONANOSECONDS; diff --git a/libc/str/timevaltowindowstime.c b/libc/str/timevaltowindowstime.c index ee32ad900..dcf65fe20 100644 --- a/libc/str/timevaltowindowstime.c +++ b/libc/str/timevaltowindowstime.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" int64_t TimeValToWindowsTime(struct timeval t) { return t.tv_usec * 10 + (t.tv_sec + MODERNITYSECONDS) * HECTONANOSECONDS; diff --git a/libc/str/windowsdurationtotimespec.c b/libc/str/windowsdurationtotimespec.c index b1b5c3ef8..1426c5219 100644 --- a/libc/str/windowsdurationtotimespec.c +++ b/libc/str/windowsdurationtotimespec.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" struct timespec WindowsDurationToTimeSpec(int64_t x) { return (struct timespec){x / HECTONANOSECONDS, x % HECTONANOSECONDS * 100}; diff --git a/libc/str/windowsdurationtotimeval.c b/libc/str/windowsdurationtotimeval.c index 5e7f1110a..6cbf32bde 100644 --- a/libc/str/windowsdurationtotimeval.c +++ b/libc/str/windowsdurationtotimeval.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" struct timeval WindowsDurationToTimeVal(int64_t x) { return (struct timeval){x / HECTONANOSECONDS, x % HECTONANOSECONDS / 10}; diff --git a/libc/str/windowstimetotimespec.c b/libc/str/windowstimetotimespec.c index a87a575f3..8b116265b 100644 --- a/libc/str/windowstimetotimespec.c +++ b/libc/str/windowstimetotimespec.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" /** * Converts Windows COBOL timestamp to UNIX epoch in nanoseconds. diff --git a/libc/str/windowstimetotimeval.c b/libc/str/windowstimetotimeval.c index 615897b4f..ad4139c29 100644 --- a/libc/str/windowstimetotimeval.c +++ b/libc/str/windowstimetotimeval.c @@ -16,7 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" /** * Converts Windows COBOL timestamp to UNIX epoch in microseconds. diff --git a/libc/sysv/calls/sys_clock_gettime.S b/libc/sysv/calls/sys_clock_gettime.S deleted file mode 100644 index 42653a63f..000000000 --- a/libc/sysv/calls/sys_clock_gettime.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/macros.internal.h" -.scall sys_clock_gettime,0x1ab0570e8ffff0e4,113,4095,globl,hidden diff --git a/libc/sysv/calls/sys_gettimeofday.S b/libc/sysv/calls/sys_gettimeofday.S deleted file mode 100644 index 77ee3fbd8..000000000 --- a/libc/sysv/calls/sys_gettimeofday.S +++ /dev/null @@ -1,2 +0,0 @@ -#include "libc/sysv/macros.internal.h" -.scall sys_gettimeofday,0x1a20430742074060,169,116,globl,hidden diff --git a/libc/sysv/consts.sh b/libc/sysv/consts.sh index cb66ccd64..f2d8ab620 100755 --- a/libc/sysv/consts.sh +++ b/libc/sysv/consts.sh @@ -584,7 +584,7 @@ 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 # +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_PROF 127 127 127 127 2 127 2 127 # syscon clock CLOCK_BOOTTIME 7 7 127 127 127 6 127 127 # diff --git a/libc/sysv/consts/ENOBUFS.S b/libc/sysv/consts/ENOBUFS.S index 164795804..04fd4102d 100644 --- a/libc/sysv/consts/ENOBUFS.S +++ b/libc/sysv/consts/ENOBUFS.S @@ -1,2 +1,5 @@ #include "libc/sysv/consts/syscon.internal.h" .syscon errno,ENOBUFS,105,105,55,55,55,55,55,10055 +#ifdef __x86_64__ +.yoink kDos2Errno.ENOBUFS +#endif diff --git a/libc/sysv/syscall.S b/libc/sysv/syscall.S deleted file mode 100644 index 0c8c490fe..000000000 --- a/libc/sysv/syscall.S +++ /dev/null @@ -1,85 +0,0 @@ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ -│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 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/dce.h" -#include "libc/macros.internal.h" -.privileged - -// Performs raw System Five system call. -// -// This function provides a direct path into system call support -// that's friendly to C code, since it doesn't need an intermediate -// thunk. It only supports arities up to six, since there's no way -// to do more safely; this isn't a problem with Linux, although -// certain BSD calls may not be available. -// -// @param %rdi is system call ordinal, which isn't translated, -// and must be correct for the underlying host system -// @param %rsi,%rdx,%rcx,%r8,%r9 may supply parameters 1 through 5 -// @param sixth is optionally pushed on the stack before call -// @return %rax has result, or -1 w/ errno on failure - .ftrace1 -syscall: - .ftrace2 - push %rbp - mov %rsp,%rbp - -// slide arguments into their right places - mov %rdi,%rax // nr - mov %rsi,%rdi // arg 1 - mov %rdx,%rsi // arg 2 - mov %rcx,%rdx // arg 3 - mov %r8,%rcx // arg 4 - mov %r9,%r8 // arg 5 - mov 16(%rbp),%r9 // arg 6 - push 32(%rbp) // arg 8 - push 24(%rbp) // arg 7 - -// convert from consts.sh to syscalls.sh encoding - push %rcx - mov __hostos(%rip),%cl - test $_HOSTLINUX,%cl - jnz 2f -1: test $_HOSTFREEBSD,%cl - jz 1f - shl $4*7,%rax - jmp 2f -1: test $_HOSTOPENBSD,%cl - jz 1f - shl $4*10,%rax - jmp 2f -1: test $_HOSTNETBSD,%cl - jz 1f - shl $4*13,%rax - jmp 2f -1: test $_HOSTXNU,%cl - jz 2f - mov %eax,%ecx - and $0x0f000000,%ecx - and $0x00000fff,%eax - shl $4*3,%eax - or %ecx,%eax -2: pop %rcx - -// trigger the system call - call *__systemfive(%rip) - -// clean up stack and return - leave - ret - .endfn syscall,globl diff --git a/libc/nexgen32e/setlongerjmp.S b/libc/sysv/syscall2.S similarity index 68% rename from libc/nexgen32e/setlongerjmp.S rename to libc/sysv/syscall2.S index b40fcc57c..04de25d07 100644 --- a/libc/nexgen32e/setlongerjmp.S +++ b/libc/sysv/syscall2.S @@ -1,7 +1,7 @@ /*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ │vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ ╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2022 Justine Alexandra Roberts Tunney │ +│ 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 │ @@ -18,46 +18,33 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -// Saves caller CPU state to cacheline. +// Invokes system call w/ arity of two. // -// @param rdi points to jmp_buf -// @return eax contains 0 when set, and 1 if jumped -// @return rdx contains value passed to longerjmp() -// @returnstwice - .ftrace1 -setlongerjmp: - .ftrace2 -#ifdef __x86_64__ - lea 8(%rsp),%rax - mov %rax,(%rdi) - mov %rbx,8(%rdi) - mov %rbp,16(%rdi) - mov %r12,24(%rdi) - mov %r13,32(%rdi) - mov %r14,40(%rdi) - mov %r15,48(%rdi) - mov (%rsp),%rax - mov %rax,56(%rdi) - xor %eax,%eax - xor %edx,%edx +// This function has three parameters. The first two are for +// args passed along to the system call. The third's for the +// the magic number, indicating which system call is called. +// +// The returned value follows the Linux kernel convention ie +// errors are returned as `-errno`, rather than -1 w/ errno. +__syscall2: +#ifdef __aarch64__ + mov x8,x2 // syscall number (linux) + mov x16,x2 // syscall number (xnu) + mov x9,0 // clear carry flag + adds x9,x9,0 // clear carry flag + svc 0 + bcs 1f ret -#elif defined(__aarch64__) - stp x19,x20,[x0,#0] - stp x21,x22,[x0,#16] - stp x23,x24,[x0,#32] - stp x25,x26,[x0,#48] - stp x27,x28,[x0,#64] - stp x29,x30,[x0,#80] - mov x2,sp - str x2,[x0,#104] - stp d8,d9,[x0,#112] - stp d10,d11,[x0,#128] - stp d12,d13,[x0,#144] - stp d14,d15,[x0,#160] - mov x0,#0 - mov x1,#0 +1: neg x0,x0 ret +#elif defined(__x86_64__) + mov %edx,%eax // arg3 -> syscall number + clc // linux saves carry flag + syscall // bsds set carry on errs + jnc 1f + neg %rax // normalizes to system v +1: ret #else #error "unsupported architecture" #endif - .endfn setlongerjmp,globl + .endfn __syscall2,globl diff --git a/libc/nexgen32e/longerjmp.S b/libc/sysv/syscall3.S similarity index 68% rename from libc/nexgen32e/longerjmp.S rename to libc/sysv/syscall3.S index 129ee4b93..8316971b9 100644 --- a/libc/nexgen32e/longerjmp.S +++ b/libc/sysv/syscall3.S @@ -1,7 +1,7 @@ /*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ │vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ ╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ 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 │ @@ -18,41 +18,33 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/macros.internal.h" -// Loads previously saved processor state. +// Invokes system call w/ arity of three. // -// @param rdi points to the jmp_buf -// @param rsi is returned by setlongerjmp() invocation -// @noreturn - .ftrace1 -longerjmp: - .ftrace2 -#ifdef __x86_64__ - mov $1,%eax - mov %rsi,%rdx - mov (%rdi),%rsp - mov 8(%rdi),%rbx - mov 16(%rdi),%rbp - mov 24(%rdi),%r12 - mov 32(%rdi),%r13 - mov 40(%rdi),%r14 - mov 48(%rdi),%r15 - jmp *56(%rdi) -#elif defined(__aarch64__) - ldp x19,x20,[x0,#0] - ldp x21,x22,[x0,#16] - ldp x23,x24,[x0,#32] - ldp x25,x26,[x0,#48] - ldp x27,x28,[x0,#64] - ldp x29,x30,[x0,#80] - ldr x2,[x0,#104] - mov sp,x2 - ldp d8 ,d9,[x0,#112] - ldp d10,d11,[x0,#128] - ldp d12,d13,[x0,#144] - ldp d14,d15,[x0,#160] - mov x0,x1 - br x30 +// This function takes four params. The first three are for +// args passed along to the system call. The 4th is for the +// the magic number, indicating which system call is called +// +// The return value follows the Linux Kernel (System V) ABI +// where -errno is returned, rather than doing -1 w/ errno. +__syscall3: +#ifdef __aarch64__ + mov x8,x3 // syscall number (linux) + mov x16,x3 // syscall number (xnu) + mov x9,0 // clear carry flag + adds x9,x9,0 // clear carry flag + svc 0 + bcs 1f + ret +1: neg x0,x0 + ret +#elif defined(__x86_64__) + mov %ecx,%eax // arg4 -> syscall number + clc // linux saves carry flag + syscall // bsds set carry on errs + jnc 1f + neg %rax // normalizes to system v +1: ret #else #error "unsupported architecture" #endif - .endfn longerjmp,globl + .endfn __syscall3,globl diff --git a/libc/sysv/syscalls.sh b/libc/sysv/syscalls.sh index adfbea1ee..cfe3afb2a 100755 --- a/libc/sysv/syscalls.sh +++ b/libc/sysv/syscalls.sh @@ -127,7 +127,6 @@ scall sys_unlink 0x00a00a00a200a057 0x0b5 globl hidden scall sys_fchmod 0x07c07c07c207c05b 0x034 globl hidden scall sys_fchown 0x07b07b07b207b05d 0x037 globl hidden # @asyncsignalsafe scall sys_umask 0x03c03c03c203c05f 0x0a6 globl hidden -scall sys_gettimeofday 0x1a20430742074060 0x0a9 globl hidden # xnu esi/edx=0 scall sys_getrlimit 0x0c20c20c220c2061 0x0a3 globl hidden scall __sys_getrusage 0x1bd0130752075062 0x0a5 globl hidden scall sys_sysinfo 0xfffffffffffff063 0x0b3 globl hidden @@ -251,7 +250,6 @@ scall sys_ktimer_getoverrun 0xffffff0effffffff 0xfff globl # no wrapper scall sys_ktimer_gettime 0xffffff0eefffffff 0xfff globl # no wrapper scall sys_ktimer_settime 0xffffff0edfffffff 0xfff globl # no wrapper scall sys_clock_settime 0x1ac0580e9ffff0e3 0x070 globl hidden # no wrapper -scall sys_clock_gettime 0x1ab0570e8ffff0e4 0x071 globl hidden # Linux 2.6+ (c. 2003); XNU uses magic address scall sys_clock_getres 0x1ad0590eaffff0e5 0x072 globl hidden scall sys_mbind 0xfffffffffffff0ed 0x0eb globl # no wrapper; numa numa yeah scall set_mempolicy 0xfffffffffffff0ee 0x0ed globl diff --git a/libc/sysv/sysv.mk b/libc/sysv/sysv.mk index 00a96f3e8..9ea8e042a 100644 --- a/libc/sysv/sysv.mk +++ b/libc/sysv/sysv.mk @@ -38,7 +38,8 @@ LIBC_SYSV_A_FILES := \ libc/sysv/syslib.S \ libc/sysv/syscount.S \ libc/sysv/restorert.S \ - libc/sysv/syscall.S \ + libc/sysv/syscall2.S \ + libc/sysv/syscall3.S \ libc/sysv/systemfive.S \ libc/sysv/sysret.c \ libc/sysv/sysv.c \ @@ -165,6 +166,10 @@ o/$(MODE)/libc/sysv/syslib.o: libc/sysv/syslib.S @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) $< o/$(MODE)/libc/sysv/syscount.o: libc/sysv/syscount.S @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) $< +o/$(MODE)/libc/sysv/syscall2.o: libc/sysv/syscall2.S + @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) $< +o/$(MODE)/libc/sysv/syscall3.o: libc/sysv/syscall3.S + @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) $< o/$(MODE)/libc/sysv/restorert.o: libc/sysv/restorert.S @$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) $< o/$(MODE)/libc/sysv/calls/%.o: libc/sysv/calls/%.S diff --git a/libc/testlib/ezbenchcontrol.c b/libc/testlib/ezbenchcontrol.c index f6526ddd2..f3775c4db 100644 --- a/libc/testlib/ezbenchcontrol.c +++ b/libc/testlib/ezbenchcontrol.c @@ -19,6 +19,8 @@ #include "libc/calls/calls.h" #include "libc/fmt/itoa.h" #include "libc/intrin/kprintf.h" +#include "libc/runtime/runtime.h" +#include "libc/str/str.h" #include "libc/testlib/ezbench.h" #include "libc/testlib/testlib.h" @@ -26,6 +28,7 @@ static bool once; static double g_ezbenchcontrol; double __testlib_ezbenchcontrol(void) { + char host[64]; char ibuf[12]; int Core, Tries, Interrupts; if (!once) { @@ -41,9 +44,11 @@ double __testlib_ezbenchcontrol(void) { if (Tries == 10) { tinyprint(2, "warning: failed to accurately benchmark control\n"); } + strcpy(host, "unknown"); + gethostname(host, 64); FormatInt32(ibuf, g_ezbenchcontrol); - tinyprint(2, "will subtract benchmark overhead of ", ibuf, " cycles\n\n", - NULL); + tinyprint(2, "benchmarks on ", host, " (", __describe_os(), + "; overhead of ", ibuf, " cycles)\n", NULL); once = true; } return g_ezbenchcontrol; diff --git a/libc/thread/makecontext.c b/libc/thread/makecontext.c index 02af6ea57..5014c288c 100644 --- a/libc/thread/makecontext.c +++ b/libc/thread/makecontext.c @@ -88,7 +88,6 @@ static void runcontext(struct Gadget *call, ucontext_t *link) { * which if null will result in pthread_exit() being called * @param argc is effectively ignored (see notes above) * @see setcontext(), getcontext(), swapcontext() - * @threadsafe */ void makecontext(ucontext_t *uc, void func(), int argc, ...) { va_list va; diff --git a/libc/thread/pthread_create.c b/libc/thread/pthread_create.c index 275dfa5e8..51586acd3 100644 --- a/libc/thread/pthread_create.c +++ b/libc/thread/pthread_create.c @@ -335,7 +335,6 @@ static const char *DescribeHandle(char buf[12], errno_t err, pthread_t *th) { * @raise EPERM if scheduling policy was requested and user account * isn't authorized to use it * @returnserrno - * @threadsafe */ errno_t pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) { diff --git a/libc/thread/pthread_detach.c b/libc/thread/pthread_detach.c index ac479c9ca..336f7f84f 100644 --- a/libc/thread/pthread_detach.c +++ b/libc/thread/pthread_detach.c @@ -62,7 +62,6 @@ static errno_t pthread_detach_impl(struct PosixThread *pt) { * @return 0 on success, or errno with error * @raise EINVAL if `thread` isn't joinable * @returnserrno - * @threadsafe */ errno_t pthread_detach(pthread_t thread) { struct PosixThread *pt = (struct PosixThread *)thread; diff --git a/libc/thread/pthread_exit.c b/libc/thread/pthread_exit.c index 62088a458..f1c46ebad 100644 --- a/libc/thread/pthread_exit.c +++ b/libc/thread/pthread_exit.c @@ -94,7 +94,6 @@ void _pthread_unkey(struct CosmoTib *tib) { * destructors is also undefined. * * @param rc is reported later to pthread_join() - * @threadsafe * @noreturn */ wontreturn void pthread_exit(void *rc) { diff --git a/libc/thread/pthread_join.c b/libc/thread/pthread_join.c index 233a4372b..3906c3fa2 100644 --- a/libc/thread/pthread_join.c +++ b/libc/thread/pthread_join.c @@ -35,7 +35,6 @@ * @raise ECANCELED if calling thread was cancelled in masked mode * @cancellationpoint * @returnserrno - * @threadsafe */ errno_t pthread_join(pthread_t thread, void **value_ptr) { return pthread_timedjoin_np(thread, value_ptr, 0); diff --git a/libc/thread/pthread_timedjoin_np.c b/libc/thread/pthread_timedjoin_np.c index d636ac926..ceb68d9c0 100644 --- a/libc/thread/pthread_timedjoin_np.c +++ b/libc/thread/pthread_timedjoin_np.c @@ -99,7 +99,6 @@ static errno_t _pthread_wait(atomic_int *ctid, struct timespec *abstime) { * @raise EBUSY if `abstime` deadline elapsed * @cancellationpoint * @returnserrno - * @threadsafe */ errno_t pthread_timedjoin_np(pthread_t thread, void **value_ptr, struct timespec *abstime) { diff --git a/libc/thread/pthread_tryjoin_np.c b/libc/thread/pthread_tryjoin_np.c index ae5f02881..896426317 100644 --- a/libc/thread/pthread_tryjoin_np.c +++ b/libc/thread/pthread_tryjoin_np.c @@ -35,7 +35,6 @@ * @raise ECANCELED if calling thread was cancelled in masked mode * @cancellationpoint * @returnserrno - * @threadsafe */ errno_t pthread_tryjoin_np(pthread_t thread, void **value_ptr) { return pthread_timedjoin_np(thread, value_ptr, ×pec_zero); diff --git a/libc/thread/sem_open.c b/libc/thread/sem_open.c index a73269b80..eafd0a37d 100644 --- a/libc/thread/sem_open.c +++ b/libc/thread/sem_open.c @@ -165,7 +165,6 @@ static struct Semaphore *sem_open_get(const sem_t *sem, * @raise ENFILE if system-wide file limit has been reached * @raise ENOMEM if we require more vespene gas * @raise EINTR if signal handler was called - * @threadsafe */ sem_t *sem_open(const char *name, int oflag, ...) { sem_t *sem; diff --git a/libc/thread/tls.h b/libc/thread/tls.h index f0677b4fc..28fba51e8 100644 --- a/libc/thread/tls.h +++ b/libc/thread/tls.h @@ -3,9 +3,8 @@ #define TLS_ALIGNMENT 64 -#define TIB_FLAG_TIME_CRITICAL 1 -#define TIB_FLAG_VFORKED 2 -#define TIB_FLAG_WINCRASHING 4 +#define TIB_FLAG_VFORKED 1 +#define TIB_FLAG_WINCRASHING 2 #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ diff --git a/libc/time/ctime.c b/libc/time/ctime.c index c77c453d8..f0e90fbdb 100644 --- a/libc/time/ctime.c +++ b/libc/time/ctime.c @@ -2,6 +2,10 @@ #include "libc/time/struct/tm.h" #include "libc/time/time.h" +/** + * Represents time as string. + * @threadunsafe + */ char *ctime(const time_t *timep) { /* ** Section 4.12.3.2 of X3.159-1989 requires that diff --git a/libc/time/iso8601.c b/libc/time/iso8601.c index a131124ea..0f12b8ffc 100644 --- a/libc/time/iso8601.c +++ b/libc/time/iso8601.c @@ -55,7 +55,6 @@ * @return pointer to nul terminator within `p`, cf. stpcpy() * @see iso8601us() for microsecond timestamps * @asyncsignalsafe - * @threadsafe */ char *iso8601(char p[hasatleast 20], struct tm *tm) { int x; diff --git a/libc/time/iso8601us.c b/libc/time/iso8601us.c index 1fb24f501..c624aa363 100644 --- a/libc/time/iso8601us.c +++ b/libc/time/iso8601us.c @@ -62,7 +62,6 @@ * @return pointer to nul terminator within `p`, cf. stpcpy() * @see iso8601() if microsecond resolution isn't desirable * @asyncsignalsafe - * @threadsafe */ char *iso8601us(char p[hasatleast 27], struct tm *tm, long ns) { p = iso8601(p, tm); diff --git a/libc/time/localtime.c b/libc/time/localtime.c index a69e31b5c..26e2dab19 100644 --- a/libc/time/localtime.c +++ b/libc/time/localtime.c @@ -1615,6 +1615,9 @@ gmtsub(struct state const *sp, time_t const *timep, int_fast32_t offset, * Re-entrant version of gmtime. */ +/** + * Converts UNIX timestamp to broken-down representation. + */ struct tm * gmtime_r(const time_t *timep, struct tm *tmp) { @@ -1622,6 +1625,10 @@ gmtime_r(const time_t *timep, struct tm *tmp) return gmtsub(gmtptr, timep, 0, tmp); } +/** + * Converts UNIX timestamp to broken-down representation. + * @threadunsafe (see gmtime_r) + */ struct tm * gmtime(const time_t *timep) { diff --git a/libc/time/time.h b/libc/time/time.h index 3e9a0c1d2..42e03a53f 100644 --- a/libc/time/time.h +++ b/libc/time/time.h @@ -15,6 +15,7 @@ char *ctime_r(const int64_t *, char[hasatleast 26]); double difftime(int64_t, int64_t) pureconst; int64_t posix2time(int64_t) pureconst; int64_t time2posix(int64_t) pureconst; +int stime(const int64_t *); void tzset(void); #ifdef _COSMO_SOURCE diff --git a/libc/time/times.c b/libc/time/times.c index d31759135..cfbc20f79 100644 --- a/libc/time/times.c +++ b/libc/time/times.c @@ -22,7 +22,7 @@ #include "libc/calls/struct/tms.h" #include "libc/calls/syscall_support-nt.internal.h" #include "libc/dce.h" -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" #include "libc/nt/accounting.h" #include "libc/nt/runtime.h" #include "libc/runtime/clktck.h" diff --git a/libc/x/xload.c b/libc/x/xload.c index 89dae7e9c..e0e0e3f53 100644 --- a/libc/x/xload.c +++ b/libc/x/xload.c @@ -39,7 +39,6 @@ * @param n is byte length of deflated data * @param m is byte length of inflated data * @return pointer to inflated data - * @threadsafe */ void *xload(_Atomic(void *) *a, const void *p, size_t n, size_t m) { void *r, *z; diff --git a/test/libc/calls/clock_gettime_test.c b/test/libc/calls/clock_gettime_test.c index ec6079029..bff8c1792 100644 --- a/test/libc/calls/clock_gettime_test.c +++ b/test/libc/calls/clock_gettime_test.c @@ -16,7 +16,6 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/clock_gettime.internal.h" #include "libc/calls/internal.h" #include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timespec.internal.h" @@ -32,20 +31,23 @@ #include "libc/testlib/testlib.h" #include "libc/time/time.h" +TEST(clock_gettime, nullResult_validatesClockParam) { + ASSERT_SYS(EINVAL, -1, clock_gettime(666, 0)); +} + TEST(clock_gettime, test) { struct timespec ts = {0}; ASSERT_EQ(0, clock_gettime(0, &ts)); ASSERT_NE(0, ts.tv_sec); ASSERT_NE(0, ts.tv_nsec); -#ifndef __aarch64__ - bool isfast; - // we support vdso on aarch64 but qemu-aarch64 won't let us test it - if (IsLinux() && __is_linux_2_6_23()) { - ASSERT_GT((intptr_t)__clock_gettime_get(&isfast), - getauxval(AT_SYSINFO_EHDR)); - ASSERT_TRUE(isfast); - } -#endif +} + +TEST(clock_gettime, testClockRealtime) { + struct timeval tv; + struct timespec ts; + EXPECT_NE(-1, gettimeofday(&tv, NULL)); + EXPECT_NE(-1, clock_gettime(CLOCK_REALTIME, &ts)); + EXPECT_LT((unsigned)ABS(ts.tv_sec - tv.tv_sec), 5u); } BENCH(clock_gettime, bench) { @@ -54,25 +56,21 @@ BENCH(clock_gettime, bench) { gettimeofday(&tv, 0); // trigger init clock_gettime(0, &ts); // trigger init EZBENCH2("rdtsc", donothing, rdtsc()); - EZBENCH2("gettimeofday", donothing, gettimeofday(&tv, 0)); - EZBENCH2("timespec_real", donothing, timespec_real()); - EZBENCH2("clock_gettime 0", donothing, - clock_gettime(CLOCK_REALTIME_FAST, &ts)); - EZBENCH2("clock_gettime 1", donothing, + EZBENCH2("clock_gettime(mono)", donothing, clock_gettime(CLOCK_MONOTONIC_FAST, &ts)); - EZBENCH2("__clock_gettime 0", donothing, - __clock_gettime(CLOCK_REALTIME_FAST, &ts)); - EZBENCH2("__clock_gettime 1", donothing, - __clock_gettime(CLOCK_MONOTONIC_FAST, &ts)); + EZBENCH2("clock_gettime(real)", donothing, + clock_gettime(CLOCK_REALTIME_FAST, &ts)); + EZBENCH2("timespec_real", donothing, timespec_real()); + EZBENCH2("gettimeofday", donothing, gettimeofday(&tv, 0)); if (IsWindows()) { - EZBENCH2("sys_clock_gettime 0", donothing, + EZBENCH2("sys_clock_gettime r", donothing, sys_clock_gettime_nt(CLOCK_REALTIME_FAST, &ts)); - EZBENCH2("sys_clock_gettime 1", donothing, + EZBENCH2("sys_clock_gettime m", donothing, sys_clock_gettime_nt(CLOCK_MONOTONIC_FAST, &ts)); } else { - EZBENCH2("sys_clock_gettime 0", donothing, + EZBENCH2("sys_clock_gettime r", donothing, sys_clock_gettime(CLOCK_REALTIME_FAST, &ts)); - EZBENCH2("sys_clock_gettime 1", donothing, + EZBENCH2("sys_clock_gettime m", donothing, sys_clock_gettime(CLOCK_MONOTONIC_FAST, &ts)); } } diff --git a/test/libc/calls/commandv_test.c b/test/libc/calls/commandv_test.c index 85810a5d7..0b0a24122 100644 --- a/test/libc/calls/commandv_test.c +++ b/test/libc/calls/commandv_test.c @@ -48,31 +48,41 @@ void TearDown(void) { } TEST(commandv, testPathSearch) { - EXPECT_SYS(0, 0, touch("bin/sh", 0755)); + EXPECT_SYS(0, 3, creat("bin/sh", 0755)); + EXPECT_SYS(0, 2, write(3, "MZ", 2)); + EXPECT_SYS(0, 0, close(3)); EXPECT_STREQ("bin/sh", commandv("sh", pathbuf, sizeof(pathbuf))); } TEST(commandv, testSlashes_wontSearchPath_butChecksAccess) { - EXPECT_SYS(0, 0, touch("home/sh.com", 0755)); + EXPECT_SYS(0, 3, creat("home/sh.com", 0755)); + EXPECT_SYS(0, 2, write(3, "MZ", 2)); + EXPECT_SYS(0, 0, close(3)); EXPECT_STREQ("home/sh.com", commandv("home/sh.com", pathbuf, sizeof(pathbuf))); } TEST(commandv, testSameDir_doesntHappenByDefaultUnlessItsWindows) { - EXPECT_SYS(0, 0, touch("bog.com", 0755)); + EXPECT_SYS(0, 3, creat("bog.com", 0755)); + EXPECT_SYS(0, 2, write(3, "MZ", 2)); + EXPECT_SYS(0, 0, close(3)); EXPECT_STREQ(NULL, commandv("bog.com", pathbuf, sizeof(pathbuf))); EXPECT_EQ(ENOENT, errno); } TEST(commandv, testSameDir_willHappenWithColonBlank) { ASSERT_NE(-1, setenv("PATH", "bin:", true)); - EXPECT_SYS(0, 0, touch("bog.com", 0755)); + EXPECT_SYS(0, 3, creat("bog.com", 0755)); + EXPECT_SYS(0, 2, write(3, "MZ", 2)); + EXPECT_SYS(0, 0, close(3)); EXPECT_STREQ("bog.com", commandv("bog.com", pathbuf, sizeof(pathbuf))); } TEST(commandv, testSameDir_willHappenWithColonBlank2) { ASSERT_NE(-1, setenv("PATH", ":bin", true)); - EXPECT_SYS(0, 0, touch("bog.com", 0755)); + EXPECT_SYS(0, 3, creat("bog.com", 0755)); + EXPECT_SYS(0, 2, write(3, "MZ", 2)); + EXPECT_SYS(0, 0, close(3)); EXPECT_STREQ("bog.com", commandv("bog.com", pathbuf, sizeof(pathbuf))); } diff --git a/test/libc/calls/open_test.c b/test/libc/calls/open_test.c index 0ef42909f..3d5309351 100644 --- a/test/libc/calls/open_test.c +++ b/test/libc/calls/open_test.c @@ -343,7 +343,7 @@ TEST(open, readOnlyCreatMode) { char buf[8]; struct stat st; ASSERT_SYS(0, 3, open("x", O_RDWR | O_CREAT | O_TRUNC, 0500)); - ASSERT_SYS(0, 2, pwrite(3, "hi", 2, 0)); + ASSERT_SYS(0, 2, pwrite(3, "MZ", 2, 0)); ASSERT_SYS(0, 2, pread(3, buf, 8, 0)); ASSERT_SYS(0, 0, close(3)); ASSERT_SYS(0, 0, stat("x", &st)); @@ -410,13 +410,13 @@ TEST(open, readonlyCreateMode_dontChangeStatusIfExists) { char buf[8]; struct stat st; ASSERT_SYS(0, 3, creat("wut", 0700)); - ASSERT_SYS(0, 2, pwrite(3, "hi", 2, 0)); + ASSERT_SYS(0, 2, pwrite(3, "MZ", 2, 0)); ASSERT_SYS(0, 0, close(3)); // since the file already exists, unix doesn't change read-only ASSERT_SYS(0, 3, open("wut", O_CREAT | O_TRUNC | O_RDWR, 0500)); ASSERT_SYS(0, 0, pread(3, buf, 8, 0)); ASSERT_SYS(0, 0, fstat(3, &st)); - ASSERT_EQ(0100700, st.st_mode); + ASSERT_EQ(0100600, st.st_mode & 0700666); ASSERT_SYS(0, 0, close(3)); } @@ -424,7 +424,7 @@ TEST(open, creatRdonly) { char buf[8]; ASSERT_SYS(EINVAL, -1, open("foo", O_CREAT | O_TRUNC | O_RDONLY, 0700)); ASSERT_SYS(0, 3, open("foo", O_CREAT | O_RDONLY, 0700)); - ASSERT_SYS(EBADF, -1, pwrite(3, "hi", 2, 0)); + ASSERT_SYS(EBADF, -1, pwrite(3, "MZ", 2, 0)); ASSERT_SYS(0, 0, pread(3, buf, 8, 0)); ASSERT_SYS(0, 0, close(3)); } diff --git a/test/libc/calls/sigbus_test.c b/test/libc/calls/sigbus_test.c new file mode 100644 index 000000000..4bb852b7d --- /dev/null +++ b/test/libc/calls/sigbus_test.c @@ -0,0 +1,108 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2023 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/struct/sigaction.h" +#include "libc/calls/struct/siginfo.h" +#include "libc/calls/struct/sigset.h" +#include "libc/calls/ucontext.h" +#include "libc/dce.h" +#include "libc/runtime/runtime.h" +#include "libc/runtime/sysconf.h" +#include "libc/sysv/consts/auxv.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/o.h" +#include "libc/sysv/consts/prot.h" +#include "libc/sysv/consts/sa.h" +#include "libc/sysv/consts/sicode.h" +#include "libc/sysv/consts/sig.h" +#include "libc/testlib/testlib.h" +#include "third_party/xed/x86.h" + +volatile int gotsig; +volatile int gotcode; + +void SetUpOnce(void) { + testlib_enable_tmp_setup_teardown(); +} + +void SetUp(void) { + gotsig = 0; +} + +void OnSig(int sig, siginfo_t *si, void *arg) { + ucontext_t *ctx = arg; + gotsig = sig; + gotcode = si->si_code; +#ifdef __aarch64__ + ctx->uc_mcontext.pc += 4; +#elif defined(__x86_64__) + struct XedDecodedInst xedd; + xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_LONG_64); + xed_instruction_length_decode(&xedd, (void *)ctx->uc_mcontext.rip, 15); + ctx->uc_mcontext.rip += xedd.length; +#else +#error "unsupported architecture" +#endif /* __x86_64__ */ +} + +TEST(sigbus, test) { + + if (IsWindows()) { + // TODO(jart): Just write a kernel style memory manager from scratch + // for WIN32 and don't depend on their mapping functions + return; + } + + // create a file with less than one page of content + ASSERT_SYS(0, 3, open("foo", O_CREAT | O_RDWR, 0666)); + ASSERT_SYS(0, 2, write(3, "hi", 2)); + + // map two pages of the file into memory + char *map; + long pagesz = getauxval(AT_PAGESZ); + ASSERT_NE(MAP_FAILED, + (map = mmap(0, pagesz * 2, PROT_READ, MAP_PRIVATE, 3, 0))); + + // verify the file content is there + ASSERT_EQ('h', map[0]); + ASSERT_EQ('i', map[1]); + + // memory reads past file eof on first page get zero-filled + ASSERT_EQ(0, map[2]); + + // listen for sigbus + struct sigaction sa; + struct sigaction oldsa; + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = OnSig; + sigemptyset(&sa.sa_mask); + sigaction(SIGBUS, &sa, &oldsa); + + // memory reads past file eof on subsequent pages cause page fault to sigbus + volatile char x = map[pagesz]; + (void)x; + + // verify the signal was raised + EXPECT_EQ(SIGBUS, gotsig); + EXPECT_EQ(BUS_ADRERR, gotcode); + + // clean up + sigaction(SIGBUS, &oldsa, 0); + munmap(map, pagesz * 2); +} diff --git a/test/libc/calls/stat_test.c b/test/libc/calls/stat_test.c index e505cc288..1e0427799 100644 --- a/test/libc/calls/stat_test.c +++ b/test/libc/calls/stat_test.c @@ -24,6 +24,7 @@ #include "libc/calls/struct/stat.h" #include "libc/dce.h" #include "libc/errno.h" +#include "libc/limits.h" #include "libc/mem/gc.internal.h" #include "libc/nt/files.h" #include "libc/runtime/runtime.h" @@ -97,11 +98,19 @@ TEST(stat, zipos) { EXPECT_SYS(0, 0, stat("/zip/.python/", &st)); } +BENCH(fstat, bench) { + struct stat st; + ASSERT_SYS(0, 3, creat("foo.sh", 0777)); + ASSERT_SYS(0, 2, write(3, "#!", 2)); + EZBENCH2("fstat() fs", donothing, fstat(3, &st)); + ASSERT_SYS(0, 0, close(3)); +} + BENCH(stat, bench) { + char path[PATH_MAX]; struct stat st; union metastat ms; EXPECT_SYS(0, 0, makedirs(".python/test", 0755)); - EZBENCH2("__stat2cosmo", donothing, __stat2cosmo(&st, &ms)); EXPECT_SYS(0, 0, touch(".python/test/" "tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt", @@ -114,4 +123,6 @@ BENCH(stat, bench) { stat("/zip/.python/test/" "tokenize_tests-latin1-coding-cookie-and-utf8-bom-sig.txt", &st)); + EZBENCH2("getcwd()", donothing, getcwd(path, PATH_MAX)); + EZBENCH2("__stat2cosmo", donothing, __stat2cosmo(&st, &ms)); } diff --git a/test/libc/fmt/timevaltofiletime_test.c b/test/libc/fmt/timevaltofiletime_test.c index 720043cd0..2ed2f8ea4 100644 --- a/test/libc/fmt/timevaltofiletime_test.c +++ b/test/libc/fmt/timevaltofiletime_test.c @@ -16,11 +16,11 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/time/time.h" #include "libc/calls/struct/timeval.h" -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" #include "libc/nt/struct/filetime.h" #include "libc/testlib/testlib.h" -#include "libc/time/time.h" TEST(TimeValToFileTime, roundTrip) { struct timeval tv1, tv2; diff --git a/test/libc/proc/posix_spawn_test.c b/test/libc/proc/posix_spawn_test.c index a9ad58283..543620541 100644 --- a/test/libc/proc/posix_spawn_test.c +++ b/test/libc/proc/posix_spawn_test.c @@ -128,31 +128,6 @@ TEST(posix_spawn, ape) { ASSERT_EQ(42, WEXITSTATUS(ws)); } -TEST(posix_spawn, withoutComExtension_stillWorks) { - int ws, pid; - char *prog = "./life"; - char *args[] = {prog, 0}; - char *envs[] = {0}; - testlib_extract("/zip/life.com", prog, 0755); - ASSERT_EQ(0, posix_spawn(&pid, prog, NULL, NULL, args, envs)); - ASSERT_NE(-1, waitpid(pid, &ws, 0)); - ASSERT_TRUE(WIFEXITED(ws)); - ASSERT_EQ(42, WEXITSTATUS(ws)); -} - -TEST(posix_spawn, execveAutoAppendsComSuffix) { - if (!IsWindows()) return; // only on windows for now - int ws, pid; - char *prog = "./life"; - char *args[] = {prog, 0}; - char *envs[] = {0}; - testlib_extract("/zip/life.com", "life.com", 0755); - ASSERT_EQ(0, posix_spawn(&pid, prog, NULL, NULL, args, envs)); - ASSERT_NE(-1, waitpid(pid, &ws, 0)); - ASSERT_TRUE(WIFEXITED(ws)); - ASSERT_EQ(42, WEXITSTATUS(ws)); -} - TEST(posix_spawn, elf) { if (IsXnu() || IsWindows() || IsMetal()) return; int ws, pid; diff --git a/test/libc/time/clock_gettime_test.c b/test/libc/time/clock_gettime_test.c deleted file mode 100644 index 05eaf6c75..000000000 --- a/test/libc/time/clock_gettime_test.c +++ /dev/null @@ -1,35 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 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/struct/timespec.h" -#include "libc/fmt/conv.h" -#include "libc/macros.internal.h" -#include "libc/mem/gc.internal.h" -#include "libc/stdio/stdio.h" -#include "libc/sysv/consts/clock.h" -#include "libc/testlib/testlib.h" -#include "libc/time/time.h" -#include "libc/x/x.h" - -TEST(clock_gettime, testClockRealtime) { - struct timeval tv; - struct timespec ts; - EXPECT_NE(-1, gettimeofday(&tv, NULL)); - EXPECT_NE(-1, clock_gettime(CLOCK_REALTIME, &ts)); - EXPECT_LT((unsigned)ABS(ts.tv_sec - tv.tv_sec), 5u); -} diff --git a/third_party/chibicc/alloc.c b/third_party/chibicc/alloc.c index c33919a7c..13f08b087 100644 --- a/third_party/chibicc/alloc.c +++ b/third_party/chibicc/alloc.c @@ -16,8 +16,8 @@ │ 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/stdio/stdio.h" #include "third_party/chibicc/chibicc.h" long alloc_node_count; @@ -26,7 +26,7 @@ long alloc_obj_count; long alloc_type_count; wontreturn void __oom_hook(size_t request) { - fprintf(stderr, "error: chibicc ran out of memory\n"); + tinyprint(2, "error: chibicc ran out of memory\n", NULL); exit(1); } diff --git a/third_party/libcxx/filesystem_common.hh b/third_party/libcxx/filesystem_common.hh index 42f665183..c2686af0b 100644 --- a/third_party/libcxx/filesystem_common.hh +++ b/third_party/libcxx/filesystem_common.hh @@ -18,6 +18,7 @@ #include "third_party/libcxx/cstdlib" #include "libc/calls/struct/stat.h" #include "libc/sysv/consts/at.h" +#include "libc/calls/struct/timeval.h" #include "third_party/libcxx/climits" #define _LIBCPP_USE_UTIMENSAT diff --git a/third_party/libcxx/thread.cc b/third_party/libcxx/thread.cc index e6c7420d6..179f5eddb 100644 --- a/third_party/libcxx/thread.cc +++ b/third_party/libcxx/thread.cc @@ -29,7 +29,7 @@ #include "libc/calls/calls.h" #include "libc/calls/struct/rlimit.h" #include "libc/calls/struct/rusage.h" -#include "libc/calls/sysparam.h" +#include "libc/stdio/sysparam.h" #include "libc/calls/weirdtypes.h" #include "libc/limits.h" #include "libc/sysv/consts/endian.h" diff --git a/third_party/musl/grp.c b/third_party/musl/grp.c index a1a5e06be..ec9093676 100644 --- a/third_party/musl/grp.c +++ b/third_party/musl/grp.c @@ -215,14 +215,27 @@ static struct GetgrentState { struct group gr; } g_getgrent[1]; +/** + * Closes group database. + * @threadunsafe + */ void endgrent() { setgrent(); } + +/** + * Rewinds to beginning of group database. + * @threadunsafe + */ void setgrent() { if (g_getgrent->f) fclose(g_getgrent->f); g_getgrent->f = 0; } +/** + * Returns successive entries in /etc/group database. + * @threadunsafe + */ struct group *getgrent() { struct group *res; size_t size = 0, nmem = 0; diff --git a/third_party/musl/pwd.c b/third_party/musl/pwd.c index d81ac8238..3964ec2c4 100644 --- a/third_party/musl/pwd.c +++ b/third_party/musl/pwd.c @@ -240,6 +240,7 @@ static struct GetpwentState { * Closes global handle to password database. * * @see getpwent() + * @threadunsafe */ void endpwent(void) @@ -251,6 +252,7 @@ endpwent(void) * Rewinds global handle to password database. * * @see getpwent() + * @threadunsafe */ void setpwent(void) @@ -264,7 +266,8 @@ setpwent(void) * Returns next entry in password database. * * @return pointer to entry static memory, or NULL on EOF - * @see getpwent() + * @see setpwent() + * @threadunsafe */ struct passwd * getpwent() @@ -287,6 +290,7 @@ getpwent() * if `/etc/passwd` doesn't exist, or is fake (e.g. MacOS). * * @return pointer to passwd entry static memory, or NULL if not found + * @threadunsafe */ struct passwd * getpwuid(uid_t uid) @@ -305,6 +309,7 @@ getpwuid(uid_t uid) * if `/etc/passwd` doesn't exist, or is fake (e.g. MacOS). * * @return pointer to passwd entry static memory, or NULL if not found + * @threadunsafe */ struct passwd * getpwnam(const char *name) diff --git a/third_party/nsync/futex.c b/third_party/nsync/futex.c index 9d6b47268..227d96044 100644 --- a/third_party/nsync/futex.c +++ b/third_party/nsync/futex.c @@ -290,9 +290,7 @@ int nsync_futex_wait_ (atomic_int *w, int expect, char pshare, const struct time } } else { Polyfill: - tib->tib_flags |= TIB_FLAG_TIME_CRITICAL; rc = nsync_futex_polyfill_ (w, expect, timeout); - tib->tib_flags &= ~TIB_FLAG_TIME_CRITICAL; } Finished: diff --git a/third_party/python/Modules/_threadmodule.c b/third_party/python/Modules/_threadmodule.c index d15a0b8ca..11428a4e0 100644 --- a/third_party/python/Modules/_threadmodule.c +++ b/third_party/python/Modules/_threadmodule.c @@ -20,7 +20,7 @@ #include "libc/calls/struct/utsname.h" #include "libc/calls/struct/winsize.h" #include "libc/calls/syscall-sysv.internal.h" -#include "libc/calls/sysparam.h" +#include "libc/stdio/sysparam.h" #include "libc/calls/termios.h" #include "libc/calls/weirdtypes.h" #include "libc/dce.h" diff --git a/third_party/python/Modules/posixmodule.c b/third_party/python/Modules/posixmodule.c index 51240832d..a29ef0841 100644 --- a/third_party/python/Modules/posixmodule.c +++ b/third_party/python/Modules/posixmodule.c @@ -22,7 +22,7 @@ #include "libc/calls/struct/utsname.h" #include "libc/calls/struct/winsize.h" #include "libc/calls/syscall-sysv.internal.h" -#include "libc/calls/sysparam.h" +#include "libc/stdio/sysparam.h" #include "libc/calls/termios.h" #include "libc/calls/weirdtypes.h" #include "libc/dce.h" diff --git a/third_party/python/Modules/timemodule.c b/third_party/python/Modules/timemodule.c index dc139310d..d02650681 100644 --- a/third_party/python/Modules/timemodule.c +++ b/third_party/python/Modules/timemodule.c @@ -10,7 +10,7 @@ #include "libc/calls/struct/tms.h" #include "libc/dce.h" #include "libc/errno.h" -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" #include "libc/nt/accounting.h" #include "libc/nt/runtime.h" #include "libc/runtime/clktck.h" diff --git a/third_party/python/PC/winreg.c b/third_party/python/PC/winreg.c index 9ae9e1086..0aa32f944 100644 --- a/third_party/python/PC/winreg.c +++ b/third_party/python/PC/winreg.c @@ -4,18 +4,44 @@ │ Python 3 │ │ https://docs.python.org/3/license.html │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/isystem/windows.h" #include "libc/nt/registry.h" #include "third_party/python/Include/abstract.h" #include "third_party/python/Include/ceval.h" #include "third_party/python/Include/listobject.h" #include "third_party/python/Include/longobject.h" #include "third_party/python/Include/modsupport.h" +#include "third_party/python/Include/object.h" #include "third_party/python/Include/objimpl.h" #include "third_party/python/Include/pyerrors.h" #include "third_party/python/Include/pyhash.h" #include "third_party/python/Include/pymacro.h" #include "third_party/python/Include/structmember.h" + +#undef NULL +#define NULL 0 + +#define BOOL bool32 +#define DWORD32 uint32_t +#define HKEY int64_t +#define ULONG uint32_t +#define ACCESS_MASK ULONG +#define REGSAM ACCESS_MASK + +#define HKEY_CLASSES_ROOT kNtHkeyClassesRoot +#define HKEY_CURRENT_USER kNtHkeyCurrentUser +#define HKEY_LOCAL_MACHINE kNtHkeyLocalMachine +#define HKEY_USERS kNtHkeyUsers +#define HKEY_PERFORMANCE_DATA kNtHkeyPerformanceData +#define HKEY_PERFORMANCE_TEXT kNtHkeyPerformanceText +#define HKEY_PERFORMANCE_NLSTEXT kNtHkeyPerformanceNlstext +#define HKEY_CURRENT_CONFIG kNtHkeyCurrentConfig +#define HKEY_DYN_DATA kNtHkeyDynData +#define HKEY_CURRENT_USER_LOCAL_SETTINGS kNtHkeyCurrentUserLocalSettings +#define KEY_READ kNtKeyRead +#define KEY_WRITE kNtKeyWrite +#define KEY_EXECUTE kNtKeyExecute +#define KEY_ALL_ACCESS kNtKeyAllAccess + /* clang-format off */ /* diff --git a/third_party/sqlite3/os_unix.c b/third_party/sqlite3/os_unix.c index 1bf5b0067..801ed24da 100644 --- a/third_party/sqlite3/os_unix.c +++ b/third_party/sqlite3/os_unix.c @@ -126,7 +126,7 @@ #include "libc/sysv/consts/ok.h" #include "libc/calls/struct/rlimit.h" #include "libc/calls/struct/rusage.h" -#include "libc/calls/sysparam.h" +#include "libc/stdio/sysparam.h" #include "libc/limits.h" #endif /* SQLITE_ENABLE_LOCKING_STYLE */ diff --git a/third_party/zip/unix.c b/third_party/zip/unix.c index b815c35c5..0af1e2c31 100644 --- a/third_party/zip/unix.c +++ b/third_party/zip/unix.c @@ -705,7 +705,7 @@ char *d; /* directory to delete */ #include "libc/calls/calls.h" #include "libc/calls/struct/rlimit.h" #include "libc/calls/struct/rusage.h" -#include "libc/calls/sysparam.h" +#include "libc/stdio/sysparam.h" #include "libc/calls/weirdtypes.h" #include "libc/limits.h" #include "libc/sysv/consts/endian.h" diff --git a/third_party/zstd/programs/util.c b/third_party/zstd/programs/util.c index 0c36955ab..04e070d7b 100644 --- a/third_party/zstd/programs/util.c +++ b/third_party/zstd/programs/util.c @@ -1631,7 +1631,7 @@ failed: #include "libc/calls/calls.h" #include "libc/calls/struct/rlimit.h" #include "libc/calls/struct/rusage.h" -#include "libc/calls/sysparam.h" +#include "libc/stdio/sysparam.h" #include "libc/calls/weirdtypes.h" #include "libc/limits.h" #include "libc/sysv/consts/endian.h" diff --git a/tool/build/lib/elfwriter_zip.c b/tool/build/lib/elfwriter_zip.c index caf29bc0e..ea4829bfe 100644 --- a/tool/build/lib/elfwriter_zip.c +++ b/tool/build/lib/elfwriter_zip.c @@ -18,7 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/dos.internal.h" #include "libc/elf/def.h" -#include "libc/fmt/conv.h" +#include "libc/fmt/wintime.internal.h" #include "libc/limits.h" #include "libc/log/check.h" #include "libc/mem/gc.h" diff --git a/tool/decode/zip.c b/tool/decode/zip.c index 8f7a0762f..51b9df1c3 100644 --- a/tool/decode/zip.c +++ b/tool/decode/zip.c @@ -18,8 +18,8 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/struct/stat.h" -#include "libc/fmt/conv.h" #include "libc/fmt/libgen.h" +#include "libc/fmt/wintime.internal.h" #include "libc/intrin/bits.h" #include "libc/intrin/safemacros.internal.h" #include "libc/log/check.h" diff --git a/tool/net/redbean.c b/tool/net/redbean.c index f6d5c0c63..c67b7c6e7 100644 --- a/tool/net/redbean.c +++ b/tool/net/redbean.c @@ -38,6 +38,7 @@ #include "libc/errno.h" #include "libc/fmt/conv.h" #include "libc/fmt/itoa.h" +#include "libc/fmt/wintime.internal.h" #include "libc/intrin/atomic.h" #include "libc/intrin/bits.h" #include "libc/intrin/bsr.h"