diff --git a/ape/ape.lds b/ape/ape.lds index 11b1e0cea..7e8a045d1 100644 --- a/ape/ape.lds +++ b/ape/ape.lds @@ -304,7 +304,6 @@ SECTIONS { KEEP(*(.keep.text)) *(.text .stub .text.*) KEEP(*(SORT_BY_NAME(.sort.text.*))) - *(.subrs) KEEP(*(.ape.pad.test)); *(.test.unlikely) @@ -402,6 +401,7 @@ SECTIONS { /*BEGIN: NT FORK COPYING */ KEEP(*(.dataprologue)) *(.data .data.*) + *(.subrs) /* for emacs */ KEEP(*(SORT_BY_NAME(.sort.data.*))) . += . > 0 ? CODE_GRANULE : 0; diff --git a/libc/intrin/kprintf.greg.c b/libc/intrin/kprintf.greg.c index 82a031f89..b1952fa68 100644 --- a/libc/intrin/kprintf.greg.c +++ b/libc/intrin/kprintf.greg.c @@ -103,6 +103,7 @@ break; \ } +_Hide long __klog_handle; extern _Hide struct SymbolTable *__symtab; privileged static inline char *kadvance(char *p, char *e, long n) { @@ -190,18 +191,30 @@ privileged bool kisdangerous(const void *p) { return true; } -privileged dontinline void klog(const char *b, size_t n) { +privileged static long kloghandle(void) { + if (__klog_handle) { + return __klog_handle; + } else if (!IsWindows()) { + return 2; + } else { + return __imp_GetStdHandle(kNtStdErrorHandle); + } +} + +privileged void _klog(const char *b, size_t n) { #ifdef __x86_64__ int e; + long h; bool cf; size_t i; uint16_t dx; uint32_t wrote; unsigned char al; long rax, rdi, rsi, rdx; + h = kloghandle(); if (IsWindows()) { e = __imp_GetLastError(); - __imp_WriteFile(__imp_GetStdHandle(kNtStdErrorHandle), b, n, &wrote, 0); + __imp_WriteFile(h, b, n, &wrote, 0); __imp_SetLastError(e); } else if (IsMetal()) { if (_weaken(_klog_vga)) _weaken(_klog_vga)(b, n); @@ -220,11 +233,11 @@ privileged dontinline void klog(const char *b, size_t n) { } else { asm volatile("syscall" : "=a"(rax), "=D"(rdi), "=S"(rsi), "=d"(rdx) - : "0"(__NR_write), "1"(2), "2"(b), "3"(n) + : "0"(__NR_write), "1"(h), "2"(b), "3"(n) : "rcx", "r8", "r9", "r10", "r11", "memory", "cc"); } #elif defined(__aarch64__) - register long r0 asm("x0") = (long)2; + register long r0 asm("x0") = (long)h; register long r1 asm("x1") = (long)b; register long r2 asm("x2") = (long)n; register long r8 asm("x8") = (long)__NR_write; @@ -840,7 +853,7 @@ privileged void kvprintf(const char *fmt, va_list v) { size_t n; char b[4000]; n = kformat(b, sizeof(b), fmt, v); - klog(b, MIN(n, sizeof(b) - 1)); + _klog(b, MIN(n, sizeof(b) - 1)); } /** diff --git a/libc/intrin/kprintf.h b/libc/intrin/kprintf.h index 5bc910675..98548985c 100644 --- a/libc/intrin/kprintf.h +++ b/libc/intrin/kprintf.h @@ -8,6 +8,7 @@ size_t ksnprintf(char *, size_t, const char *, ...); void kvprintf(const char *, va_list); size_t kvsnprintf(char *, size_t, const char *, va_list); bool kisdangerous(const void *); +void _klog(const char *, size_t); COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/log/backtrace2.c b/libc/log/backtrace2.c index 26d9b63c9..5ccebe24e 100644 --- a/libc/log/backtrace2.c +++ b/libc/log/backtrace2.c @@ -148,11 +148,11 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) { strlen(" (discriminator ") - 1)) && (p3 = memchr(p2, '\n', got - (p2 - p1)))) { if (p3 > p2 && p3[-1] == '\r') --p3; - sys_write(2, p1, p2 - p1); + _klog(p1, p2 - p1); got -= p3 - p1; p1 += p3 - p1; } else { - sys_write(2, p1, got); + _klog(p1, got); break; } } diff --git a/libc/log/log.h b/libc/log/log.h index ff4e7ebe2..523ebdf06 100644 --- a/libc/log/log.h +++ b/libc/log/log.h @@ -40,6 +40,7 @@ void _meminfo(int); /* shows malloc statistics &c. */ void _memsummary(int); /* light version of same thing */ bool IsTerminalInarticulate(void) nosideeffect; const char *commandvenv(const char *, const char *); +int LogKprintfToFile(const char *); const char *GetAddr2linePath(void); const char *GetGdbPath(void); void ShowCrashReports(void); diff --git a/libc/log/logkprintftofile.c b/libc/log/logkprintftofile.c new file mode 100644 index 000000000..778e1fab8 --- /dev/null +++ b/libc/log/logkprintftofile.c @@ -0,0 +1,57 @@ +/*-*- 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/internal.h" +#include "libc/dce.h" +#include "libc/log/log.h" +#include "libc/sysv/consts/f.h" +#include "libc/sysv/consts/o.h" + +static int __klog_fd; +extern _Hide long __klog_handle; + +/** + * Redirects kprintf(), `--strace`, etc. output to file. + * + * @param path is filename to append to; if null is specified then + * this file logging facility will be disabled; when the empty + * string is specified, then the default path shall be used + * @return 0 on success, or -1 w/ errno + */ +int LogKprintfToFile(const char *path) { + int fd, dd; + if (!path) { + if (__klog_fd) { + __klog_handle = 0; + close(__klog_fd); + __klog_fd = 0; + } + return 0; + } + if (!*path) path = "/tmp/kprintf.log"; + fd = open(path, O_WRONLY | O_APPEND | O_CREAT, 0644); + if (fd == -1) return -1; + dd = fcntl(fd, F_DUPFD_CLOEXEC, 100); + close(fd); + if (dd == -1) return -1; + if (__klog_fd) close(__klog_fd); + __klog_fd = dd; + __klog_handle = IsWindows() ? g_fds.p[dd].handle : dd; + return 0; +} diff --git a/libc/log/oncrash_amd64.c b/libc/log/oncrash_amd64.c index d827a8c51..ffab0921b 100644 --- a/libc/log/oncrash_amd64.c +++ b/libc/log/oncrash_amd64.c @@ -235,11 +235,11 @@ relegated void ShowCrashReport(int err, int sig, struct siginfo *si, p = ShowGeneralRegisters(p, ctx); p = ShowSseRegisters(p, ctx); *p++ = '\n'; - write(2, buf, p - buf); + _klog(buf, p - buf); ShowFunctionCalls(ctx); } else { *p++ = '\n'; - write(2, buf, p - buf); + _klog(buf, p - buf); } kprintf("\n"); if (!IsWindows()) __print_maps(); diff --git a/libc/runtime/finddebugbinary.c b/libc/runtime/finddebugbinary.c index 0db821288..56b8fd209 100644 --- a/libc/runtime/finddebugbinary.c +++ b/libc/runtime/finddebugbinary.c @@ -61,7 +61,8 @@ static bool IsMyDebugBinaryImpl(const char *path) { // which is currently running in memory. if ((size = lseek(fd, 0, SEEK_END)) != -1 && (map = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0)) != MAP_FAILED) { - if (GetElfSymbolValue(map, size, "_etext", &value)) { + if (IsElf64Binary(map, size) && + GetElfSymbolValue(map, size, "_etext", &value)) { res = !_etext || value == (uintptr_t)_etext; } munmap(map, size); @@ -94,7 +95,8 @@ const char *FindDebugBinary(void) { if (!once) { p = GetProgramExecutableName(); n = strlen(p); - if (n > 4 && READ32LE(p + n - 4) == READ32LE(".dbg")) { + if (n > 4 && READ32LE(p + n - 4) == READ32LE(".dbg") || + IsMyDebugBinary(p)) { res = p; } else if (n > 4 && READ32LE(p + n - 4) == READ32LE(".com") && n + 4 < ARRAYLEN(buf)) { diff --git a/libc/sock/pselect.c b/libc/sock/pselect.c index 22215fc40..2e7eaae3b 100644 --- a/libc/sock/pselect.c +++ b/libc/sock/pselect.c @@ -17,7 +17,10 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/cp.internal.h" +#include "libc/calls/struct/itimerval.internal.h" +#include "libc/calls/struct/sigset.internal.h" #include "libc/calls/struct/timespec.h" +#include "libc/calls/struct/timespec.internal.h" #include "libc/calls/struct/timeval.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" @@ -25,6 +28,7 @@ #include "libc/intrin/strace.internal.h" #include "libc/sock/internal.h" #include "libc/sock/select.h" +#include "libc/sysv/consts/nrlinux.h" #include "libc/sysv/errfuns.h" /** @@ -99,7 +103,7 @@ int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, END_CANCELLATION_POINT; POLLTRACE("pselect(%d, %p, %p, %p, %s, %s) → %d% m", nfds, readfds, writefds, - exceptfds, DescribeTimeval(0, timeout), DescribeSigset(0, sigmask), + exceptfds, DescribeTimespec(0, timeout), DescribeSigset(0, sigmask), rc); return rc; } diff --git a/libc/sock/select.c b/libc/sock/select.c index a7d0df06b..25cca8f49 100644 --- a/libc/sock/select.c +++ b/libc/sock/select.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/sock/select.h" #include "libc/calls/cp.internal.h" +#include "libc/calls/struct/itimerval.internal.h" #include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timeval.h" #include "libc/dce.h" diff --git a/tool/scripts/cosmoc++ b/tool/scripts/cosmoc++ index 20f8e5ebf..576a62538 100755 --- a/tool/scripts/cosmoc++ +++ b/tool/scripts/cosmoc++ @@ -30,7 +30,7 @@ exit 0 fi CXX="/opt/cosmo/o/third_party/gcc/bin/x86_64-linux-musl-g++" -CCFLAGS="-g -O2 -fdata-sections -ffunction-sections -fno-pie -pg -mnop-mcount -mno-tls-direct-seg-refs -fportcosmo -include /opt/cosmo/build/portcosmo.h" +CCFLAGS="-g -fdata-sections -ffunction-sections -fno-pie -pg -mnop-mcount -mno-tls-direct-seg-refs -fportcosmo -include /opt/cosmo/build/portcosmo.h" CXXFLAGS="-fno-exceptions -fuse-cxa-atexit -fno-threadsafe-statics" CPPFLAGS="-DNDEBUG -nostdinc -iquote /opt/cosmo -isystem /opt/cosmos/include -isystem /opt/cosmo/libc/isystem -include libc/integral/normalize.inc" LDFLAGS="-static -no-pie -nostdlib -fuse-ld=bfd -Wl,-melf_x86_64 -Wl,--gc-sections -L/opt/cosmos/lib -Wl,-T,/opt/cosmo/o/ape/public/ape.lds /opt/cosmo/o/ape/ape-no-modify-self.o /opt/cosmo/o/libc/crt/crt.o" diff --git a/tool/scripts/cosmocc b/tool/scripts/cosmocc index dc1809ee7..1ee2816cd 100755 --- a/tool/scripts/cosmocc +++ b/tool/scripts/cosmocc @@ -33,7 +33,7 @@ exit 0 fi CC="/opt/cosmo/o/third_party/gcc/bin/x86_64-linux-musl-gcc" -CFLAGS="-g -O2 -fdata-sections -ffunction-sections -fno-pie -pg -mnop-mcount -mno-tls-direct-seg-refs -fportcosmo -include /opt/cosmo/build/portcosmo.h" +CFLAGS="-g -fdata-sections -ffunction-sections -fno-pie -pg -mnop-mcount -mno-tls-direct-seg-refs -fportcosmo -include /opt/cosmo/build/portcosmo.h" CPPFLAGS="-DNDEBUG -nostdinc -iquote /opt/cosmo -isystem $COSMOS/include -isystem /opt/cosmo/libc/isystem -include libc/integral/normalize.inc" LDFLAGS="-static -no-pie -nostdlib -fuse-ld=bfd -Wl,-melf_x86_64 -Wl,--gc-sections -Wl,-z,max-page-size=0x1000 -L$COSMOS/lib -Wl,-T,/opt/cosmo/o/ape/public/ape.lds /opt/cosmo/o/ape/ape-no-modify-self.o /opt/cosmo/o/libc/crt/crt.o" LDLIBS="/opt/cosmo/o/cosmopolitan.a"