diff --git a/Makefile b/Makefile index 80ef2288a..317d95270 100644 --- a/Makefile +++ b/Makefile @@ -329,7 +329,7 @@ o/$(MODE)/hdrs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(HDRS) $( o/$(MODE)/incs.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(INCS) $(INCS),$(dir $(x)))) $(INCS) $(INCS) $(file >$@,$(INCS)) o/$(MODE)/depend: o/$(MODE)/.x o/$(MODE)/srcs.txt o/$(MODE)/hdrs.txt o/$(MODE)/incs.txt $(SRCS) $(HDRS) $(INCS) - $(COMPILE) -AMKDEPS -L320 $(MKDEPS) -o $@ -r o/$(MODE)/ @o/$(MODE)/srcs.txt @o/$(MODE)/hdrs.txt @o/$(MODE)/incs.txt + $(COMPILE) -AMKDEPS -L320 $(MKDEPS) -o $@ -s -r o/$(MODE)/ @o/$(MODE)/srcs.txt @o/$(MODE)/hdrs.txt @o/$(MODE)/incs.txt o/$(MODE)/srcs-old.txt: o/$(MODE)/.x $(MAKEFILES) $(call uniq,$(foreach x,$(SRCS),$(dir $(x)))) $(file >$@) $(foreach x,$(SRCS),$(file >>$@,$(x))) diff --git a/bin/fatcosmocc b/bin/fatcosmocc index ca7e9a9bf..7c2345c32 100755 --- a/bin/fatcosmocc +++ b/bin/fatcosmocc @@ -240,6 +240,8 @@ NEED_JOIN= NEED_EQUAL= NEED_OUTPUT= APELINKFLAGS= +FLAGS_X86_64= +FLAGS_AARCH64= INPUT_FILE_COUNT=0 for x; do if [ x"$x" != x"${x#* }" ]; then @@ -335,6 +337,14 @@ for x; do continue elif [ x"$x" = x"-march=native" ]; then fatal_error "-march=native can't be used when building fat binaries" + elif [ x"$x" != x"${x#-Xx86_64}" ]; then + x=${x#-Xx86_64} # e.g. -Xx86_64,-msse3,-mavx,-mavx2,-mf16c,-mfma + FLAGS_X86_64="$FLAGS_X86_64 ${x//,/ }" + continue + elif [ x"$x" != x"${x#-Xaarch64}" ]; then + x=${x#-Xaarch64} + FLAGS_aarch64="$FLAGS_aarch64 ${x//,/ }" + continue elif [ x"$x" = x"-dumpversion" ]; then echo $GCC_VERSION Exit 0 @@ -473,6 +483,7 @@ build_object() { $CFLAGS_X86_64 \ $CPPFLAGS_X86_64 \ "$@" \ + $FLAGS_X86_64 \ $PRECIOUS log_command "$@" "$@" || exit @@ -492,6 +503,7 @@ build_object() { $CFLAGS_AARCH64 \ $CPPFLAGS_AARCH64 \ "$@" \ + $FLAGS_AARCH64 \ $PRECIOUS && log_command "$@" "$@" || exit diff --git a/build/bootstrap/mkdeps.com b/build/bootstrap/mkdeps.com index e850c2ae1..6b1e5b74f 100755 Binary files a/build/bootstrap/mkdeps.com and b/build/bootstrap/mkdeps.com differ diff --git a/libc/calls/getrlimit.c b/libc/calls/getrlimit.c index 4ba4ea41d..72420395c 100644 --- a/libc/calls/getrlimit.c +++ b/libc/calls/getrlimit.c @@ -23,6 +23,7 @@ #include "libc/intrin/asan.internal.h" #include "libc/intrin/describeflags.internal.h" #include "libc/intrin/strace.internal.h" +#include "libc/runtime/runtime.h" #include "libc/runtime/stack.h" #include "libc/runtime/syslib.internal.h" #include "libc/sysv/consts/rlimit.h" diff --git a/libc/calls/internal.h b/libc/calls/internal.h index f2fa4d731..f5c980256 100644 --- a/libc/calls/internal.h +++ b/libc/calls/internal.h @@ -31,10 +31,6 @@ int64_t GetConsoleOutputHandle(void); int IsWindowsExecutable(int64_t, const char16_t *); void InterceptTerminalCommands(const char *, size_t); -forceinline int64_t __getfdhandleactual(int fd) { - return g_fds.p[fd].handle; -} - forceinline bool __isfdopen(int fd) { return 0 <= fd && fd < g_fds.n && g_fds.p[fd].kind != kFdEmpty; } diff --git a/libc/calls/ioctl.c b/libc/calls/ioctl.c index 819416fec..6b31c3d96 100644 --- a/libc/calls/ioctl.c +++ b/libc/calls/ioctl.c @@ -75,7 +75,7 @@ static int ioctl_default(int fd, unsigned long request, void *arg) { return sys_ioctl(fd, request, arg); } else if (__isfdopen(fd)) { if (g_fds.p[fd].kind == kFdSocket) { - handle = __getfdhandleactual(fd); + handle = g_fds.p[fd].handle; if ((rc = _weaken(__sys_ioctlsocket_nt)(handle, request, arg)) != -1) { return rc; } else { diff --git a/libc/calls/ischardev.c b/libc/calls/ischardev.c index 06e026531..da7ad7641 100644 --- a/libc/calls/ischardev.c +++ b/libc/calls/ischardev.c @@ -56,6 +56,6 @@ bool32 ischardev(int fd) { } else { return __isfdkind(fd, kFdConsole) || __isfdkind(fd, kFdDevNull) || (__isfdkind(fd, kFdFile) && - GetFileType(__getfdhandleactual(fd)) == kNtFileTypeChar); + GetFileType(g_fds.p[fd].handle) == kNtFileTypeChar); } } diff --git a/libc/calls/pthread_yield.c b/libc/calls/pthread_yield.c index 20462fe79..f3dfd002a 100644 --- a/libc/calls/pthread_yield.c +++ b/libc/calls/pthread_yield.c @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/dce.h" -#include "libc/nexgen32e/yield.h" #include "libc/runtime/runtime.h" #include "libc/runtime/syslib.internal.h" #include "libc/thread/thread.h" @@ -32,7 +31,7 @@ int pthread_yield(void) { if (IsXnuSilicon()) { __syslib->__pthread_yield_np(); } else if (IsOpenbsd()) { - spin_yield(); // sched_yield() is punishingly slow on OpenBSD + pthread_pause_np(); // sched_yield() is punishingly slow on OpenBSD } else { sched_yield(); } diff --git a/libc/calls/read-nt.c b/libc/calls/read-nt.c index 1924ee002..8ffe0a346 100644 --- a/libc/calls/read-nt.c +++ b/libc/calls/read-nt.c @@ -142,7 +142,7 @@ struct Keystrokes { static struct Keystrokes __keystroke; -textwindows void __keystroke_wipe(void) { +textwindows void WipeKeystrokes(void) { bzero(&__keystroke, sizeof(__keystroke)); } @@ -754,8 +754,8 @@ static textwindows ssize_t ReadFromConsole(struct Fd *f, void *data, return rc; } -textwindows ssize_t sys_read_nt_impl(int fd, void *data, size_t size, - int64_t offset, sigset_t waitmask) { +textwindows ssize_t ReadBuffer(int fd, void *data, size_t size, int64_t offset, + sigset_t waitmask) { // switch to terminal polyfill if reading from win32 console struct Fd *f = g_fds.p + fd; @@ -786,9 +786,9 @@ textwindows ssize_t sys_read_nt_impl(int fd, void *data, size_t size, } } -static textwindows ssize_t sys_read_nt2(int fd, const struct iovec *iov, - size_t iovlen, int64_t opt_offset, - sigset_t waitmask) { +static textwindows ssize_t ReadIovecs(int fd, const struct iovec *iov, + size_t iovlen, int64_t opt_offset, + sigset_t waitmask) { ssize_t rc; size_t i, total; if (opt_offset < -1) return einval(); @@ -796,8 +796,8 @@ static textwindows ssize_t sys_read_nt2(int fd, const struct iovec *iov, if (iovlen) { for (total = i = 0; i < iovlen; ++i) { if (!iov[i].iov_len) continue; - rc = sys_read_nt_impl(fd, iov[i].iov_base, iov[i].iov_len, opt_offset, - waitmask); + rc = + ReadBuffer(fd, iov[i].iov_base, iov[i].iov_len, opt_offset, waitmask); if (rc == -1) { if (total && errno != ECANCELED) { return total; @@ -811,7 +811,7 @@ static textwindows ssize_t sys_read_nt2(int fd, const struct iovec *iov, } return total; } else { - return sys_read_nt_impl(fd, NULL, 0, opt_offset, waitmask); + return ReadBuffer(fd, NULL, 0, opt_offset, waitmask); } } @@ -819,7 +819,7 @@ textwindows ssize_t sys_read_nt(int fd, const struct iovec *iov, size_t iovlen, int64_t opt_offset) { ssize_t rc; sigset_t m = __sig_block(); - rc = sys_read_nt2(fd, iov, iovlen, opt_offset, m); + rc = ReadIovecs(fd, iov, iovlen, opt_offset, m); __sig_unblock(m); return rc; } diff --git a/libc/calls/setrlimit.c b/libc/calls/setrlimit.c index 2883c5f72..6e1b1fb39 100644 --- a/libc/calls/setrlimit.c +++ b/libc/calls/setrlimit.c @@ -25,6 +25,7 @@ #include "libc/intrin/describeflags.internal.h" #include "libc/intrin/strace.internal.h" #include "libc/macros.internal.h" +#include "libc/runtime/runtime.h" #include "libc/runtime/syslib.internal.h" #include "libc/sysv/consts/rlimit.h" #include "libc/sysv/errfuns.h" diff --git a/libc/calls/sig.c b/libc/calls/sig.c index 8c620ee93..c6e208e25 100644 --- a/libc/calls/sig.c +++ b/libc/calls/sig.c @@ -201,7 +201,6 @@ textwindows int __sig_raise(volatile int sig, int sic) { STRACE("__sig_raise(%G, %t) mask %s", sig, __sig_handler(rva), (DescribeSigset)(ssbuf, 0, (sigset_t *)&pt->tib->tib_sigmask)); __sig_handler(rva)(sig, &si, &ctx); - (void)ssbuf; // record this handler if (flags & SA_RESTART) { @@ -271,7 +270,6 @@ static textwindows wontreturn void __sig_tramp(struct SignalFrame *sf) { (DescribeSigset)(ssbuf[0], 0, &sf->ctx.uc_sigmask), (DescribeSigset)(ssbuf[1], 0, (sigset_t *)&tib->tib_sigmask)); __sig_handler(sf->rva)(sig, &sf->si, &sf->ctx); - (void)ssbuf; // restore the signal mask that was used by the interrupted code // this may have been modified by the signal handler in the callback diff --git a/libc/calls/sigtimedwait.c b/libc/calls/sigtimedwait.c index 051d91a95..1b47e61ad 100644 --- a/libc/calls/sigtimedwait.c +++ b/libc/calls/sigtimedwait.c @@ -51,7 +51,6 @@ int sigtimedwait(const sigset_t *set, siginfo_t *info, struct timespec ts; union siginfo_meta si = {0}; BEGIN_CANCELATION_POINT; - (void)strsig; if (IsAsan() && (!__asan_is_valid(set, sizeof(*set)) || (info && !__asan_is_valid(info, sizeof(*info))) || diff --git a/libc/calls/sync.c b/libc/calls/sync.c index 9fa35a520..809158269 100644 --- a/libc/calls/sync.c +++ b/libc/calls/sync.c @@ -21,6 +21,7 @@ #include "libc/calls/syscall-sysv.internal.h" #include "libc/dce.h" #include "libc/intrin/strace.internal.h" +#include "libc/runtime/runtime.h" /** * Flushes file system changes to disk by any means necessary. diff --git a/libc/calls/sys_ptrace.c b/libc/calls/sys_ptrace.c index 6abdb9703..bdecfc2ea 100644 --- a/libc/calls/sys_ptrace.c +++ b/libc/calls/sys_ptrace.c @@ -22,6 +22,7 @@ #include "libc/intrin/describeflags.internal.h" #include "libc/intrin/likely.h" #include "libc/intrin/strace.internal.h" +#include "libc/runtime/runtime.h" #define IsPeek(request) (IsLinux() && (request)-1u < 3) diff --git a/libc/calls/winexec.c b/libc/calls/winexec.c index c8c96cb7d..5cd1d5141 100644 --- a/libc/calls/winexec.c +++ b/libc/calls/winexec.c @@ -28,9 +28,10 @@ #include "libc/str/tab.internal.h" #include "third_party/linenoise/linenoise.h" -#define EXT(s) READ32LE(s "\0\0") +#define Read32(s) (s[3] << 24 | s[2] << 16 | s[1] << 8 | s[0]) +#define EXT(s) Read32(s "\0\0") -static bool IsGraph(wint_t c) { +static inline bool IsGraph(wint_t c) { return 0x21 <= c && c <= 0x7E; } diff --git a/libc/intrin/__getenv.c b/libc/intrin/__getenv.c index d8c382a91..c76632727 100644 --- a/libc/intrin/__getenv.c +++ b/libc/intrin/__getenv.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/dce.h" #include "libc/intrin/getenv.internal.h" +#include "libc/intrin/kprintf.h" privileged struct Env __getenv(char **p, const char *k) { char *t; diff --git a/libc/intrin/createfile.c b/libc/intrin/createfile.c index 2aab825be..4b092c4b9 100644 --- a/libc/intrin/createfile.c +++ b/libc/intrin/createfile.c @@ -49,13 +49,9 @@ CreateFile(const char16_t *lpFileName, // int64_t hHandle; uint32_t micros = 1; char buf_accessflags[512]; - (void)buf_accessflags; char buf_shareflags[64]; - (void)buf_shareflags; char buf_secattr[32]; - (void)buf_secattr; char buf_flagattr[256]; - (void)buf_flagattr; TryAgain: hHandle = __imp_CreateFileW(lpFileName, dwDesiredAccess, dwShareMode, opt_lpSecurity, dwCreationDisposition, diff --git a/libc/intrin/cxalock.c b/libc/intrin/cxalock.c index 632698675..7142f5c2f 100644 --- a/libc/intrin/cxalock.c +++ b/libc/intrin/cxalock.c @@ -33,7 +33,10 @@ void __cxa_unlock(void) { pthread_mutex_unlock(&__cxa_lock_obj); } -__attribute__((__constructor__)) static void __cxa_init(void) { - __cxa_wipe(); +static textstartup void __cxa_init() { pthread_atfork(__cxa_lock, __cxa_unlock, __cxa_wipe); } + +const void *const __cxa_ctor[] initarray = { + __cxa_init, +}; diff --git a/libc/intrin/ftrace_enabled.c b/libc/intrin/ftrace_enabled.c index 1e448fbe6..1313f01fa 100644 --- a/libc/intrin/ftrace_enabled.c +++ b/libc/intrin/ftrace_enabled.c @@ -25,7 +25,7 @@ * @param delta is added to enabled state * @return enabled state before `delta` was applied */ -dontinstrument int ftrace_enabled(int delta) { +dontinstrument int(ftrace_enabled)(int delta) { int res; struct CosmoTib *tib; if (__tls_enabled) { diff --git a/libc/intrin/isdebuggerpresent.c b/libc/intrin/isdebuggerpresent.c index 7ee193002..e455d55e5 100644 --- a/libc/intrin/isdebuggerpresent.c +++ b/libc/intrin/isdebuggerpresent.c @@ -50,7 +50,7 @@ int IsDebuggerPresent(bool force) { int e, fd, res; char *p, buf[1024]; if (!force && IsGenuineBlink()) return 0; - if (!force && __getenv(environ, "HEISENDEBUG").s) return 0; + if (!force && environ && __getenv(environ, "HEISENDEBUG").s) return 0; if (IsWindows()) return IsBeingDebugged(); if (__isworker) return false; if (!PLEDGED(RPATH)) return false; diff --git a/libc/intrin/kprintf.greg.c b/libc/intrin/kprintf.greg.c index 1cefe2480..41306f305 100644 --- a/libc/intrin/kprintf.greg.c +++ b/libc/intrin/kprintf.greg.c @@ -345,7 +345,7 @@ privileged long kloghandle(void) { // it's too early in the initialization process for kprintf return -1; } - path = __getenv(__envp, "KPRINTF_LOG").s; + path = environ ? __getenv(environ, "KPRINTF_LOG").s : 0; closefd = false; if (!path) { fd = STDERR_FILENO; diff --git a/libc/intrin/pthread_mutex_lock.c b/libc/intrin/pthread_mutex_lock.c index d61b5c9b8..01ca6cb0e 100644 --- a/libc/intrin/pthread_mutex_lock.c +++ b/libc/intrin/pthread_mutex_lock.c @@ -22,7 +22,6 @@ #include "libc/intrin/atomic.h" #include "libc/intrin/strace.internal.h" #include "libc/intrin/weaken.h" -#include "libc/nexgen32e/yield.h" #include "libc/runtime/internal.h" #include "libc/thread/thread.h" #include "libc/thread/tls.h" @@ -83,7 +82,7 @@ errno_t pthread_mutex_lock(pthread_mutex_t *mutex) { if (mutex->_type == PTHREAD_MUTEX_NORMAL) { while (atomic_exchange_explicit(&mutex->_lock, 1, memory_order_acquire)) { - spin_yield(); + pthread_pause_np(); } return 0; } @@ -103,7 +102,7 @@ errno_t pthread_mutex_lock(pthread_mutex_t *mutex) { } while (atomic_exchange_explicit(&mutex->_lock, 1, memory_order_acquire)) { - spin_yield(); + pthread_pause_np(); } mutex->_depth = 0; diff --git a/libc/intrin/pthread_next.c b/libc/intrin/pthread_next.c index 59f906a35..82d0d46d3 100644 --- a/libc/intrin/pthread_next.c +++ b/libc/intrin/pthread_next.c @@ -19,8 +19,8 @@ #include "libc/assert.h" #include "libc/dce.h" #include "libc/intrin/atomic.h" -#include "libc/nexgen32e/yield.h" #include "libc/thread/posixthread.internal.h" +#include "libc/thread/thread.h" intptr_t _pthread_syshand(struct PosixThread *pt) { intptr_t syshand; @@ -28,6 +28,6 @@ intptr_t _pthread_syshand(struct PosixThread *pt) { for (;;) { syshand = atomic_load_explicit(&pt->tib->tib_syshand, memory_order_acquire); if (syshand) return syshand; - spin_yield(); + pthread_pause_np(); } } diff --git a/libc/intrin/pthread_tid.c b/libc/intrin/pthread_tid.c index 726e46436..4f1a8b16e 100644 --- a/libc/intrin/pthread_tid.c +++ b/libc/intrin/pthread_tid.c @@ -17,13 +17,13 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/intrin/atomic.h" -#include "libc/nexgen32e/yield.h" #include "libc/thread/posixthread.internal.h" +#include "libc/thread/thread.h" int _pthread_tid(struct PosixThread *pt) { int tid = 0; while (pt && !(tid = atomic_load_explicit(&pt->ptid, memory_order_acquire))) { - spin_yield(); + pthread_pause_np(); } return tid; } diff --git a/libc/intrin/strace.internal.h b/libc/intrin/strace.internal.h index 92cc9101e..5ad187324 100644 --- a/libc/intrin/strace.internal.h +++ b/libc/intrin/strace.internal.h @@ -1,7 +1,9 @@ #ifndef COSMOPOLITAN_LIBC_CALLS_STRACE_INTERNAL_H_ #define COSMOPOLITAN_LIBC_CALLS_STRACE_INTERNAL_H_ -#include "libc/intrin/likely.h" -#include "libc/runtime/runtime.h" + +#ifndef SYSDEBUG +#define SYSDEBUG 1 +#endif #define _NTTRACE 0 /* not configurable w/ flag yet */ #define _POLLTRACE 0 /* not configurable w/ flag yet */ @@ -16,60 +18,40 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -#ifdef SYSDEBUG -#define STRACE(FMT, ...) \ - do { \ - if (UNLIKELY(strace_enter())) { \ - __stracef(STRACE_PROLOGUE FMT "\n", ##__VA_ARGS__); \ - ftrace_enabled(+1); \ - } \ - } while (0) -#else -#define STRACE(FMT, ...) (void)0 -#endif +#define STRACE(FMT, ...) \ + ((void)(SYSDEBUG && strace_enabled(0) > 0 && \ + (__stracef(STRACE_PROLOGUE FMT "\n", ##__VA_ARGS__), 0))) -#if defined(SYSDEBUG) && _DATATRACE -#define DATATRACE(FMT, ...) STRACE(FMT, ##__VA_ARGS__) -#else -#define DATATRACE(FMT, ...) (void)0 -#endif +#define DATATRACE(FMT, ...) \ + ((void)(SYSDEBUG && _DATATRACE && strace_enabled(0) > 0 && \ + (__stracef(STRACE_PROLOGUE FMT "\n", ##__VA_ARGS__), 0))) -#if defined(SYSDEBUG) && _POLLTRACE -#define POLLTRACE(FMT, ...) STRACE(FMT, ##__VA_ARGS__) -#else -#define POLLTRACE(FMT, ...) (void)0 -#endif +#define POLLTRACE(FMT, ...) \ + ((void)(SYSDEBUG && _POLLTRACE && strace_enabled(0) > 0 && \ + (__stracef(STRACE_PROLOGUE FMT "\n", ##__VA_ARGS__), 0))) -#if defined(SYSDEBUG) && _KERNTRACE -#define KERNTRACE(FMT, ...) STRACE(FMT, ##__VA_ARGS__) -#else -#define KERNTRACE(FMT, ...) (void)0 -#endif +#define KERNTRACE(FMT, ...) \ + ((void)(SYSDEBUG && _KERNTRACE && strace_enabled(0) > 0 && \ + (__stracef(STRACE_PROLOGUE FMT "\n", ##__VA_ARGS__), 0))) -#if defined(SYSDEBUG) && _STDIOTRACE -#define STDIOTRACE(FMT, ...) STRACE(FMT, ##__VA_ARGS__) -#else -#define STDIOTRACE(FMT, ...) (void)0 -#endif +#define STDIOTRACE(FMT, ...) \ + ((void)(SYSDEBUG && _STDIOTRACE && strace_enabled(0) > 0 && \ + (__stracef(STRACE_PROLOGUE FMT "\n", ##__VA_ARGS__), 0))) -#if defined(SYSDEBUG) && _NTTRACE -#define NTTRACE(FMT, ...) STRACE("\e[2m" FMT "\e[0m", ##__VA_ARGS__) -#else -#define NTTRACE(FMT, ...) (void)0 -#endif +#define NTTRACE(FMT, ...) \ + ((void)(SYSDEBUG && _NTTRACE && strace_enabled(0) > 0 && \ + (__stracef(STRACE_PROLOGUE "\e[2m" FMT "\e[0m\n", ##__VA_ARGS__), \ + 0))) -#if defined(SYSDEBUG) && _LOCKTRACE -#define LOCKTRACE(FMT, ...) STRACE(FMT, ##__VA_ARGS__) -#else -#define LOCKTRACE(FMT, ...) (void)0 -#endif +#define LOCKTRACE(FMT, ...) \ + ((void)(SYSDEBUG && _LOCKTRACE && strace_enabled(0) > 0 && \ + (__stracef(STRACE_PROLOGUE FMT "\n", ##__VA_ARGS__), 0))) -#if defined(SYSDEBUG) && _TIMETRACE -#define TIMETRACE(FMT, ...) STRACE(FMT, ##__VA_ARGS__) -#else -#define TIMETRACE(FMT, ...) (void)0 -#endif +#define TIMETRACE(FMT, ...) \ + ((void)(SYSDEBUG && _TIMETRACE && strace_enabled(0) > 0 && \ + (__stracef(STRACE_PROLOGUE FMT "\n", ##__VA_ARGS__), 0))) +int strace_enabled(int); void __stracef(const char *, ...); COSMOPOLITAN_C_END_ diff --git a/libc/intrin/strace_enabled.c b/libc/intrin/strace_enabled.c index e3783b36c..a04d3d6c1 100644 --- a/libc/intrin/strace_enabled.c +++ b/libc/intrin/strace_enabled.c @@ -25,7 +25,7 @@ * @param delta is added to enabled state * @return enabled state before `delta` was applied */ -dontinstrument int strace_enabled(int delta) { +dontinstrument int(strace_enabled)(int delta) { int res; struct CosmoTib *tib; if (__tls_enabled) { diff --git a/libc/intrin/strace_enter.c b/libc/intrin/strace_enter.c deleted file mode 100644 index 64e4c9e59..000000000 --- a/libc/intrin/strace_enter.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 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/runtime/runtime.h" -#ifdef SYSDEBUG - -dontinstrument bool strace_enter(void) { - if (strace_enabled(0) > 0) { - ftrace_enabled(-1); - return true; - } else { - return false; - } -} - -#endif /* SYSDEBUG */ diff --git a/libc/intrin/stracef.greg.c b/libc/intrin/stracef.greg.c index 874bd9ce1..4dadf3375 100644 --- a/libc/intrin/stracef.greg.c +++ b/libc/intrin/stracef.greg.c @@ -19,15 +19,10 @@ #include "libc/intrin/kprintf.h" #include "libc/intrin/strace.internal.h" #include "libc/runtime/runtime.h" -#include "libc/thread/tls.h" -#include "libc/thread/tls2.internal.h" -privileged void __stracef(const char *fmt, ...) { +dontinstrument void __stracef(const char *fmt, ...) { va_list v; - if (__strace <= 0 || - (__tls_enabled && __get_tls_privileged()->tib_strace <= 0)) { - return; - } + if (strace_enabled(0) <= 0) return; va_start(v, fmt); kvprintf(fmt, v); va_end(v); diff --git a/libc/nexgen32e/yield.h b/libc/nexgen32e/yield.h old mode 100644 new mode 100755 index 221b70ece..e69de29bb --- a/libc/nexgen32e/yield.h +++ b/libc/nexgen32e/yield.h @@ -1,16 +0,0 @@ -#ifndef COSMOPOLITAN_LIBC_YIELD_H_ -#define COSMOPOLITAN_LIBC_YIELD_H_ -#if !(__ASSEMBLER__ + __LINKER__ + 0) -#ifdef _COSMO_SOURCE - -static inline void spin_yield(void) { -#if defined(__GNUC__) && defined(__aarch64__) - __asm__ volatile("yield"); -#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) - __asm__ volatile("pause"); -#endif -} - -#endif /* _COSMO_SOURCE */ -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ -#endif /* COSMOPOLITAN_LIBC_YIELD_H_ */ diff --git a/libc/proc/execve.c b/libc/proc/execve.c index 586c71ead..a90d934e7 100644 --- a/libc/proc/execve.c +++ b/libc/proc/execve.c @@ -29,6 +29,7 @@ #include "libc/intrin/strace.internal.h" #include "libc/intrin/weaken.h" #include "libc/log/libfatal.internal.h" +#include "libc/runtime/runtime.h" #include "libc/runtime/zipos.internal.h" #include "libc/sysv/consts/o.h" #include "libc/sysv/errfuns.h" diff --git a/libc/proc/fork-nt.c b/libc/proc/fork-nt.c index 1be406dd1..61aec9c0d 100644 --- a/libc/proc/fork-nt.c +++ b/libc/proc/fork-nt.c @@ -58,7 +58,7 @@ #include "libc/thread/tls.h" #ifdef __x86_64__ -void __keystroke_wipe(void); +void WipeKeystrokes(void); static textwindows wontreturn void AbortFork(const char *func) { #ifdef SYSDEBUG @@ -310,9 +310,9 @@ textwindows int sys_fork_nt(uint32_t dwCreationFlags) { bzero(&startinfo, sizeof(startinfo)); startinfo.cb = sizeof(struct NtStartupInfo); startinfo.dwFlags = kNtStartfUsestdhandles; - startinfo.hStdInput = __getfdhandleactual(0); - startinfo.hStdOutput = __getfdhandleactual(1); - startinfo.hStdError = __getfdhandleactual(2); + startinfo.hStdInput = g_fds.p[0].handle; + startinfo.hStdOutput = g_fds.p[1].handle; + startinfo.hStdError = g_fds.p[2].handle; args = __argv; #ifdef SYSDEBUG // If --strace was passed to this program, then propagate it the @@ -395,7 +395,7 @@ textwindows int sys_fork_nt(uint32_t dwCreationFlags) { } // reset core runtime services __proc_wipe(); - __keystroke_wipe(); + WipeKeystrokes(); if (_weaken(__itimer_wipe)) { _weaken(__itimer_wipe)(); } diff --git a/libc/proc/fork.c b/libc/proc/fork.c index ac69bbd0c..87fb1c75f 100644 --- a/libc/proc/fork.c +++ b/libc/proc/fork.c @@ -44,7 +44,6 @@ int _fork(uint32_t dwCreationFlags) { struct Dll *e; int ax, dx, tid, parent; parent = __pid; - (void)parent; BLOCK_SIGNALS; if (IsWindows()) __proc_lock(); if (__threaded && _weaken(_pthread_onfork_prepare)) { diff --git a/libc/proc/proc.c b/libc/proc/proc.c index 10a8a80ee..2449927ad 100644 --- a/libc/proc/proc.c +++ b/libc/proc/proc.c @@ -269,10 +269,9 @@ textwindows void __proc_wipe(void) { textwindows struct Proc *__proc_new(void) { struct Dll *e; struct Proc *proc = 0; - int i, n = ARRAYLEN(__proc.pool); - if (atomic_load_explicit(&__proc.allocated, memory_order_acquire) < n && - (i = atomic_fetch_add(&__proc.allocated, 1)) < n) { - proc = __proc.pool + i; + // fork() + wait() don't depend on malloc() so neither shall we + if (__proc.allocated < ARRAYLEN(__proc.pool)) { + proc = __proc.pool + __proc.allocated++; } else { if ((e = dll_first(__proc.free))) { proc = PROC_CONTAINER(e); diff --git a/libc/runtime/runtime.h b/libc/runtime/runtime.h index 9417c9f48..be91f9b8a 100644 --- a/libc/runtime/runtime.h +++ b/libc/runtime/runtime.h @@ -91,7 +91,6 @@ void ShowCrashReports(void); int ftrace_install(void); int ftrace_enabled(int); int strace_enabled(int); -bool strace_enter(void); void __print_maps(void); void __printargs(const char *); /* builtin sh-like system/popen dsl */ @@ -139,10 +138,10 @@ __funline int __trace_disabled(int x) { return 0; } #ifndef FTRACE -#define ftrace_enabled __trace_disabled +#define ftrace_enabled(...) __trace_disabled(__VA_ARGS__) #endif #ifndef SYSDEBUG -#define strace_enabled __trace_disabled +#define strace_enabled(...) __trace_disabled(__VA_ARGS__) #endif #endif /* _COSMO_SOURCE */ diff --git a/libc/runtime/zipos-get.c b/libc/runtime/zipos-get.c index 397fc5e12..0a2385a32 100644 --- a/libc/runtime/zipos-get.c +++ b/libc/runtime/zipos-get.c @@ -152,7 +152,6 @@ static void __zipos_init(void) { progpath = 0; msg = -777; } - (void)msg; STRACE("__zipos_get(%#s) → %d% m", progpath, msg); } diff --git a/libc/sock/kntwsadata.c b/libc/sock/kntwsadata.c index 660819021..d8456aa24 100644 --- a/libc/sock/kntwsadata.c +++ b/libc/sock/kntwsadata.c @@ -38,7 +38,6 @@ struct NtWsaData kNtWsaData; static textwindows void WinSockCleanup(void) { int rc; - (void)rc; rc = WSACleanup(); NTTRACE("WSACleanup() → %d% lm", rc); } diff --git a/libc/sock/sendmsg.c b/libc/sock/sendmsg.c index 280ec1854..be3033c81 100644 --- a/libc/sock/sendmsg.c +++ b/libc/sock/sendmsg.c @@ -27,6 +27,7 @@ #include "libc/intrin/describeflags.internal.h" #include "libc/intrin/kprintf.h" #include "libc/intrin/strace.internal.h" +#include "libc/runtime/runtime.h" #include "libc/sock/internal.h" #include "libc/sock/sock.h" #include "libc/sock/struct/msghdr.h" @@ -87,7 +88,8 @@ ssize_t sendmsg(int fd, const struct msghdr *msg, int flags) { END_CANCELATION_POINT; #if defined(SYSDEBUG) && _DATATRACE - if (__strace > 0 && strace_enabled(0) > 0) { + // TODO(jart): Write a DescribeMsg() function. + if (strace_enabled(0) > 0) { kprintf(STRACE_PROLOGUE "sendmsg("); if ((!IsAsan() && kisdangerous(msg)) || (IsAsan() && !__asan_is_valid(msg, sizeof(*msg)))) { diff --git a/libc/stdio/fread.c b/libc/stdio/fread.c index ee82f8275..58564cd46 100644 --- a/libc/stdio/fread.c +++ b/libc/stdio/fread.c @@ -19,7 +19,7 @@ #include "libc/intrin/describeflags.internal.h" #include "libc/intrin/strace.internal.h" #include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" +#include "libc/stdio/internal.h" /** * Reads data from stream. diff --git a/libc/stdio/fseek.c b/libc/stdio/fseek.c index 0da8e521b..b29f7cfd5 100644 --- a/libc/stdio/fseek.c +++ b/libc/stdio/fseek.c @@ -18,7 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/intrin/describeflags.internal.h" #include "libc/intrin/strace.internal.h" -#include "libc/stdio/stdio.h" +#include "libc/stdio/internal.h" /** * Repositions open file stream. diff --git a/libc/stdio/fwrite.c b/libc/stdio/fwrite.c index 7888be1b7..972b92508 100644 --- a/libc/stdio/fwrite.c +++ b/libc/stdio/fwrite.c @@ -18,7 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/intrin/describeflags.internal.h" #include "libc/intrin/strace.internal.h" -#include "libc/stdio/stdio.h" +#include "libc/stdio/internal.h" /** * Writes data to stream. diff --git a/libc/stdio/stdio.mk b/libc/stdio/stdio.mk index fb67da936..d18ea53b6 100644 --- a/libc/stdio/stdio.mk +++ b/libc/stdio/stdio.mk @@ -8,6 +8,7 @@ LIBC_STDIO = $(LIBC_STDIO_A_DEPS) $(LIBC_STDIO_A) LIBC_STDIO_A = o/$(MODE)/libc/stdio/stdio.a LIBC_STDIO_A_FILES := $(wildcard libc/stdio/*) LIBC_STDIO_A_HDRS = $(filter %.h,$(LIBC_STDIO_A_FILES)) +LIBC_STDIO_A_INCS = $(filter %.inc,$(LIBC_STDIO_A_FILES)) LIBC_STDIO_A_SRCS_S = $(filter %.S,$(LIBC_STDIO_A_FILES)) LIBC_STDIO_A_SRCS_C = $(filter %.c,$(LIBC_STDIO_A_FILES)) @@ -68,6 +69,7 @@ o/$(MODE)/libc/stdio/mt19937.o: private \ LIBC_STDIO_LIBS = $(foreach x,$(LIBC_STDIO_ARTIFACTS),$($(x))) LIBC_STDIO_SRCS = $(foreach x,$(LIBC_STDIO_ARTIFACTS),$($(x)_SRCS)) LIBC_STDIO_HDRS = $(foreach x,$(LIBC_STDIO_ARTIFACTS),$($(x)_HDRS)) +LIBC_STDIO_INCS = $(foreach x,$(LIBC_STDIO_ARTIFACTS),$($(x)_INCS)) LIBC_STDIO_CHECKS = $(foreach x,$(LIBC_STDIO_ARTIFACTS),$($(x)_CHECKS)) LIBC_STDIO_OBJS = $(foreach x,$(LIBC_STDIO_ARTIFACTS),$($(x)_OBJS)) $(LIBC_STDIO_OBJS): $(BUILD_FILES) libc/stdio/stdio.mk diff --git a/libc/sysv/systemfive.S b/libc/sysv/systemfive.S index 978c448db..cb489d966 100644 --- a/libc/sysv/systemfive.S +++ b/libc/sysv/systemfive.S @@ -399,7 +399,9 @@ _init_systemfive_magnums: jz 5f ezlea .Llog,di mov %r8d,%esi + push %rax call *%rax + pop %rax 5: pop %rsi pop %rdi #endif /* DEBUGSYS */ diff --git a/libc/testlib/testmain.c b/libc/testlib/testmain.c index ccec6f593..676140eda 100644 --- a/libc/testlib/testmain.c +++ b/libc/testlib/testmain.c @@ -33,6 +33,7 @@ #include "libc/log/log.h" #include "libc/macros.internal.h" #include "libc/mem/mem.h" +#include "libc/nexgen32e/nexgen32e.h" #include "libc/runtime/runtime.h" #include "libc/runtime/symbols.internal.h" #include "libc/str/str.h" @@ -122,6 +123,7 @@ dontasan int main(int argc, char *argv[]) { } // run tests + CheckStackIsAligned(); testlib_runalltests(); // run benchmarks diff --git a/libc/testlib/testrunner.c b/libc/testlib/testrunner.c index f30eaafe8..7ffaf918b 100644 --- a/libc/testlib/testrunner.c +++ b/libc/testlib/testrunner.c @@ -91,8 +91,10 @@ void testlib_runtestcases(const testfn_t *start, const testfn_t *end, // the linker sorts into an array. char host[64]; struct Dll *e; + const char *user; const testfn_t *fn; struct TestAspect *a; + user = getenv("USER"); strcpy(host, "unknown"); gethostname(host, sizeof(host)), errno = 0; for (fn = start; fn != end; ++fn) { @@ -111,7 +113,7 @@ void testlib_runtestcases(const testfn_t *start, const testfn_t *end, if (warmup) warmup(); testlib_clearxmmregisters(); STRACE(""); - STRACE("# running test %t on %s@%s", fn, __getenv(environ, "USER").s, host); + STRACE("# running test %t on %s@%s", fn, user, host); (*fn)(); STRACE(""); STRACE("# tearing down %t", fn); diff --git a/libc/thread/thread.h b/libc/thread/thread.h index c15383111..068b3d42e 100644 --- a/libc/thread/thread.h +++ b/libc/thread/thread.h @@ -213,6 +213,14 @@ void pthread_testcancel(void); pthread_cleanup_pop(&_buffer, (execute)); \ } +#if defined(__GNUC__) && defined(__aarch64__) +#define pthread_pause_np() __asm__ volatile("yield") +#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__)) +#define pthread_pause_np() __asm__ volatile("pause") +#else +#define pthread_pause_np() (void)0 +#endif + #if (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 407 && \ !defined(__STRICT_ANSI__) && !defined(MODE_DBG) extern const errno_t EBUSY; @@ -220,6 +228,7 @@ extern const errno_t EBUSY; ({ \ pthread_spinlock_t *_s = pSpin; \ while (__atomic_test_and_set(&_s->_lock, __ATOMIC_ACQUIRE)) { \ + pthread_pause_np(); \ } \ 0; \ }) diff --git a/test/libc/stdio/test.mk b/test/libc/stdio/test.mk index 7d83a8de1..9c41ebdbd 100644 --- a/test/libc/stdio/test.mk +++ b/test/libc/stdio/test.mk @@ -3,7 +3,9 @@ PKGS += TEST_LIBC_STDIO -TEST_LIBC_STDIO_SRCS := $(wildcard test/libc/stdio/*.c) +TEST_LIBC_STDIO_FILES := $(wildcard test/libc/stdio/*) +TEST_LIBC_STDIO_SRCS = $(filter %.c,$(TEST_LIBC_STDIO_FILES)) +TEST_LIBC_STDIO_INCS = $(filter %.inc,$(TEST_LIBC_STDIO_FILES)) TEST_LIBC_STDIO_SRCS_TEST = $(filter %_test.c,$(TEST_LIBC_STDIO_SRCS)) TEST_LIBC_STDIO_OBJS = \ diff --git a/third_party/dlmalloc/dlmalloc.c b/third_party/dlmalloc/dlmalloc.c index bee028cfd..7f9f738f8 100644 --- a/third_party/dlmalloc/dlmalloc.c +++ b/third_party/dlmalloc/dlmalloc.c @@ -11,7 +11,6 @@ #include "libc/macros.internal.h" #include "libc/mem/mem.h" #include "libc/nexgen32e/rdtsc.h" -#include "libc/nexgen32e/yield.h" #include "libc/runtime/internal.h" #include "libc/runtime/runtime.h" #include "libc/runtime/sysconf.h" diff --git a/third_party/dlmalloc/locks.inc b/third_party/dlmalloc/locks.inc index ee73aa2e9..15313b7b0 100644 --- a/third_party/dlmalloc/locks.inc +++ b/third_party/dlmalloc/locks.inc @@ -45,7 +45,7 @@ static int malloc_lock(MLOCK_T *lk) { if (!__threaded) return 0; #ifdef TINY while (atomic_exchange_explicit(lk, 1, memory_order_acquire)) { - spin_yield(); + pthread_pause_np(); } #else nsync_mu_lock(lk); diff --git a/third_party/double-conversion/test/checks.h b/third_party/double-conversion/test/checks.h index cbf90a43b..6314ae8c8 100644 --- a/third_party/double-conversion/test/checks.h +++ b/third_party/double-conversion/test/checks.h @@ -26,7 +26,7 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef V8_CHECKS_H_ #define V8_CHECKS_H_ -#include "third_party/double-conversion/test/flags.h" +//#include "third_party/double-conversion/test/flags.h" // clang-format off extern "C" void V8_Fatal(const char* file, int line, const char* format, ...); diff --git a/third_party/libcxx/__functional_base b/third_party/libcxx/__functional_base index cb7ddda5c..a6b69b084 100644 --- a/third_party/libcxx/__functional_base +++ b/third_party/libcxx/__functional_base @@ -303,7 +303,7 @@ struct __invoke_return #else // defined(_LIBCPP_CXX03_LANG) -#include "third_party/libcxx/__functional_base_03" +//#include "third_party/libcxx/__functional_base_03" #endif // !defined(_LIBCPP_CXX03_LANG) diff --git a/third_party/libcxx/__functional_base_03 b/third_party/libcxx/__functional_base_03 deleted file mode 100644 index e6dac90c8..000000000 --- a/third_party/libcxx/__functional_base_03 +++ /dev/null @@ -1,223 +0,0 @@ -// -*- C++ -*- -//===----------------------------------------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef _LIBCPP_FUNCTIONAL_BASE_03 -#define _LIBCPP_FUNCTIONAL_BASE_03 - -// manual variadic expansion for - -// __invoke - -template -struct __enable_invoke_imp; - -template -struct __enable_invoke_imp<_Ret, _T1, true, true> { - typedef _Ret _Bullet1; - typedef _Bullet1 type; -}; - -template -struct __enable_invoke_imp<_Ret, _T1, true, false> { - typedef _Ret _Bullet2; - typedef _Bullet2 type; -}; - -template -struct __enable_invoke_imp<_Ret, _T1, false, true> { - typedef typename add_lvalue_reference< - typename __apply_cv<_T1, _Ret>::type - >::type _Bullet3; - typedef _Bullet3 type; -}; - -template -struct __enable_invoke_imp<_Ret, _T1, false, false> { - typedef typename add_lvalue_reference< - typename __apply_cv()), _Ret>::type - >::type _Bullet4; - typedef _Bullet4 type; -}; - -template -struct __enable_invoke_imp<_Ret, _T1*, false, false> { - typedef typename add_lvalue_reference< - typename __apply_cv<_T1, _Ret>::type - >::type _Bullet4; - typedef _Bullet4 type; -}; - -template , - class _Ret = typename _Traits::_ReturnType, - class _Class = typename _Traits::_ClassType> -struct __enable_invoke : __enable_invoke_imp< - _Ret, _T1, - is_member_function_pointer<_Fn>::value, - is_base_of<_Class, typename remove_reference<_T1>::type>::value> -{ -}; - -__nat __invoke(__any, ...); - -// first bullet - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet1 -__invoke(_Fn __f, _T1& __t1) { - return (__t1.*__f)(); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet1 -__invoke(_Fn __f, _T1& __t1, _A0& __a0) { - return (__t1.*__f)(__a0); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet1 -__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) { - return (__t1.*__f)(__a0, __a1); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet1 -__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) { - return (__t1.*__f)(__a0, __a1, __a2); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet2 -__invoke(_Fn __f, _T1& __t1) { - return ((*__t1).*__f)(); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet2 -__invoke(_Fn __f, _T1& __t1, _A0& __a0) { - return ((*__t1).*__f)(__a0); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet2 -__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) { - return ((*__t1).*__f)(__a0, __a1); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet2 -__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) { - return ((*__t1).*__f)(__a0, __a1, __a2); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet3 -__invoke(_Fn __f, _T1& __t1) { - return __t1.*__f; -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __enable_invoke<_Fn, _T1>::_Bullet4 -__invoke(_Fn __f, _T1& __t1) { - return (*__t1).*__f; -} - -// fifth bullet - -template -inline _LIBCPP_INLINE_VISIBILITY -decltype(_VSTD::declval<_Fp&>()()) -__invoke(_Fp& __f) -{ - return __f(); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>())) -__invoke(_Fp& __f, _A0& __a0) -{ - return __f(__a0); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>())) -__invoke(_Fp& __f, _A0& __a0, _A1& __a1) -{ - return __f(__a0, __a1); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>(), _VSTD::declval<_A2&>())) -__invoke(_Fp& __f, _A0& __a0, _A1& __a1, _A2& __a2) -{ - return __f(__a0, __a1, __a2); -} - -template >::value> -struct __invoke_return -{ - typedef typename __weak_result_type<_Fp>::result_type type; -}; - -template -struct __invoke_return<_Fp, false> -{ - typedef decltype(__invoke(_VSTD::declval<_Fp&>())) type; -}; - -template -struct __invoke_return0 -{ - typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>())) type; -}; - -template -struct __invoke_return0<_Rp _Tp::*, _A0> -{ - typedef typename __enable_invoke<_Rp _Tp::*, _A0>::type type; -}; - -template -struct __invoke_return1 -{ - typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(), - _VSTD::declval<_A1&>())) type; -}; - -template -struct __invoke_return1<_Rp _Class::*, _A0, _A1> { - typedef typename __enable_invoke<_Rp _Class::*, _A0>::type type; -}; - -template -struct __invoke_return2 -{ - typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(), - _VSTD::declval<_A1&>(), - _VSTD::declval<_A2&>())) type; -}; - -template -struct __invoke_return2<_Ret _Class::*, _A0, _A1, _A2> { - typedef typename __enable_invoke<_Ret _Class::*, _A0>::type type; -}; -#endif // _LIBCPP_FUNCTIONAL_BASE_03 diff --git a/third_party/libcxx/__locale b/third_party/libcxx/__locale index 7e2d0c88a..e0ff7ab79 100644 --- a/third_party/libcxx/__locale +++ b/third_party/libcxx/__locale @@ -18,29 +18,6 @@ #include "third_party/libcxx/cstdint" #include "third_party/libcxx/cctype" #include "third_party/libcxx/locale.h" -#if defined(_LIBCPP_MSVCRT_LIKE) -# include "third_party/libcxx/cstring" -# include "third_party/libcxx/support/win32/locale_win32.h" -#elif defined(_AIX) -# include "third_party/libcxx/support/ibm/xlocale.h" -#elif defined(__ANDROID__) -# include "third_party/libcxx/support/android/locale_bionic.h" -#elif defined(__sun__) -# include "third_party/libcxx/xlocale.h" -# include "third_party/libcxx/support/solaris/xlocale.h" -#elif defined(_NEWLIB_VERSION) -# include "third_party/libcxx/support/newlib/xlocale.h" -#elif (defined(__APPLE__) || defined(__FreeBSD__) \ - || defined(__EMSCRIPTEN__) || defined(__IBMCPP__)) -# include "third_party/libcxx/xlocale.h" -#elif defined(__Fuchsia__) -# include "third_party/libcxx/support/fuchsia/xlocale.h" -#elif defined(__wasi__) -// WASI libc uses musl's locales support. -# include "third_party/libcxx/support/musl/xlocale.h" -#elif defined(_LIBCPP_HAS_MUSL_LIBC) -# include "third_party/libcxx/support/musl/xlocale.h" -#endif #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header diff --git a/third_party/libcxx/__threading_support b/third_party/libcxx/__threading_support index 52ba3a9eb..f21862c22 100644 --- a/third_party/libcxx/__threading_support +++ b/third_party/libcxx/__threading_support @@ -22,7 +22,7 @@ #endif #if defined(_LIBCPP_HAS_THREAD_API_EXTERNAL) -# include "third_party/libcxx/__external_threading" +//# include "third_party/libcxx/__external_threading" #elif !defined(_LIBCPP_HAS_NO_THREADS) #if defined(_LIBCPP_HAS_THREAD_API_PTHREAD) diff --git a/third_party/libcxx/algorithm b/third_party/libcxx/algorithm index bf8f3b9f1..505c4238e 100644 --- a/third_party/libcxx/algorithm +++ b/third_party/libcxx/algorithm @@ -23,7 +23,7 @@ #include "third_party/libcxx/version" #if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17 -# include "third_party/libcxx/__pstl_algorithm" +//# include "third_party/libcxx/__pstl_algorithm" #endif #include "third_party/libcxx/__debug" diff --git a/third_party/libcxx/execution b/third_party/libcxx/execution index c9ef9edde..f497d122e 100644 --- a/third_party/libcxx/execution +++ b/third_party/libcxx/execution @@ -14,7 +14,7 @@ #include "third_party/libcxx/__config" #if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17 -# include "third_party/libcxx/__pstl_execution" +//# include "third_party/libcxx/__pstl_execution" #endif #endif // _LIBCPP_EXECUTION diff --git a/third_party/libcxx/functional b/third_party/libcxx/functional index ff98a20e3..5b191efba 100644 --- a/third_party/libcxx/functional +++ b/third_party/libcxx/functional @@ -2528,7 +2528,7 @@ swap(function<_Rp(_ArgTypes...)>& __x, function<_Rp(_ArgTypes...)>& __y) _NOEXCE #else // _LIBCPP_CXX03_LANG -# include "third_party/libcxx/__functional_03" +//# include "third_party/libcxx/__functional_03" #endif diff --git a/third_party/libcxx/locale b/third_party/libcxx/locale index bef8d232f..9a47138ab 100644 --- a/third_party/libcxx/locale +++ b/third_party/libcxx/locale @@ -26,11 +26,11 @@ #include "third_party/libcxx/cstdio" #ifdef _LIBCPP_HAS_CATOPEN # include "libc/str/locale.h" -# include "third_party/libcxx/nl_types.h" +//# include "third_party/libcxx/nl_types.h" #endif #ifdef _LIBCPP_LOCALE__L_EXTENSIONS -# include "third_party/libcxx/__bsd_locale_defaults.h" +//# include "third_party/libcxx/__bsd_locale_defaults.h" #else #include "third_party/libcxx/__bsd_locale_fallbacks.h" #endif diff --git a/third_party/libcxx/memory b/third_party/libcxx/memory index a1634471c..60205548b 100644 --- a/third_party/libcxx/memory +++ b/third_party/libcxx/memory @@ -5364,7 +5364,7 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS #if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17 -# include "third_party/libcxx/__pstl_memory" +//# include "third_party/libcxx/__pstl_memory" #endif #endif // _LIBCPP_MEMORY diff --git a/third_party/libcxx/numeric b/third_party/libcxx/numeric index 554eef98c..01a268b7a 100644 --- a/third_party/libcxx/numeric +++ b/third_party/libcxx/numeric @@ -587,7 +587,7 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS #if defined(_LIBCPP_HAS_PARALLEL_ALGORITHMS) && _LIBCPP_STD_VER >= 17 -# include "third_party/libcxx/__pstl_numeric" +//# include "third_party/libcxx/__pstl_numeric" #endif #endif // _LIBCPP_NUMERIC diff --git a/third_party/lua/lua.mk b/third_party/lua/lua.mk index 8abd0148d..494483b9e 100644 --- a/third_party/lua/lua.mk +++ b/third_party/lua/lua.mk @@ -63,6 +63,10 @@ THIRD_PARTY_LUA_A_HDRS = \ third_party/lua/tms.h \ third_party/lua/visitor.h +THIRD_PARTY_LUA_A_INCS = \ + third_party/lua/ljumptab.inc \ + third_party/lua/lopnames.inc + THIRD_PARTY_LUA_A_SRCS = \ third_party/lua/lapi.c \ third_party/lua/lauxlib.c \ @@ -294,6 +298,7 @@ THIRD_PARTY_LUA_SRCS = \ THIRD_PARTY_LUA_LIBS = $(foreach x,$(THIRD_PARTY_LUA_ARTIFACTS),$($(x))) THIRD_PARTY_LUA_HDRS = $(foreach x,$(THIRD_PARTY_LUA_ARTIFACTS),$($(x)_HDRS)) +THIRD_PARTY_LUA_INCS = $(foreach x,$(THIRD_PARTY_LUA_ARTIFACTS),$($(x)_INCS)) THIRD_PARTY_LUA_OBJS = $(foreach x,$(THIRD_PARTY_LUA_ARTIFACTS),$($(x)_OBJS)) $(THIRD_PARTY_LUA_OBJS): third_party/lua/lua.mk diff --git a/third_party/python/python.mk b/third_party/python/python.mk index fba778e6f..dcaf2d867 100644 --- a/third_party/python/python.mk +++ b/third_party/python/python.mk @@ -297,6 +297,7 @@ THIRD_PARTY_PYTHON_INCS = \ third_party/python/Modules/clinic/_pickle.inc \ third_party/python/Modules/clinic/cmathmodule.inc \ third_party/python/Modules/clinic/_elementtree.inc \ + third_party/python/Modules/clinic/_struct.inc \ third_party/python/Modules/clinic/pwdmodule.inc \ third_party/python/Modules/clinic/audioop.inc diff --git a/third_party/sqlite3/.clang-format b/third_party/sqlite3/.clang-format new file mode 100644 index 000000000..47a38a93f --- /dev/null +++ b/third_party/sqlite3/.clang-format @@ -0,0 +1,2 @@ +DisableFormat: true +SortIncludes: Never diff --git a/third_party/sqlite3/fts3_tokenizer.c b/third_party/sqlite3/fts3_tokenizer.c index 769407108..fbd251957 100644 --- a/third_party/sqlite3/fts3_tokenizer.c +++ b/third_party/sqlite3/fts3_tokenizer.c @@ -227,9 +227,9 @@ int sqlite3Fts3InitTokenizer( #ifdef SQLITE_TEST #if defined(INCLUDE_SQLITE_TCL_H) -# include "sqlite_tcl.h" +//# include "sqlite_tcl.h" #else -# include "tcl.h" +//# include "tcl.h" #endif #include diff --git a/third_party/sqlite3/sqliteInt.h b/third_party/sqlite3/sqliteInt.h index e5607827d..a6a511f85 100644 --- a/third_party/sqlite3/sqliteInt.h +++ b/third_party/sqlite3/sqliteInt.h @@ -165,9 +165,9 @@ ** disabled. */ #if defined(_HAVE_MINGW_H) -# include "mingw.h" +//# include "mingw.h" #elif defined(_HAVE__MINGW_H) -# include "_mingw.h" +//# include "_mingw.h" #endif /* diff --git a/third_party/unzip/fileio.c b/third_party/unzip/fileio.c index 6a447eaf1..354d5a600 100644 --- a/third_party/unzip/fileio.c +++ b/third_party/unzip/fileio.c @@ -67,10 +67,6 @@ #define st_mtime st_mtim.tv_sec -#if defined( UNIX) && defined( __APPLE__) -#include "third_party/unzip/unix/macosx.h" -#endif /* defined( UNIX) && defined( __APPLE__) */ - /* setup of codepage conversion for decryption passwords */ #if CRYPT # if (defined(CRYP_USES_ISO2OEM) && !defined(IZ_ISO2OEM_ARRAY)) diff --git a/third_party/unzip/globals.h b/third_party/unzip/globals.h index 841a76b24..485538186 100644 --- a/third_party/unzip/globals.h +++ b/third_party/unzip/globals.h @@ -152,10 +152,6 @@ #include "third_party/bzip2/bzlib.h" #endif -#if defined( UNIX) && defined( __APPLE__) -#include "third_party/unzip/unix/macosx.h" -#endif /* defined( UNIX) && defined( __APPLE__) */ - /*************/ /* Globals */ diff --git a/tool/build/mkdeps.c b/tool/build/mkdeps.c index 3af37a3aa..f8d1e92bc 100644 --- a/tool/build/mkdeps.c +++ b/tool/build/mkdeps.c @@ -17,10 +17,12 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" +#include "libc/calls/struct/stat.h" #include "libc/errno.h" #include "libc/fmt/libgen.h" #include "libc/fmt/magnumstrs.internal.h" #include "libc/intrin/bits.h" +#include "libc/intrin/kprintf.h" #include "libc/limits.h" #include "libc/macros.internal.h" #include "libc/mem/alg.h" @@ -30,60 +32,65 @@ #include "libc/stdio/append.h" #include "libc/stdio/stdio.h" #include "libc/str/str.h" +#include "libc/str/tab.internal.h" #include "libc/sysv/consts/map.h" #include "libc/sysv/consts/o.h" #include "libc/sysv/consts/prot.h" +#include "libc/sysv/consts/s.h" #include "third_party/getopt/getopt.internal.h" #include "tool/build/lib/getargs.h" #define VERSION \ - "cosmopolitan mkdeps v2.0\n" \ + "cosmopolitan mkdeps v3.0\n" \ "copyright 2023 justine tunney\n" \ "https://github.com/jart/cosmopolitan\n" -#define MANUAL \ - " -r o// -o OUTPUT INPUT...\n" \ - "\n" \ - "DESCRIPTION\n" \ - "\n" \ - " Generates makefile defining header dependencies.\n" \ - "\n" \ - " Includes look like this:\n" \ - "\n" \ - " - #include \"root/of/repository/foo.h\"\n" \ - " - .include \"root/of/repository/foo.inc\"\n" \ - "\n" \ - " They do NOT look like this:\n" \ - "\n" \ - " - #include \n" \ - " - #include \"foo.h\"\n" \ - " - # include \"foo.h\"\n" \ - " - #include \"foo.h\"\n" \ - "\n" \ - " Your generated make code looks like this:\n" \ - "\n" \ - " o//package/foo.o: \\\n" \ - " package/foo.c \\\n" \ - " package/foo.h \\\n" \ - " package/bar.h\n" \ - " o//package/bar.o: \\\n" \ - " package/bar.c \\\n" \ - " package/bar.h\n" \ - "\n" \ - "FLAGS\n" \ - "\n" \ - " -h show usage\n" \ - " -o OUTPUT set output path\n" \ - " -r ROOT set build output prefix, e.g. o//\n" \ - "\n" \ - "ARGUMENTS\n" \ - "\n" \ - " OUTPUT shall be makefile code\n" \ - " INPUT should be source or @args.txt\n" \ +#define MANUAL \ + " -r o// -o OUTPUT INPUT...\n" \ + "\n" \ + "DESCRIPTION\n" \ + "\n" \ + " Generates header file dependencies for your makefile\n" \ + "\n" \ + " This tool computes the transitive closure of included paths\n" \ + " for every source file in your repository. This program does\n" \ + " it orders of a magnitude faster than `gcc -M` on each file.\n" \ + "\n" \ + " Includes look like this:\n" \ + "\n" \ + " - #include \n" \ + " - #include \"samedir.h\"\n" \ + " - #include \"root/of/repository/foo.h\"\n" \ + " - .include \"asm/x86_64/foo.s\"\n" \ + "\n" \ + " Your generated make code looks like this:\n" \ + "\n" \ + " o//package/foo.o: \\\n" \ + " package/foo.c \\\n" \ + " package/foo.h \\\n" \ + " package/bar.h \\\n" \ + " libc/isystem/stdio.h\n" \ + " o//package/bar.o: \\\n" \ + " package/bar.c \\\n" \ + " package/bar.h\n" \ + "\n" \ + "FLAGS\n" \ + "\n" \ + " -h show usage\n" \ + " -o OUTPUT set output path\n" \ + " -g ROOT set generated path [default: o/]\n" \ + " -r ROOT set build output path, e.g. o/$(MODE)/\n" \ + " -S PATH isystem include path [default: libc/isystem/]\n" \ + " -s hermetically sealed mode [repeatable]\n" \ + "\n" \ + "ARGUMENTS\n" \ + "\n" \ + " OUTPUT shall be makefile code\n" \ + " INPUT should be source or @args.txt\n" \ "\n" -#define kIncludePrefix "include " -#define kSystemIncludes "libc/isystem/" +#define Read32(s) (s[3] << 24 | s[2] << 16 | s[1] << 8 | s[0]) +#define EXT(s) Read32(s "\0\0") struct Source { unsigned hash; @@ -111,17 +118,34 @@ struct Edges { struct Edge *p; }; -static const char kSourceExts[][5] = {".s", ".S", ".c", ".cc", ".cpp"}; +static const uint32_t kSourceExts[] = { + EXT("s"), // assembly + EXT("S"), // assembly with c preprocessor + EXT("c"), // c + EXT("cc"), // c++ + EXT("cpp"), // c++ +}; static char *names; +static int hermetic; static unsigned counter; static const char *prog; static struct Edges edges; static struct Sauce *sauces; static struct Sources sources; +static const char *systempath; static const char *buildroot; +static const char *genroot; static const char *outpath; +static inline bool IsBlank(int c) { + return c == ' ' || c == '\t'; +} + +static inline bool IsGraph(wint_t c) { + return 0x21 <= c && c <= 0x7E; +} + static wontreturn void Die(const char *reason) { tinyprint(2, prog, ": ", reason, "\n", NULL); exit(1); @@ -132,6 +156,11 @@ static wontreturn void DieSys(const char *thing) { exit(1); } +static wontreturn void DiePathTooLong(const char *path) { + errno = ENAMETOOLONG; + DieSys(path); +} + static wontreturn void DieOom(void) { Die("out of memory"); } @@ -233,7 +262,7 @@ static void Rehash(void) { free(old.p); } -static unsigned GetSourceId(const char *name, size_t len) { +static int HashSource(const char *name, size_t len, bool create) { unsigned hash; size_t i, step; i = 0; @@ -249,6 +278,7 @@ static unsigned GetSourceId(const char *name, size_t len) { step++; } while (sources.p[i].hash); } + if (!create) return -1; if (++sources.i >= (sources.n >> 1)) { Rehash(); step = 0; @@ -264,21 +294,118 @@ static unsigned GetSourceId(const char *name, size_t len) { return (sources.p[i].id = counter++); } +static int CreateSourceId(const char *name) { + return HashSource(name, strlen(name), true); +} + +static int GetSourceId(const char *name) { + return HashSource(name, strlen(name), false); +} + +// `p` should point to substring "include " +// `map` and `mapsize` define legal memory range +// returns pointer to path, or null if `p` isn't an include +// +// syntax like the following is supported: +// +// - `#include "foo.h"` +// - `#include ` +// - `# include ` +// - `#include ` +// - ` #include ` +// - `.include "foo.h"` (for .s files only) +// +// known issues: +// +// - we can't tell if it's inside a /* comment */ +// - whitespace like vertical tab isn't supported +// +static const char *FindIncludePath(const char *map, size_t mapsize, + const char *p, bool is_assembly) { + const char *q = p; + + // scan backwards for hash character + for (;;) { + if (q == map) { + return false; + } + if (IsBlank(q[-1])) { + --q; + continue; + } + if (q[-1] == '#' && !is_assembly) { + --q; + break; + } else if (q[-1] == '.' && is_assembly) { + --q; + break; + } else { + return false; + } + } + + // scan backwards for newline character + if (!is_assembly) { + for (;;) { + if (q == map) { + break; + } + if (IsBlank(q[-1])) { + --q; + continue; + } + if (q[-1] == '\n') { + break; + } else { + return false; + } + } + } + + // scan forward for path + q = p + strlen("include "); + for (;;) { + if (q >= map + mapsize) { + break; + } + if (IsBlank(*q)) { + ++q; + continue; + } + if (*q == '"' || (*q == '<' && !is_assembly)) { + ++q; + break; + } else { + return false; + } + } + + // return pointer to path + return q; +} + static void LoadRelationships(int argc, char *argv[]) { int fd; char *map; ssize_t rc; + size_t size; + bool is_assembly; struct GetArgs ga; - char srcdirbuf[256]; - size_t n, size, inclen; - unsigned srcid, dependency; + int srcid, dependency; + static char srcdirbuf[PATH_MAX]; const char *p, *pe, *src, *path, *pathend, *srcdir; getargs_init(&ga, argv + optind); - inclen = strlen(kIncludePrefix); while ((src = getargs_next(&ga))) { - n = strlen(src); - srcid = GetSourceId(src, n); - strlcpy(srcdirbuf, src, sizeof(srcdirbuf)); + CreateSourceId(src); + } + getargs_destroy(&ga); + getargs_init(&ga, argv + optind); + while ((src = getargs_next(&ga))) { + is_assembly = endswith(src, ".s"); + srcid = GetSourceId(src); + if (strlcpy(srcdirbuf, src, PATH_MAX) >= PATH_MAX) { + DiePathTooLong(src); + } srcdir = dirname(srcdirbuf); if ((fd = open(src, O_RDONLY)) == -1) { if (errno == ENOENT && ga.path) { @@ -296,45 +423,66 @@ static void LoadRelationships(int argc, char *argv[]) { DieSys(src); } if ((size = rc)) { - map = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0); + // repeatedly map to same fixed address so in order to weasel out + // of incurring the additional overhead of all these munmap calls + map = mmap((void *)0x311987030000, size, PROT_READ, + MAP_SHARED | MAP_FIXED, fd, 0); if (map == MAP_FAILED) { DieSys(src); } - for (p = map + 1, pe = map + size; p < pe; ++p) { - int right; - char juf[256], *jb; - char buf[256], *bp = buf; - if (!(p = memmem(p, pe - p, kIncludePrefix, inclen))) break; - path = p + inclen + 1; - if (path[-1] == '"') { - right = '"'; - } else if (path[-1] == '<') { - bp = mempcpy(bp, kSystemIncludes, strlen(kSystemIncludes)); + for (p = map, pe = map + size; p < pe; ++p) { + char *bp; + char right; + char buf[PATH_MAX]; + if (!(p = memmem(p, pe - p, "include ", 8))) break; + if (!(path = FindIncludePath(map, size, p, is_assembly))) continue; + bp = buf; + if (path[-1] == '<') { + if (!systempath) continue; + bp = stpcpy(bp, systempath); right = '>'; } else { - continue; + right = '"'; } - pathend = memchr(path, right, pe - path); - if (pathend && pathend - path > 0 && // - (p[-1] == '#' || p[-1] == '.') && // - (p - map == 1 || p[-2] == '\n') && // - (bp - buf) + (pathend - path) < sizeof(buf)) { // + if ((pathend = memchr(path, right, pe - path))) { + const char *final; + char juf[PATH_MAX]; + if ((bp - buf) + (pathend - path) >= PATH_MAX) { + tinyprint(2, src, ": include path too long\n", NULL); + exit(1); + } *(bp = mempcpy(bp, path, pathend - path)) = 0; - if (right == '>' && !isregularfile(buf)) continue; - if (!strchr(buf, '/') && !isregularfile(buf)) { - if (!(jb = __join_paths(juf, sizeof(juf), srcdir, buf))) continue; - if (!isregularfile(jb)) continue; - dependency = GetSourceId(jb, strlen(jb)); - } else { - dependency = GetSourceId(buf, bp - buf); + // let foo/bar.c say `#include "foo/hdr.h"` + dependency = GetSourceId((final = buf)); + // let foo/bar.c say `#include "hdr.h"` + if (dependency == -1 && right == '"' && !strchr(buf, '/')) { + if (!(final = __join_paths(juf, PATH_MAX, srcdir, buf))) { + DiePathTooLong(buf); + } + dependency = GetSourceId(final); + } + if (dependency == -1) { + if (startswith(buf, genroot)) { + dependency = CreateSourceId(src); + } else if (!hermetic) { + continue; + } else if (hermetic == 1 && right == '>') { + // chances are the `#include ` is in some #ifdef + // that'll never actually be executed; thus we ignore + // since landlock make unveil() shall catch it anyway + continue; + } else { + tinyprint( + 2, final, + ": path not specified by HDRS/SRCS/INCS make variables\n", + NULL); + exit(1); + } } AppendEdge(&edges, dependency, srcid); - p = pathend; + p = pathend + 1; } } - if (munmap(map, size)) { - DieSys(src); - } } if (close(fd)) { DieSys(src); @@ -350,14 +498,35 @@ static wontreturn void ShowUsage(int rc, int fd) { static void GetOpts(int argc, char *argv[]) { int opt; - while ((opt = getopt(argc, argv, "hno:r:")) != -1) { + while ((opt = getopt(argc, argv, "hnsgS:o:r:")) != -1) { switch (opt) { + case 's': + ++hermetic; + break; + case 'S': + if (systempath) { + Die("multiple system paths not supported yet"); + } + systempath = optarg; + break; case 'o': + if (outpath) { + Die("multiple output paths specified"); + } outpath = optarg; break; case 'r': + if (buildroot) { + Die("multiple build roots specified"); + } buildroot = optarg; break; + case 'g': + if (genroot) { + Die("multiple generated roots specified"); + } + genroot = optarg; + break; case 'n': exit(0); case 'h': @@ -366,29 +535,83 @@ static void GetOpts(int argc, char *argv[]) { ShowUsage(1, 2); } } - if (!outpath) { - Die("need output path"); - } - if (!buildroot) { - Die("need build output prefix"); - } if (optind == argc) { Die("missing input argument"); } + if (!genroot) { + genroot = "o/"; + } + if (!endswith(genroot, "/")) { + Die("generated output path must end with slash"); + } + if (!buildroot) { + Die("need build output path"); + } + if (!endswith(buildroot, "/")) { + Die("build output path must end with slash"); + } + if (!startswith(buildroot, genroot)) { + Die("build output path must start with generated output path"); + } + if (!systempath && hermetic) { + systempath = "libc/isystem/"; + } + if (systempath && !hermetic) { + Die("system path can only be specified in hermetic mode"); + } + if (systempath) { + size_t n; + struct stat st; + if (stat(systempath, &st)) { + DieSys(systempath); + } + if (!S_ISDIR(st.st_mode)) { + errno = ENOTDIR; + DieSys(systempath); + } + if ((n = strlen(systempath)) >= PATH_MAX) { + DiePathTooLong(systempath); + } + if (!n || systempath[n - 1] != '/') { + Die("system path must end with slash"); + } + } } -static const char *StripExt(char pathbuf[PATH_MAX + 1], const char *s) { +static const char *StripExt(char pathbuf[hasatleast PATH_MAX], const char *s) { static char *dot; - strlcpy(pathbuf, s, PATH_MAX + 1); + if (strlcpy(pathbuf, s, PATH_MAX) >= PATH_MAX) { + DiePathTooLong(s); + } dot = strrchr(pathbuf, '.'); if (dot) *dot = '\0'; return pathbuf; } +static uint32_t GetFileExtension(const char *s) { + uint32_t w; + size_t i, n; + n = s ? strlen(s) : 0; + for (i = w = 0; n--;) { + wint_t c = s[n]; + if (!IsGraph(c)) return 0; + if (c == '.') break; + if (++i > 4) return 0; + w <<= 8; + w |= kToLower[c]; + } + return w; +} + static bool IsObjectSource(const char *name) { int i; - for (i = 0; i < ARRAYLEN(kSourceExts); ++i) { - if (endswith(name, kSourceExts[i])) return true; + uint32_t ext; + if ((ext = GetFileExtension(name))) { + for (i = 0; i < ARRAYLEN(kSourceExts); ++i) { + if (ext == kSourceExts[i]) { + return true; + } + } } return false; } @@ -416,17 +639,16 @@ static char *Explore(void) { unsigned *visited; size_t i, visilen; char *makefile = 0; - char buf[PATH_MAX + 1]; + char buf[PATH_MAX]; visilen = (sources.i + sizeof(*visited) * CHAR_BIT - 1) / (sizeof(*visited) * CHAR_BIT); visited = Malloc(visilen * sizeof(*visited)); for (i = 0; i < sources.i; ++i) { path = names + sauces[i].name; if (!IsObjectSource(path)) continue; + if (startswith(path, genroot)) continue; Appendw(&makefile, '\n'); - if (!startswith(path, "o/")) { - Appends(&makefile, buildroot); - } + Appends(&makefile, buildroot); Appends(&makefile, StripExt(buf, path)); Appendw(&makefile, READ64LE(".o: \\\n\t")); Appends(&makefile, path); @@ -441,7 +663,7 @@ static char *Explore(void) { } int main(int argc, char *argv[]) { - int fd; + int fd = 1; ssize_t rc; size_t i, n; char *makefile; @@ -454,7 +676,8 @@ int main(int argc, char *argv[]) { LoadRelationships(argc, argv); Crunch(); makefile = Explore(); - if ((fd = open(outpath, O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) { + if (outpath && + (fd = open(outpath, O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) { DieSys(outpath); } n = appendz(makefile).i; @@ -463,7 +686,7 @@ int main(int argc, char *argv[]) { DieSys(outpath); } } - if (close(fd)) { + if (outpath && close(fd)) { DieSys(outpath); } free(makefile); diff --git a/tool/net/net.mk b/tool/net/net.mk index 82b262d92..b1869d369 100644 --- a/tool/net/net.mk +++ b/tool/net/net.mk @@ -6,6 +6,7 @@ PKGS += TOOL_NET TOOL_NET_FILES := $(wildcard tool/net/*) TOOL_NET_SRCS = $(filter %.c,$(TOOL_NET_FILES)) TOOL_NET_HDRS = $(filter %.h,$(TOOL_NET_FILES)) +TOOL_NET_INCS = $(filter %.inc,$(TOOL_NET_FILES)) TOOL_NET_OBJS = \ $(TOOL_NET_SRCS:%.c=o/$(MODE)/%.o) diff --git a/tool/viz/rlimit.c b/tool/viz/rlimit.c index 2dac60cf2..0cedfe648 100644 --- a/tool/viz/rlimit.c +++ b/tool/viz/rlimit.c @@ -7,13 +7,14 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif -#include "libc/calls/calls.h" -#include "libc/intrin/strace.internal.h" #include "libc/calls/struct/rlimit.h" +#include "libc/calls/calls.h" #include "libc/errno.h" #include "libc/intrin/describeflags.internal.h" +#include "libc/intrin/strace.internal.h" #include "libc/log/color.internal.h" #include "libc/macros.internal.h" +#include "libc/runtime/runtime.h" #include "libc/stdio/stdio.h" #include "libc/str/str.h" #include "libc/sysv/consts/rlim.h"