mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-04 18:28:30 +00:00
Add MODE=optlinux build mode (#141)
This commit is contained in:
parent
226aaf3547
commit
67b5200a0b
111 changed files with 934 additions and 854 deletions
|
@ -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 *);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue