Implement crash reporting for AARCH64

The ShowCrashReports() feature for aarch64 should work even better than
the x86 crash reports. Thanks to the benefit of hindsight these reports
should be rock solid reliable and beautiful to read.

This change also improves the syscall polyfills for aarch64. Some of the
sys_foo() functions have been removed, usually because they're legacy or
downright footguns not worth building.
This commit is contained in:
Justine Tunney 2023-05-12 05:47:54 -07:00
parent 285e8a2348
commit 1f2a5a8fc1
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
42 changed files with 540 additions and 247 deletions

View file

@ -51,8 +51,14 @@ int dup2(int oldfd, int newfd) {
int rc;
if (__isfdkind(oldfd, kFdZip)) {
rc = enotsup();
#ifdef __aarch64__
} else if (oldfd == newfd) {
// linux aarch64 defines dup3() but not dup2(), which wasn't such a
// great decision, since the two syscalls don't behave the same way
if (!(rc = read(oldfd, 0, 0))) rc = oldfd;
#endif
} else if (!IsWindows()) {
rc = sys_dup2(oldfd, newfd);
rc = sys_dup2(oldfd, newfd, 0);
} else if (newfd < 0) {
rc = ebadf();
} else if (oldfd == newfd) {

View file

@ -63,6 +63,6 @@ int32_t sys_dup3(int32_t oldfd, int32_t newfd, int flags) {
if (!g_dup3.demodernize) {
return __sys_dup3(oldfd, newfd, flags);
} else {
return __fixupnewfd(sys_dup2(oldfd, newfd), flags);
return __fixupnewfd(sys_dup2(oldfd, newfd, 0), flags);
}
}

View file

@ -29,7 +29,7 @@
int getpgrp(void) {
int rc;
if (!IsWindows()) {
rc = sys_getpgrp();
rc = sys_getpgid(0);
} else {
rc = getpid();
}

View file

@ -19,9 +19,11 @@
#include "libc/calls/calls.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/nt/ipc.h"
#include "libc/sysv/consts/at.h"
#include "libc/sysv/consts/s.h"
#include "libc/sysv/errfuns.h"
@ -35,13 +37,20 @@
*/
int mkfifo(const char *pathname, unsigned mode) {
// TODO(jart): Windows?
int rc;
int e, rc;
if (IsAsan() && !__asan_is_valid_str(pathname)) {
rc = efault();
} else if (IsLinux()) {
rc = sys_mknod(pathname, mode | S_IFIFO, 0);
} else {
e = errno;
rc = sys_mkfifo(pathname, mode);
if (rc == -1 && rc == ENOSYS) {
errno = e;
rc = sys_mknod(pathname, mode | S_IFIFO, 0);
if (rc == -1 && rc == ENOSYS) {
errno = e;
rc = sys_mknodat(AT_FDCWD, pathname, mode | S_IFIFO, 0);
}
}
}
STRACE("mkfifo(%#s, %#o) → %d% m", pathname, mode, rc);
return rc;

View file

@ -19,8 +19,10 @@
#include "libc/calls/calls.h"
#include "libc/calls/syscall-sysv.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/strace.internal.h"
#include "libc/sysv/consts/at.h"
#include "libc/sysv/consts/s.h"
#include "libc/sysv/errfuns.h"
@ -39,14 +41,19 @@
* @asyncsignalsafe
*/
int mknod(const char *path, uint32_t mode, uint64_t dev) {
int rc;
int e, rc;
if (IsAsan() && !__asan_is_valid_str(path)) return efault();
if (mode & S_IFREG) return creat(path, mode & ~S_IFREG);
if (mode & S_IFDIR) return mkdir(path, mode & ~S_IFDIR);
if (mode & S_IFIFO) return mkfifo(path, mode & ~S_IFIFO);
if (!IsWindows()) {
/* TODO(jart): Whys there code out there w/ S_xxx passed via dev? */
e = errno;
rc = sys_mknod(path, mode, dev);
if (rc == -1 && rc == ENOSYS) {
errno = e;
rc = sys_mknodat(AT_FDCWD, path, mode, dev);
}
} else {
rc = enosys();
}

View file

@ -61,7 +61,11 @@ int pause(void) {
// function shall block until interrupted by a signal." ──Quoth
// IEEE 1003.1-2017 §functions/select
//
#ifdef __aarch64__
rc = sys_pselect(0, 0, 0, 0, 0, 0);
#else
rc = sys_select(0, 0, 0, 0, 0);
#endif
} else {
rc = sys_pause_nt();
}

40
libc/calls/poll-sysv.c Normal file
View file

@ -0,0 +1,40 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2023 Justine Alexandra Roberts Tunney
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted, provided that the
above copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/calls/struct/timespec.h"
#include "libc/errno.h"
#include "libc/sock/struct/pollfd.internal.h"
int sys_poll(struct pollfd *fds, size_t nfds, int timeout_ms) {
int e, rc;
struct timespec ts, *tp;
if (timeout_ms >= 0) {
ts = timespec_frommillis(timeout_ms);
tp = &ts;
} else {
tp = 0;
}
e = errno;
rc = sys_ppoll(fds, nfds, tp, 0, 0);
if (rc == -1 && errno == ENOSYS) {
errno = e;
rc = __sys_poll(fds, nfds, timeout_ms);
}
return rc;
}

View file

@ -7,7 +7,6 @@ COSMOPOLITAN_C_START_
axdx_t sys_gettimeofday(struct timeval *, struct timezone *, void *) _Hide;
int sys_futimes(int, const struct timeval *) _Hide;
int sys_futimesat(int, const char *, const struct timeval *) _Hide;
int sys_lutimes(const char *, const struct timeval *) _Hide;
int sys_utimes(const char *, const struct timeval *) _Hide;
axdx_t sys_gettimeofday_xnu(struct timeval *, struct timezone *, void *) _Hide;

View file

@ -32,9 +32,8 @@ i32 sys_chroot(const char *) _Hide;
i32 sys_close(i32) _Hide;
i32 sys_close_range(u32, u32, u32) _Hide;
i32 sys_closefrom(i32) _Hide;
i32 sys_creat(const char *, u32) _Hide;
i32 sys_dup(i32) _Hide;
i32 sys_dup2(i32, i32) _Hide;
i32 sys_dup2(i32, i32, i32) _Hide;
i32 sys_dup3(i32, i32, i32) _Hide;
i32 sys_execve(const char *, char *const[], char *const[]) _Hide;
i32 sys_execveat(i32, const char *, char *const[], char *const[], i32) _Hide;
@ -55,7 +54,6 @@ i32 sys_fsync(i32) _Hide;
i32 sys_ftruncate(i32, i64, i64) _Hide;
i32 sys_getcontext(void *) _Hide;
i32 sys_getpgid(i32) _Hide;
i32 sys_getpgrp(void) _Hide;
i32 sys_getppid(void) _Hide;
i32 sys_getpriority(i32, u32) _Hide;
i32 sys_getresgid(u32 *, u32 *, u32 *) _Hide;
@ -73,6 +71,7 @@ i32 sys_mincore(void *, u64, unsigned char *) _Hide;
i32 sys_mkdirat(i32, const char *, u32) _Hide;
i32 sys_mkfifo(const char *, u32) _Hide;
i32 sys_mknod(const char *, u32, u64) _Hide;
i32 sys_mknodat(i32, const char *, u32, u64) _Hide;
i32 sys_mprotect(void *, u64, i32) _Hide;
i32 sys_msync(void *, u64, i32) _Hide;
i32 sys_munmap(void *, u64) _Hide;
@ -127,7 +126,6 @@ i64 sys_lseek(i32, i64, i64, i64) _Hide;
i64 sys_pread(i32, void *, u64, i64, i64) _Hide;
i64 sys_pwrite(i32, const void *, u64, i64, i64) _Hide;
i64 sys_read(i32, void *, u64) _Hide;
i64 sys_readlink(const char *, char *, u64) _Hide;
i64 sys_readlinkat(i32, const char *, char *, u64) _Hide;
i64 sys_sendfile(i32, i32, i64 *, u64) _Hide;
i64 sys_splice(i32, i64 *, i32, i64 *, u64, u32) _Hide;