diff --git a/Makefile b/Makefile index cc96b98dd..6314ab1e0 100644 --- a/Makefile +++ b/Makefile @@ -60,7 +60,7 @@ # build/config.mk SHELL = /bin/sh -HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 xnu #win7 win10 +HOSTS ?= freebsd openbsd netbsd rhel7 rhel5 xnu win7 win10 SANITY := $(shell build/sanitycheck $$PPID) .SUFFIXES: @@ -69,7 +69,10 @@ SANITY := $(shell build/sanitycheck $$PPID) .PHONY: all o bins check test depend tags all: o -o: o/$(MODE)/ape \ +o: o/$(MODE) + +o/$(MODE): \ + o/$(MODE)/ape \ o/$(MODE)/dsp \ o/$(MODE)/net \ o/$(MODE)/libc \ diff --git a/build/bootstrap/compile.com b/build/bootstrap/compile.com index f6093f72d..705f5c5f2 100755 Binary files a/build/bootstrap/compile.com and b/build/bootstrap/compile.com differ diff --git a/build/config.mk b/build/config.mk index ceb7f9764..17827a02e 100644 --- a/build/config.mk +++ b/build/config.mk @@ -131,7 +131,8 @@ CONFIG_CCFLAGS += \ -O2 \ -fno-inline CONFIG_COPTS += \ - -fsanitize=address + -fsanitize=address \ + -fsanitize=undefined TARGET_ARCH ?= \ -msse3 OVERRIDE_CCFLAGS += \ diff --git a/examples/auto-launch-gdb-on-crash.c b/examples/auto-launch-gdb-on-crash.c index 24b18c57e..56c5d86c7 100644 --- a/examples/auto-launch-gdb-on-crash.c +++ b/examples/auto-launch-gdb-on-crash.c @@ -40,7 +40,7 @@ */ int main(int argc, char *argv[]) { - showcrashreports(); + ShowCrashReports(); asm("int3"); /* cf. __die(), perror("msg"), abort(), exit(1), _Exit(1) */ return 0; } diff --git a/examples/breakpoint.c b/examples/breakpoint.c index b3c639c11..6298bf933 100644 --- a/examples/breakpoint.c +++ b/examples/breakpoint.c @@ -14,7 +14,7 @@ #include "libc/stdio/stdio.h" int main(int argc, char *argv[]) { - showcrashreports(); + ShowCrashReports(); if (IsDebuggerPresent(false)) { printf("debugger found!\r\n"); DebugBreak(); diff --git a/examples/crashreport.c b/examples/crashreport.c index 24c951083..bef370ac6 100644 --- a/examples/crashreport.c +++ b/examples/crashreport.c @@ -24,6 +24,6 @@ int main(int argc, char *argv[]) { volatile int64_t x; - showcrashreports(); + ShowCrashReports(); return 1 / (x = 0); } diff --git a/examples/curl.c b/examples/curl.c index 97e7c81cf..c1330bb2a 100644 --- a/examples/curl.c +++ b/examples/curl.c @@ -121,7 +121,7 @@ static wontreturn void PrintUsage(FILE *f, int rc) { } int main(int argc, char *argv[]) { - if (!NoDebug()) showcrashreports(); + if (!NoDebug()) ShowCrashReports(); /* * Read flags. diff --git a/examples/datauri.c b/examples/datauri.c index 6758d063f..4c49d4c73 100644 --- a/examples/datauri.c +++ b/examples/datauri.c @@ -43,7 +43,7 @@ void PrintUri(const char *path) { } int main(int argc, char *argv[]) { - showcrashreports(); + ShowCrashReports(); int i; while ((i = getopt(argc, argv, "?h")) != -1) { switch (i) { diff --git a/examples/img.c b/examples/img.c index 34d4a840f..e456e3a85 100644 --- a/examples/img.c +++ b/examples/img.c @@ -67,7 +67,7 @@ void PrintImg(const char *path) { } int main(int argc, char *argv[]) { - showcrashreports(); + ShowCrashReports(); int i; while ((i = getopt(argc, argv, "?huas01234")) != -1) { switch (i) { diff --git a/examples/ispell.c b/examples/ispell.c index 4ddbe09a1..e8e72746c 100644 --- a/examples/ispell.c +++ b/examples/ispell.c @@ -153,7 +153,7 @@ void LoadWords(void) { } int main(int argc, char *argv[]) { - showcrashreports(); + ShowCrashReports(); LoadWords(); SpellChecker(); return 0; diff --git a/examples/panels.c b/examples/panels.c index 856aac2d4..53d6d1ba9 100644 --- a/examples/panels.c +++ b/examples/panels.c @@ -152,7 +152,7 @@ void Draw(void) { int main(int argc, char *argv[]) { struct sigaction sa[2] = {{.sa_handler = OnShutdown}, {.sa_handler = OnInvalidate}}; - showcrashreports(); + ShowCrashReports(); Setup(); Enter(); GetTtySize(); diff --git a/examples/uname.c b/examples/uname.c new file mode 100644 index 000000000..9cf0c5154 --- /dev/null +++ b/examples/uname.c @@ -0,0 +1,24 @@ +#if 0 +/*─────────────────────────────────────────────────────────────────╗ +│ To the extent possible under law, Justine Tunney has waived │ +│ all copyright and related or neighboring rights to this file, │ +│ as it is written in the following disclaimers: │ +│ • http://unlicense.org/ │ +│ • http://creativecommons.org/publicdomain/zero/1.0/ │ +╚─────────────────────────────────────────────────────────────────*/ +#endif +#include "libc/calls/calls.h" +#include "libc/calls/struct/utsname.h" +#include "libc/stdio/stdio.h" + +int main(int argc, char *argv[]) { + struct utsname names; + if (uname(&names)) return 1; + printf("%-10s %s\n", "sysname", names.sysname); + printf("%-10s %s\n", "nodename", names.nodename); + printf("%-10s %s\n", "release", names.release); + printf("%-10s %s\n", "version", names.version); + printf("%-10s %s\n", "machine", names.machine); + printf("%-10s %s\n", "domainname", names.domainname); + return 0; +} diff --git a/libc/calls/gethostname-nt.c b/libc/calls/gethostname-nt.c index 020147d6e..2cdf8c0f6 100644 --- a/libc/calls/gethostname-nt.c +++ b/libc/calls/gethostname-nt.c @@ -22,11 +22,11 @@ #include "libc/nt/systeminfo.h" #include "libc/str/str.h" -textwindows int gethostname_nt(char *name, size_t len) { +textwindows int gethostname_nt(char *name, size_t len, int kind) { uint32_t nSize; char16_t name16[256]; nSize = ARRAYLEN(name16); - if (GetComputerNameEx(kNtComputerNamePhysicalDnsHostname, name16, &nSize)) { + if (GetComputerNameEx(kind, name16, &nSize)) { tprecode16to8(name, len, name16); return 0; } else { diff --git a/libc/calls/gethostname.c b/libc/calls/gethostname.c index 5e4337331..46f23eae3 100644 --- a/libc/calls/gethostname.c +++ b/libc/calls/gethostname.c @@ -19,6 +19,7 @@ #include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/dce.h" +#include "libc/nt/enum/computernameformat.h" #include "libc/sysv/errfuns.h" /** @@ -37,6 +38,6 @@ int gethostname(char *name, size_t len) { return gethostname_bsd(name, len); } } else { - return gethostname_nt(name, len); + return gethostname_nt(name, len, kNtComputerNamePhysicalDnsHostname); } } diff --git a/libc/calls/internal.h b/libc/calls/internal.h index fa044746d..a133840e6 100644 --- a/libc/calls/internal.h +++ b/libc/calls/internal.h @@ -234,7 +234,7 @@ void __sigenter_xnu(void *, i32, i32, struct __darwin_siginfo *, struct __darwin_ucontext *) hidden; int gethostname_linux(char *, size_t) hidden; int gethostname_bsd(char *, size_t) hidden; -int gethostname_nt(char *, size_t) hidden; +int gethostname_nt(char *, size_t, int) hidden; size_t __iovec_size(const struct iovec *, size_t) hidden; void __rusage2linux(struct rusage *) hidden; int __notziposat(int, const char *); diff --git a/libc/calls/ntcontext2linux.c b/libc/calls/ntcontext2linux.c index d9bdc1b12..b6c75be1b 100644 --- a/libc/calls/ntcontext2linux.c +++ b/libc/calls/ntcontext2linux.c @@ -24,6 +24,7 @@ textwindows void ntcontext2linux(ucontext_t *ctx, const struct NtContext *cr) { if (!cr) return; ctx->uc_flags = cr->EFlags; + ctx->uc_mcontext.gregs[REG_EFL] = cr->EFlags; ctx->uc_mcontext.rax = cr->Rax; ctx->uc_mcontext.rbx = cr->Rbx; ctx->uc_mcontext.rcx = cr->Rcx; diff --git a/libc/calls/uname.c b/libc/calls/uname.c index c080e0627..9f9c7c960 100644 --- a/libc/calls/uname.c +++ b/libc/calls/uname.c @@ -18,34 +18,72 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/strace.internal.h" #include "libc/calls/struct/utsname.h" +#include "libc/dce.h" +#include "libc/fmt/itoa.h" +#include "libc/intrin/asan.internal.h" +#include "libc/nt/enum/computernameformat.h" +#include "libc/nt/struct/teb.h" +#include "libc/runtime/runtime.h" #include "libc/str/str.h" +#include "libc/sysv/errfuns.h" + +static inline textwindows noasan int NtGetMajorVersion(void) { + return NtGetPeb()->OSMajorVersion; +} + +static inline textwindows noasan int NtGetMinorVersion(void) { + return NtGetPeb()->OSMinorVersion; +} + +static inline textwindows noasan int NtGetBuildNumber(void) { + return NtGetPeb()->OSBuildNumber; +} /** * Asks kernel to give us the `uname -a` data. * @return 0 on success, or -1 w/ errno */ int uname(struct utsname *lool) { - char *out; + int rc, v; + char *out, *p; size_t i, j, len; char tmp[sizeof(struct utsname)]; - bzero(tmp, sizeof(tmp)); - if (sys_uname(tmp) != -1) { - out = (char *)lool; - i = 0; - j = 0; - for (;;) { - len = strlen(&tmp[j]); - if (len >= sizeof(struct utsname) - i) break; - memcpy(&out[i], &tmp[j], len + 1); - i += SYS_NMLN; - j += len; - while (j < sizeof(tmp) && tmp[j] == '\0') ++j; - if (j == sizeof(tmp)) break; - } - return 0; + if (!lool) return efault(); + if (!lool || (IsAsan() && !__asan_is_valid(lool, sizeof(*lool)))) { + rc = efault(); } else { - bzero(lool, sizeof(struct utsname)); - return -1; + bzero(tmp, sizeof(tmp)); + if (!IsWindows()) { + if ((rc = sys_uname(tmp)) != -1) { + out = (char *)lool; + for (i = j = 0;;) { + len = strlen(&tmp[j]); + if (len >= sizeof(struct utsname) - i) break; + memcpy(&out[i], &tmp[j], len + 1); + i += SYS_NMLN; + j += len; + while (j < sizeof(tmp) && tmp[j] == '\0') ++j; + if (j == sizeof(tmp)) break; + } + } + } else { + v = NtGetVersion(); + p = lool->version; + p = FormatUint32(p, NtGetMajorVersion()), *p++ = '.'; + p = FormatUint32(p, NtGetMinorVersion()), *p++ = '-'; + p = FormatUint32(p, NtGetBuildNumber()); + strcpy(lool->sysname, "The New Technology"); + strcpy(lool->machine, "x86_64"); + rc = gethostname_nt(lool->nodename, sizeof(lool->nodename), + kNtComputerNamePhysicalDnsHostname); + rc |= gethostname_nt(lool->domainname, sizeof(lool->domainname), + kNtComputerNamePhysicalDnsDomain); + } } + STRACE("uname([%s, %s, %s, %s, %s, %s]) → %d% m", lool->sysname, + lool->nodename, lool->release, lool->version, lool->machine, + lool->domainname, rc); + return rc; } diff --git a/libc/calls/wincrash.c b/libc/calls/wincrash.c index 62aa0b55c..158e78ba3 100644 --- a/libc/calls/wincrash.c +++ b/libc/calls/wincrash.c @@ -24,9 +24,10 @@ #include "libc/nt/enum/signal.h" #include "libc/nt/struct/ntexceptionpointers.h" #include "libc/str/str.h" +#include "libc/sysv/consts/sicode.h" textwindows unsigned __wincrash(struct NtExceptionPointers *ep) { - int sig, rva; + int sig, rva, code; struct Goodies { ucontext_t ctx; struct siginfo si; @@ -34,44 +35,69 @@ textwindows unsigned __wincrash(struct NtExceptionPointers *ep) { STRACE("__wincrash"); switch (ep->ExceptionRecord->ExceptionCode) { case kNtSignalBreakpoint: + code = TRAP_BRKPT; sig = SIGTRAP; break; case kNtSignalIllegalInstruction: + code = ILL_ILLOPC; + sig = SIGILL; + break; case kNtSignalPrivInstruction: + code = ILL_PRVOPC; sig = SIGILL; break; case kNtSignalGuardPage: - case kNtSignalAccessViolation: case kNtSignalInPageError: + code = SEGV_MAPERR; + sig = SIGSEGV; + break; + case kNtSignalAccessViolation: + code = SEGV_ACCERR; sig = SIGSEGV; break; case kNtSignalInvalidHandle: case kNtSignalInvalidParameter: case kNtSignalAssertionFailure: + code = SI_USER; sig = SIGABRT; break; - case kNtSignalFltDenormalOperand: case kNtSignalFltDivideByZero: - case kNtSignalFltInexactResult: - case kNtSignalFltInvalidOperation: + code = FPE_FLTDIV; + sig = SIGFPE; + break; case kNtSignalFltOverflow: - case kNtSignalFltStackCheck: + code = FPE_FLTOVF; + sig = SIGFPE; + break; case kNtSignalFltUnderflow: + code = FPE_FLTUND; + sig = SIGFPE; + break; + case kNtSignalFltInexactResult: + code = FPE_FLTRES; + sig = SIGFPE; + break; + case kNtSignalFltDenormalOperand: + case kNtSignalFltInvalidOperation: + case kNtSignalFltStackCheck: case kNtSignalIntegerDivideByZero: case kNtSignalFloatMultipleFaults: case kNtSignalFloatMultipleTraps: + code = FPE_FLTINV; sig = SIGFPE; break; case kNtSignalDllNotFound: case kNtSignalOrdinalNotFound: case kNtSignalEntrypointNotFound: case kNtSignalDllInitFailed: + code = SI_KERNEL; sig = SIGSYS; break; default: return kNtExceptionContinueSearch; } bzero(&g, sizeof(g)); + g.si.si_code = code; rva = __sighandrvas[sig]; if (rva >= kSigactionMinRva) { ntcontext2linux(&g.ctx, ep->ContextRecord); diff --git a/libc/dce.h b/libc/dce.h index 6b02b308b..9b80e4d06 100644 --- a/libc/dce.h +++ b/libc/dce.h @@ -57,7 +57,7 @@ #define IsOptimized() 0 #endif -#ifdef __FSANITIZE_ADDRESS__ +#ifdef __SANITIZE_ADDRESS__ #define IsAsan() 1 #else #define IsAsan() 0 diff --git a/libc/intrin/kprintf.greg.c b/libc/intrin/kprintf.greg.c index c4928e447..8d3fded6d 100644 --- a/libc/intrin/kprintf.greg.c +++ b/libc/intrin/kprintf.greg.c @@ -43,9 +43,6 @@ #include "libc/sysv/consts/nr.h" #include "libc/sysv/consts/prot.h" -#define MAXT (24 * 60 * 60 * 1000000000ull) -#define WRAP ((MAXT + 1) / 10 * 33) - struct Timestamps { unsigned long long birth; unsigned long long start; @@ -56,6 +53,13 @@ extern bool __replmode; extern bool __nomultics; volatile unsigned long long __kbirth; +static inline uint64_t ClocksToNanos(uint64_t x, uint64_t y) { + // approximation of round(x*.323018) which is usually + // the ratio between inva rdtsc ticks and nanoseconds + uint128_t difference = x - y; + return (difference * 338709) >> 20; +} + privileged static struct Timestamps kenter(void) { struct Timestamps ts; ts.start = rdtsc(); @@ -336,7 +340,7 @@ privileged static size_t kformat(char *b, size_t n, const char *fmt, va_list va, } continue; case 'T': - x = unsignedsubtract(ts.start, ts.birth) % WRAP * 10 / 33; + x = ClocksToNanos(ts.start, ts.birth) % 86400000000000; goto FormatUnsigned; case 'P': if (!__vforked) { diff --git a/libc/intrin/ubsan.c b/libc/intrin/ubsan.c index 2b0458ff1..2b047176e 100644 --- a/libc/intrin/ubsan.c +++ b/libc/intrin/ubsan.c @@ -22,6 +22,7 @@ #include "libc/calls/calls.h" #include "libc/fmt/fmt.h" #include "libc/intrin/kprintf.h" +#include "libc/log/color.internal.h" #include "libc/log/internal.h" #include "libc/log/libfatal.internal.h" #include "libc/log/log.h" @@ -37,6 +38,8 @@ #define kUbsanKindFloat 1 #define kUbsanKindUnknown 0xffff +typedef void __ubsan_die_f(void); + struct UbsanSourceLocation { const char *file; uint32_t line; @@ -188,17 +191,42 @@ static uintptr_t __ubsan_extend(struct UbsanTypeDescriptor *t, uintptr_t x) { return x; } -void __ubsan_abort(const struct UbsanSourceLocation *loc, - const char *description) { - kprintf("%n%s:%d: ubsan error: %s%n", loc->file, loc->line, description); - if (weaken(__die)) weaken(__die)(); - _Exit(134); +static wontreturn void __ubsan_unreachable(void) { + for (;;) __builtin_trap(); +} + +static void __ubsan_exit(void) { + kprintf("your ubsan runtime needs%n" + "\tSTATIC_YOINK(\"__die\");%n" + "in order to show you backtraces%n"); + _Exit(99); +} + +nodiscard static __ubsan_die_f *__ubsan_die(void) { + if (weaken(__die)) { + return weaken(__die); + } else { + return __ubsan_exit; + } +} + +static void __ubsan_warning(const struct UbsanSourceLocation *loc, + const char *description) { + kprintf("%s:%d: %subsan warning: %s is undefined behavior%s%n", loc->file, + loc->line, SUBTLE, description, RESET); +} + +nodiscard __ubsan_die_f *__ubsan_abort(const struct UbsanSourceLocation *loc, + const char *description) { + kprintf("%n%s:%d: %subsan error%s: %s%n", loc->file, loc->line, RED2, RESET, + description); + return __ubsan_die(); } static const char *__ubsan_describe_shift( struct UbsanShiftOutOfBoundsInfo *info, uintptr_t lhs, uintptr_t rhs) { if (__ubsan_negative(info->rhs_type, rhs)) { - return "shift exponent is negative"; + return "negative shift exponent"; } else if (rhs >= __ubsan_bits(info->lhs_type)) { return "shift exponent too large for type"; } else if (__ubsan_negative(info->lhs_type, lhs)) { @@ -210,9 +238,10 @@ static const char *__ubsan_describe_shift( } } -void __ubsan_handle_shift_out_of_bounds(struct UbsanShiftOutOfBoundsInfo *info, - uintptr_t lhs, uintptr_t rhs) { - char buf[512], *p = buf; +static char *__ubsan_describe_shift_out_of_bounds( + char buf[512], struct UbsanShiftOutOfBoundsInfo *info, uintptr_t lhs, + uintptr_t rhs) { + char *p = buf; lhs = __ubsan_extend(info->lhs_type, lhs); rhs = __ubsan_extend(info->rhs_type, rhs); p = __stpcpy(p, __ubsan_describe_shift(info, lhs, rhs)), *p++ = ' '; @@ -220,12 +249,22 @@ void __ubsan_handle_shift_out_of_bounds(struct UbsanShiftOutOfBoundsInfo *info, p = __stpcpy(p, info->lhs_type->name), *p++ = ' '; p = __ubsan_itpcpy(p, info->rhs_type, rhs), *p++ = ' '; p = __stpcpy(p, info->rhs_type->name); - __ubsan_abort(&info->location, buf); + return buf; +} + +void __ubsan_handle_shift_out_of_bounds(struct UbsanShiftOutOfBoundsInfo *info, + uintptr_t lhs, uintptr_t rhs) { + char buf[512]; + __ubsan_warning(&info->location, + __ubsan_describe_shift_out_of_bounds(buf, info, lhs, rhs)); } void __ubsan_handle_shift_out_of_bounds_abort( struct UbsanShiftOutOfBoundsInfo *info, uintptr_t lhs, uintptr_t rhs) { - __ubsan_handle_shift_out_of_bounds(info, lhs, rhs); + char buf[512]; + __ubsan_abort(&info->location, + __ubsan_describe_shift_out_of_bounds(buf, info, lhs, rhs))(); + __ubsan_unreachable(); } void __ubsan_handle_out_of_bounds(struct UbsanOutOfBoundsInfo *info, @@ -237,7 +276,8 @@ void __ubsan_handle_out_of_bounds(struct UbsanOutOfBoundsInfo *info, p = __stpcpy(p, " into "); p = __stpcpy(p, info->array_type->name); p = __stpcpy(p, " out of bounds"); - __ubsan_abort(&info->location, buf); + __ubsan_abort(&info->location, buf)(); + __ubsan_unreachable(); } void __ubsan_handle_out_of_bounds_abort(struct UbsanOutOfBoundsInfo *info, @@ -245,11 +285,11 @@ void __ubsan_handle_out_of_bounds_abort(struct UbsanOutOfBoundsInfo *info, __ubsan_handle_out_of_bounds(info, index); } -void __ubsan_handle_type_mismatch(struct UbsanTypeMismatchInfo *info, - uintptr_t pointer) { +static __ubsan_die_f *__ubsan_type_mismatch_handler( + struct UbsanTypeMismatchInfo *info, uintptr_t pointer) { const char *kind; char buf[512], *p = buf; - if (!pointer) __ubsan_abort(&info->location, "null pointer access"); + if (!pointer) return __ubsan_abort(&info->location, "null pointer access"); kind = __ubsan_dubnul(kUbsanTypeCheckKinds, info->type_check_kind); if (info->alignment && (pointer & (info->alignment - 1))) { p = __stpcpy(p, "unaligned "); @@ -266,41 +306,57 @@ void __ubsan_handle_type_mismatch(struct UbsanTypeMismatchInfo *info, p = __stpcpy(p, " with insufficient space for object of type "); p = __stpcpy(p, info->type->name); } - __ubsan_abort(&info->location, buf); + return __ubsan_abort(&info->location, buf); +} + +void __ubsan_handle_type_mismatch(struct UbsanTypeMismatchInfo *info, + uintptr_t pointer) { + __ubsan_type_mismatch_handler(info, pointer)(); + __ubsan_unreachable(); } void __ubsan_handle_type_mismatch_abort(struct UbsanTypeMismatchInfo *info, uintptr_t pointer) { - __ubsan_handle_type_mismatch(info, pointer); + __ubsan_type_mismatch_handler(info, pointer)(); + __ubsan_unreachable(); } -void __ubsan_handle_type_mismatch_v1( +static __ubsan_die_f *__ubsan_type_mismatch_v1_handler( struct UbsanTypeMismatchInfoClang *type_mismatch, uintptr_t pointer) { struct UbsanTypeMismatchInfo mm; mm.location = type_mismatch->location; mm.type = type_mismatch->type; mm.alignment = 1u << type_mismatch->log_alignment; mm.type_check_kind = type_mismatch->type_check_kind; - __ubsan_handle_type_mismatch(&mm, pointer); + return __ubsan_type_mismatch_handler(&mm, pointer); +} + +void __ubsan_handle_type_mismatch_v1( + struct UbsanTypeMismatchInfoClang *type_mismatch, uintptr_t pointer) { + __ubsan_type_mismatch_v1_handler(type_mismatch, pointer)(); + __ubsan_unreachable(); } void __ubsan_handle_type_mismatch_v1_abort( struct UbsanTypeMismatchInfoClang *type_mismatch, uintptr_t pointer) { - __ubsan_handle_type_mismatch_v1(type_mismatch, pointer); + __ubsan_type_mismatch_v1_handler(type_mismatch, pointer)(); + __ubsan_unreachable(); } void __ubsan_handle_float_cast_overflow(void *data_raw, void *from_raw) { struct UbsanFloatCastOverflowData *data = (struct UbsanFloatCastOverflowData *)data_raw; #if __GNUC__ + 0 >= 6 - __ubsan_abort(&data->location, "float cast overflow"); + __ubsan_abort(&data->location, "float cast overflow")(); + __ubsan_unreachable(); #else const struct UbsanSourceLocation kUnknownLocation = { "", pushpop(0), pushpop(0), }; - __ubsan_abort(((void)data, &kUnknownLocation), "float cast overflow"); + __ubsan_abort(((void)data, &kUnknownLocation), "float cast overflow")(); + __ubsan_unreachable(); #endif } @@ -309,7 +365,8 @@ void __ubsan_handle_float_cast_overflow_abort(void *data_raw, void *from_raw) { } void __ubsan_handle_add_overflow(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "add overflow"); + __ubsan_abort(loc, "add overflow")(); + __ubsan_unreachable(); } void __ubsan_handle_add_overflow_abort(const struct UbsanSourceLocation *loc) { @@ -318,7 +375,8 @@ void __ubsan_handle_add_overflow_abort(const struct UbsanSourceLocation *loc) { void __ubsan_handle_alignment_assumption( const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "alignment assumption"); + __ubsan_abort(loc, "alignment assumption")(); + __ubsan_unreachable(); } void __ubsan_handle_alignment_assumption_abort( @@ -327,7 +385,8 @@ void __ubsan_handle_alignment_assumption_abort( } void __ubsan_handle_builtin_unreachable(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "builtin unreachable"); + __ubsan_abort(loc, "builtin unreachable")(); + __ubsan_unreachable(); } void __ubsan_handle_builtin_unreachable_abort( @@ -336,7 +395,8 @@ void __ubsan_handle_builtin_unreachable_abort( } void __ubsan_handle_cfi_bad_type(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "cfi bad type"); + __ubsan_abort(loc, "cfi bad type")(); + __ubsan_unreachable(); } void __ubsan_handle_cfi_bad_type_abort(const struct UbsanSourceLocation *loc) { @@ -344,7 +404,8 @@ void __ubsan_handle_cfi_bad_type_abort(const struct UbsanSourceLocation *loc) { } void __ubsan_handle_cfi_check_fail(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "cfi check fail"); + __ubsan_abort(loc, "cfi check fail")(); + __ubsan_unreachable(); } void __ubsan_handle_cfi_check_fail_abort( @@ -353,7 +414,8 @@ void __ubsan_handle_cfi_check_fail_abort( } void __ubsan_handle_divrem_overflow(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "divrem overflow"); + __ubsan_abort(loc, "divrem overflow")(); + __ubsan_unreachable(); } void __ubsan_handle_divrem_overflow_abort( @@ -363,7 +425,8 @@ void __ubsan_handle_divrem_overflow_abort( void __ubsan_handle_dynamic_type_cache_miss( const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "dynamic type cache miss"); + __ubsan_abort(loc, "dynamic type cache miss")(); + __ubsan_unreachable(); } void __ubsan_handle_dynamic_type_cache_miss_abort( @@ -373,7 +436,8 @@ void __ubsan_handle_dynamic_type_cache_miss_abort( void __ubsan_handle_function_type_mismatch( const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "function type mismatch"); + __ubsan_abort(loc, "function type mismatch")(); + __ubsan_unreachable(); } void __ubsan_handle_function_type_mismatch_abort( @@ -382,7 +446,8 @@ void __ubsan_handle_function_type_mismatch_abort( } void __ubsan_handle_implicit_conversion(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "implicit conversion"); + __ubsan_abort(loc, "implicit conversion")(); + __ubsan_unreachable(); } void __ubsan_handle_implicit_conversion_abort( @@ -391,7 +456,8 @@ void __ubsan_handle_implicit_conversion_abort( } void __ubsan_handle_invalid_builtin(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "invalid builtin"); + __ubsan_abort(loc, "invalid builtin")(); + __ubsan_unreachable(); } void __ubsan_handle_invalid_builtin_abort( @@ -400,7 +466,8 @@ void __ubsan_handle_invalid_builtin_abort( } void __ubsan_handle_load_invalid_value(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "load invalid value (uninitialized? bool∌[01]?)"); + __ubsan_abort(loc, "load invalid value (uninitialized? bool∌[01]?)")(); + __ubsan_unreachable(); } void __ubsan_handle_load_invalid_value_abort( @@ -409,7 +476,8 @@ void __ubsan_handle_load_invalid_value_abort( } void __ubsan_handle_missing_return(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "missing return"); + __ubsan_abort(loc, "missing return")(); + __ubsan_unreachable(); } void __ubsan_handle_missing_return_abort( @@ -418,7 +486,8 @@ void __ubsan_handle_missing_return_abort( } void __ubsan_handle_mul_overflow(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "multiply overflow"); + __ubsan_abort(loc, "multiply overflow")(); + __ubsan_unreachable(); } void __ubsan_handle_mul_overflow_abort(const struct UbsanSourceLocation *loc) { @@ -426,7 +495,8 @@ void __ubsan_handle_mul_overflow_abort(const struct UbsanSourceLocation *loc) { } void __ubsan_handle_negate_overflow(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "negate overflow"); + __ubsan_abort(loc, "negate overflow")(); + __ubsan_unreachable(); } void __ubsan_handle_negate_overflow_abort( @@ -435,24 +505,28 @@ void __ubsan_handle_negate_overflow_abort( } void __ubsan_handle_nonnull_arg(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "nonnull argument"); + __ubsan_warning(loc, "null argument here"); } void __ubsan_handle_nonnull_arg_abort(const struct UbsanSourceLocation *loc) { - __ubsan_handle_nonnull_arg(loc); + __ubsan_abort(loc, "nonnull argument")(); + __ubsan_unreachable(); } void __ubsan_handle_nonnull_return_v1(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "non-null return (v1)"); + __ubsan_abort(loc, "non-null return (v1)")(); + __ubsan_unreachable(); } void __ubsan_handle_nonnull_return_v1_abort( const struct UbsanSourceLocation *loc) { - __ubsan_handle_nonnull_return_v1(loc); + __ubsan_abort(loc, "non-null return (v1)")(); + __ubsan_unreachable(); } void __ubsan_handle_nullability_arg(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "nullability arg"); + __ubsan_abort(loc, "nullability arg")(); + __ubsan_unreachable(); } void __ubsan_handle_nullability_arg_abort( @@ -462,7 +536,8 @@ void __ubsan_handle_nullability_arg_abort( void __ubsan_handle_nullability_return_v1( const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "nullability return (v1)"); + __ubsan_abort(loc, "nullability return (v1)")(); + __ubsan_unreachable(); } void __ubsan_handle_nullability_return_v1_abort( @@ -471,7 +546,8 @@ void __ubsan_handle_nullability_return_v1_abort( } void __ubsan_handle_pointer_overflow(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "pointer overflow"); + __ubsan_abort(loc, "pointer overflow")(); + __ubsan_unreachable(); } void __ubsan_handle_pointer_overflow_abort( @@ -480,7 +556,8 @@ void __ubsan_handle_pointer_overflow_abort( } void __ubsan_handle_sub_overflow(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "subtract overflow"); + __ubsan_abort(loc, "subtract overflow")(); + __ubsan_unreachable(); } void __ubsan_handle_sub_overflow_abort(const struct UbsanSourceLocation *loc) { @@ -489,7 +566,8 @@ void __ubsan_handle_sub_overflow_abort(const struct UbsanSourceLocation *loc) { void __ubsan_handle_vla_bound_not_positive( const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "vla bound not positive"); + __ubsan_abort(loc, "vla bound not positive")(); + __ubsan_unreachable(); } void __ubsan_handle_vla_bound_not_positive_abort( @@ -498,7 +576,8 @@ void __ubsan_handle_vla_bound_not_positive_abort( } void __ubsan_handle_nonnull_return(const struct UbsanSourceLocation *loc) { - __ubsan_abort(loc, "nonnull return"); + __ubsan_abort(loc, "nonnull return")(); + __ubsan_unreachable(); } void __ubsan_handle_nonnull_return_abort( diff --git a/libc/log/attachdebugger.c b/libc/log/attachdebugger.c index e1d731268..6617fb71a 100644 --- a/libc/log/attachdebugger.c +++ b/libc/log/attachdebugger.c @@ -42,7 +42,7 @@ * possible UX for debugging your app, for varying levels of available * information, on most of the various platforms. * - * Before calling this function, consider placing showcrashreports() in + * Before calling this function, consider placing ShowCrashReports() in * your main function and calling DebugBreak() wherever you want; it's * safer. Also note the "GDB" environment variable can be set to empty * string, as a fail-safe for disabling this behavior. diff --git a/libc/log/backtrace2.c b/libc/log/backtrace2.c index b1e0b0ead..0648b13d4 100644 --- a/libc/log/backtrace2.c +++ b/libc/log/backtrace2.c @@ -79,7 +79,7 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) { * DWARF is a weak standard. Platforms that use LLVM or old GNU * usually can't be counted upon to print backtraces correctly. */ - if (!IsLinux() /* && !IsWindows() */) { + if (!IsLinux() && !IsWindows()) { ShowHint("won't print addr2line backtrace because probably llvm"); return -1; } diff --git a/libc/log/oncrash.c b/libc/log/oncrash.c index b19a7e8fd..b5792bfd3 100644 --- a/libc/log/oncrash.c +++ b/libc/log/oncrash.c @@ -231,7 +231,7 @@ relegated void ShowCrashReport(int err, int sig, struct siginfo *si, ? "Stack Overflow" : GetSiCodeName(sig, si->si_code), host, __getpid(), program_invocation_name, names.sysname, - names.nodename, names.release, names.version); + names.version, names.nodename, names.release); if (ctx) { kprintf("%n"); ShowFunctionCalls(ctx); diff --git a/libc/log/onkill.c b/libc/log/onkill.c index 1c37c0d61..971a0c94d 100644 --- a/libc/log/onkill.c +++ b/libc/log/onkill.c @@ -51,7 +51,7 @@ textexit static void __onkill(int sig, struct siginfo *si, /** * Installs default handlers for friendly kill signals. - * @see showcrashreports() + * @see ShowCrashReports() */ void callexitontermination(sigset_t *opt_out_exitsigs) { struct sigaction sa; diff --git a/libc/macros-cpp.internal.inc b/libc/macros-cpp.internal.inc index bee6d2e44..173ef7877 100644 --- a/libc/macros-cpp.internal.inc +++ b/libc/macros-cpp.internal.inc @@ -195,7 +195,7 @@ .endm .macro .poison name:req kind:req -#ifdef __FSANITIZE_ADDRESS__ +#ifdef __SANITIZE_ADDRESS__ 2323: .quad 0 .init.start 304,"_init_\name\()_poison_\@" push %rdi @@ -211,13 +211,13 @@ .endm .macro .underrun -#ifdef __FSANITIZE_ADDRESS__ +#ifdef __SANITIZE_ADDRESS__ .poison __BASE_FILE__, kAsanGlobalUnderrun #endif .endm .macro .overrun -#ifdef __FSANITIZE_ADDRESS__ +#ifdef __SANITIZE_ADDRESS__ .poison __BASE_FILE__, kAsanGlobalUnderrun #endif .endm diff --git a/libc/runtime/fork-nt.c b/libc/runtime/fork-nt.c index 6424df3e1..7accbf596 100644 --- a/libc/runtime/fork-nt.c +++ b/libc/runtime/fork-nt.c @@ -16,45 +16,30 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/assert.h" #include "libc/bits/weaken.h" -#include "libc/calls/calls.h" #include "libc/calls/internal.h" #include "libc/calls/ntspawn.h" #include "libc/calls/strace.internal.h" -#include "libc/dce.h" #include "libc/fmt/itoa.h" #include "libc/intrin/kprintf.h" #include "libc/macros.internal.h" #include "libc/mem/alloca.h" #include "libc/nexgen32e/nt2sysv.h" -#include "libc/nt/dll.h" -#include "libc/nt/enum/exceptionhandleractions.h" #include "libc/nt/enum/filemapflags.h" -#include "libc/nt/enum/memflags.h" #include "libc/nt/enum/pageflags.h" #include "libc/nt/enum/startf.h" -#include "libc/nt/enum/wt.h" -#include "libc/nt/files.h" #include "libc/nt/ipc.h" #include "libc/nt/memory.h" #include "libc/nt/process.h" #include "libc/nt/runtime.h" #include "libc/nt/signals.h" -#include "libc/nt/struct/context.h" #include "libc/nt/struct/ntexceptionpointers.h" -#include "libc/nt/synchronization.h" -#include "libc/nt/thread.h" #include "libc/runtime/directmap.internal.h" #include "libc/runtime/memtrack.internal.h" #include "libc/runtime/runtime.h" -#include "libc/str/str.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/sig.h" -#include "libc/sysv/errfuns.h" extern int __pid; extern unsigned long long __kbirth; diff --git a/libc/runtime/printargs.c b/libc/runtime/printargs.c index 986be2115..c8b08acae 100644 --- a/libc/runtime/printargs.c +++ b/libc/runtime/printargs.c @@ -102,15 +102,15 @@ textstartup void __printargs(int argc, char **argv, char **envp, } } STRACE("SPECIALS"); - STRACE(" ☼ %21s = %#s", "kTmpPath", kTmpPath); - STRACE(" ☼ %21s = %#s", "kNtSystemDirectory", kNtSystemDirectory); - STRACE(" ☼ %21s = %#s", "kNtWindowsDirectory", kNtWindowsDirectory); - STRACE(" ☼ %21s = %#s", "program_executable_name", program_executable_name); - STRACE(" ☼ %21s = %#s", "GetInterpreterExecutableName()", + STRACE(" ☼ %30s = %#s", "kTmpPath", kTmpPath); + STRACE(" ☼ %30s = %#s", "kNtSystemDirectory", kNtSystemDirectory); + STRACE(" ☼ %30s = %#s", "kNtWindowsDirectory", kNtWindowsDirectory); + STRACE(" ☼ %30s = %#s", "program_executable_name", program_executable_name); + STRACE(" ☼ %30s = %#s", "GetInterpreterExecutableName()", GetInterpreterExecutableName(path, sizeof(path))); - STRACE(" ☼ %21s = %p", "RSP", __builtin_frame_address(0)); - STRACE(" ☼ %21s = %p", "GetStackAddr()", GetStackAddr(0)); - STRACE(" ☼ %21s = %p", "GetStaticStackAddr(0)", GetStaticStackAddr(0)); - STRACE(" ☼ %21s = %p", "GetStackSize()", GetStackSize()); + STRACE(" ☼ %30s = %p", "RSP", __builtin_frame_address(0)); + STRACE(" ☼ %30s = %p", "GetStackAddr()", GetStackAddr(0)); + STRACE(" ☼ %30s = %p", "GetStaticStackAddr(0)", GetStaticStackAddr(0)); + STRACE(" ☼ %30s = %p", "GetStackSize()", GetStackSize()); #endif } diff --git a/libc/runtime/vfork.S b/libc/runtime/vfork.S index 11c6e1cfb..c10080021 100644 --- a/libc/runtime/vfork.S +++ b/libc/runtime/vfork.S @@ -36,7 +36,7 @@ // @returnstwice // @vforksafe vfork: -#ifdef __FSANITIZE_ADDRESS__ +#ifdef __SANITIZE_ADDRESS__ jmp fork # TODO: asan and vfork don't mix? .endfn vfork,globl #else @@ -98,4 +98,4 @@ vfork.bsd: .previous #endif /* DEBUGSYS */ -#endif /* __FSANITIZE_ADDRESS__ */ +#endif /* __SANITIZE_ADDRESS__ */ diff --git a/libc/stdio/appendd.c b/libc/stdio/appendd.c index 4a6c63775..b5b3c0468 100644 --- a/libc/stdio/appendd.c +++ b/libc/stdio/appendd.c @@ -59,7 +59,11 @@ ssize_t appendd(char **b, const void *s, size_t l) { return -1; } } - *(char *)mempcpy(p + z.i, s, l) = 0; + if (l) { + *(char *)mempcpy(p + z.i, s, l) = 0; + } else { + p[z.i] = 0; + } z.i += l; if (!IsTiny() && W == 8) z.i |= (size_t)APPEND_COOKIE << 48; *(size_t *)(p + z.n - W) = z.i; diff --git a/libc/stdio/fread.c b/libc/stdio/fread.c index 52fea4d94..4b47c862a 100644 --- a/libc/stdio/fread.c +++ b/libc/stdio/fread.c @@ -53,7 +53,7 @@ size_t fread(void *buf, size_t stride, size_t count, FILE *f) { p = buf; n = stride * count; m = f->end - f->beg; - memcpy(p, f->buf + f->beg, MIN(n, m)); + if (MIN(n, m)) memcpy(p, f->buf + f->beg, MIN(n, m)); if (n < m) { f->beg += n; return count; diff --git a/libc/str/crc32c.c b/libc/str/crc32c.c index b41b9340e..122b37942 100644 --- a/libc/str/crc32c.c +++ b/libc/str/crc32c.c @@ -35,6 +35,9 @@ uint32_t crc32c(uint32_t init, const void *data, size_t size) { pe = p + size; h = init ^ 0xffffffff; if (X86_HAVE(SSE4_2)) { + while (p < pe && ((intptr_t)p & 7)) { + h = h >> 8 ^ kCrc32cTab[(h & 0xff) ^ *p++]; + } for (; p + 8 <= pe; p += 8) { asm("crc32q\t%1,%0" : "+r"(h) : "rm"(*(const uint64_t *)p)); } diff --git a/test/libc/intrin/getenv_test.c b/test/libc/intrin/getenv_test.c index 21642a97c..5ef0c98df 100644 --- a/test/libc/intrin/getenv_test.c +++ b/test/libc/intrin/getenv_test.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" #include "libc/runtime/runtime.h" +#include "libc/testlib/ezbench.h" #include "libc/testlib/testlib.h" TEST(getenv, test) { @@ -26,3 +27,8 @@ TEST(getenv, test) { unsetenv("X"); EXPECT_EQ(NULL, getenv("X")); } + +BENCH(getenv, bench) { + char *getenv_(const char *) asm("getenv"); + EZBENCH2("getenv(TZ)", donothing, getenv_("TZ")); +} diff --git a/test/libc/intrin/kprintf_test.c b/test/libc/intrin/kprintf_test.c index 9aa5d6e92..4c9e8c1d5 100644 --- a/test/libc/intrin/kprintf_test.c +++ b/test/libc/intrin/kprintf_test.c @@ -18,6 +18,7 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/bits.h" #include "libc/calls/calls.h" +#include "libc/dce.h" #include "libc/errno.h" #include "libc/fmt/fmt.h" #include "libc/intrin/kprintf.h" @@ -230,6 +231,7 @@ TEST(ksnprintf, fuzzTheUnbreakable) { } TEST(kprintf, testFailure_wontClobberErrnoAndBypassesSystemCallSupport) { + if (IsWindows()) return; // TODO(jart): fixme int n; ASSERT_EQ(0, errno); EXPECT_SYS(0, 3, dup(2)); diff --git a/test/libc/log/backtrace_test.c b/test/libc/log/backtrace_test.c index 737ed908e..f6a64148f 100644 --- a/test/libc/log/backtrace_test.c +++ b/test/libc/log/backtrace_test.c @@ -16,11 +16,13 @@ │ 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/dce.h" #include "libc/errno.h" #include "libc/fmt/conv.h" #include "libc/intrin/asan.internal.h" +#include "libc/intrin/kprintf.h" #include "libc/log/libfatal.internal.h" #include "libc/log/log.h" #include "libc/mem/mem.h" @@ -280,15 +282,20 @@ TEST(ShowCrashReports, testStackOverrunCrash) { gc(IndentLines(output, -1, 0, 4))); __die(); } - if (!strstr(output, "☺☻♥♦♣♠•◘○")) { - fprintf(stderr, "ERROR: crash report didn't have memory diagram\n%s\n", - gc(IndentLines(output, -1, 0, 4))); - __die(); - } - if (!strstr(output, "stack overrun")) { - fprintf(stderr, "ERROR: crash report misclassified stack overrun\n%s\n", - gc(IndentLines(output, -1, 0, 4))); - __die(); + if (strstr(output, "'int' index 10 into 'char [10]' out of bounds")) { + // ubsan nailed it + } else { + // asan nailed it + if (!strstr(output, "☺☻♥♦♣♠•◘○")) { + fprintf(stderr, "ERROR: crash report didn't have memory diagram\n%s\n", + gc(IndentLines(output, -1, 0, 4))); + __die(); + } + if (!strstr(output, "stack overrun")) { + fprintf(stderr, "ERROR: crash report misclassified stack overrun\n%s\n", + gc(IndentLines(output, -1, 0, 4))); + __die(); + } } free(output); } @@ -376,7 +383,7 @@ TEST(ShowCrashReports, testDivideByZero) { } ASSERT_NE(-1, wait(&ws)); EXPECT_TRUE(WIFEXITED(ws)); - EXPECT_EQ(128 + SIGFPE, WEXITSTATUS(ws)); + assert(128 + SIGFPE == WEXITSTATUS(ws) || 77 == WEXITSTATUS(ws)); /* NULL is stopgap until we can copy symbol tablces into binary */ #ifdef __FNO_OMIT_FRAME_POINTER__ if (!OutputHasSymbol(output, "FpuCrash")) { @@ -385,35 +392,53 @@ TEST(ShowCrashReports, testDivideByZero) { __die(); } #endif - if (!strstr(output, gc(xasprintf("%d", pid)))) { - fprintf(stderr, "ERROR: crash report didn't have pid\n%s\n", - gc(IndentLines(output, -1, 0, 4))); - __die(); - } - if (!strstr(output, "SIGFPE")) { - fprintf(stderr, "ERROR: crash report didn't have signal name\n%s\n", - gc(IndentLines(output, -1, 0, 4))); - __die(); - } - if (!strstr(output, "3.141")) { - fprintf(stderr, "ERROR: crash report didn't have fpu register\n%s\n", - gc(IndentLines(output, -1, 0, 4))); - __die(); - } - if (!strstr(output, "0f0e0d0c0b0a09080706050403020100")) { - fprintf(stderr, "ERROR: crash report didn't have sse register\n%s\n", - gc(IndentLines(output, -1, 0, 4))); - __die(); - } - if (!strstr(output, "3133731337")) { - fprintf(stderr, "ERROR: crash report didn't have general register\n%s\n", - gc(IndentLines(output, -1, 0, 4))); - __die(); + if (strstr(output, "divrem overflow")) { + // UBSAN handled it + } else { + // ShowCrashReports() handled it + if (!strstr(output, gc(xasprintf("%d", pid)))) { + fprintf(stderr, "ERROR: crash report didn't have pid\n%s\n", + gc(IndentLines(output, -1, 0, 4))); + __die(); + } + if (!strstr(output, "SIGFPE")) { + fprintf(stderr, "ERROR: crash report didn't have signal name\n%s\n", + gc(IndentLines(output, -1, 0, 4))); + __die(); + } + if (!strstr(output, "3.141")) { + fprintf(stderr, "ERROR: crash report didn't have fpu register\n%s\n", + gc(IndentLines(output, -1, 0, 4))); + __die(); + } + if (!strstr(output, "0f0e0d0c0b0a09080706050403020100")) { + fprintf(stderr, "ERROR: crash report didn't have sse register\n%s\n", + gc(IndentLines(output, -1, 0, 4))); + __die(); + } + if (!strstr(output, "3133731337")) { + fprintf(stderr, "ERROR: crash report didn't have general register\n%s\n", + gc(IndentLines(output, -1, 0, 4))); + __die(); + } } free(output); } // clang-format off +// +// test/libc/log/backtrace_test.c:59: ubsan error: 'int' index 10 into 'char [10]' out of bounds +// 0x000000000040a352: __die at libc/log/die.c:40 +// 0x0000000000489bc8: __ubsan_abort at libc/intrin/ubsan.c:196 +// 0x0000000000489e1c: __ubsan_handle_out_of_bounds at libc/intrin/ubsan.c:242 +// 0x0000000000423666: BssOverrunCrash at test/libc/log/backtrace_test.c:59 +// 0x0000000000423e0a: SetUp at test/libc/log/backtrace_test.c:115 +// 0x000000000049350b: testlib_runtestcases at libc/testlib/testrunner.c:98 +// 0x000000000048ab50: testlib_runalltests at libc/testlib/runner.c:37 +// 0x00000000004028d0: main at libc/testlib/testmain.c:94 +// 0x0000000000403977: cosmo at libc/runtime/cosmo.S:69 +// 0x00000000004021ae: _start at libc/crt/crt.S:78 +// // asan error: global redzone 1-byte store at 0x00000048cf2a shadow 0x0000800899e5 // x // ........................................OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO @@ -444,7 +469,9 @@ TEST(ShowCrashReports, testDivideByZero) { // 0x00000000004026db: main at libc/testlib/testmain.c:155 // 0x000000000040323f: cosmo at libc/runtime/cosmo.S:64 // 0x000000000040219b: _start at libc/crt/crt.S:67 +// // clang-format on + TEST(ShowCrashReports, testBssOverrunCrash) { if (!IsAsan()) return; size_t got; @@ -486,7 +513,8 @@ TEST(ShowCrashReports, testBssOverrunCrash) { __die(); } #endif - if (!strstr(output, "☺☻♥♦♣♠•◘○") || !strstr(output, "global redzone")) { + if (!strstr(output, "'int' index 10 into 'char [10]' out of bounds") && + (!strstr(output, "☺☻♥♦♣♠•◘○") || !strstr(output, "global redzone"))) { fprintf(stderr, "ERROR: crash report didn't have memory diagram\n%s\n", gc(IndentLines(output, -1, 0, 4))); __die(); @@ -556,7 +584,7 @@ TEST(ShowCrashReports, testNpeCrash) { EXPECT_TRUE(WIFEXITED(ws)); EXPECT_EQ(77, WEXITSTATUS(ws)); /* NULL is stopgap until we can copy symbol tables into binary */ - if (!strstr(output, "null pointer dereference")) { + if (!strstr(output, "null pointer")) { fprintf(stderr, "ERROR: crash report didn't diagnose the problem\n%s\n", gc(IndentLines(output, -1, 0, 4))); __die(); @@ -568,10 +596,15 @@ TEST(ShowCrashReports, testNpeCrash) { __die(); } #endif - if (!strstr(output, "∅∅∅∅")) { - fprintf(stderr, "ERROR: crash report didn't have shadow diagram\n%s\n", - gc(IndentLines(output, -1, 0, 4))); - __die(); + if (strstr(output, "null pointer access")) { + // ubsan nailed it + } else { + // asan nailed it + if (!strstr(output, "∅∅∅∅")) { + fprintf(stderr, "ERROR: crash report didn't have shadow diagram\n%s\n", + gc(IndentLines(output, -1, 0, 4))); + __die(); + } } free(output); } @@ -617,7 +650,8 @@ TEST(ShowCrashReports, testDataOverrunCrash) { __die(); } #endif - if (!strstr(output, "☺☻♥♦♣♠•◘○") || !strstr(output, "global redzone")) { + if (!strstr(output, "'int' index 10 into 'char [10]' out of bounds") && + (!strstr(output, "☺☻♥♦♣♠•◘○") || !strstr(output, "global redzone"))) { fprintf(stderr, "ERROR: crash report didn't have memory diagram\n%s\n", gc(IndentLines(output, -1, 0, 4))); __die(); @@ -663,8 +697,7 @@ TEST(ShowCrashReports, testNpeCrashAfterFinalize) { EXPECT_TRUE(WIFEXITED(ws)); EXPECT_EQ(IsAsan() ? 77 : 128 + SIGSEGV, WEXITSTATUS(ws)); /* NULL is stopgap until we can copy symbol tables into binary */ - if (!strstr(output, IsAsan() ? "null pointer dereference" - : "Uncaught SIGSEGV (SEGV_MAPERR)")) { + if (!strstr(output, IsAsan() ? "null pointer" : "Uncaught SIGSEGV (SEGV_")) { fprintf(stderr, "ERROR: crash report didn't diagnose the problem\n%s\n", gc(IndentLines(output, -1, 0, 4))); __die(); diff --git a/test/libc/release/smoke.c b/test/libc/release/smoke.c index 322fd4ace..2c7d3b4e9 100644 --- a/test/libc/release/smoke.c +++ b/test/libc/release/smoke.c @@ -2,7 +2,7 @@ int main(int argc, char *argv[]) { int rc; char *s; FILE *f; - showcrashreports(); + ShowCrashReports(); s = strdup(argv[0]); s[0] = 'Z'; f = fopen("/dev/null", "w"); diff --git a/third_party/chibicc/as.c b/third_party/chibicc/as.c index 1e0382a6c..e02999665 100644 --- a/third_party/chibicc/as.c +++ b/third_party/chibicc/as.c @@ -1255,7 +1255,7 @@ static void EmitData(struct As *a, const void *p, uint128_t n) { struct Slice *s; s = &a->sections.p[a->section].binary; s->p = realloc(s->p, s->n + n); - memcpy(s->p + s->n, p, n); + if (n) memcpy(s->p + s->n, p, n); s->n += n; } @@ -3910,8 +3910,10 @@ static void Objectify(struct As *a, int path) { Fail(a, "unsupported relocation type"); } } - memcpy(elfwriter_reserve(elf, a->sections.p[i].binary.n), - a->sections.p[i].binary.p, a->sections.p[i].binary.n); + if (a->sections.p[i].binary.n) { + memcpy(elfwriter_reserve(elf, a->sections.p[i].binary.n), + a->sections.p[i].binary.p, a->sections.p[i].binary.n); + } elfwriter_commit(elf, a->sections.p[i].binary.n); elfwriter_finishsection(elf); } diff --git a/third_party/chibicc/as.main.c b/third_party/chibicc/as.main.c index 6e61db41b..c20008130 100644 --- a/third_party/chibicc/as.main.c +++ b/third_party/chibicc/as.main.c @@ -19,7 +19,7 @@ #include "third_party/chibicc/chibicc.h" int main(int argc, char *argv[]) { - showcrashreports(); + ShowCrashReports(); Assembler(argc, argv); return 0; } diff --git a/third_party/infozip/infozip.mk b/third_party/infozip/infozip.mk index 12b59237d..96b7ec53e 100644 --- a/third_party/infozip/infozip.mk +++ b/third_party/infozip/infozip.mk @@ -119,28 +119,28 @@ o/$(MODE)/third_party/infozip/zip.com.dbg: \ $(THIRD_PARTY_ZIP_DEPS) \ $(THIRD_PARTY_ZIP_COM_OBJS) \ $(CRT) \ - $(APE) + $(APE_NO_MODIFY_SELF) @$(APELINK) o/$(MODE)/third_party/infozip/zipsplit.com.dbg: \ $(THIRD_PARTY_ZIP_DEPS) \ $(THIRD_PARTY_ZIPSPLIT_OBJS) \ $(CRT) \ - $(APE) + $(APE_NO_MODIFY_SELF) @$(APELINK) o/$(MODE)/third_party/infozip/zipnote.com.dbg: \ $(THIRD_PARTY_ZIP_DEPS) \ $(THIRD_PARTY_ZIPNOTE_OBJS) \ $(CRT) \ - $(APE) + $(APE_NO_MODIFY_SELF) @$(APELINK) o/$(MODE)/third_party/infozip/zipcloak.com.dbg: \ $(THIRD_PARTY_ZIP_DEPS) \ $(THIRD_PARTY_ZIPCLOAK_OBJS) \ $(CRT) \ - $(APE) + $(APE_NO_MODIFY_SELF) @$(APELINK) .PHONY: o/$(MODE)/third_party/infozip diff --git a/third_party/infozip/zip/zip.c b/third_party/infozip/zip/zip.c index b380a833d..e16c21938 100644 --- a/third_party/infozip/zip/zip.c +++ b/third_party/infozip/zip/zip.c @@ -2195,7 +2195,7 @@ char **argv; /* command line tokens */ char **args = NULL; /* could be wide argv */ - if (!IsTiny()) showcrashreports(); + if (!IsTiny()) ShowCrashReports(); #ifdef THEOS /* the argument expansion from the standard library is full of bugs */ diff --git a/third_party/make/src/file.c b/third_party/make/src/file.c index f5d4ca12c..4e21aa450 100644 --- a/third_party/make/src/file.c +++ b/third_party/make/src/file.c @@ -872,7 +872,7 @@ file_timestamp_cons (const char *fname, time_t stamp, long int ns) char buf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1]; const char *f = fname ? fname : _("Current time"); ts = s <= OLD_MTIME ? ORDINARY_MTIME_MIN : ORDINARY_MTIME_MAX; - file_timestamp_sprintf (buf, ts); + file_timestamp_sprintf (buf, sizeof(buf), ts); OSS (error, NILF, _("%s: Timestamp out of range; substituting %s"), f, buf); } @@ -933,27 +933,37 @@ file_timestamp_now (int *resolution) /* Place into the buffer P a printable representation of the file timestamp TS. */ void -file_timestamp_sprintf (char *p, FILE_TIMESTAMP ts) +file_timestamp_sprintf (char *p, int n, FILE_TIMESTAMP ts) { + /* + * [jart] patch weakness upstream because buffer can probably overflow + * if integer timestamp is irreguular + */ + int m; time_t t = FILE_TIMESTAMP_S (ts); struct tm *tm = localtime (&t); if (tm) - sprintf (p, "%04d-%02d-%02d %02d:%02d:%02d", - tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); + snprintf (p, n, "%04d-%02d-%02d %02d:%02d:%02d", + tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec); else if (t < 0) - sprintf (p, "%ld", (long) t); + snprintf (p, n, "%ld", (long) t); else - sprintf (p, "%lu", (unsigned long) t); - p += strlen (p); + snprintf (p, n, "%lu", (unsigned long) t); + m = strlen (p); + p += m; + n -= m; + if (n <= 0) return; /* Append nanoseconds as a fraction, but remove trailing zeros. We don't know the actual timestamp resolution, since clock_getres applies only to local times, whereas this timestamp might come from a remote filesystem. So removing trailing zeros is the best guess that we can do. */ - sprintf (p, ".%09d", FILE_TIMESTAMP_NS (ts)); - p += strlen (p) - 1; + snprintf (p, n, ".%09d", FILE_TIMESTAMP_NS (ts)); + m = strlen (p) - 1; + p += m; + n += m; while (*p == '0') p--; p += *p != '.'; @@ -1052,7 +1062,7 @@ print_file (const void *item) else { char buf[FILE_TIMESTAMP_PRINT_LEN_BOUND + 1]; - file_timestamp_sprintf (buf, f->last_mtime); + file_timestamp_sprintf (buf, sizeof(buf), f->last_mtime); printf (_("# Last modified %s\n"), buf); } puts (f->updated diff --git a/third_party/make/src/filedef.h b/third_party/make/src/filedef.h index 3da844177..f8472b96e 100644 --- a/third_party/make/src/filedef.h +++ b/third_party/make/src/filedef.h @@ -164,14 +164,14 @@ int stemlen_compare (const void *v1, const void *v2); add 4 to allow for any 4-digit epoch year (e.g. 1970); add 25 to allow for "-MM-DD HH:MM:SS.NNNNNNNNN". */ #define FLOOR_LOG2_SECONDS_PER_YEAR 24 -#define FILE_TIMESTAMP_PRINT_LEN_BOUND \ +#define FILE_TIMESTAMP_PRINT_LEN_BOUND /* 62 */ \ (((sizeof (FILE_TIMESTAMP) * CHAR_BIT - 1 - FLOOR_LOG2_SECONDS_PER_YEAR) \ * 302 / 1000) \ + 1 + 1 + 4 + 25) FILE_TIMESTAMP file_timestamp_cons (char const *, time_t, long int); FILE_TIMESTAMP file_timestamp_now (int *); -void file_timestamp_sprintf (char *p, FILE_TIMESTAMP ts); +void file_timestamp_sprintf (char *, int, FILE_TIMESTAMP ); /* Return the mtime of file F (a struct file *), caching it. The value is NONEXISTENT_MTIME if the file does not exist. */ diff --git a/third_party/mbedtls/rsa.c b/third_party/mbedtls/rsa.c index dbb2ad8cf..2524c5fe0 100644 --- a/third_party/mbedtls/rsa.c +++ b/third_party/mbedtls/rsa.c @@ -15,6 +15,7 @@ │ See the License for the specific language governing permissions and │ │ limitations under the License. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/intrin/kprintf.h" #include "libc/rand/rand.h" #include "libc/runtime/runtime.h" #include "third_party/mbedtls/common.h" @@ -763,6 +764,10 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx, const unsigned char *input, unsigned char *output ) { + RSA_VALIDATE_RET( ctx ); + RSA_VALIDATE_RET( input ); + RSA_VALIDATE_RET( output ); + int ret = MBEDTLS_ERR_THIS_CORRUPTION; size_t olen; @@ -798,10 +803,6 @@ int mbedtls_rsa_private( mbedtls_rsa_context *ctx, * checked result; should be the same in the end. */ mbedtls_mpi I, C; - RSA_VALIDATE_RET( ctx ); - RSA_VALIDATE_RET( input ); - RSA_VALIDATE_RET( output ); - if( rsa_check_context( ctx, 1 /* private key checks */, f_rng != NULL /* blinding y/n */ ) != 0 ) { diff --git a/third_party/mbedtls/test/lib.c b/third_party/mbedtls/test/lib.c index 2869ea005..a95392471 100644 --- a/third_party/mbedtls/test/lib.c +++ b/third_party/mbedtls/test/lib.c @@ -87,7 +87,7 @@ int mbedtls_test_platform_setup(void) { char *p; int ret = 0; static char mybuf[2][BUFSIZ]; - showcrashreports(); + ShowCrashReports(); setvbuf(stdout, mybuf[0], _IOLBF, BUFSIZ); setvbuf(stderr, mybuf[1], _IOLBF, BUFSIZ); #if defined(MBEDTLS_PLATFORM_C) @@ -794,7 +794,8 @@ static int convert_params(size_t cnt, char **params, int *int_params_store) { * * \return 0 for success else 1 */ -static dontinline int test_snprintf(size_t n, const char *ref_buf, int ref_ret) { +static dontinline int test_snprintf(size_t n, const char *ref_buf, + int ref_ret) { int ret; char buf[10] = "xxxxxxxxx"; const char ref[10] = "xxxxxxxxx"; diff --git a/third_party/python/Objects/abstract.c b/third_party/python/Objects/abstract.c index d25c7def2..ea36ec8bd 100644 --- a/third_party/python/Objects/abstract.c +++ b/third_party/python/Objects/abstract.c @@ -2410,9 +2410,11 @@ _PyObject_FastCall_Prepend(PyObject *callable, /* use borrowed references */ args2[0] = obj; - memcpy(&args2[1], - args, - (nargs - 1)* sizeof(PyObject *)); + if (nargs > 1) { + memcpy(&args2[1], + args, + (nargs - 1)* sizeof(PyObject *)); + } result = _PyObject_FastCall(callable, args2, nargs); if (args2 != small_stack) { diff --git a/third_party/python/Objects/obmalloc.c b/third_party/python/Objects/obmalloc.c index ef574d950..06960776e 100644 --- a/third_party/python/Objects/obmalloc.c +++ b/third_party/python/Objects/obmalloc.c @@ -97,7 +97,7 @@ static inline void * _PyMem_RawMalloc(void *ctx, size_t size) { #ifdef __COSMOPOLITAN__ -#ifdef __FSANITIZE_ADDRESS__ +#ifdef __SANITIZE_ADDRESS__ return __asan_memalign(16, size); #else return dlmalloc(size); @@ -117,7 +117,7 @@ static inline void * _PyMem_RawCalloc(void *ctx, size_t nelem, size_t elsize) { #ifdef __COSMOPOLITAN__ -#ifdef __FSANITIZE_ADDRESS__ +#ifdef __SANITIZE_ADDRESS__ return __asan_calloc(nelem, elsize); #else return dlcalloc(nelem, elsize); @@ -141,7 +141,7 @@ _PyMem_RawRealloc(void *ctx, void *ptr, size_t size) if (size == 0) size = 1; #ifdef __COSMOPOLITAN__ -#ifdef __FSANITIZE_ADDRESS__ +#ifdef __SANITIZE_ADDRESS__ return __asan_realloc(ptr, size); #else return dlrealloc(ptr, size); @@ -155,7 +155,7 @@ static inline void _PyMem_RawFree(void *ctx, void *ptr) { #ifdef __COSMOPOLITAN__ -#ifdef __FSANITIZE_ADDRESS__ +#ifdef __SANITIZE_ADDRESS__ __asan_free(ptr); #else dlfree(ptr); @@ -2029,11 +2029,13 @@ int static void _PyMem_DebugRawFree(void *ctx, void *p) { - debug_alloc_api_t *api = (debug_alloc_api_t *)ctx; - uint8_t *q = (uint8_t *)p - 2*SST; /* address returned from malloc */ + debug_alloc_api_t *api; + uint8_t *q; size_t nbytes; if (p == NULL) return; + api = (debug_alloc_api_t *)ctx; + q = (uint8_t *)p - 2*SST; /* address returned from malloc */ _PyMem_DebugCheckAddress(api->api_id, p); nbytes = read_size_t(q); nbytes += 4*SST; diff --git a/third_party/python/Parser/tokenizer.c b/third_party/python/Parser/tokenizer.c index 5b83f8ad8..559bd8235 100644 --- a/third_party/python/Parser/tokenizer.c +++ b/third_party/python/Parser/tokenizer.c @@ -1501,7 +1501,8 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end) } while (c == ' ' || c == '\t' || c == '\014'); /* Set start of current token */ - tok->start = tok->cur - 1; + if (tok->cur) + tok->start = tok->cur - 1; /* Skip comment */ if (c == '#') { diff --git a/third_party/python/Python/pystate.c b/third_party/python/Python/pystate.c index af6abbd55..57ba86bce 100644 --- a/third_party/python/Python/pystate.c +++ b/third_party/python/Python/pystate.c @@ -17,7 +17,7 @@ #include "third_party/python/Include/pystate.h" /* clang-format off */ -#if defined(__FSANITIZE_ADDRESS__) || defined(__FSANITIZE_UNDEFINED__) +#if defined(__SANITIZE_ADDRESS__) || defined(__SANITIZE_UNDEFINED__) STATIC_YOINK("__die"); /* to guarantee backtraces */ #endif diff --git a/third_party/python/pyconfig.h b/third_party/python/pyconfig.h index a3f951d8c..33d6a177a 100644 --- a/third_party/python/pyconfig.h +++ b/third_party/python/pyconfig.h @@ -505,7 +505,7 @@ /* #undef WITH_LIBINTL */ /* Define if you want to compile in Python-specific mallocs */ -#ifndef __FSANITIZE_ADDRESS__ +#ifndef __SANITIZE_ADDRESS__ #define WITH_PYMALLOC 0 #endif @@ -580,7 +580,7 @@ /* #define FAST_LOOPS 1 /\* froot loops *\/ */ -#ifdef __FSANITIZE_UNDEFINED__ +#ifdef __SANITIZE_UNDEFINED__ #define HAVE_ALIGNED_REQUIRED 1 #endif diff --git a/third_party/quickjs/libbf.c b/third_party/quickjs/libbf.c index 4ded06508..3d81db9e3 100644 --- a/third_party/quickjs/libbf.c +++ b/third_party/quickjs/libbf.c @@ -297,7 +297,7 @@ int bf_set(bf_t *r, const bf_t *a) } r->sign = a->sign; r->expn = a->expn; - memcpy(r->tab, a->tab, a->len * sizeof(limb_t)); + if (a->len) memcpy(r->tab, a->tab, a->len * sizeof(limb_t)); return 0; } diff --git a/third_party/quickjs/qjs.c b/third_party/quickjs/qjs.c index 3eb9c2ea0..595dae456 100644 --- a/third_party/quickjs/qjs.c +++ b/third_party/quickjs/qjs.c @@ -24,6 +24,7 @@ */ #include "libc/assert.h" #include "libc/calls/weirdtypes.h" +#include "libc/dce.h" #include "libc/log/log.h" #include "libc/mem/mem.h" #include "libc/runtime/runtime.h" @@ -328,6 +329,10 @@ int main(int argc, char **argv) #endif size_t stack_size = 0; +#if IsModeDbg() + ShowCrashReports(); +#endif + #ifdef CONFIG_BIGNUM /* load jscalc runtime if invoked as 'qjscalc' */ { diff --git a/third_party/quickjs/qjsc.c b/third_party/quickjs/qjsc.c index a5bc56cf9..ebfb2399f 100644 --- a/third_party/quickjs/qjsc.c +++ b/third_party/quickjs/qjsc.c @@ -488,6 +488,11 @@ int main(int argc, char **argv) BOOL bignum_ext = FALSE; #endif namelist_t dynamic_module_list; + +#if IsModeDbg() + ShowCrashReports(); +#endif + if (argc == 2 && !strcmp(argv[1], "-n")) return 0; out_filename = NULL; output_type = OUTPUT_EXECUTABLE; diff --git a/third_party/quickjs/quickjs.c b/third_party/quickjs/quickjs.c index 00b941cf8..151311542 100644 --- a/third_party/quickjs/quickjs.c +++ b/third_party/quickjs/quickjs.c @@ -10926,7 +10926,7 @@ typedef struct CodeContext { #define M2(op1, op2) ((op1) | ((op2) << 8)) #define M3(op1, op2, op3) ((op1) | ((op2) << 8) | ((op3) << 16)) -#define M4(op1, op2, op3, op4) ((op1) | ((op2) << 8) | ((op3) << 16) | ((op4) << 24)) +#define M4(op1, op2, op3, op4) ((op1) | ((op2) << 8) | ((op3) << 16) | ((uint32_t)(op4) << 24)) static BOOL code_match(CodeContext *s, int pos, ...) { diff --git a/third_party/quickjs/run-test262.c b/third_party/quickjs/run-test262.c index 7e026a679..1527e9806 100644 --- a/third_party/quickjs/run-test262.c +++ b/third_party/quickjs/run-test262.c @@ -1950,7 +1950,7 @@ int main(int argc, char **argv) BOOL is_test262_harness = FALSE; BOOL is_module = FALSE; - showcrashreports(); + ShowCrashReports(); #if !defined(_WIN32) /* Date tests assume California local time */ diff --git a/third_party/sqlite3/sqlite3.mk b/third_party/sqlite3/sqlite3.mk index a93eb28ef..6976ac398 100644 --- a/third_party/sqlite3/sqlite3.mk +++ b/third_party/sqlite3/sqlite3.mk @@ -174,8 +174,8 @@ o/$(MODE)/%.shell.o: %.c o/$(MODE)/%.o @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) $(OUTPUT_OPTION) $< o/$(MODE)/third_party/sqlite3/shell.shell.o: QUOTA = -M512m -C16 -o/$(MODE)/third_party/sqlite3/vdbe.o: QUOTA = -M512m -o/$(MODE)/third_party/sqlite3/vdbe.shell.o: QUOTA = -M512m +o/$(MODE)/third_party/sqlite3/vdbe.o: QUOTA = -M1024m +o/$(MODE)/third_party/sqlite3/vdbe.shell.o: QUOTA = -M1024m o/$(MODE)/third_party/sqlite3/fts5.o: QUOTA = -M512m -C16 o/$(MODE)/third_party/sqlite3/fts5.shell.o: QUOTA = -M512m -C16 diff --git a/third_party/zlib/trees.c b/third_party/zlib/trees.c index b1ce64568..d4a69e75f 100644 --- a/third_party/zlib/trees.c +++ b/third_party/zlib/trees.c @@ -809,7 +809,9 @@ void _tr_stored_block(struct DeflateState *s, charf *buf, uint64_t stored_len, bi_windup(s); /* align on byte boundary */ put_short(s, (uint16_t)stored_len); put_short(s, (uint16_t)~stored_len); - memcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len); + if (stored_len) { + memcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len); + } s->pending += stored_len; #ifdef ZLIB_DEBUG s->compressed_len = (s->compressed_len + 3 + 7) & (uint64_t)~7L; diff --git a/tool/build/blinkenlights.c b/tool/build/blinkenlights.c index 584922e06..a45f7a7dd 100644 --- a/tool/build/blinkenlights.c +++ b/tool/build/blinkenlights.c @@ -3105,7 +3105,7 @@ static void OnlyRunOnFirstCpu(void) { } int main(int argc, char *argv[]) { - if (!NoDebug()) showcrashreports(); + if (!NoDebug()) ShowCrashReports(); pty = NewPty(); pty->conf |= kPtyNocanon; m = NewMachine(); diff --git a/tool/build/calculator.c b/tool/build/calculator.c index dbda58008..cc2d7e98d 100644 --- a/tool/build/calculator.c +++ b/tool/build/calculator.c @@ -727,7 +727,7 @@ void GetOpts(int argc, char *argv[]) { int main(int argc, char *argv[]) { int i, rc; - showcrashreports(); + ShowCrashReports(); GetOpts(argc, argv); xsigaction(SIGFPE, OnDivideError, 0, 0, 0); if (optind == argc) { diff --git a/tool/build/compile.c b/tool/build/compile.c index d6fb9af26..a30df1e30 100644 --- a/tool/build/compile.c +++ b/tool/build/compile.c @@ -101,7 +101,7 @@ FLAGS\n\ -C SECS set cpu limit [default 16]\n\ -L SECS set lat limit [default 90]\n\ -M BYTES set mem limit [default 512m]\n\ - -F BYTES set fsz limit [default 100m]\n\ + -F BYTES set fsz limit [default 256m]\n\ -O BYTES set out limit [default 1m]\n\ -s decrement verbosity [default 4]\n\ -v increments verbosity [default 4]\n\ @@ -725,14 +725,15 @@ int main(int argc, char *argv[]) { int ws, opt, exitcode; char *s, *p, *q, **envp; + mode = firstnonnull(getenv("MODE"), MODE); + /* * parse prefix arguments */ - mode = MODE; verbose = 4; timeout = 90; /* secs */ cpuquota = 16; /* secs */ - fszquota = 100 * 1000 * 1000; /* bytes */ + fszquota = 256 * 1000 * 1000; /* bytes */ memquota = 512 * 1024 * 1024; /* bytes */ if ((s = getenv("V"))) verbose = atoi(s); while ((opt = getopt(argc, argv, "hnvstC:M:F:A:T:V:O:L:")) != -1) { @@ -785,6 +786,16 @@ int main(int argc, char *argv[]) { exit(1); } + /* + * extend limits for slow UBSAN in particular + */ + if (!strcmp(mode, "dbg") || !strcmp(mode, "ubsan")) { + cpuquota *= 2; + fszquota *= 2; + memquota *= 2; + timeout *= 2; + } + cmd = argv[optind]; if (!strchr(cmd, '/')) { if (!(cmd = commandv(cmd, ccpath))) exit(127); @@ -957,11 +968,13 @@ int main(int argc, char *argv[]) { } if (wantasan) { AddArg("-fsanitize=address"); - AddArg("-D__FSANITIZE_ADDRESS__"); + /* compiler adds this by default */ + /* AddArg("-D__SANITIZE_ADDRESS__"); */ } if (wantubsan) { AddArg("-fsanitize=undefined"); AddArg("-fno-data-sections"); + AddArg("-D__SANITIZE_UNDEFINED__"); } if (no_sanitize_null) { AddArg("-fno-sanitize=null"); diff --git a/tool/build/dis.c b/tool/build/dis.c index 401792e4c..3189f2f40 100644 --- a/tool/build/dis.c +++ b/tool/build/dis.c @@ -275,7 +275,7 @@ void Disassemble(void) { } int main(int argc, char *argv[]) { - showcrashreports(); + ShowCrashReports(); int fd; void *map; struct stat st; diff --git a/tool/build/lib/elfwriter.c b/tool/build/lib/elfwriter.c index 580c2df47..35b449947 100644 --- a/tool/build/lib/elfwriter.c +++ b/tool/build/lib/elfwriter.c @@ -141,7 +141,9 @@ static void FlushTables(struct ElfWriter *elf) { symtab = AppendSection(elf, ".symtab", SHT_SYMTAB, 0); for (i = 0; i < ARRAYLEN(elf->syms); ++i) { size = elf->syms[i]->i * sizeof(Elf64_Sym); - memcpy(elfwriter_reserve(elf, size), elf->syms[i]->p, size); + if (size) { + memcpy(elfwriter_reserve(elf, size), elf->syms[i]->p, size); + } elfwriter_commit(elf, size); } FinishSection(elf); diff --git a/tool/build/lz4toasm.c b/tool/build/lz4toasm.c index e3b5ad70b..037925cbf 100644 --- a/tool/build/lz4toasm.c +++ b/tool/build/lz4toasm.c @@ -63,7 +63,7 @@ int main(int argc, char *argv[]) { int opt; FILE *fin, *fout; - showcrashreports(); + ShowCrashReports(); while ((opt = getopt(argc, argv, "ho:s:z:")) != -1) { switch (opt) { diff --git a/tool/build/runitd.c b/tool/build/runitd.c index 2d2225a8b..9887efaa9 100644 --- a/tool/build/runitd.c +++ b/tool/build/runitd.c @@ -87,7 +87,7 @@ * - 1 byte exit status */ -#define DEATH_CLOCK_SECONDS 16 +#define DEATH_CLOCK_SECONDS 32 #define kLogFile "o/runitd.log" #define kLogMaxBytes (2 * 1000 * 1000) diff --git a/tool/decode/elf.c b/tool/decode/elf.c index 1948ae7d9..4d9a5c4a3 100644 --- a/tool/decode/elf.c +++ b/tool/decode/elf.c @@ -302,7 +302,7 @@ static void printelfrelocations(void) { int main(int argc, char *argv[]) { int fd; - showcrashreports(); + ShowCrashReports(); if (argc != 2) { fprintf(stderr, "usage: %s FILE\n", argv[0]); return 1; diff --git a/tool/decode/scrubdox.c b/tool/decode/scrubdox.c index 01b662d34..5a778a00a 100644 --- a/tool/decode/scrubdox.c +++ b/tool/decode/scrubdox.c @@ -150,7 +150,7 @@ static void DoIt(int y, int x) { int main(int argc, char *argv[]) { char *s; int y, x; - showcrashreports(); + ShowCrashReports(); f = stdin; while ((s = chomp(xgetline(f)))) { n = strwidth(s, 0); diff --git a/tool/decode/zip.c b/tool/decode/zip.c index 549ec77ed..66d38def3 100644 --- a/tool/decode/zip.c +++ b/tool/decode/zip.c @@ -488,7 +488,7 @@ int main(int argc, char *argv[]) { int fd; uint8_t *map; struct stat st; - showcrashreports(); + ShowCrashReports(); CHECK_EQ(2, argc); CHECK_NE(-1, (fd = open(argv[1], O_RDONLY))); CHECK_NE(-1, fstat(fd, &st)); diff --git a/tool/decode/zip2.c b/tool/decode/zip2.c index 039abe1d9..dcc88ada5 100644 --- a/tool/decode/zip2.c +++ b/tool/decode/zip2.c @@ -266,7 +266,7 @@ int main(int argc, char *argv[]) { int fd; uint8_t *map; struct stat st; - showcrashreports(); + ShowCrashReports(); CHECK_EQ(2, argc); CHECK_NE(-1, (fd = open(argv[1], O_RDONLY))); CHECK_NE(-1, fstat(fd, &st)); diff --git a/tool/emacs/c.lang b/tool/emacs/c.lang index 3ab13c568..860ca33ef 100644 --- a/tool/emacs/c.lang +++ b/tool/emacs/c.lang @@ -1793,7 +1793,8 @@ Keywords={ "__PG__", "__MFENTRY__", "__MNO_VZEROUPPER__", -"__FSANITIZE_UNDEFINED__", +"__SANITIZE_ADDRESS__", +"__SANITIZE_UNDEFINED__", "__MNOP_MCOUNT__", "__MRECORD_MCOUNT__", "__x86_64__", diff --git a/tool/emacs/cosmo-c-builtins.el b/tool/emacs/cosmo-c-builtins.el index bda245d50..fa3f767d9 100644 --- a/tool/emacs/cosmo-c-builtins.el +++ b/tool/emacs/cosmo-c-builtins.el @@ -45,6 +45,8 @@ "__INTMAX_C" "__UINTMAX_C" "__TIMESTAMP__" + "__SANITIZE_ADDRESS__" + "__SANITIZE_UNDEFINED__" "__FP_FAST_FMA" "__FP_FAST_FMAF" "__FP_FAST_FMAL" diff --git a/tool/emacs/cosmo-cpp-constants.el b/tool/emacs/cosmo-cpp-constants.el index c9d6e0337..a9ca7fb8c 100644 --- a/tool/emacs/cosmo-cpp-constants.el +++ b/tool/emacs/cosmo-cpp-constants.el @@ -158,8 +158,6 @@ "__PG__" "__MFENTRY__" "__MNO_VZEROUPPER__" - "__FSANITIZE_ADDRESS__" - "__FSANITIZE_UNDEFINED__" "__MNO_RED_ZONE__" "__MNOP_MCOUNT__" "__MRECORD_MCOUNT__" diff --git a/tool/net/dig.c b/tool/net/dig.c index 385759831..9e6cc1f48 100644 --- a/tool/net/dig.c +++ b/tool/net/dig.c @@ -75,7 +75,7 @@ void lookup(const char *name) { int main(int argc, char *argv[]) { int i; - showcrashreports(); + ShowCrashReports(); for (i = 1; i < argc; ++i) lookup(argv[i]); return 0; } diff --git a/tool/net/redbean.c b/tool/net/redbean.c index b930363c7..ec461818c 100644 --- a/tool/net/redbean.c +++ b/tool/net/redbean.c @@ -7341,7 +7341,7 @@ void RedBean(int argc, char *argv[]) { int main(int argc, char *argv[]) { if (!IsTiny()) { setenv("GDB", "", true); - showcrashreports(); + ShowCrashReports(); } RedBean(argc, argv); if (IsModeDbg()) { diff --git a/tool/viz/derasterize.c b/tool/viz/derasterize.c index f6fe689c1..45f5115ae 100644 --- a/tool/viz/derasterize.c +++ b/tool/viz/derasterize.c @@ -588,7 +588,7 @@ int main(int argc, char *argv[]) { size_t size; char *option; unsigned yd, xd; - showcrashreports(); + ShowCrashReports(); GetOpts(argc, argv); // if sizes are given, 2 cases: // - positive values: use that as the target size diff --git a/tool/viz/generatematrix.c b/tool/viz/generatematrix.c index 4f47bdddb..3fb237913 100644 --- a/tool/viz/generatematrix.c +++ b/tool/viz/generatematrix.c @@ -306,7 +306,7 @@ void GenerateMatrix(FILE *f) { int main(int argc, char *argv[]) { int i; FILE *f; - showcrashreports(); + ShowCrashReports(); GetOpts(argc, argv); CHECK_NOTNULL((f = fopen(path_, "w"))); if (optind < argc) FATALF("TODO(jart): support input files"); diff --git a/tool/viz/life.c b/tool/viz/life.c index fad4e69a8..73adffe54 100644 --- a/tool/viz/life.c +++ b/tool/viz/life.c @@ -1397,7 +1397,7 @@ static void Gui(void) { ╚────────────────────────────────────────────────────────────────────────────│*/ int main(int argc, char *argv[]) { - if (!NoDebug()) showcrashreports(); + if (!NoDebug()) ShowCrashReports(); out = 1; speed = 1; tyn = right = 80; diff --git a/tool/viz/magikarp.c b/tool/viz/magikarp.c index 253d89445..3cba134aa 100644 --- a/tool/viz/magikarp.c +++ b/tool/viz/magikarp.c @@ -465,8 +465,8 @@ static unsigned char Opacify2(unsigned yw, unsigned xw, } static dontinline void PrintImage2(unsigned yw, unsigned xw, - unsigned char img[4][yw][xw], unsigned yn, - unsigned xn) { + unsigned char img[4][yw][xw], unsigned yn, + unsigned xn) { bool didhalfy; unsigned y, x; didhalfy = false; @@ -501,8 +501,8 @@ static dontinline void PrintImage2(unsigned yw, unsigned xw, } static dontinline void *DeblinterlaceRgba2(unsigned yn, unsigned xn, - unsigned char D[4][yn][xn], - const unsigned char S[yn][xn][4]) { + unsigned char D[4][yn][xn], + const unsigned char S[yn][xn][4]) { unsigned y, x; for (y = 0; y < yn; ++y) { for (x = 0; x < xn; ++x) { @@ -588,8 +588,8 @@ void ProcessImageMagikarp(unsigned yn, unsigned xn, } dontinline void WithImageFile(const char *path, - void fn(unsigned yn, unsigned xn, - unsigned char img[yn][xn][4])) { + void fn(unsigned yn, unsigned xn, + unsigned char img[yn][xn][4])) { struct stat st; int fd, yn, xn; void *map, *data; @@ -634,7 +634,7 @@ int main(int argc, char *argv[]) { break; } } - showcrashreports(); + ShowCrashReports(); for (i = optind; i < argc; ++i) { WithImageFile(argv[i], scaler); } diff --git a/tool/viz/memzoom.c b/tool/viz/memzoom.c index f70fad40b..5d801d459 100644 --- a/tool/viz/memzoom.c +++ b/tool/viz/memzoom.c @@ -926,7 +926,7 @@ static void GetOpts(int argc, char *argv[]) { } int main(int argc, char *argv[]) { - if (!NoDebug()) showcrashreports(); + if (!NoDebug()) ShowCrashReports(); out = 1; GetOpts(argc, argv); Open(); diff --git a/tool/viz/ntmaster.c b/tool/viz/ntmaster.c index 55cd92fea..349d3fc9e 100644 --- a/tool/viz/ntmaster.c +++ b/tool/viz/ntmaster.c @@ -35,7 +35,7 @@ int main(int argc, char *argv[]) { FILE *f; int i, n, t; char *sym, tabs[64]; - showcrashreports(); + ShowCrashReports(); f = fopen("/tmp/syms.txt", "r"); memset(tabs, '\t', 64); while ((sym = chomp(xgetline(f)))) { diff --git a/tool/viz/printpeb.c b/tool/viz/printpeb.c index 1a31a9399..43eb84d26 100644 --- a/tool/viz/printpeb.c +++ b/tool/viz/printpeb.c @@ -38,6 +38,7 @@ #include "libc/stdio/stdio.h" #include "libc/sysv/consts/madv.h" #include "libc/sysv/consts/o.h" +#include "libc/time/time.h" #include "tool/decode/lib/flagger.h" #include "tool/decode/lib/idname.h" @@ -518,7 +519,6 @@ void PrintModulesMemoryOrder(void) { } int main(int argc, char *argv[]) { - showcrashreports(); if (IsLinux()) { return NextBestThing(); } diff --git a/tool/viz/printvideo.c b/tool/viz/printvideo.c index 4f312e3c1..4d54bb71d 100644 --- a/tool/viz/printvideo.c +++ b/tool/viz/printvideo.c @@ -1536,7 +1536,7 @@ int main(int argc, char *argv[]) { sigaddset(&wut, SIGCHLD); sigaddset(&wut, SIGPIPE); sigprocmask(SIG_SETMASK, &wut, NULL); - showcrashreports(); + ShowCrashReports(); fullclear_ = true; GetOpts(argc, argv); if (!tuned_) PickDefaults();