Add MODE=optlinux build mode (#141)

This commit is contained in:
Justine Tunney 2021-10-14 19:36:49 -07:00
parent 226aaf3547
commit 67b5200a0b
111 changed files with 934 additions and 854 deletions

View file

@ -1,10 +1,18 @@
#ifndef COSMOPOLITAN_LIBC_LOG_BACKTRACE_H_
#define COSMOPOLITAN_LIBC_LOG_BACKTRACE_H_
#include "libc/nexgen32e/stackframe.h"
#include "libc/runtime/memtrack.internal.h"
#include "libc/runtime/symbols.internal.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
forceinline pureconst bool IsValidStackFramePointer(struct StackFrame *x) {
return IsLegalPointer(x) && !((uintptr_t)x & 15) &&
(IsStaticStackFrame((uintptr_t)x >> 16) ||
IsSigAltStackFrame((uintptr_t)x >> 16) ||
IsOldStackFrame((uintptr_t)x >> 16));
}
void ShowBacktrace(int, const struct StackFrame *);
int PrintBacktraceUsingSymbols(int, const struct StackFrame *,
struct SymbolTable *);

View file

@ -70,6 +70,9 @@ static noasan int PrintBacktraceUsingAddr2line(int fd,
garbage = weaken(__garbage);
gi = garbage ? garbage->i : 0;
for (frame = bp; frame && i < kBacktraceMaxFrames - 1; frame = frame->next) {
if (!IsValidStackFramePointer(frame)) {
return -1;
}
addr = frame->addr;
if (addr == weakaddr("__gc")) {
do {
@ -172,6 +175,7 @@ static noasan int PrintBacktrace(int fd, const struct StackFrame *bp) {
}
noasan void ShowBacktrace(int fd, const struct StackFrame *bp) {
#ifdef __FNO_OMIT_FRAME_POINTER__
/* asan runtime depends on this function */
static bool noreentry;
++g_ftrace;
@ -182,4 +186,9 @@ noasan void ShowBacktrace(int fd, const struct StackFrame *bp) {
noreentry = false;
}
--g_ftrace;
#else
__printf("ShowBacktrace() needs these flags to show C backtrace:\n"
"\t-D__FNO_OMIT_FRAME_POINTER__\n"
"\t-fno-omit-frame-pointer\n");
#endif
}

View file

@ -56,6 +56,10 @@ noinstrument noasan int PrintBacktraceUsingSymbols(int fd,
garbage = weaken(__garbage);
gi = garbage ? garbage->i : 0;
for (i = 0, frame = bp; frame; frame = frame->next) {
if (!IsValidStackFramePointer(frame)) {
__printf("%p corrupt frame pointer\n", frame);
break;
}
if (++i == LIMIT) {
__printf("<truncated backtrace>\n");
break;

View file

@ -17,10 +17,10 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/errno.h"
#include "libc/fmt/itoa.h"
#include "libc/log/internal.h"
#include "libc/log/log.h"
#include "libc/log/libfatal.internal.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
/**
* Handles failure of CHECK_xx() macros in -DNDEBUG mode.
@ -34,17 +34,9 @@
*/
relegated void ___check_fail_ndebug(uint64_t want, uint64_t got,
const char *opchar) {
char bx[21];
int lasterr;
lasterr = errno;
__start_fatal_ndebug();
__print_string("check failed: 0x");
__print(bx, uint64toarray_radix16(want, bx));
__print_string(" ");
__print_string(opchar);
__print_string(" 0x");
__print(bx, uint64toarray_radix16(got, bx));
__print_string(" (");
__print(bx, int64toarray_radix10(lasterr, bx));
__print_string(")\n");
__restore_tty(1);
__printf("\n%serror: %s: check failed: 0x%x %s 0x%x (%s)\n",
!g_isterminalinarticulate ? "\e[J" : "", program_invocation_name,
want, opchar, got, strerror(errno));
exit(1);
}

View file

@ -22,6 +22,7 @@
#include "libc/log/internal.h"
#include "libc/log/libfatal.internal.h"
#include "libc/log/log.h"
#include "libc/runtime/runtime.h"
/**
* Aborts process after printing a backtrace.
@ -33,11 +34,12 @@ relegated wontreturn void __die(void) {
static bool once;
if (cmpxchg(&once, false, true)) {
__restore_tty(1);
if (IsDebuggerPresent(false)) DebugBreak();
if (IsDebuggerPresent(false)) {
DebugBreak();
}
ShowBacktrace(2, NULL);
exit(77);
} else {
__write_str("PANIC: __DIE() DIED\r\n");
_exit(78);
quick_exit(77);
}
__write_str("PANIC: __DIE() DIED\r\n");
_Exit(78);
}

View file

@ -14,7 +14,6 @@ extern hidden struct termios g_oldtermios;
extern hidden struct sigaction g_oldcrashacts[8];
void __start_fatal(const char *, int) hidden;
void __start_fatal_ndebug(void) hidden;
void __oncrash(int, struct siginfo *, struct ucontext *) relegated;
void __restore_tty(int);

View file

@ -1,5 +1,6 @@
#ifndef COSMOPOLITAN_LIBC_LOG_LIBFATAL_INTERNAL_H_
#define COSMOPOLITAN_LIBC_LOG_LIBFATAL_INTERNAL_H_
#include "libc/calls/calls.h"
#include "libc/dce.h"
#include "libc/macros.internal.h"
#include "libc/nexgen32e/bsr.h"
@ -13,65 +14,96 @@ COSMOPOLITAN_C_START_
extern char __fatalbuf[];
void __printf(const char *, ...);
void __vprintf(const char *, va_list);
forceinline void __sysv_exit(long rc) {
forceinline long __sysv_exit(long rc) {
long ax;
#if defined(__MNO_RED_ZONE__) && defined(__GNUC__) && !defined(__STRICT_ANSI__)
asm volatile("call\t__syscall__"
: /* no outputs */
: "a"(__NR_exit_group), "D"(rc)
: "=a"(ax)
: "0"(__NR_exit_group), "D"(rc)
: "memory", "cc");
#else
ax = syscall(__NR_exit_group, rc);
#endif
return ax;
}
forceinline int __sysv_close(long fd) {
long ax;
#if defined(__MNO_RED_ZONE__) && defined(__GNUC__) && !defined(__STRICT_ANSI__)
asm volatile("call\t__syscall__"
: "=a"(ax)
: "0"(__NR_close), "D"(fd)
: "rdx", "memory", "cc");
#else
ax = syscall(__NR_close, fd);
#endif
return ax;
}
forceinline int __sysv_open(const char *path, long flags, long mode) {
long ax, dx;
#if defined(__MNO_RED_ZONE__) && defined(__GNUC__) && !defined(__STRICT_ANSI__)
asm volatile("call\t__syscall__"
: "=a"(ax), "=d"(dx)
: "0"(__NR_open), "D"(path), "S"(flags), "1"(mode)
: "memory", "cc");
#else
ax = syscall(__NR_open, path, flags, mode);
#endif
return ax;
}
forceinline long __sysv_read(long fd, void *data, unsigned long size) {
long ax, dx;
#if defined(__MNO_RED_ZONE__) && defined(__GNUC__) && !defined(__STRICT_ANSI__)
asm volatile("call\t__syscall__"
: "=a"(ax), "=d"(dx)
: "0"(__NR_read), "D"(fd), "S"(data), "1"(size)
: "memory", "cc");
#else
ax = syscall(__NR_read, fd, data, size);
#endif
return ax;
}
forceinline long __sysv_write(long fd, const void *data, unsigned long size) {
long ax, dx;
#if defined(__MNO_RED_ZONE__) && defined(__GNUC__) && !defined(__STRICT_ANSI__)
asm volatile("call\t__syscall__"
: "=a"(ax), "=d"(dx)
: "0"(__NR_write), "D"(fd), "S"(data), "1"(size)
: "memory", "cc");
#else
ax = syscall(__NR_write, fd, data, size);
#endif
return ax;
}
forceinline long __sysv_mprotect(void *addr, size_t size, long prot) {
long ax, dx;
#if defined(__MNO_RED_ZONE__) && defined(__GNUC__) && !defined(__STRICT_ANSI__)
asm volatile("call\t__syscall__"
: "=a"(ax), "=d"(dx)
: "0"(__NR_mprotect), "D"(addr), "S"(size), "1"(prot)
: "memory", "cc");
#else
ax = syscall(__NR_mprotect, addr, size, prot);
#endif
return ax;
}
forceinline int __sysv_getpid(void) {
long ax;
#if defined(__MNO_RED_ZONE__) && defined(__GNUC__) && !defined(__STRICT_ANSI__)
asm volatile("call\t__syscall__"
: "=a"(ax)
: "0"(__NR_getpid)
: "rdx", "memory", "cc");
#else
ax = syscall(__NR_getpid);
#endif
return ax;
}
@ -122,17 +154,32 @@ forceinline char *__stpcpy(char *d, const char *s) {
}
forceinline void *__repstosb(void *di, char al, size_t cx) {
#if defined(__x86__) && defined(__GNUC__) && !defined(__STRICT_ANSI__)
asm("rep stosb"
: "=D"(di), "=c"(cx), "=m"(*(char(*)[cx])di)
: "0"(di), "1"(cx), "a"(al));
return di;
#else
size_t i;
volatile char *volatile d = di;
while (cx--) *d++ = al;
return d;
#endif
}
forceinline void *__repmovsb(void *di, void *si, size_t cx) {
#if defined(__x86__) && defined(__GNUC__) && !defined(__STRICT_ANSI__)
asm("rep movsb"
: "=D"(di), "=S"(si), "=c"(cx), "=m"(*(char(*)[cx])di)
: "0"(di), "1"(si), "2"(cx), "m"(*(char(*)[cx])si));
return di;
#else
size_t i;
volatile char *volatile d = di;
volatile char *volatile s = si;
while (cx--) *d++ = *s++;
return d;
#endif
}
forceinline void *__mempcpy(void *d, const void *s, size_t n) {

View file

@ -99,7 +99,11 @@ relegated static const char *TinyStrSignal(int sig) {
relegated static void ShowFunctionCalls(ucontext_t *ctx) {
struct StackFrame *bp;
struct StackFrame goodframe;
if (ctx->uc_mcontext.rip && ctx->uc_mcontext.rbp) {
if (!ctx->uc_mcontext.rip) {
__printf("%s is NULL can't show backtrace\n", "RIP");
} else if (!ctx->uc_mcontext.rbp) {
__printf("%s is NULL can't show backtrace\n", "RBP");
} else {
goodframe.next = (struct StackFrame *)ctx->uc_mcontext.rbp;
goodframe.addr = ctx->uc_mcontext.rip;
bp = &goodframe;

View file

@ -25,7 +25,6 @@
* Prints initial part of fatal message.
*
* @note this is support code for __check_fail(), __assert_fail(), etc.
* @see __start_fatal_ndebug()
*/
relegated void __start_fatal(const char *file, int line) {
bool colorful;

View file

@ -1,44 +0,0 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/log/color.internal.h"
#include "libc/log/internal.h"
#include "libc/stdio/stdio.h"
asm(".section .privileged,\"ax\",@progbits\n__syscall:\n\t"
"syscall\n\t"
"ret\n\t"
".previous");
/**
* Prints initial part of fatal message.
*
* @note this is support code for __check_fail(), __assert_fail(), etc.
* @see __start_fatal()
*/
relegated void __start_fatal_ndebug(void) {
char s[16 + 16 + 16 + 16 + PATH_MAX + 16], *p = s;
__restore_tty(1);
*p++ = '\r';
if (cancolor()) p = stpcpy(p, "\e[J");
p = stpcpy(p, "error:");
p = stpcpy(p, program_invocation_name);
p = stpcpy(p, ": ");
write(2, s, p - s);
}