Make redbean StoreAsset() work better

- Better UBSAN error messages
- POSIX Advisory Locks polyfills
- Move redbean manual to /.help.txt
- System call memory safety in ASAN mode
- Character classification now does UNICODE
This commit is contained in:
Justine Tunney 2021-05-14 05:36:58 -07:00
parent 919b6fec10
commit 690be544da
228 changed files with 3653 additions and 3015 deletions

Binary file not shown.

View file

@ -20,7 +20,6 @@
#include "libc/stdio/stdio.h" #include "libc/stdio/stdio.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/sysv/consts/af.h" #include "libc/sysv/consts/af.h"
#include "libc/sysv/consts/ai.h"
#include "libc/sysv/consts/ipproto.h" #include "libc/sysv/consts/ipproto.h"
#include "libc/sysv/consts/shut.h" #include "libc/sysv/consts/shut.h"
#include "libc/sysv/consts/sock.h" #include "libc/sysv/consts/sock.h"

View file

@ -137,8 +137,8 @@ int mlockall(int);
int munlock(const void *, size_t); int munlock(const void *, size_t);
int munlockall(void); int munlockall(void);
int nice(int); int nice(int);
int open(const char *, int, ...) nodiscard; int open(const char *, int, ...);
int openanon(char *, unsigned) nodiscard; int openanon(char *, unsigned);
int openat(int, const char *, int, ...); int openat(int, const char *, int, ...);
int pause(void); int pause(void);
int personality(uint64_t); int personality(uint64_t);
@ -176,7 +176,7 @@ int stat(const char *, struct stat *);
int symlink(const char *, const char *); int symlink(const char *, const char *);
int symlinkat(const char *, int, const char *); int symlinkat(const char *, int, const char *);
int sync_file_range(int, int64_t, int64_t, unsigned); int sync_file_range(int, int64_t, int64_t, unsigned);
int sysinfo(struct sysinfo *) paramsnonnull(); int sysinfo(struct sysinfo *);
int touch(const char *, uint32_t); int touch(const char *, uint32_t);
int truncate(const char *, uint64_t); int truncate(const char *, uint64_t);
int ttyname_r(int, char *, size_t); int ttyname_r(int, char *, size_t);

View file

@ -18,36 +18,87 @@
*/ */
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/internal.h" #include "libc/calls/internal.h"
#include "libc/calls/struct/flock.h"
#include "libc/nt/enum/accessmask.h" #include "libc/nt/enum/accessmask.h"
#include "libc/nt/enum/fileflagandattributes.h" #include "libc/nt/enum/fileflagandattributes.h"
#include "libc/nt/enum/filelockflags.h"
#include "libc/nt/enum/filesharemode.h" #include "libc/nt/enum/filesharemode.h"
#include "libc/nt/files.h" #include "libc/nt/files.h"
#include "libc/nt/struct/byhandlefileinformation.h"
#include "libc/nt/struct/overlapped.h"
#include "libc/sysv/consts/f.h" #include "libc/sysv/consts/f.h"
#include "libc/sysv/consts/fd.h" #include "libc/sysv/consts/fd.h"
#include "libc/sysv/consts/o.h" #include "libc/sysv/consts/o.h"
#include "libc/sysv/errfuns.h" #include "libc/sysv/errfuns.h"
textwindows int sys_fcntl_nt(int fd, int cmd, unsigned arg) { static textwindows int sys_fcntl_nt_lock(struct Fd *f, int cmd, uintptr_t arg) {
uint32_t flags;
struct flock *l;
struct NtOverlapped ov;
int64_t pos, off, len, size;
struct NtByHandleFileInformation info;
l = (struct flock *)arg;
len = l->l_len;
off = l->l_start;
if (!len || l->l_whence == SEEK_END) {
if (!GetFileInformationByHandle(f->handle, &info)) return __winerr();
size = (uint64_t)info.nFileSizeHigh << 32 | info.nFileSizeLow;
} else {
size = 0;
}
if (l->l_whence != SEEK_SET) {
if (l->l_whence == SEEK_CUR) {
if (!SetFilePointerEx(f->handle, 0, &pos, SEEK_CUR)) return __winerr();
off = pos + off;
} else if (l->l_whence == SEEK_END) {
off = size - off;
} else {
return einval();
}
}
if (!len) len = size - off;
if (off < 0 || len < 0) return einval();
offset2overlap(off, &ov);
if (l->l_type == F_RDLCK || l->l_type == F_WRLCK) {
flags = 0;
if (cmd == F_SETLK) flags |= kNtLockfileFailImmediately;
if (l->l_type == F_WRLCK) flags |= kNtLockfileExclusiveLock;
if (LockFileEx(f->handle, flags, 0, len, len >> 32, &ov)) {
return 0;
} else {
return __winerr();
}
} else if (l->l_type == F_UNLCK) {
if (UnlockFileEx(f->handle, 0, len, len >> 32, &ov)) {
return 0;
} else {
return __winerr();
}
} else {
return einval();
}
}
textwindows int sys_fcntl_nt(int fd, int cmd, uintptr_t arg) {
uint32_t flags; uint32_t flags;
if (__isfdkind(fd, kFdFile) || __isfdkind(fd, kFdSocket)) { if (__isfdkind(fd, kFdFile) || __isfdkind(fd, kFdSocket)) {
switch (cmd) { if (cmd == F_GETFL) {
case F_GETFL:
return g_fds.p[fd].flags & (O_ACCMODE | O_APPEND | O_ASYNC | O_DIRECT | return g_fds.p[fd].flags & (O_ACCMODE | O_APPEND | O_ASYNC | O_DIRECT |
O_NOATIME | O_NONBLOCK); O_NOATIME | O_NONBLOCK);
case F_SETFL: } else if (cmd == F_SETFL) {
/* /*
* - O_APPEND doesn't appear to be tunable at cursory glance * - O_APPEND doesn't appear to be tunable at cursory glance
* - O_NONBLOCK might require we start doing all i/o in threads * - O_NONBLOCK might require we start doing all i/o in threads
* - O_DSYNC / O_RSYNC / O_SYNC maybe if we fsync() everything * - O_DSYNC / O_RSYNC / O_SYNC maybe if we fsync() everything
*/ */
return einval(); return einval();
case F_GETFD: } else if (cmd == F_GETFD) {
if (g_fds.p[fd].flags & O_CLOEXEC) { if (g_fds.p[fd].flags & O_CLOEXEC) {
return FD_CLOEXEC; return FD_CLOEXEC;
} else { } else {
return 0; return 0;
} }
case F_SETFD: } else if (cmd == F_SETFD) {
if (arg & FD_CLOEXEC) { if (arg & FD_CLOEXEC) {
g_fds.p[fd].flags |= O_CLOEXEC; g_fds.p[fd].flags |= O_CLOEXEC;
return FD_CLOEXEC; return FD_CLOEXEC;
@ -55,7 +106,9 @@ textwindows int sys_fcntl_nt(int fd, int cmd, unsigned arg) {
g_fds.p[fd].flags &= ~O_CLOEXEC; g_fds.p[fd].flags &= ~O_CLOEXEC;
return 0; return 0;
} }
default: } else if (cmd == F_SETLK || cmd == F_SETLKW) {
return sys_fcntl_nt_lock(g_fds.p + fd, cmd, arg);
} else {
return einval(); return einval();
} }
} else { } else {

31
libc/calls/fcntl-sysv.c Normal file
View file

@ -0,0 +1,31 @@
/*-*- 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 2021 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/internal.h"
#include "libc/calls/struct/flock.h"
#include "libc/sysv/consts/f.h"
int sys_fcntl(int fd, int cmd, uintptr_t arg) {
int rc;
bool islock;
islock = cmd == F_SETLK || cmd == F_SETLKW || cmd == F_GETLK;
if (islock) cosmo2flock(arg);
rc = __sys_fcntl(fd, cmd, arg);
if (islock) flock2cosmo(arg);
return rc;
}

View file

@ -25,6 +25,12 @@
* *
* CHECK_NE(-1, fcntl(fd, F_SETFD, FD_CLOEXEC)); * CHECK_NE(-1, fcntl(fd, F_SETFD, FD_CLOEXEC));
* *
* This function implements POSIX Advisory Locks, e.g.
*
* CHECK_NE(-1, fcntl(zfd, F_SETLKW, &(struct flock){F_WRLCK}));
* // ...
* CHECK_NE(-1, fcntl(zfd, F_SETLK, &(struct flock){F_UNLCK}));
*
* @param cmd can be F_{GET,SET}{FD,FL}, etc. * @param cmd can be F_{GET,SET}{FD,FL}, etc.
* @param arg can be FD_CLOEXEC, etc. depending * @param arg can be FD_CLOEXEC, etc. depending
* @return 0 on success, or -1 w/ errno * @return 0 on success, or -1 w/ errno
@ -32,9 +38,9 @@
*/ */
int fcntl(int fd, int cmd, ...) { int fcntl(int fd, int cmd, ...) {
va_list va; va_list va;
unsigned arg; uintptr_t arg;
va_start(va, cmd); va_start(va, cmd);
arg = va_arg(va, unsigned); arg = va_arg(va, uintptr_t);
va_end(va); va_end(va);
if (!IsWindows()) { if (!IsWindows()) {
return sys_fcntl(fd, cmd, arg); return sys_fcntl(fd, cmd, arg);

View file

@ -28,7 +28,7 @@
int __fixupnewfd(int fd, int flags) { int __fixupnewfd(int fd, int flags) {
if (fd != -1) { if (fd != -1) {
if (flags & O_CLOEXEC) { if (flags & O_CLOEXEC) {
sys_fcntl(fd, F_SETFD, FD_CLOEXEC); __sys_fcntl(fd, F_SETFD, FD_CLOEXEC);
} }
} }
return fd; return fd;

View file

@ -23,6 +23,8 @@
/** /**
* Acquires lock on file. * Acquires lock on file.
* *
* Please note multiple file descriptors means multiple locks.
*
* @param op can have LOCK_{SH,EX,NB,UN} for shared, exclusive, * @param op can have LOCK_{SH,EX,NB,UN} for shared, exclusive,
* non-blocking, and unlocking * non-blocking, and unlocking
* @return 0 on success, or -1 w/ errno * @return 0 on success, or -1 w/ errno

View file

@ -20,6 +20,7 @@
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/internal.h" #include "libc/calls/internal.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/sysv/errfuns.h" #include "libc/sysv/errfuns.h"
#include "libc/zipos/zipos.internal.h" #include "libc/zipos/zipos.internal.h"
@ -28,6 +29,7 @@
* @asyncsignalsafe * @asyncsignalsafe
*/ */
int fstat(int fd, struct stat *st) { int fstat(int fd, struct stat *st) {
if (IsAsan() && (!st || !__asan_is_valid(st, sizeof(*st)))) return efault();
if (__isfdkind(fd, kFdZip)) { if (__isfdkind(fd, kFdZip)) {
return weaken(__zipos_fstat)( return weaken(__zipos_fstat)(
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, st); (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, st);

View file

@ -20,7 +20,9 @@
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/internal.h" #include "libc/calls/internal.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/intrin/asan.internal.h"
#include "libc/sysv/consts/at.h" #include "libc/sysv/consts/at.h"
#include "libc/sysv/errfuns.h"
#include "libc/zipos/zipos.internal.h" #include "libc/zipos/zipos.internal.h"
/** /**
@ -36,6 +38,7 @@
*/ */
int fstatat(int dirfd, const char *path, struct stat *st, uint32_t flags) { int fstatat(int dirfd, const char *path, struct stat *st, uint32_t flags) {
struct ZiposUri zipname; struct ZiposUri zipname;
if (IsAsan() && (!st || !__asan_is_valid(st, sizeof(*st)))) return efault();
if (weaken(__zipos_stat) && weaken(__zipos_parseuri)(path, &zipname) != -1) { if (weaken(__zipos_stat) && weaken(__zipos_parseuri)(path, &zipname) != -1) {
return weaken(__zipos_stat)(&zipname, st); return weaken(__zipos_stat)(&zipname, st);
} else if (!IsWindows()) { } else if (!IsWindows()) {

View file

@ -34,7 +34,7 @@ char *sys_getcwd_xnu(char *res, size_t size) {
if ((fd = sys_openat(AT_FDCWD, ".", O_RDONLY | O_DIRECTORY, 0)) != -1) { if ((fd = sys_openat(AT_FDCWD, ".", O_RDONLY | O_DIRECTORY, 0)) != -1) {
if (sys_fstat(fd, &st[0]) != -1) { if (sys_fstat(fd, &st[0]) != -1) {
if (st[0].st_dev && st[0].st_ino) { if (st[0].st_dev && st[0].st_ino) {
if (sys_fcntl(fd, XNU_F_GETPATH, buf) != -1) { if (__sys_fcntl(fd, XNU_F_GETPATH, (uintptr_t)buf) != -1) {
if (sys_fstatat(AT_FDCWD, buf, &st[1], 0) != -1) { if (sys_fstatat(AT_FDCWD, buf, &st[1], 0) != -1) {
if (st[0].st_dev == st[1].st_dev && st[0].st_ino == st[1].st_ino) { if (st[0].st_dev == st[1].st_dev && st[0].st_ino == st[1].st_ino) {
if (memccpy(res, buf, '\0', size)) { if (memccpy(res, buf, '\0', size)) {

View file

@ -22,7 +22,7 @@
* Returns parent process id. * Returns parent process id.
* @asyncsignalsafe * @asyncsignalsafe
*/ */
int32_t getppid(void) { int getppid(void) {
if (!IsWindows()) { if (!IsWindows()) {
if (!IsNetbsd()) { if (!IsNetbsd()) {
return sys_getppid(); return sys_getppid();

View file

@ -109,6 +109,7 @@ char *sys_getcwd(char *, u64) hidden;
char *sys_getcwd_xnu(char *, u64) hidden; char *sys_getcwd_xnu(char *, u64) hidden;
i32 __sys_dup3(i32, i32, i32) hidden; i32 __sys_dup3(i32, i32, i32) hidden;
i32 __sys_execve(const char *, char *const[], char *const[]) hidden; i32 __sys_execve(const char *, char *const[], char *const[]) hidden;
i32 __sys_fcntl(i32, i32, u64) hidden;
i32 __sys_fstat(i32, struct stat *) hidden; i32 __sys_fstat(i32, struct stat *) hidden;
i32 __sys_fstatat(i32, const char *, struct stat *, i32) hidden; i32 __sys_fstatat(i32, const char *, struct stat *, i32) hidden;
i32 __sys_getrusage(i32, struct rusage *) hidden; i32 __sys_getrusage(i32, struct rusage *) hidden;
@ -131,7 +132,7 @@ i32 sys_fchmod(i32, u32) hidden;
i32 sys_fchmodat(i32, const char *, u32, u32) hidden; i32 sys_fchmodat(i32, const char *, u32, u32) hidden;
i32 sys_fchown(i64, u32, u32) hidden; i32 sys_fchown(i64, u32, u32) hidden;
i32 sys_fchownat(i32, const char *, u32, u32, u32) hidden; i32 sys_fchownat(i32, const char *, u32, u32, u32) hidden;
i32 sys_fcntl(i32, i32, ...) hidden; i32 sys_fcntl(i32, i32, u64) hidden;
i32 sys_fdatasync(i32) hidden; i32 sys_fdatasync(i32) hidden;
i32 sys_flock(i32, i32) hidden; i32 sys_flock(i32, i32) hidden;
i32 sys_fstat(i32, struct stat *) hidden; i32 sys_fstat(i32, struct stat *) hidden;
@ -229,6 +230,8 @@ int gethostname_nt(char *, size_t) hidden;
size_t __iovec_size(const struct iovec *, size_t) hidden; size_t __iovec_size(const struct iovec *, size_t) hidden;
void __rusage2linux(struct rusage *) hidden; void __rusage2linux(struct rusage *) hidden;
ssize_t WritevUninterruptible(int, struct iovec *, int); ssize_t WritevUninterruptible(int, struct iovec *, int);
void flock2cosmo(uintptr_t);
void cosmo2flock(uintptr_t);
/*───────────────────────────────────────────────────────────────────────────│─╗ /*───────────────────────────────────────────────────────────────────────────│─╗
cosmopolitan § syscalls » windows nt » veneers cosmopolitan § syscalls » windows nt » veneers
@ -245,7 +248,7 @@ int sys_execve_nt(const char *, char *const[], char *const[]) hidden;
int sys_faccessat_nt(int, const char *, int, uint32_t) hidden; int sys_faccessat_nt(int, const char *, int, uint32_t) hidden;
int sys_fadvise_nt(int, u64, u64, int) hidden; int sys_fadvise_nt(int, u64, u64, int) hidden;
int sys_fchdir_nt(int) hidden; int sys_fchdir_nt(int) hidden;
int sys_fcntl_nt(int, int, unsigned) hidden; int sys_fcntl_nt(int, int, uintptr_t) hidden;
int sys_fdatasync_nt(int) hidden; int sys_fdatasync_nt(int) hidden;
int sys_flock_nt(int, int) hidden; int sys_flock_nt(int, int) hidden;
int sys_fork_nt(void) hidden; int sys_fork_nt(void) hidden;

164
libc/calls/metaflock.c Normal file
View file

@ -0,0 +1,164 @@
/*-*- 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 2021 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/internal.h"
#include "libc/calls/struct/flock.h"
union metaflock {
struct flock cosmo;
struct flock_linux {
int16_t l_type;
int16_t l_whence;
int64_t l_start;
int64_t l_len;
int32_t l_pid;
} linux;
struct flock_xnu {
int64_t l_start;
int64_t l_len;
int32_t l_pid;
int16_t l_type;
int16_t l_whence;
} xnu;
struct flock_freebsd {
int64_t l_start;
int64_t l_len;
int32_t l_pid;
int16_t l_type;
int16_t l_whence;
int32_t l_sysid;
} freebsd;
struct flock_openbsd {
int64_t l_start;
int64_t l_len;
int32_t l_pid;
int16_t l_type;
int16_t l_whence;
} openbsd;
struct flock_netbsd {
int64_t l_start;
int64_t l_len;
int32_t l_pid;
int16_t l_type;
int16_t l_whence;
} netbsd;
};
void flock2cosmo(uintptr_t memory) {
int64_t l_start;
int64_t l_len;
int32_t l_pid;
int16_t l_type;
int16_t l_whence;
int32_t l_sysid;
union metaflock *u;
u = (union metaflock *)memory;
if (IsLinux()) {
l_start = u->linux.l_start;
l_len = u->linux.l_len;
l_pid = u->linux.l_pid;
l_type = u->linux.l_type;
l_whence = u->linux.l_whence;
l_sysid = 0;
} else if (IsXnu()) {
l_start = u->xnu.l_start;
l_len = u->xnu.l_len;
l_pid = u->xnu.l_pid;
l_type = u->xnu.l_type;
l_whence = u->xnu.l_whence;
l_sysid = 0;
} else if (IsFreebsd()) {
l_start = u->freebsd.l_start;
l_len = u->freebsd.l_len;
l_pid = u->freebsd.l_pid;
l_type = u->freebsd.l_type;
l_whence = u->freebsd.l_whence;
l_sysid = u->freebsd.l_sysid;
} else if (IsOpenbsd()) {
l_start = u->openbsd.l_start;
l_len = u->openbsd.l_len;
l_pid = u->openbsd.l_pid;
l_type = u->openbsd.l_type;
l_whence = u->openbsd.l_whence;
l_sysid = 0;
} else if (IsNetbsd()) {
l_start = u->netbsd.l_start;
l_len = u->netbsd.l_len;
l_pid = u->netbsd.l_pid;
l_type = u->netbsd.l_type;
l_whence = u->netbsd.l_whence;
l_sysid = 0;
} else {
return;
}
u->cosmo.l_start = l_start;
u->cosmo.l_len = l_len;
u->cosmo.l_pid = l_pid;
u->cosmo.l_type = l_type;
u->cosmo.l_whence = l_whence;
u->cosmo.l_sysid = l_sysid;
}
void cosmo2flock(uintptr_t memory) {
int64_t l_start;
int64_t l_len;
int32_t l_pid;
int16_t l_type;
int16_t l_whence;
int32_t l_sysid;
union metaflock *u;
u = (union metaflock *)memory;
l_start = u->cosmo.l_start;
l_len = u->cosmo.l_len;
l_pid = u->cosmo.l_pid;
l_type = u->cosmo.l_type;
l_whence = u->cosmo.l_whence;
l_sysid = u->cosmo.l_sysid;
if (IsLinux()) {
u->linux.l_start = l_start;
u->linux.l_len = l_len;
u->linux.l_pid = l_pid;
u->linux.l_type = l_type;
u->linux.l_whence = l_whence;
} else if (IsXnu()) {
u->xnu.l_start = l_start;
u->xnu.l_len = l_len;
u->xnu.l_pid = l_pid;
u->xnu.l_type = l_type;
u->xnu.l_whence = l_whence;
} else if (IsFreebsd()) {
u->freebsd.l_start = l_start;
u->freebsd.l_len = l_len;
u->freebsd.l_pid = l_pid;
u->freebsd.l_type = l_type;
u->freebsd.l_whence = l_whence;
u->freebsd.l_sysid = l_sysid;
} else if (IsOpenbsd()) {
u->openbsd.l_start = l_start;
u->openbsd.l_len = l_len;
u->openbsd.l_pid = l_pid;
u->openbsd.l_type = l_type;
u->openbsd.l_whence = l_whence;
} else if (IsNetbsd()) {
u->netbsd.l_start = l_start;
u->netbsd.l_len = l_len;
u->netbsd.l_pid = l_pid;
u->netbsd.l_type = l_type;
u->netbsd.l_whence = l_whence;
}
}

View file

@ -36,7 +36,7 @@ int sys_openat(int dirfd, const char *file, int flags, unsigned mode) {
errno = err; errno = err;
fd = __sys_openat(dirfd, file, flags & ~O_CLOEXEC, mode); fd = __sys_openat(dirfd, file, flags & ~O_CLOEXEC, mode);
if (fd != -1 && (flags & O_CLOEXEC)) { if (fd != -1 && (flags & O_CLOEXEC)) {
sys_fcntl(fd, F_SETFD, FD_CLOEXEC); __sys_fcntl(fd, F_SETFD, FD_CLOEXEC);
} }
} }

View file

@ -23,6 +23,7 @@
#include "libc/calls/struct/iovec.h" #include "libc/calls/struct/iovec.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/intrin/asan.internal.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/sysv/consts/iov.h" #include "libc/sysv/consts/iov.h"
#include "libc/sysv/errfuns.h" #include "libc/sysv/errfuns.h"
@ -45,6 +46,7 @@ ssize_t preadv(int fd, struct iovec *iov, int iovlen, int64_t off) {
if (fd < 0) return einval(); if (fd < 0) return einval();
if (iovlen < 0) return einval(); if (iovlen < 0) return einval();
if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) return efault();
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) { if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
return weaken(__zipos_read)( return weaken(__zipos_read)(
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, off); (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, off);

View file

@ -22,6 +22,7 @@
#include "libc/calls/struct/iovec.h" #include "libc/calls/struct/iovec.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/errno.h" #include "libc/errno.h"
#include "libc/intrin/asan.internal.h"
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
#include "libc/sysv/consts/iov.h" #include "libc/sysv/consts/iov.h"
#include "libc/sysv/errfuns.h" #include "libc/sysv/errfuns.h"
@ -49,6 +50,7 @@ ssize_t pwritev(int fd, const struct iovec *iov, int iovlen, int64_t off) {
if (fd < 0) return einval(); if (fd < 0) return einval();
if (iovlen < 0) return einval(); if (iovlen < 0) return einval();
if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) return efault();
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) { if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
return weaken(__zipos_write)( return weaken(__zipos_write)(
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, off); (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, off);

View file

@ -20,6 +20,7 @@
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/internal.h" #include "libc/calls/internal.h"
#include "libc/calls/struct/iovec.h" #include "libc/calls/struct/iovec.h"
#include "libc/intrin/asan.internal.h"
#include "libc/sock/internal.h" #include "libc/sock/internal.h"
#include "libc/sysv/errfuns.h" #include "libc/sysv/errfuns.h"
#include "libc/zipos/zipos.internal.h" #include "libc/zipos/zipos.internal.h"
@ -31,8 +32,8 @@
* @asyncsignalsafe * @asyncsignalsafe
*/ */
ssize_t readv(int fd, const struct iovec *iov, int iovlen) { ssize_t readv(int fd, const struct iovec *iov, int iovlen) {
if (fd < 0) return einval(); if (fd >= 0 && iovlen >= 0) {
if (iovlen < 0) return einval(); if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) return efault();
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) { if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
return weaken(__zipos_read)( return weaken(__zipos_read)(
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, -1); (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, -1);
@ -45,4 +46,7 @@ ssize_t readv(int fd, const struct iovec *iov, int iovlen) {
} else { } else {
return sys_readv_nt(g_fds.p + fd, iov, iovlen); return sys_readv_nt(g_fds.p + fd, iov, iovlen);
} }
} else {
return einval();
}
} }

View file

@ -2,12 +2,13 @@
#define COSMOPOLITAN_LIBC_CALLS_STRUCT_FLOCK_H_ #define COSMOPOLITAN_LIBC_CALLS_STRUCT_FLOCK_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0) #if !(__ASSEMBLER__ + __LINKER__ + 0)
struct flock { struct flock { /* cosmopolitan abi */
short l_type; int16_t l_type; /* F_RDLCK, F_WRLCK, F_UNLCK */
short l_whence; int16_t l_whence; /* SEEK_SET, SEEK_CUR, SEEK_END */
int64_t l_start; int64_t l_start; /* starting offset */
int64_t l_len; int64_t l_len; /* 0 means until end of file */
int l_pid; int32_t l_pid; /* lock owner */
int32_t l_sysid; /* remote system id or zero for local */
}; };
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -21,11 +21,13 @@
#include "libc/calls/internal.h" #include "libc/calls/internal.h"
#include "libc/calls/struct/sysinfo.h" #include "libc/calls/struct/sysinfo.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/nt/accounting.h" #include "libc/nt/accounting.h"
#include "libc/nt/runtime.h" #include "libc/nt/runtime.h"
#include "libc/nt/struct/memorystatusex.h" #include "libc/nt/struct/memorystatusex.h"
#include "libc/nt/systeminfo.h" #include "libc/nt/systeminfo.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/sysv/errfuns.h"
/** /**
* Returns amount of system ram, cores, etc. * Returns amount of system ram, cores, etc.
@ -34,6 +36,11 @@
*/ */
int sysinfo(struct sysinfo *info) { int sysinfo(struct sysinfo *info) {
int rc; int rc;
if (IsAsan()) {
if (info && !__asan_is_valid(info, sizeof(*info))) {
return efault();
}
}
memset(info, 0, sizeof(*info)); memset(info, 0, sizeof(*info));
if (!IsWindows()) { if (!IsWindows()) {
rc = sys_sysinfo(info); rc = sys_sysinfo(info);

View file

@ -18,7 +18,9 @@
*/ */
#include "libc/calls/internal.h" #include "libc/calls/internal.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/sysv/consts/at.h" #include "libc/sysv/consts/at.h"
#include "libc/sysv/errfuns.h"
#include "libc/time/time.h" #include "libc/time/time.h"
/** /**
@ -30,6 +32,11 @@
* @see stat() * @see stat()
*/ */
int utimes(const char *path, const struct timeval tv[2]) { int utimes(const char *path, const struct timeval tv[2]) {
if (IsAsan()) {
if (tv && !__asan_is_valid(tv, sizeof(*tv) * 2)) {
return efault();
}
}
if (!IsWindows()) { if (!IsWindows()) {
/* /*
* we don't modernize utimes() into utimensat() because the * we don't modernize utimes() into utimensat() because the

View file

@ -20,6 +20,8 @@
#include "libc/calls/internal.h" #include "libc/calls/internal.h"
#include "libc/calls/wait4.h" #include "libc/calls/wait4.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/sysv/errfuns.h"
/** /**
* Waits for status to change on process. * Waits for status to change on process.
@ -35,6 +37,16 @@
*/ */
int wait4(int pid, int *opt_out_wstatus, int options, int wait4(int pid, int *opt_out_wstatus, int options,
struct rusage *opt_out_rusage) { struct rusage *opt_out_rusage) {
if (IsAsan()) {
if (opt_out_wstatus &&
!__asan_is_valid(opt_out_wstatus, sizeof(*opt_out_wstatus))) {
return efault();
}
if (opt_out_rusage &&
!__asan_is_valid(opt_out_rusage, sizeof(*opt_out_rusage))) {
return efault();
}
}
if (!IsWindows()) { if (!IsWindows()) {
return sys_wait4(pid, opt_out_wstatus, options, opt_out_rusage); return sys_wait4(pid, opt_out_wstatus, options, opt_out_rusage);
} else { } else {

View file

@ -19,6 +19,7 @@
#include "libc/bits/weaken.h" #include "libc/bits/weaken.h"
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/internal.h" #include "libc/calls/internal.h"
#include "libc/intrin/asan.internal.h"
#include "libc/sock/internal.h" #include "libc/sock/internal.h"
#include "libc/sysv/errfuns.h" #include "libc/sysv/errfuns.h"
#include "libc/zipos/zipos.internal.h" #include "libc/zipos/zipos.internal.h"
@ -34,8 +35,8 @@
* @return number of bytes actually handed off, or -1 w/ errno * @return number of bytes actually handed off, or -1 w/ errno
*/ */
ssize_t writev(int fd, const struct iovec *iov, int iovlen) { ssize_t writev(int fd, const struct iovec *iov, int iovlen) {
if (fd < 0) return einval(); if (fd >= 0 && iovlen >= 0) {
if (iovlen < 0) return einval(); if (IsAsan() && !__asan_is_valid_iov(iov, iovlen)) return efault();
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) { if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
return weaken(__zipos_write)( return weaken(__zipos_write)(
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, -1); (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, -1);
@ -48,4 +49,7 @@ ssize_t writev(int fd, const struct iovec *iov, int iovlen) {
} else { } else {
return sys_writev_nt(g_fds.p + fd, iov, iovlen); return sys_writev_nt(g_fds.p + fd, iov, iovlen);
} }
} else {
return einval();
}
} }

View file

@ -57,6 +57,12 @@
#define IsOptimized() 0 #define IsOptimized() 0
#endif #endif
#ifdef __FSANITIZE_ADDRESS__
#define IsAsan() 1
#else
#define IsAsan() 0
#endif
#if defined(__PIE__) || defined(__PIC__) #if defined(__PIE__) || defined(__PIC__)
#define IsPositionIndependent() 1 #define IsPositionIndependent() 1
#else #else

View file

@ -27,6 +27,15 @@
#define EAI_INTR -104 #define EAI_INTR -104
#define EAI_NOTCANCELED -102 #define EAI_NOTCANCELED -102
/* AI_* conforms to NT ABI */
#define AI_PASSIVE 1
#define AI_CANONNAME 2
#define AI_NUMERICHOST 4
#define AI_NUMERICSERV 8
#define AI_ALL 0x0100
#define AI_ADDRCONFIG 0x0400
#define AI_V4MAPPED 0x0800
#if !(__ASSEMBLER__ + __LINKER__ + 0) #if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_ COSMOPOLITAN_C_START_

View file

@ -26,7 +26,6 @@
#include "libc/sock/sock.h" #include "libc/sock/sock.h"
#include "libc/str/str.h" #include "libc/str/str.h"
#include "libc/sysv/consts/af.h" #include "libc/sysv/consts/af.h"
#include "libc/sysv/consts/ai.h"
#include "libc/sysv/consts/inaddr.h" #include "libc/sysv/consts/inaddr.h"
#include "libc/sysv/errfuns.h" #include "libc/sysv/errfuns.h"

View file

@ -21,7 +21,7 @@
.macro .e e .macro .e e
.long \e - kErrorNames .long \e - kErrorNames
.long 1f - kErrorNames .long 1f - kErrorNames
.section .rodata.str1.1 .rodata.str1.1
1: .string "\e" 1: .string "\e"
.previous .previous
.endm .endm
@ -114,51 +114,5 @@ kErrorNames:
.e ENOTRECOVERABLE .e ENOTRECOVERABLE
.e ENONET .e ENONET
.e ERESTART .e ERESTART
.e ECHRNG
.e EL2NSYNC
.e EL3HLT
.e EL3RST
.e ELNRNG
.e EUNATCH
.e ENOCSI
.e EL2HLT
.e EBADE
.e EBADR
.e EXFULL
.e ENOANO
.e EBADRQC
.e EBADSLT
.e ENOSTR
.e ENODATA
.e ENOSR
.e ENOPKG
.e ENOLINK
.e EADV
.e ESRMNT
.e ECOMM
.e EMULTIHOP
.e EDOTDOT
.e ENOTUNIQ
.e EBADFD
.e EREMCHG
.e ELIBACC
.e ELIBBAD
.e ELIBSCN
.e ELIBMAX
.e ELIBEXEC
.e ESTRPIPE
.e EUCLEAN
.e ENOTNAM
.e ENAVAIL
.e EISNAM
.e EREMOTEIO
.e ENOMEDIUM
.e EMEDIUMTYPE
.e ENOKEY
.e EKEYEXPIRED
.e EKEYREVOKED
.e EKEYREJECTED
.e ERFKILL
.e EHWPOISON
.long 0 .long 0
.endobj kErrorNames,globl,hidden .endobj kErrorNames,globl,hidden

View file

@ -21,6 +21,7 @@
#include "libc/bits/likely.h" #include "libc/bits/likely.h"
#include "libc/bits/weaken.h" #include "libc/bits/weaken.h"
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/calls/struct/iovec.h"
#include "libc/dce.h" #include "libc/dce.h"
#include "libc/intrin/asan.internal.h" #include "libc/intrin/asan.internal.h"
#include "libc/log/log.h" #include "libc/log/log.h"
@ -116,7 +117,7 @@ struct AsanMorgue {
static struct AsanMorgue __asan_morgue; static struct AsanMorgue __asan_morgue;
static uint64_t __asan_bsrl(uint64_t x) { static inline int __asan_bsrl(uint64_t x) {
return __builtin_clzll(x) ^ 63; return __builtin_clzll(x) ^ 63;
} }
@ -137,7 +138,7 @@ static size_t __asan_strlen(const char *s) {
static int __asan_strcmp(const char *l, const char *r) { static int __asan_strcmp(const char *l, const char *r) {
size_t i = 0; size_t i = 0;
while (l[i] == r[i] && r[i]) ++i; while (l[i] == r[i] && r[i]) ++i;
return (l[i] & 0xff) - (r[i] & 0xff); return (l[i] & 255) - (r[i] & 255);
} }
static char *__asan_stpcpy(char *d, const char *s) { static char *__asan_stpcpy(char *d, const char *s) {
@ -168,7 +169,7 @@ static void *__asan_memset(void *p, int c, size_t n) {
size_t i; size_t i;
uint64_t x; uint64_t x;
b = p; b = p;
x = 0x0101010101010101 * (c & 0xff); x = 0x0101010101010101 * (c & 255);
switch (n) { switch (n) {
case 0: case 0:
return p; return p;
@ -293,74 +294,106 @@ static void *__asan_memcpy(void *dst, const void *src, size_t n) {
return dst; return dst;
} }
static size_t __asan_int2hex(uint64_t x, char b[17], uint8_t k) { static char *__asan_hexcpy(char *p, uint64_t x, uint8_t k) {
int i; while (k) *p++ = "0123456789abcdef"[(x >> (k -= 4)) & 15];
char *p; return p;
for (p = b; k > 0;) {
*p++ = "0123456789abcdef"[(x >> (k -= 4)) & 15];
}
*p = '\0';
return p - b;
} }
static size_t __asan_uint2str(uint64_t i, char *a) { static char *__asan_uint2str(char *p, uint64_t i) {
size_t j; int j = 0;
j = 0;
do { do {
a[j++] = i % 10 + '0'; p[j++] = i % 10 + '0';
i /= 10; i /= 10;
} while (i > 0); } while (i > 0);
a[j] = '\0'; reverse(p, j);
reverse(a, j); return p + j;
return j;
} }
static size_t __asan_int2str(int64_t i, char *a) { static char *__asan_intcpy(char *p, int64_t i) {
if (i >= 0) return __asan_uint2str(i, a); if (i >= 0) return __asan_uint2str(p, i);
*a++ = '-'; *p++ = '-';
return 1 + __asan_uint2str(-i, a); return __asan_uint2str(p, -i);
} }
void __asan_poison(uintptr_t p, size_t n, int kind) { void __asan_poison(uintptr_t p, size_t n, int t) {
int k; signed char k, *s;
char *s; k = p & 7;
if (!n) return; s = (signed char *)((p >> 3) + 0x7fff8000);
if (UNLIKELY(p & 7)) { if (UNLIKELY(k)) {
k = MIN(8 - (p & 7), n); if (n && (!*s || *s > k) && 8 - k >= n) *s = k;
s = SHADOW(p); ++s, n -= MIN(8 - k, n);
if (*s == 0 || *s > (p & 7)) {
*s = p & 7;
} }
n -= k; __asan_memset(s, t, n >> 3);
p += k;
}
__asan_memset(SHADOW(p), kind, n >> 3);
if ((k = n & 7)) { if ((k = n & 7)) {
s = SHADOW(p + n); s += n >> 3;
if (*s < 0 || (*s > 0 && *s >= k)) { if (*s < 0 || 0 < *s && *s <= k) *s = t;
*s = kind;
}
} }
} }
void __asan_unpoison(uintptr_t p, size_t n) { void __asan_unpoison(uintptr_t p, size_t n) {
int k; signed char k, *s;
char *s; k = p & 7;
if (!n) return; s = (signed char *)((p >> 3) + 0x7fff8000);
if (UNLIKELY(p & 7)) { if (UNLIKELY(k)) {
k = MIN(8 - (p & 7), n); if (n) *s = 0;
s = SHADOW(p); ++s, n -= MIN(8 - k, n);
*s = 0;
n -= k;
p += k;
} }
__asan_memset(SHADOW(p), 0, n >> 3); __asan_memset(s, 0, n >> 3);
if ((k = n & 7)) { if ((k = n & 7)) {
s = SHADOW(p + n); s += n >> 3;
if (*s && *s < k) { if (*s && *s < k) *s = k;
*s = k;
} }
} }
bool __asan_is_valid(const void *p, size_t n) {
signed char k, *s, *e;
if (n) {
k = (uintptr_t)p & 7;
s = (signed char *)(((uintptr_t)p >> 3) + 0x7fff8000);
if (UNLIKELY(k)) {
if (n && !(!*s || *s >= k + n)) return false;
++s, n -= MIN(8 - k, n);
}
e = s;
k = n & 7;
e += n >> 3;
for (; s + 8 <= e; s += 8) {
if ((uint64_t)(255 & s[0]) << 000 | (uint64_t)(255 & s[1]) << 010 |
(uint64_t)(255 & s[2]) << 020 | (uint64_t)(255 & s[3]) << 030 |
(uint64_t)(255 & s[4]) << 040 | (uint64_t)(255 & s[5]) << 050 |
(uint64_t)(255 & s[6]) << 060 | (uint64_t)(255 & s[7]) << 070) {
return false;
}
}
while (s < e) {
if (*s++) {
return false;
}
}
if (k) {
if (!(!*s || *s >= k)) {
return false;
}
}
}
return true;
}
bool __asan_is_valid_iov(const struct iovec *iov, int iovlen) {
int i;
size_t size;
if (iovlen >= 0 &&
!__builtin_mul_overflow(iovlen, sizeof(struct iovec), &size) &&
__asan_is_valid(iov, size)) {
for (i = 0; i < iovlen; ++i) {
if (!__asan_is_valid(iov[i].iov_base, iov[i].iov_len)) {
return false;
}
}
return true;
} else {
return false;
}
} }
static const char *__asan_dscribe_heap_poison(long c) { static const char *__asan_dscribe_heap_poison(long c) {
@ -376,7 +409,7 @@ static const char *__asan_dscribe_heap_poison(long c) {
} }
} }
static const char *__asan_describe_access_poison(char *p) { static const char *__asan_describe_access_poison(signed char *p) {
int c = p[0]; int c = p[0];
if (1 <= c && c <= 7) c = p[1]; if (1 <= c && c <= 7) c = p[1];
switch (c) { switch (c) {
@ -445,15 +478,10 @@ static ssize_t __asan_write_string(const char *s) {
return __asan_write(s, __asan_strlen(s)); return __asan_write(s, __asan_strlen(s));
} }
static wontreturn void __asan_abort(void) {
if (weaken(__die)) weaken(__die)();
__asan_exit(134);
}
static wontreturn void __asan_die(const char *msg) { static wontreturn void __asan_die(const char *msg) {
__asan_write_string(msg); __asan_write_string(msg);
if (weaken(__die)) weaken(__die)(); if (weaken(__die)) weaken(__die)();
__asan_abort(); __asan_exit(134);
} }
static char *__asan_report_start(char *p) { static char *__asan_report_start(char *p) {
@ -472,9 +500,9 @@ static wontreturn void __asan_report_heap_fault(void *addr, long c) {
p = __asan_report_start(buf); p = __asan_report_start(buf);
p = __asan_stpcpy(p, __asan_dscribe_heap_poison(c)); p = __asan_stpcpy(p, __asan_dscribe_heap_poison(c));
p = __asan_stpcpy(p, " at 0x"); p = __asan_stpcpy(p, " at 0x");
p = __asan_mempcpy(p, ibuf, __asan_int2hex((intptr_t)addr, ibuf, 48)); p = __asan_hexcpy(p, (intptr_t)addr, 48);
p = __asan_stpcpy(p, " shadow 0x"); p = __asan_stpcpy(p, " shadow 0x");
p = __asan_mempcpy(p, ibuf, __asan_int2hex((intptr_t)SHADOW(addr), ibuf, 48)); p = __asan_hexcpy(p, (intptr_t)SHADOW(addr), 48);
p = __asan_stpcpy(p, "\r\n"); p = __asan_stpcpy(p, "\r\n");
__asan_die(buf); __asan_die(buf);
} }
@ -485,20 +513,20 @@ static wontreturn void __asan_report_memory_fault(uint8_t *addr, int size,
p = __asan_report_start(buf); p = __asan_report_start(buf);
p = __asan_stpcpy(p, __asan_describe_access_poison(SHADOW(addr))); p = __asan_stpcpy(p, __asan_describe_access_poison(SHADOW(addr)));
p = __asan_stpcpy(p, " "); p = __asan_stpcpy(p, " ");
p = __asan_mempcpy(p, ibuf, __asan_int2str(size, ibuf)); p = __asan_intcpy(p, size);
p = __asan_stpcpy(p, "-byte "); p = __asan_stpcpy(p, "-byte ");
p = __asan_stpcpy(p, kind); p = __asan_stpcpy(p, kind);
p = __asan_stpcpy(p, " at 0x"); p = __asan_stpcpy(p, " at 0x");
p = __asan_mempcpy(p, ibuf, __asan_int2hex((intptr_t)addr, ibuf, 48)); p = __asan_hexcpy(p, (uintptr_t)addr, 48);
p = __asan_stpcpy(p, " shadow 0x"); p = __asan_stpcpy(p, " shadow 0x");
p = __asan_mempcpy(p, ibuf, __asan_int2hex((intptr_t)SHADOW(addr), ibuf, 48)); p = __asan_hexcpy(p, (uintptr_t)SHADOW(addr), 48);
p = __asan_stpcpy(p, "\r\n"); p = __asan_stpcpy(p, "\r\n");
__asan_die(buf); __asan_die(buf);
} }
const void *__asan_morgue_add(void *p) { const void *__asan_morgue_add(void *p) {
void *r; void *r;
unsigned i, j; int i, j;
for (;;) { for (;;) {
i = __asan_morgue.i; i = __asan_morgue.i;
j = (i + 1) & (ARRAYLEN(__asan_morgue.p) - 1); j = (i + 1) & (ARRAYLEN(__asan_morgue.p) - 1);
@ -511,8 +539,8 @@ const void *__asan_morgue_add(void *p) {
} }
static void __asan_morgue_flush(void) { static void __asan_morgue_flush(void) {
int i;
void *p; void *p;
unsigned i;
for (i = 0; i < ARRAYLEN(__asan_morgue.p); ++i) { for (i = 0; i < ARRAYLEN(__asan_morgue.p); ++i) {
p = __asan_morgue.p[i]; p = __asan_morgue.p[i];
if (cmpxchg(__asan_morgue.p + i, p, NULL)) { if (cmpxchg(__asan_morgue.p + i, p, NULL)) {
@ -532,15 +560,16 @@ static size_t __asan_heap_size(size_t n) {
} }
static void *__asan_allocate(size_t a, size_t n, int underrun, int overrun) { static void *__asan_allocate(size_t a, size_t n, int underrun, int overrun) {
char *p;
size_t c; size_t c;
char *p, *f;
if ((p = weaken(dlmemalign)(a, __asan_heap_size(n)))) { if ((p = weaken(dlmemalign)(a, __asan_heap_size(n)))) {
c = weaken(dlmalloc_usable_size)(p); c = weaken(dlmalloc_usable_size)(p);
__asan_unpoison((uintptr_t)p, n); __asan_unpoison((uintptr_t)p, n);
__asan_poison((uintptr_t)p - 16, 16, underrun); /* see dlmalloc design */ __asan_poison((uintptr_t)p - 16, 16, underrun); /* see dlmalloc design */
__asan_poison((uintptr_t)p + n, c - n, overrun); __asan_poison((uintptr_t)p + n, c - n, overrun);
__asan_memset(p, 0xF9, n); __asan_memset(p, 0xF9, n);
WRITE64BE(p + c - sizeof(n), n); f = p + c - 8;
WRITE64BE(f, n);
} }
return p; return p;
} }
@ -548,7 +577,7 @@ static void *__asan_allocate(size_t a, size_t n, int underrun, int overrun) {
static size_t __asan_malloc_usable_size(const void *p) { static size_t __asan_malloc_usable_size(const void *p) {
size_t c, n; size_t c, n;
if ((c = weaken(dlmalloc_usable_size)(p)) >= 8) { if ((c = weaken(dlmalloc_usable_size)(p)) >= 8) {
if ((n = READ64BE((char *)p + c - sizeof(n))) <= c) { if ((n = READ64BE((char *)p + c - 8)) <= c) {
return n; return n;
} else { } else {
__asan_report_heap_fault(p, n); __asan_report_heap_fault(p, n);
@ -561,9 +590,9 @@ static size_t __asan_malloc_usable_size(const void *p) {
static void __asan_deallocate(char *p, long kind) { static void __asan_deallocate(char *p, long kind) {
size_t c, n; size_t c, n;
if ((c = weaken(dlmalloc_usable_size)(p)) >= 8) { if ((c = weaken(dlmalloc_usable_size)(p)) >= 8) {
if ((n = READ64BE((char *)p + c - sizeof(n))) <= c) { if ((n = READ64BE(p + c - 8)) <= c) {
WRITE64BE((char *)p + c - sizeof(n), kind); WRITE64BE(p + c - 8, kind);
__asan_poison((uintptr_t)p, n, kind); __asan_poison((uintptr_t)p, c - 8, kind);
if (weaken(dlfree)) { if (weaken(dlfree)) {
weaken(dlfree)(__asan_morgue_add(p)); weaken(dlfree)(__asan_morgue_add(p));
} }
@ -588,43 +617,47 @@ static void *__asan_malloc(size_t size) {
return __asan_memalign(16, size); return __asan_memalign(16, size);
} }
static void *__asan_calloc(size_t nelem, size_t elsize) { static void *__asan_calloc(size_t n, size_t m) {
char *p; char *p;
size_t n; if (__builtin_mul_overflow(n, m, &n)) n = -1;
if (__builtin_mul_overflow(nelem, elsize, &n)) n = -1;
if ((p = __asan_malloc(n))) __asan_memset(p, 0, n); if ((p = __asan_malloc(n))) __asan_memset(p, 0, n);
return p; return p;
} }
static void *__asan_realloc(void *p, size_t n) { static void *__asan_realloc(void *p, size_t n) {
char *p2; char *q, *f;
size_t c, m; size_t c, m;
if (p) { if (p) {
if (n) { if (n) {
if ((c = weaken(dlmalloc_usable_size)(p)) < 8) if ((c = weaken(dlmalloc_usable_size)(p)) >= 8) {
__asan_report_heap_fault(p, 0); f = (char *)p + c - 8;
if ((m = READ64BE((char *)p + c - sizeof(n))) > c) if ((m = READ64BE(f)) <= c) {
__asan_report_heap_fault(p, m);
if (n <= m) { /* shrink */ if (n <= m) { /* shrink */
__asan_poison((uintptr_t)p + n, m - n, kAsanHeapOverrun); __asan_poison((uintptr_t)p + n, m - n, kAsanHeapOverrun);
WRITE64BE((char *)p + c - sizeof(n), n); WRITE64BE(f, n);
p2 = p; q = p;
} else if (n <= c - 8) { /* small growth */ } else if (n <= c - 8) { /* small growth */
__asan_unpoison((uintptr_t)p + m, n - m); __asan_unpoison((uintptr_t)p + m, n - m);
WRITE64BE((char *)p + c - sizeof(n), n); WRITE64BE(f, n);
p2 = p; q = p;
} else if ((p2 = __asan_malloc(n))) { /* exponential growth */ } else if ((q = __asan_malloc(n))) { /* exponential growth */
__asan_memcpy(p2, p, m); __asan_memcpy(q, p, m);
__asan_deallocate(p, kAsanRelocated); __asan_deallocate(p, kAsanRelocated);
} }
} else { } else {
__asan_free(p); __asan_report_heap_fault(p, m);
p2 = NULL;
} }
} else { } else {
p2 = __asan_malloc(n); __asan_report_heap_fault(p, 0);
} }
return p2; } else {
__asan_free(p);
q = NULL;
}
} else {
q = __asan_malloc(n);
}
return q;
} }
static void *__asan_valloc(size_t n) { static void *__asan_valloc(size_t n) {

View file

@ -1,5 +1,6 @@
#ifndef COSMOPOLITAN_LIBC_INTRIN_ASAN_H_ #ifndef COSMOPOLITAN_LIBC_INTRIN_ASAN_H_
#define COSMOPOLITAN_LIBC_INTRIN_ASAN_H_ #define COSMOPOLITAN_LIBC_INTRIN_ASAN_H_
#include "libc/calls/struct/iovec.h"
#define kAsanScale 3 #define kAsanScale 3
#define kAsanMagic 0x7fff8000 #define kAsanMagic 0x7fff8000
@ -17,10 +18,12 @@
#define kAsanUnscoped -12 #define kAsanUnscoped -12
#define kAsanUnmapped -13 #define kAsanUnmapped -13
#define SHADOW(x) ((char *)(((uintptr_t)(x) >> kAsanScale) + kAsanMagic)) #define SHADOW(x) ((signed char *)(((uintptr_t)(x) >> kAsanScale) + kAsanMagic))
void __asan_map_shadow(uintptr_t, size_t); void __asan_map_shadow(uintptr_t, size_t);
void __asan_poison(uintptr_t, size_t, int); void __asan_poison(uintptr_t, size_t, int);
void __asan_unpoison(uintptr_t, size_t); void __asan_unpoison(uintptr_t, size_t);
bool __asan_is_valid(const void *, size_t);
bool __asan_is_valid_iov(const struct iovec *, int);
#endif /* COSMOPOLITAN_LIBC_INTRIN_ASAN_H_ */ #endif /* COSMOPOLITAN_LIBC_INTRIN_ASAN_H_ */

View file

@ -19,6 +19,16 @@
#include "libc/macros.internal.h" #include "libc/macros.internal.h"
.source __FILE__ .source __FILE__
.macro .acall fn:req
xor %eax,%eax
mov $1,%r10b
cmpxchg %r10b,__asan_noreentry(%rip)
jnz 2f
call \fn
decb __asan_noreentry(%rip)
2: nop
.endm
.rodata.cst4 .rodata.cst4
__asan_option_detect_stack_use_after_return: __asan_option_detect_stack_use_after_return:
.long 0 .long 0
@ -32,181 +42,362 @@ __asan_noreentry:
.previous .previous
__asan_report_load1: __asan_report_load1:
push $1 push %rbp
jmp OnReportLoad mov %rsp,%rbp
.profilable
mov $1,%esi
.acall __asan_report_load
pop %rbp
ret
.endfn __asan_report_load1,globl .endfn __asan_report_load1,globl
__asan_report_load2: __asan_report_load2:
push $2 push %rbp
jmp OnReportLoad mov %rsp,%rbp
.profilable
mov $2,%esi
.acall __asan_report_load
pop %rbp
ret
.endfn __asan_report_load2,globl .endfn __asan_report_load2,globl
__asan_report_load4: __asan_report_load4:
push $4 push %rbp
jmp OnReportLoad mov %rsp,%rbp
.profilable
mov $4,%esi
.acall __asan_report_load
pop %rbp
ret
.endfn __asan_report_load4,globl .endfn __asan_report_load4,globl
__asan_report_load8: __asan_report_load8:
push $8 push %rbp
jmp OnReportLoad mov %rsp,%rbp
.profilable
mov $8,%esi
.acall __asan_report_load
pop %rbp
ret
.endfn __asan_report_load8,globl .endfn __asan_report_load8,globl
__asan_report_load16: __asan_report_load16:
push $16 push %rbp
jmp OnReportLoad mov %rsp,%rbp
.profilable
mov $16,%esi
.acall __asan_report_load
pop %rbp
ret
.endfn __asan_report_load16,globl .endfn __asan_report_load16,globl
__asan_report_load32: __asan_report_load32:
push $32 push %rbp
// 𝑠𝑙𝑖𝑑𝑒 mov %rsp,%rbp
.profilable
mov $32,%esi
.acall __asan_report_load
pop %rbp
ret
.endfn __asan_report_load32,globl .endfn __asan_report_load32,globl
OnReportLoad:
pop %rsi
// 𝑠𝑙𝑖𝑑𝑒
.endfn OnReportLoad
__asan_report_load_n: __asan_report_load_n:
lea __asan_report_load(%rip),%r11 push %rbp
jmp __asan_report_noreentry mov %rsp,%rbp
.profilable
.acall __asan_report_load
pop %rbp
ret
.endfn __asan_report_load_n,globl .endfn __asan_report_load_n,globl
__asan_report_store1: __asan_report_store1:
push $1
jmp ReportStore
.endfn __asan_report_store1,globl
__asan_report_store2:
push $2
jmp ReportStore
.endfn __asan_report_store2,globl
__asan_report_store4:
push $4
jmp ReportStore
.endfn __asan_report_store4,globl
__asan_report_store8:
push $8
jmp ReportStore
.endfn __asan_report_store8,globl
__asan_report_store16:
push $16
jmp ReportStore
.endfn __asan_report_store16,globl
__asan_report_store32:
push $32
// 𝑠𝑙𝑖𝑑𝑒
.endfn __asan_report_store32,globl
ReportStore:
pop %rsi
// 𝑠𝑙𝑖𝑑𝑒
.endfn ReportStore
__asan_report_store_n:
lea __asan_report_store(%rip),%r11
// 𝑠𝑙𝑖𝑑𝑒
.endfn __asan_report_store_n,globl
__asan_report_noreentry:
push %rbp push %rbp
mov %rsp,%rbp mov %rsp,%rbp
xor %eax,%eax .profilable
mov $1,%r10b mov $1,%esi
cmpxchg %r10b,__asan_noreentry(%rip) .acall __asan_report_store
jnz 2f pop %rbp
call *%r11
decb __asan_noreentry(%rip)
2: pop %rbp
ret ret
.endfn __asan_report_noreentry .endfn __asan_report_store1,globl
__asan_report_store2:
push %rbp
mov %rsp,%rbp
.profilable
mov $2,%esi
.acall __asan_report_store
pop %rbp
ret
.endfn __asan_report_store2,globl
__asan_report_store4:
push %rbp
mov %rsp,%rbp
.profilable
mov $4,%esi
.acall __asan_report_store
pop %rbp
ret
.endfn __asan_report_store4,globl
__asan_report_store8:
push %rbp
mov %rsp,%rbp
.profilable
mov $8,%esi
.acall __asan_report_store
pop %rbp
ret
.endfn __asan_report_store8,globl
__asan_report_store16:
push %rbp
mov %rsp,%rbp
.profilable
mov $16,%esi
.acall __asan_report_store
pop %rbp
ret
.endfn __asan_report_store16,globl
__asan_report_store32:
push %rbp
mov %rsp,%rbp
.profilable
mov $32,%esi
.acall __asan_report_store
pop %rbp
ret
.endfn __asan_report_store32,globl
__asan_report_store_n:
push %rbp
mov %rsp,%rbp
.profilable
.acall __asan_report_store
pop %rbp
ret
.endfn __asan_report_store_n,globl
__asan_stack_free_0: __asan_stack_free_0:
push $0 push %rbp
jmp OnStackFree mov %rsp,%rbp
.profilable
mov $0,%edx
call __asan_stack_free
pop %rbp
ret
.endfn __asan_stack_free_0,globl .endfn __asan_stack_free_0,globl
__asan_stack_free_1: __asan_stack_free_1:
push $1 push %rbp
jmp OnStackFree mov %rsp,%rbp
.profilable
mov $1,%edx
call __asan_stack_free
pop %rbp
ret
.endfn __asan_stack_free_1,globl .endfn __asan_stack_free_1,globl
__asan_stack_free_2: __asan_stack_free_2:
push $2 push %rbp
jmp OnStackFree mov %rsp,%rbp
.profilable
mov $2,%edx
call __asan_stack_free
pop %rbp
ret
.endfn __asan_stack_free_2,globl .endfn __asan_stack_free_2,globl
__asan_stack_free_3: __asan_stack_free_3:
push $3 push %rbp
jmp OnStackFree mov %rsp,%rbp
.profilable
mov $3,%edx
call __asan_stack_free
pop %rbp
ret
.endfn __asan_stack_free_3,globl .endfn __asan_stack_free_3,globl
__asan_stack_free_4: __asan_stack_free_4:
push $4 push %rbp
jmp OnStackFree mov %rsp,%rbp
.profilable
mov $4,%edx
call __asan_stack_free
pop %rbp
ret
.endfn __asan_stack_free_4,globl .endfn __asan_stack_free_4,globl
__asan_stack_free_5: __asan_stack_free_5:
push $5 push %rbp
jmp OnStackFree mov %rsp,%rbp
.profilable
mov $5,%edx
call __asan_stack_free
pop %rbp
ret
.endfn __asan_stack_free_5,globl .endfn __asan_stack_free_5,globl
__asan_stack_free_6: __asan_stack_free_6:
push $6 push %rbp
jmp OnStackFree mov %rsp,%rbp
.profilable
mov $6,%edx
call __asan_stack_free
pop %rbp
ret
.endfn __asan_stack_free_6,globl .endfn __asan_stack_free_6,globl
__asan_stack_free_7: __asan_stack_free_7:
push $7 push %rbp
jmp OnStackFree mov %rsp,%rbp
.profilable
mov $7,%edx
call __asan_stack_free
pop %rbp
ret
.endfn __asan_stack_free_7,globl .endfn __asan_stack_free_7,globl
__asan_stack_free_8: __asan_stack_free_8:
push $8 push %rbp
jmp OnStackFree mov %rsp,%rbp
.profilable
mov $8,%edx
call __asan_stack_free
pop %rbp
ret
.endfn __asan_stack_free_8,globl .endfn __asan_stack_free_8,globl
__asan_stack_free_9: __asan_stack_free_9:
push $9 push %rbp
jmp OnStackFree mov %rsp,%rbp
.profilable
mov $9,%edx
call __asan_stack_free
pop %rbp
ret
.endfn __asan_stack_free_9,globl .endfn __asan_stack_free_9,globl
__asan_stack_free_10: __asan_stack_free_10:
push $10 push %rbp
// 𝑠𝑙𝑖𝑑𝑒 mov %rsp,%rbp
.profilable
mov $10,%edx
call __asan_stack_free
pop %rbp
ret
.endfn __asan_stack_free_10,globl .endfn __asan_stack_free_10,globl
OnStackFree:
pop %rdx
jmp __asan_stack_free
.endfn OnStackFree
__asan_stack_malloc_0: __asan_stack_malloc_0:
push $0 push %rbp
jmp OnStackMalloc mov %rsp,%rbp
.profilable
mov $0,%esi
call __asan_stack_malloc
pop %rbp
ret
.endfn __asan_stack_malloc_0,globl .endfn __asan_stack_malloc_0,globl
__asan_stack_malloc_1: __asan_stack_malloc_1:
push $1 push %rbp
jmp OnStackMalloc mov %rsp,%rbp
.profilable
mov $1,%esi
call __asan_stack_malloc
pop %rbp
ret
.endfn __asan_stack_malloc_1,globl .endfn __asan_stack_malloc_1,globl
__asan_stack_malloc_2: __asan_stack_malloc_2:
push $2 push %rbp
jmp OnStackMalloc mov %rsp,%rbp
.profilable
mov $2,%esi
call __asan_stack_malloc
pop %rbp
ret
.endfn __asan_stack_malloc_2,globl .endfn __asan_stack_malloc_2,globl
__asan_stack_malloc_3: __asan_stack_malloc_3:
push $3 push %rbp
jmp OnStackMalloc mov %rsp,%rbp
.profilable
mov $3,%esi
call __asan_stack_malloc
pop %rbp
ret
.endfn __asan_stack_malloc_3,globl .endfn __asan_stack_malloc_3,globl
__asan_stack_malloc_4: __asan_stack_malloc_4:
push $4 push %rbp
jmp OnStackMalloc mov %rsp,%rbp
.profilable
mov $4,%esi
call __asan_stack_malloc
pop %rbp
ret
.endfn __asan_stack_malloc_4,globl .endfn __asan_stack_malloc_4,globl
__asan_stack_malloc_5: __asan_stack_malloc_5:
push $5 push %rbp
jmp OnStackMalloc mov %rsp,%rbp
.profilable
mov $5,%esi
call __asan_stack_malloc
pop %rbp
ret
.endfn __asan_stack_malloc_5,globl .endfn __asan_stack_malloc_5,globl
__asan_stack_malloc_6: __asan_stack_malloc_6:
push $6 push %rbp
jmp OnStackMalloc mov %rsp,%rbp
.profilable
mov $6,%esi
call __asan_stack_malloc
pop %rbp
ret
.endfn __asan_stack_malloc_6,globl .endfn __asan_stack_malloc_6,globl
__asan_stack_malloc_7: __asan_stack_malloc_7:
push $7 push %rbp
jmp OnStackMalloc mov %rsp,%rbp
.profilable
mov $7,%esi
call __asan_stack_malloc
pop %rbp
ret
.endfn __asan_stack_malloc_7,globl .endfn __asan_stack_malloc_7,globl
__asan_stack_malloc_8: __asan_stack_malloc_8:
push $8 push %rbp
jmp OnStackMalloc mov %rsp,%rbp
.profilable
mov $8,%esi
call __asan_stack_malloc
pop %rbp
ret
.endfn __asan_stack_malloc_8,globl .endfn __asan_stack_malloc_8,globl
__asan_stack_malloc_9: __asan_stack_malloc_9:
push $9 push %rbp
jmp OnStackMalloc mov %rsp,%rbp
.profilable
mov $9,%esi
call __asan_stack_malloc
pop %rbp
ret
.endfn __asan_stack_malloc_9,globl .endfn __asan_stack_malloc_9,globl
__asan_stack_malloc_10: __asan_stack_malloc_10:
push $10 push %rbp
// 𝑠𝑙𝑖𝑑𝑒 mov %rsp,%rbp
.profilable
mov $10,%esi
call __asan_stack_malloc
pop %rbp
ret
.endfn __asan_stack_malloc_10,globl .endfn __asan_stack_malloc_10,globl
OnStackMalloc:
pop %rsi
jmp __asan_stack_malloc
.endfn OnStackMalloc
__asan_version_mismatch_check_v8: __asan_version_mismatch_check_v8:
ret ret
@ -242,26 +433,31 @@ __asan_load1:
mov %rsp,%rbp mov %rsp,%rbp
ud2 ud2
.endfn __asan_load1,globl .endfn __asan_load1,globl
__asan_load2: __asan_load2:
push %rbp push %rbp
mov %rsp,%rbp mov %rsp,%rbp
ud2 ud2
.endfn __asan_load2,globl .endfn __asan_load2,globl
__asan_load4: __asan_load4:
push %rbp push %rbp
mov %rsp,%rbp mov %rsp,%rbp
ud2 ud2
.endfn __asan_load4,globl .endfn __asan_load4,globl
__asan_load8: __asan_load8:
push %rbp push %rbp
mov %rsp,%rbp mov %rsp,%rbp
ud2 ud2
.endfn __asan_load8,globl .endfn __asan_load8,globl
__asan_load16: __asan_load16:
push %rbp push %rbp
mov %rsp,%rbp mov %rsp,%rbp
ud2 ud2
.endfn __asan_load16,globl .endfn __asan_load16,globl
__asan_load32: __asan_load32:
push %rbp push %rbp
mov %rsp,%rbp mov %rsp,%rbp
@ -273,26 +469,31 @@ __asan_store1:
mov %rsp,%rbp mov %rsp,%rbp
ud2 ud2
.endfn __asan_store1,globl .endfn __asan_store1,globl
__asan_store2: __asan_store2:
push %rbp push %rbp
mov %rsp,%rbp mov %rsp,%rbp
ud2 ud2
.endfn __asan_store2,globl .endfn __asan_store2,globl
__asan_store4: __asan_store4:
push %rbp push %rbp
mov %rsp,%rbp mov %rsp,%rbp
ud2 ud2
.endfn __asan_store4,globl .endfn __asan_store4,globl
__asan_store8: __asan_store8:
push %rbp push %rbp
mov %rsp,%rbp mov %rsp,%rbp
ud2 ud2
.endfn __asan_store8,globl .endfn __asan_store8,globl
__asan_store16: __asan_store16:
push %rbp push %rbp
mov %rsp,%rbp mov %rsp,%rbp
ud2 ud2
.endfn __asan_store16,globl .endfn __asan_store16,globl
__asan_store32: __asan_store32:
push %rbp push %rbp
mov %rsp,%rbp mov %rsp,%rbp

View file

@ -1,5 +1,6 @@
#ifndef COSMOPOLITAN_LIBC_LOG_LOG_H_ #ifndef COSMOPOLITAN_LIBC_LOG_LOG_H_
#define COSMOPOLITAN_LIBC_LOG_LOG_H_ #define COSMOPOLITAN_LIBC_LOG_LOG_H_
#include "libc/bits/likely.h"
#include "libc/calls/struct/sigset.h" #include "libc/calls/struct/sigset.h"
#include "libc/calls/struct/winsize.h" #include "libc/calls/struct/winsize.h"
#include "libc/stdio/stdio.h" #include "libc/stdio/stdio.h"

View file

@ -133,7 +133,7 @@ relegated static void ShowGeneralRegisters(int fd, ucontext_t *ctx) {
} else { } else {
memset(&st, 0, sizeof(st)); memset(&st, 0, sizeof(st));
} }
dprintf(fd, " %s(%zu) %Lf", "ST", k, st); dprintf(fd, " %s(%zu) %Lg", "ST", k, st);
++k; ++k;
write(fd, "\r\n", 2); write(fd, "\r\n", 2);
} }

View file

@ -34,232 +34,495 @@ __ubsan_get_current_report_data:
.endfn __ubsan_get_current_report_data,globl .endfn __ubsan_get_current_report_data,globl
__ubsan_handle_type_mismatch_abort: __ubsan_handle_type_mismatch_abort:
jmp __ubsan_handle_type_mismatch push %rbp
mov %rsp,%rbp
.profilable
call __ubsan_handle_type_mismatch
pop %rbp
ret
.endfn __ubsan_handle_type_mismatch_abort,globl .endfn __ubsan_handle_type_mismatch_abort,globl
__ubsan_handle_float_cast_overflow_abort: __ubsan_handle_float_cast_overflow_abort:
jmp __ubsan_handle_float_cast_overflow push %rbp
mov %rsp,%rbp
.profilable
call __ubsan_handle_float_cast_overflow
pop %rbp
ret
.endfn __ubsan_handle_float_cast_overflow_abort,globl .endfn __ubsan_handle_float_cast_overflow_abort,globl
__ubsan_handle_type_mismatch_v1:
__ubsan_handle_type_mismatch_v1_abort: __ubsan_handle_type_mismatch_v1_abort:
jmp ___ubsan_handle_type_mismatch_v1 push %rbp
.endfn __ubsan_handle_type_mismatch_v1,globl mov %rsp,%rbp
.profilable
call ___ubsan_handle_type_mismatch_v1
pop %rbp
ret
.endfn __ubsan_handle_type_mismatch_v1_abort,globl .endfn __ubsan_handle_type_mismatch_v1_abort,globl
__ubsan_handle_type_mismatch_v1:
push %rbp
mov %rsp,%rbp
.profilable
call ___ubsan_handle_type_mismatch_v1
pop %rbp
ret
.endfn __ubsan_handle_type_mismatch_v1,globl
__ubsan_handle_add_overflow_abort: __ubsan_handle_add_overflow_abort:
nop push %rbp
// fallthrough mov %rsp,%rbp
.endfn __ubsan_handle_add_overflow_abort,globl .profilable
__ubsan_handle_add_overflow:
loadstr "add_overflow",si loadstr "add_overflow",si
jmp __ubsan_hop call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_add_overflow_abort,globl
__ubsan_handle_add_overflow:
push %rbp
mov %rsp,%rbp
.profilable
loadstr "add_overflow",si
call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_add_overflow,globl .endfn __ubsan_handle_add_overflow,globl
__ubsan_handle_alignment_assumption_abort: __ubsan_handle_alignment_assumption_abort:
nop push %rbp
// fallthrough mov %rsp,%rbp
.endfn __ubsan_handle_alignment_assumption_abort,globl .profilable
__ubsan_handle_alignment_assumption:
loadstr "alignment_assumption",si loadstr "alignment_assumption",si
jmp __ubsan_hop call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_alignment_assumption_abort,globl
__ubsan_handle_alignment_assumption:
push %rbp
mov %rsp,%rbp
.profilable
loadstr "alignment_assumption",si
call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_alignment_assumption,globl .endfn __ubsan_handle_alignment_assumption,globl
__ubsan_handle_builtin_unreachable_abort: __ubsan_handle_builtin_unreachable_abort:
nop push %rbp
// fallthrough mov %rsp,%rbp
.endfn __ubsan_handle_builtin_unreachable_abort,globl .profilable
__ubsan_handle_builtin_unreachable:
loadstr "builtin_unreachable",si loadstr "builtin_unreachable",si
jmp __ubsan_hop call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_builtin_unreachable_abort,globl
__ubsan_handle_builtin_unreachable:
push %rbp
mov %rsp,%rbp
.profilable
loadstr "builtin_unreachable",si
call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_builtin_unreachable,globl .endfn __ubsan_handle_builtin_unreachable,globl
__ubsan_handle_cfi_bad_type_abort: __ubsan_handle_cfi_bad_type_abort:
nop push %rbp
// fallthrough mov %rsp,%rbp
.endfn __ubsan_handle_cfi_bad_type_abort,globl .profilable
__ubsan_handle_cfi_bad_type:
loadstr "cfi_bad_type",si loadstr "cfi_bad_type",si
jmp __ubsan_hop call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_cfi_bad_type_abort,globl
__ubsan_handle_cfi_bad_type:
push %rbp
mov %rsp,%rbp
.profilable
loadstr "cfi_bad_type",si
call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_cfi_bad_type,globl .endfn __ubsan_handle_cfi_bad_type,globl
__ubsan_handle_cfi_check_fail_abort: __ubsan_handle_cfi_check_fail_abort:
nop push %rbp
// fallthrough mov %rsp,%rbp
.endfn __ubsan_handle_cfi_check_fail_abort,globl .profilable
__ubsan_handle_cfi_check_fail:
loadstr "cfi_check_fail",si loadstr "cfi_check_fail",si
jmp __ubsan_hop call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_cfi_check_fail_abort,globl
__ubsan_handle_cfi_check_fail:
push %rbp
mov %rsp,%rbp
.profilable
loadstr "cfi_check_fail",si
call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_cfi_check_fail,globl .endfn __ubsan_handle_cfi_check_fail,globl
__ubsan_handle_divrem_overflow_abort: __ubsan_handle_divrem_overflow_abort:
nop push %rbp
// fallthrough mov %rsp,%rbp
.endfn __ubsan_handle_divrem_overflow_abort,globl .profilable
__ubsan_handle_divrem_overflow:
loadstr "divrem_overflow",si loadstr "divrem_overflow",si
jmp __ubsan_hop call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_divrem_overflow_abort,globl
__ubsan_handle_divrem_overflow:
push %rbp
mov %rsp,%rbp
.profilable
loadstr "divrem_overflow",si
call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_divrem_overflow,globl .endfn __ubsan_handle_divrem_overflow,globl
__ubsan_handle_dynamic_type_cache_miss_abort: __ubsan_handle_dynamic_type_cache_miss_abort:
nop push %rbp
// fallthrough mov %rsp,%rbp
.endfn __ubsan_handle_dynamic_type_cache_miss_abort,globl .profilable
__ubsan_handle_dynamic_type_cache_miss:
loadstr "dynamic_type_cache_miss",si loadstr "dynamic_type_cache_miss",si
jmp __ubsan_hop call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_dynamic_type_cache_miss_abort,globl
__ubsan_handle_dynamic_type_cache_miss:
push %rbp
mov %rsp,%rbp
.profilable
loadstr "dynamic_type_cache_miss",si
call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_dynamic_type_cache_miss,globl .endfn __ubsan_handle_dynamic_type_cache_miss,globl
__ubsan_handle_function_type_mismatch_abort: __ubsan_handle_function_type_mismatch_abort:
nop push %rbp
// fallthrough mov %rsp,%rbp
.endfn __ubsan_handle_function_type_mismatch_abort,globl .profilable
__ubsan_handle_function_type_mismatch:
loadstr "function_type_mismatch",si loadstr "function_type_mismatch",si
jmp __ubsan_hop call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_function_type_mismatch_abort,globl
__ubsan_handle_function_type_mismatch:
push %rbp
mov %rsp,%rbp
.profilable
loadstr "function_type_mismatch",si
call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_function_type_mismatch,globl .endfn __ubsan_handle_function_type_mismatch,globl
__ubsan_handle_implicit_conversion_abort: __ubsan_handle_implicit_conversion_abort:
nop push %rbp
// fallthrough mov %rsp,%rbp
.endfn __ubsan_handle_implicit_conversion_abort,globl .profilable
__ubsan_handle_implicit_conversion:
loadstr "implicit_conversion",si loadstr "implicit_conversion",si
jmp __ubsan_hop call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_implicit_conversion_abort,globl
__ubsan_handle_implicit_conversion:
push %rbp
mov %rsp,%rbp
.profilable
loadstr "implicit_conversion",si
call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_implicit_conversion,globl .endfn __ubsan_handle_implicit_conversion,globl
__ubsan_handle_invalid_builtin_abort: __ubsan_handle_invalid_builtin_abort:
nop push %rbp
// fallthrough mov %rsp,%rbp
.endfn __ubsan_handle_invalid_builtin_abort,globl .profilable
__ubsan_handle_invalid_builtin:
loadstr "invalid_builtin",si loadstr "invalid_builtin",si
jmp __ubsan_hop call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_invalid_builtin_abort,globl
__ubsan_handle_invalid_builtin:
push %rbp
mov %rsp,%rbp
.profilable
loadstr "invalid_builtin",si
call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_invalid_builtin,globl .endfn __ubsan_handle_invalid_builtin,globl
__ubsan_handle_load_invalid_value_abort: __ubsan_handle_load_invalid_value_abort:
nop push %rbp
// fallthrough mov %rsp,%rbp
.profilable
loadstr "load_invalid_value (uninitialized? bool[01]?)",si
call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_load_invalid_value_abort,globl .endfn __ubsan_handle_load_invalid_value_abort,globl
__ubsan_handle_load_invalid_value: __ubsan_handle_load_invalid_value:
loadstr "load_invalid_value (try checking for uninitialized variables)",si push %rbp
jmp __ubsan_hop mov %rsp,%rbp
.profilable
loadstr "load_invalid_value (uninitialized? bool[01]?)",si
call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_load_invalid_value,globl .endfn __ubsan_handle_load_invalid_value,globl
__ubsan_handle_missing_return_abort: __ubsan_handle_missing_return_abort:
nop push %rbp
// fallthrough mov %rsp,%rbp
.endfn __ubsan_handle_missing_return_abort,globl .profilable
__ubsan_handle_missing_return:
loadstr "missing_return",si loadstr "missing_return",si
jmp __ubsan_hop call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_missing_return_abort,globl
__ubsan_handle_missing_return:
push %rbp
mov %rsp,%rbp
.profilable
loadstr "missing_return",si
call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_missing_return,globl .endfn __ubsan_handle_missing_return,globl
__ubsan_handle_mul_overflow_abort: __ubsan_handle_mul_overflow_abort:
nop push %rbp
// fallthrough mov %rsp,%rbp
.endfn __ubsan_handle_mul_overflow_abort,globl .profilable
__ubsan_handle_mul_overflow:
loadstr "mul_overflow",si loadstr "mul_overflow",si
jmp __ubsan_hop call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_mul_overflow_abort,globl
__ubsan_handle_mul_overflow:
push %rbp
mov %rsp,%rbp
.profilable
loadstr "mul_overflow",si
call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_mul_overflow,globl .endfn __ubsan_handle_mul_overflow,globl
__ubsan_handle_negate_overflow_abort: __ubsan_handle_negate_overflow_abort:
nop push %rbp
// fallthrough mov %rsp,%rbp
.endfn __ubsan_handle_negate_overflow_abort,globl .profilable
__ubsan_handle_negate_overflow:
loadstr "negate_overflow",si loadstr "negate_overflow",si
jmp __ubsan_hop call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_negate_overflow_abort,globl
__ubsan_handle_negate_overflow:
push %rbp
mov %rsp,%rbp
.profilable
loadstr "negate_overflow",si
call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_negate_overflow,globl .endfn __ubsan_handle_negate_overflow,globl
__ubsan_handle_nonnull_arg_abort: __ubsan_handle_nonnull_arg_abort:
nop push %rbp
// fallthrough mov %rsp,%rbp
.endfn __ubsan_handle_nonnull_arg_abort,globl .profilable
__ubsan_handle_nonnull_arg:
loadstr "nonnull_arg",si loadstr "nonnull_arg",si
jmp __ubsan_hop call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_nonnull_arg_abort,globl
__ubsan_handle_nonnull_arg:
push %rbp
mov %rsp,%rbp
.profilable
loadstr "nonnull_arg",si
call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_nonnull_arg,globl .endfn __ubsan_handle_nonnull_arg,globl
__ubsan_handle_nonnull_return_v1_abort: __ubsan_handle_nonnull_return_v1_abort:
nop push %rbp
// fallthrough mov %rsp,%rbp
.endfn __ubsan_handle_nonnull_return_v1_abort,globl .profilable
__ubsan_handle_nonnull_return_v1:
loadstr "nonnull_return_v1",si loadstr "nonnull_return_v1",si
jmp __ubsan_hop call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_nonnull_return_v1_abort,globl
__ubsan_handle_nonnull_return_v1:
push %rbp
mov %rsp,%rbp
.profilable
loadstr "nonnull_return_v1",si
call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_nonnull_return_v1,globl .endfn __ubsan_handle_nonnull_return_v1,globl
__ubsan_hop:
jmp __ubsan_abort
.endfn __ubsan_hop
__ubsan_handle_nullability_arg_abort: __ubsan_handle_nullability_arg_abort:
nop push %rbp
// fallthrough mov %rsp,%rbp
.endfn __ubsan_handle_nullability_arg_abort,globl .profilable
__ubsan_handle_nullability_arg:
loadstr "nullability_arg",si loadstr "nullability_arg",si
jmp __ubsan_hop call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_nullability_arg_abort,globl
__ubsan_handle_nullability_arg:
push %rbp
mov %rsp,%rbp
.profilable
loadstr "nullability_arg",si
call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_nullability_arg,globl .endfn __ubsan_handle_nullability_arg,globl
__ubsan_handle_nullability_return_v1_abort: __ubsan_handle_nullability_return_v1_abort:
nop push %rbp
// fallthrough mov %rsp,%rbp
.endfn __ubsan_handle_nullability_return_v1_abort,globl .profilable
__ubsan_handle_nullability_return_v1:
loadstr "nullability_return_v1",si loadstr "nullability_return_v1",si
jmp __ubsan_hop call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_nullability_return_v1_abort,globl
__ubsan_handle_nullability_return_v1:
push %rbp
mov %rsp,%rbp
.profilable
loadstr "nullability_return_v1",si
call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_nullability_return_v1,globl .endfn __ubsan_handle_nullability_return_v1,globl
__ubsan_handle_pointer_overflow_abort: __ubsan_handle_pointer_overflow_abort:
nop push %rbp
// fallthrough mov %rsp,%rbp
.endfn __ubsan_handle_pointer_overflow_abort,globl .profilable
__ubsan_handle_pointer_overflow:
loadstr "pointer_overflow",si loadstr "pointer_overflow",si
jmp __ubsan_hop call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_pointer_overflow_abort,globl
__ubsan_handle_pointer_overflow:
push %rbp
mov %rsp,%rbp
.profilable
loadstr "pointer_overflow",si
call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_pointer_overflow,globl .endfn __ubsan_handle_pointer_overflow,globl
__ubsan_handle_shift_out_of_bounds_abort: __ubsan_handle_shift_out_of_bounds_abort:
nop push %rbp
// fallthrough mov %rsp,%rbp
.profilable
call __ubsan_handle_shift_out_of_bounds
pop %rbp
ret
.endfn __ubsan_handle_shift_out_of_bounds_abort,globl .endfn __ubsan_handle_shift_out_of_bounds_abort,globl
__ubsan_handle_shift_out_of_bounds:
loadstr "shift_out_of_bounds",si
jmp __ubsan_hop
.endfn __ubsan_handle_shift_out_of_bounds,globl
__ubsan_handle_sub_overflow_abort: __ubsan_handle_sub_overflow_abort:
nop push %rbp
// fallthrough mov %rsp,%rbp
.endfn __ubsan_handle_sub_overflow_abort,globl .profilable
__ubsan_handle_sub_overflow:
loadstr "sub_overflow",si loadstr "sub_overflow",si
jmp __ubsan_hop call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_sub_overflow_abort,globl
__ubsan_handle_sub_overflow:
push %rbp
mov %rsp,%rbp
.profilable
loadstr "sub_overflow",si
call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_sub_overflow,globl .endfn __ubsan_handle_sub_overflow,globl
__ubsan_handle_vla_bound_not_positive_abort: __ubsan_handle_vla_bound_not_positive_abort:
nop push %rbp
// fallthrough mov %rsp,%rbp
.endfn __ubsan_handle_vla_bound_not_positive_abort,globl .profilable
__ubsan_handle_vla_bound_not_positive:
loadstr "vla_bound_not_positive",si loadstr "vla_bound_not_positive",si
jmp __ubsan_hop call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_vla_bound_not_positive_abort,globl
__ubsan_handle_vla_bound_not_positive:
push %rbp
mov %rsp,%rbp
.profilable
loadstr "vla_bound_not_positive",si
call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_vla_bound_not_positive,globl .endfn __ubsan_handle_vla_bound_not_positive,globl
__ubsan_handle_nonnull_return_abort: __ubsan_handle_nonnull_return_abort:
nop push %rbp
// fallthrough mov %rsp,%rbp
.endfn __ubsan_handle_nonnull_return_abort,globl .profilable
__ubsan_handle_nonnull_return:
loadstr "nonnull_return",si loadstr "nonnull_return",si
jmp __ubsan_hop call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_nonnull_return_abort,globl
__ubsan_handle_nonnull_return:
push %rbp
mov %rsp,%rbp
.profilable
loadstr "nonnull_return",si
call __ubsan_abort
pop %rbp
ret
.endfn __ubsan_handle_nonnull_return,globl .endfn __ubsan_handle_nonnull_return,globl
__ubsan_handle_out_of_bounds_abort: __ubsan_handle_out_of_bounds_abort:
jmp __ubsan_handle_out_of_bounds push %rbp
mov %rsp,%rbp
.profilable
call __ubsan_handle_out_of_bounds
pop %rbp
ret
.endfn __ubsan_handle_out_of_bounds_abort,globl .endfn __ubsan_handle_out_of_bounds_abort,globl
.previous

View file

@ -16,6 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/alg/reverse.internal.h"
#include "libc/bits/pushpop.h" #include "libc/bits/pushpop.h"
#include "libc/calls/calls.h" #include "libc/calls/calls.h"
#include "libc/fmt/fmt.h" #include "libc/fmt/fmt.h"
@ -43,6 +44,89 @@ upcast of\0\
cast to virtual base of\0\ cast to virtual base of\0\
\0"; \0";
static int __ubsan_bits(struct UbsanTypeDescriptor *t) {
return 1 << (t->info >> 1);
}
static bool __ubsan_signed(struct UbsanTypeDescriptor *t) {
return t->info & 1;
}
static bool __ubsan_negative(struct UbsanTypeDescriptor *t, uintptr_t x) {
return __ubsan_signed(t) && (intptr_t)x < 0;
}
static size_t __ubsan_strlen(const char *s) {
size_t n = 0;
while (*s++) ++n;
return n;
}
static char *__ubsan_stpcpy(char *d, const char *s) {
size_t i;
for (i = 0;; ++i) {
if (!(d[i] = s[i])) {
return d + i;
}
}
}
static char *__ubsan_poscpy(char *p, uintptr_t i) {
int j = 0;
do {
p[j++] = i % 10 + '0';
i /= 10;
} while (i > 0);
reverse(p, j);
return p + j;
}
static char *__ubsan_intcpy(char *p, intptr_t i) {
if (i >= 0) return __ubsan_poscpy(p, i);
*p++ = '-';
return __ubsan_poscpy(p, -i);
}
static char *__ubsan_hexcpy(char *p, uintptr_t x, int k) {
while (k) *p++ = "0123456789abcdef"[(x >> (k -= 4)) & 15];
return p;
}
static char *__ubsan_itpcpy(char *p, struct UbsanTypeDescriptor *t,
uintptr_t x) {
if (__ubsan_signed(t)) {
return __ubsan_intcpy(p, x);
} else {
return __ubsan_poscpy(p, x);
}
}
static const char *__ubsan_dubnul(const char *s, unsigned i) {
size_t n;
while (i--) {
if ((n = __ubsan_strlen(s))) {
s += n + 1;
} else {
return NULL;
}
}
return s;
}
static uintptr_t __ubsan_extend(struct UbsanTypeDescriptor *t, uintptr_t x) {
int w;
w = __ubsan_bits(t);
if (w < sizeof(x) * CHAR_BIT) {
x <<= sizeof(x) * CHAR_BIT - w;
if (__ubsan_signed(t)) {
x = (intptr_t)x >> w;
} else {
x >>= w;
}
}
return x;
}
void __ubsan_abort(const struct UbsanSourceLocation *loc, void __ubsan_abort(const struct UbsanSourceLocation *loc,
const char *description) { const char *description) {
static bool once; static bool once;
@ -53,43 +137,73 @@ void __ubsan_abort(const struct UbsanSourceLocation *loc,
} }
if (IsDebuggerPresent(false)) DebugBreak(); if (IsDebuggerPresent(false)) DebugBreak();
__start_fatal(loc->file, loc->line); __start_fatal(loc->file, loc->line);
fprintf(stderr, "%s\r\n", description); write(2, description, strlen(description));
write(2, "\r\n", 2);
__die(); __die();
unreachable; }
void __ubsan_handle_shift_out_of_bounds(struct UbsanShiftOutOfBoundsInfo *info,
uintptr_t lhs, uintptr_t rhs) {
char *p;
const char *s;
lhs = __ubsan_extend(info->lhs_type, lhs);
rhs = __ubsan_extend(info->rhs_type, rhs);
if (__ubsan_negative(info->rhs_type, rhs)) {
s = "shift exponent is negative";
} else if (rhs >= __ubsan_bits(info->lhs_type)) {
s = "shift exponent too large for type";
} else if (__ubsan_negative(info->lhs_type, lhs)) {
s = "left shift of negative value";
} else if (__ubsan_signed(info->lhs_type)) {
s = "signed left shift changed sign bit or overflowed";
} else {
s = "wut shift out of bounds";
}
p = __ubsan_buf;
p = __ubsan_stpcpy(p, s), *p++ = ' ';
p = __ubsan_itpcpy(p, info->lhs_type, lhs), *p++ = ' ';
p = __ubsan_stpcpy(p, info->lhs_type->name), *p++ = ' ';
p = __ubsan_itpcpy(p, info->rhs_type, rhs), *p++ = ' ';
p = __ubsan_stpcpy(p, info->rhs_type->name);
__ubsan_abort(&info->location, __ubsan_buf);
} }
void __ubsan_handle_out_of_bounds(struct UbsanOutOfBoundsInfo *info, void __ubsan_handle_out_of_bounds(struct UbsanOutOfBoundsInfo *info,
uintptr_t index) { uintptr_t index) {
snprintf(__ubsan_buf, sizeof(__ubsan_buf), char *p;
"%s index %,lu into %s out of bounds", info->index_type->name, index, p = __ubsan_buf;
info->array_type->name); p = __ubsan_stpcpy(p, info->index_type->name);
p = __ubsan_stpcpy(p, " index ");
p = __ubsan_itpcpy(p, info->index_type, index);
p = __ubsan_stpcpy(p, " into ");
p = __ubsan_stpcpy(p, info->array_type->name);
p = __ubsan_stpcpy(p, " out of bounds");
__ubsan_abort(&info->location, __ubsan_buf); __ubsan_abort(&info->location, __ubsan_buf);
unreachable;
} }
void __ubsan_handle_type_mismatch(struct UbsanTypeMismatchInfo *type_mismatch, void __ubsan_handle_type_mismatch(struct UbsanTypeMismatchInfo *info,
uintptr_t pointer) { uintptr_t pointer) {
struct UbsanSourceLocation *loc = &type_mismatch->location; char *p;
const char *description; const char *kind;
const char *kind = IndexDoubleNulString(kUbsanTypeCheckKinds, if (!pointer) __ubsan_abort(&info->location, "null pointer access");
type_mismatch->type_check_kind); p = __ubsan_buf;
if (pointer == 0) { kind = __ubsan_dubnul(kUbsanTypeCheckKinds, info->type_check_kind);
description = "null pointer access"; if (info->alignment && (pointer & (info->alignment - 1))) {
} else if (type_mismatch->alignment != 0 && p = __ubsan_stpcpy(p, "unaligned ");
(pointer & (type_mismatch->alignment - 1))) { p = __ubsan_stpcpy(p, kind), *p++ = ' ';
description = __ubsan_buf; p = __ubsan_stpcpy(p, info->type->name), *p++ = ' ', *p++ = '@';
snprintf(__ubsan_buf, sizeof(__ubsan_buf), "%s %s %s @%p %s %d", p = __ubsan_itpcpy(p, info->type, pointer);
"unaligned", kind, type_mismatch->type->name, pointer, "align", p = __ubsan_stpcpy(p, " align ");
type_mismatch->alignment); p = __ubsan_intcpy(p, info->alignment);
} else { } else {
description = __ubsan_buf; p = __ubsan_stpcpy(p, "insufficient size\r\n\t");
snprintf(__ubsan_buf, sizeof(__ubsan_buf), "%s\r\n\t%s %s %p %s %s", p = __ubsan_stpcpy(p, kind);
"insufficient size", kind, "address", pointer, p = __ubsan_stpcpy(p, " address 0x");
"with insufficient space for object of type", p = __ubsan_hexcpy(p, pointer, sizeof(pointer) * CHAR_BIT);
type_mismatch->type->name); p = __ubsan_stpcpy(p, " with insufficient space for object of type ");
p = __ubsan_stpcpy(p, info->type->name);
} }
__ubsan_abort(loc, description); __ubsan_abort(&info->location, __ubsan_buf);
unreachable;
} }
void ___ubsan_handle_type_mismatch_v1( void ___ubsan_handle_type_mismatch_v1(
@ -100,7 +214,6 @@ void ___ubsan_handle_type_mismatch_v1(
mm.alignment = 1u << type_mismatch->log_alignment; mm.alignment = 1u << type_mismatch->log_alignment;
mm.type_check_kind = type_mismatch->type_check_kind; mm.type_check_kind = type_mismatch->type_check_kind;
__ubsan_handle_type_mismatch(&mm, pointer); __ubsan_handle_type_mismatch(&mm, pointer);
unreachable;
} }
void __ubsan_handle_float_cast_overflow(void *data_raw, void *from_raw) { void __ubsan_handle_float_cast_overflow(void *data_raw, void *from_raw) {
@ -116,5 +229,4 @@ void __ubsan_handle_float_cast_overflow(void *data_raw, void *from_raw) {
}; };
__ubsan_abort(((void)data, &kUnknownLocation), "float cast overflow"); __ubsan_abort(((void)data, &kUnknownLocation), "float cast overflow");
#endif #endif
unreachable;
} }

View file

@ -1,11 +1,15 @@
#ifndef COSMOPOLITAN_LIBC_UBSAN_H_ #ifndef COSMOPOLITAN_LIBC_UBSAN_H_
#define COSMOPOLITAN_LIBC_UBSAN_H_ #define COSMOPOLITAN_LIBC_UBSAN_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
/*───────────────────────────────────────────────────────────────────────────│─╗ /*───────────────────────────────────────────────────────────────────────────│─╗
cosmopolitan § runtime » behavior enforcement cosmopolitan § runtime » behavior enforcement
*/ */
#define kUbsanKindInt 0
#define kUbsanKindFloat 1
#define kUbsanKindUnknown 0xffff
#if !(__ASSEMBLER__ + __LINKER__ + 0)
struct UbsanSourceLocation { struct UbsanSourceLocation {
const char *file; const char *file;
uint32_t line; uint32_t line;
@ -13,8 +17,8 @@ struct UbsanSourceLocation {
}; };
struct UbsanTypeDescriptor { struct UbsanTypeDescriptor {
uint16_t kind; uint16_t kind; /* int,float,... */
uint16_t info; uint16_t info; /* if int bit 0 if signed, remaining bits are log2(sizeof*8) */
char name[]; char name[];
}; };
@ -91,7 +95,7 @@ struct UbsanOutOfBoundsData {
struct UbsanTypeDescriptor *index_type; struct UbsanTypeDescriptor *index_type;
}; };
struct UbsanShiftOutOfBoundsData { struct UbsanShiftOutOfBoundsInfo {
struct UbsanSourceLocation location; struct UbsanSourceLocation location;
struct UbsanTypeDescriptor *lhs_type; struct UbsanTypeDescriptor *lhs_type;
struct UbsanTypeDescriptor *rhs_type; struct UbsanTypeDescriptor *rhs_type;

View file

@ -26,8 +26,6 @@
#define TYPE_BIT(type) (sizeof(type) * CHAR_BIT) #define TYPE_BIT(type) (sizeof(type) * CHAR_BIT)
#define TYPE_SIGNED(type) (((type)-1) < 0) #define TYPE_SIGNED(type) (((type)-1) < 0)
#define TYPE_INTEGRAL(type) (((type)0.5) != 0.5) #define TYPE_INTEGRAL(type) (((type)0.5) != 0.5)
#define INT_STRLEN_MAXIMUM(type) \
((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + 1 + TYPE_SIGNED(type))
#define ARRAYLEN(A) \ #define ARRAYLEN(A) \
((sizeof(A) / sizeof(*(A))) / ((unsigned)!(sizeof(A) % sizeof(*(A))))) ((sizeof(A) / sizeof(*(A))) / ((unsigned)!(sizeof(A) % sizeof(*(A)))))

7
libc/nt/enum/lockfile.h Normal file
View file

@ -0,0 +1,7 @@
#ifndef COSMOPOLITAN_LIBC_NT_ENUM_LOCKFILE_H_
#define COSMOPOLITAN_LIBC_NT_ENUM_LOCKFILE_H_
#define kNtLockfileFailImmediately 1
#define kNtLockfileExclusiveLock 2
#endif /* COSMOPOLITAN_LIBC_NT_ENUM_LOCKFILE_H_ */

View file

@ -29,6 +29,7 @@
* Without this, there's no guarantee memory is written back to disk. In * Without this, there's no guarantee memory is written back to disk. In
* practice, what that means is just Windows NT. * practice, what that means is just Windows NT.
* *
* @param addr needs to be 4096-byte page aligned
* @param flags needs MS_ASYNC or MS_SYNC and can have MS_INVALIDATE * @param flags needs MS_ASYNC or MS_SYNC and can have MS_INVALIDATE
* @return 0 on success or -1 w/ errno * @return 0 on success or -1 w/ errno
*/ */

View file

@ -21,9 +21,9 @@
/** /**
* Locates End Of Central Directory record in ZIP file. * Locates End Of Central Directory record in ZIP file.
* *
* The ZIP spec says this header can be anywhere in the last 64kb. * The ZIP spec says this header can be anywhere in the last 64kb. We
* We search it backwards for the ZIP-64 "PK♠" magic number. If that's * search it backwards for the ZIP-64 "PK♠" magic number. If that's not
* not found, then we search again for the original "PK♣♠" magnum. The * found, then we search again for the original "PK♣♠" magnum. The
* caller needs to check the first four bytes of the returned value to * caller needs to check the first four bytes of the returned value to
* determine whether to use ZIP_CDIR_xxx() or ZIP_CDIR64_xxx() macros. * determine whether to use ZIP_CDIR_xxx() or ZIP_CDIR64_xxx() macros.
* *
@ -31,23 +31,25 @@
* @param n is byte size of file * @param n is byte size of file
* @return pointer to EOCD64 or EOCD, or NULL if not found * @return pointer to EOCD64 or EOCD, or NULL if not found
*/ */
uint8_t *GetZipCdir(const uint8_t *p, size_t n) { void *GetZipCdir(const uint8_t *p, size_t n) {
size_t i, j; size_t i, j;
if (n >= kZipCdirHdrMinSize) { i = n - 4;
i = n - kZipCdirHdrMinSize;
do { do {
if (READ32LE(p + i) == kZipCdir64HdrMagic && IsZipCdir64(p, n, i)) { if (READ32LE(p + i) == kZipCdir64LocatorMagic &&
return (/*unconst*/ uint8_t *)(p + i); i + kZipCdir64LocatorSize <= n &&
IsZipCdir64(p, n, ZIP_LOCATE64_OFFSET(p + i))) {
return (void *)(p + ZIP_LOCATE64_OFFSET(p + i));
} else if (READ32LE(p + i) == kZipCdirHdrMagic && IsZipCdir32(p, n, i)) { } else if (READ32LE(p + i) == kZipCdirHdrMagic && IsZipCdir32(p, n, i)) {
j = i; j = i;
do { do {
if (READ32LE(p + j) == kZipCdir64HdrMagic && IsZipCdir64(p, n, j)) { if (READ32LE(p + j) == kZipCdir64LocatorMagic &&
return (/*unconst*/ uint8_t *)(p + j); j + kZipCdir64LocatorSize <= n &&
IsZipCdir64(p, n, ZIP_LOCATE64_OFFSET(p + j))) {
return (void *)(p + ZIP_LOCATE64_OFFSET(p + j));
} }
} while (j-- && i - j < 64 * 1024); } while (j-- && i - j < 64 * 1024);
return (/*unconst*/ uint8_t *)(p + i); return (void *)(p + i);
} }
} while (i--); } while (i--);
}
return NULL; return NULL;
} }

View file

@ -22,7 +22,7 @@
* Returns comment of zip central directory. * Returns comment of zip central directory.
*/ */
void *GetZipCdirComment(const uint8_t *eocd) { void *GetZipCdirComment(const uint8_t *eocd) {
if (READ32LE(eocd) == kZipCdir64HdrMagic) { if (READ32LE(eocd) == kZipCdir64HdrMagic && ZIP_CDIR64_COMMENTSIZE(eocd)) {
return ZIP_CDIR64_COMMENT(eocd); return ZIP_CDIR64_COMMENT(eocd);
} else { } else {
return ZIP_CDIR_COMMENT(eocd); return ZIP_CDIR_COMMENT(eocd);

View file

@ -22,7 +22,7 @@
* Returns comment of zip central directory. * Returns comment of zip central directory.
*/ */
uint64_t GetZipCdirCommentSize(const uint8_t *eocd) { uint64_t GetZipCdirCommentSize(const uint8_t *eocd) {
if (READ32LE(eocd) == kZipCdir64HdrMagic) { if (READ32LE(eocd) == kZipCdir64HdrMagic && ZIP_CDIR64_COMMENTSIZE(eocd)) {
return ZIP_CDIR64_COMMENTSIZE(eocd); return ZIP_CDIR64_COMMENTSIZE(eocd);
} else { } else {
return ZIP_CDIR_COMMENTSIZE(eocd); return ZIP_CDIR_COMMENTSIZE(eocd);

View file

@ -714,8 +714,7 @@ int iswlower(wint_t c) {
case u'': // LATIN SMALL D W/ HOOK AND TAIL (0x1d91) case u'': // LATIN SMALL D W/ HOOK AND TAIL (0x1d91)
case u'': // LATIN SMALL E W/ RETROFLEX HOOK (0x1d92) case u'': // LATIN SMALL E W/ RETROFLEX HOOK (0x1d92)
case u'': // LATIN SMALL OPEN E W/ RETROFLEX HOOK (0x1d93) case u'': // LATIN SMALL OPEN E W/ RETROFLEX HOOK (0x1d93)
case u'': // LATIN SMALL REVERSED OPEN E W/ RETROFLEX HOOK case u'': // LATIN SMALL REVERSED OPEN E W/ RETROFLEX HOOK (0x1d94)
// (0x1d94)
case u'': // LATIN SMALL SCHWA W/ RETROFLEX HOOK (0x1d95) case u'': // LATIN SMALL SCHWA W/ RETROFLEX HOOK (0x1d95)
case u'': // LATIN SMALL I W/ RETROFLEX HOOK (0x1d96) case u'': // LATIN SMALL I W/ RETROFLEX HOOK (0x1d96)
case u'': // LATIN SMALL OPEN O W/ RETROFLEX HOOK (0x1d97) case u'': // LATIN SMALL OPEN O W/ RETROFLEX HOOK (0x1d97)
@ -1219,8 +1218,7 @@ int iswlower(wint_t c) {
case u'': // LATIN SMALL VY (0xa761) case u'': // LATIN SMALL VY (0xa761)
case u'': // LATIN SMALL VISIGOTHIC Z (0xa763) case u'': // LATIN SMALL VISIGOTHIC Z (0xa763)
case u'': // LATIN SMALL THORN W/ STROKE (0xa765) case u'': // LATIN SMALL THORN W/ STROKE (0xa765)
case u'': // LATIN SMALL THORN W/ STROKE THROUGH DESCENDER case u'': // LATIN SMALL THORN W/ STROKE THROUGH DESCENDER (0xa767)
// (0xa767)
case u'': // LATIN SMALL VEND (0xa769) case u'': // LATIN SMALL VEND (0xa769)
case u'': // LATIN SMALL ET (0xa76b) case u'': // LATIN SMALL ET (0xa76b)
case u'': // LATIN SMALL IS (0xa76d) case u'': // LATIN SMALL IS (0xa76d)

View file

@ -23,11 +23,16 @@
* Returns true if zip64 end of central directory header seems legit. * Returns true if zip64 end of central directory header seems legit.
*/ */
bool IsZipCdir64(const uint8_t *p, size_t n, size_t i) { bool IsZipCdir64(const uint8_t *p, size_t n, size_t i) {
if (i > n || n - i < kZipCdir64HdrMinSize) return false; if (i + kZipCdir64HdrMinSize > n) return false;
if (READ32LE(p + i) != kZipCdir64HdrMagic) return false; if (READ32LE(p + i) != kZipCdir64HdrMagic) return false;
if (i + ZIP_CDIR64_HDRSIZE(p + i) > n) return false; if (i + ZIP_CDIR64_HDRSIZE(p + i) + kZipCdir64LocatorSize > n) {
if (ZIP_CDIR64_DISK(p + i) != ZIP_CDIR64_STARTINGDISK(p + i)) return false; return false;
if (ZIP_CDIR64_RECORDSONDISK(p + i) != ZIP_CDIR64_RECORDS(p + i)) { }
if (ZIP_LOCATE64_MAGIC(p + i + ZIP_CDIR64_HDRSIZE(p + i)) !=
kZipCdir64LocatorMagic) {
return false;
}
if (ZIP_LOCATE64_OFFSET(p + i + ZIP_CDIR64_HDRSIZE(p + i)) != i) {
return false; return false;
} }
if (ZIP_CDIR64_RECORDS(p + i) * kZipCfileHdrMinSize > if (ZIP_CDIR64_RECORDS(p + i) * kZipCfileHdrMinSize >

View file

@ -29,19 +29,22 @@
*/ */
void *memchr(const void *m, int c, size_t n) { void *memchr(const void *m, int c, size_t n) {
uint64_t v, w; uint64_t v, w;
const unsigned char *p, *pe; const char *p, *pe;
c &= 255; c &= 255;
v = 0x0101010101010101 * c; v = 0x0101010101010101 * c;
for (p = (const unsigned char *)m, pe = p + n; p + 8 <= pe; p += 8) { for (p = m, pe = p + n; p + 8 <= pe; p += 8) {
w = (uint64_t)p[7] << 070 | (uint64_t)p[6] << 060 | (uint64_t)p[5] << 050 | w = (uint64_t)(255 & p[7]) << 070 | (uint64_t)(255 & p[6]) << 060 |
(uint64_t)p[4] << 040 | (uint64_t)p[3] << 030 | (uint64_t)p[2] << 020 | (uint64_t)(255 & p[5]) << 050 | (uint64_t)(255 & p[4]) << 040 |
(uint64_t)p[1] << 010 | (uint64_t)p[0] << 000; (uint64_t)(255 & p[3]) << 030 | (uint64_t)(255 & p[2]) << 020 |
(uint64_t)(255 & p[1]) << 010 | (uint64_t)(255 & p[0]) << 000;
if ((w = ~(w ^ v) & ((w ^ v) - 0x0101010101010101) & 0x8080808080808080)) { if ((w = ~(w ^ v) & ((w ^ v) - 0x0101010101010101) & 0x8080808080808080)) {
return p + ((unsigned)__builtin_ctzll(w) >> 3); return p + ((unsigned)__builtin_ctzll(w) >> 3);
} }
} }
for (; p < pe; ++p) { for (; p < pe; ++p) {
if (*p == c) return p; if ((*p & 255) == c) {
return p;
}
} }
return NULL; return NULL;
} }

View file

@ -17,14 +17,16 @@
PERFORMANCE OF THIS SOFTWARE. PERFORMANCE OF THIS SOFTWARE.
*/ */
#include "libc/assert.h" #include "libc/assert.h"
#include "libc/bits/bits.h"
#include "libc/str/str.h" #include "libc/str/str.h"
noasan static inline const char *strchr_x64(const char *p, uint64_t c) { static noasan inline const char *strchr_x64(const char *p, uint64_t c) {
unsigned a, b; unsigned a, b;
uint64_t w, x, y; uint64_t w, x, y;
for (c *= 0x0101010101010101;; p += 8) { for (c *= 0x0101010101010101;; p += 8) {
w = READ64LE(p); w = (uint64_t)(255 & p[7]) << 070 | (uint64_t)(255 & p[6]) << 060 |
(uint64_t)(255 & p[5]) << 050 | (uint64_t)(255 & p[4]) << 040 |
(uint64_t)(255 & p[3]) << 030 | (uint64_t)(255 & p[2]) << 020 |
(uint64_t)(255 & p[1]) << 010 | (uint64_t)(255 & p[0]) << 000;
if ((x = ~(w ^ c) & ((w ^ c) - 0x0101010101010101) & 0x8080808080808080) | if ((x = ~(w ^ c) & ((w ^ c) - 0x0101010101010101) & 0x8080808080808080) |
(y = ~w & (w - 0x0101010101010101) & 0x8080808080808080)) { (y = ~w & (w - 0x0101010101010101) & 0x8080808080808080)) {
if (x) { if (x) {
@ -57,8 +59,8 @@ noasan static inline const char *strchr_x64(const char *p, uint64_t c) {
*/ */
char *strchr(const char *s, int c) { char *strchr(const char *s, int c) {
char *r; char *r;
for (c &= 0xff; (uintptr_t)s & 7; ++s) { for (c &= 255; (uintptr_t)s & 7; ++s) {
if ((*s & 0xff) == c) return s; if ((*s & 255) == c) return s;
if (!*s) return NULL; if (!*s) return NULL;
} }
r = strchr_x64(s, c); r = strchr_x64(s, c);

View file

@ -25,7 +25,6 @@
OTHER DEALINGS IN THE SOFTWARE. OTHER DEALINGS IN THE SOFTWARE.
*/ */
#include "libc/assert.h" #include "libc/assert.h"
#include "libc/str/str.h" #include "libc/str/str.h"

View file

@ -0,0 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall __sys_fcntl,0x05c05c05c205c048,globl,hidden

View file

@ -1,2 +0,0 @@
.include "o/libc/sysv/macros.internal.inc"
.scall sys_fcntl,0x05c05c05c205c048,globl,hidden

File diff suppressed because it is too large Load diff

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon gai,AI_ADDRCONFIG,0x20,0x0400,0x0400,0x40,0x40,0x0400

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon gai,AI_ALL,0x10,0x0100,0x0100,0,0,0x0100

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon gai,AI_CANONNAME,2,2,2,2,2,2

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon gai,AI_NUMERICHOST,4,4,4,4,4,4

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon gai,AI_NUMERICSERV,0x0400,0x1000,8,0x10,0x10,8

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon gai,AI_PASSIVE,1,1,1,1,1,1

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon gai,AI_V4MAPPED,8,0x0800,0x0800,0,0,0x0800

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon misc,BIG_ENDIAN,0x10e1,0x10e1,0x10e1,0x10e1,0x10e1,0

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon misc,BLK_BYTECOUNT,2,2,2,2,2,0

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon misc,BLK_EOF,0x40,0x40,0x40,0x40,0x40,0

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon misc,BLK_EOR,0x80,0x80,0x80,0x80,0x80,0

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon misc,BLK_ERRORS,0x20,0x20,0x20,0x20,0x20,0

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon misc,BLK_RESTART,0x10,0x10,0x10,0x10,0x10,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon misc,BUS_DEVICE_RESET,12,0,0,0,0,0 .syscon scsi,BUS_DEVICE_RESET,12,0,0,0,0,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon termios,CR0,0b0000000000000000,0b000000000000000000,0b000000000000000000,0x0,0x0,0b0000000000000000 .syscon termios,CR0,0b0000000000000000,0b000000000000000000,0b000000000000000000,0,0b000000000000000000,0b0000000000000000

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon termios,CR1,0b0000001000000000,0b000001000000000000,0b000001000000000000,0x0,0x0,0b0000001000000000 .syscon termios,CR1,0b0000001000000000,0b000001000000000000,0b000001000000000000,0,0b000001000000000000,0b0000001000000000

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon termios,CR2,0b0000010000000000,0b000010000000000000,0b000010000000000000,0x0,0x0,0b0000010000000000 .syscon termios,CR2,0b0000010000000000,0b000010000000000000,0b000010000000000000,0,0b000000010000000000,0b0000010000000000

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon termios,CR3,0b0000011000000000,0b000011000000000000,0b000011000000000000,0x0,0x0,0b0000011000000000 .syscon termios,CR3,0b0000011000000000,0b000011000000000000,0b000011000000000000,0,0b000000011000000000,0b0000011000000000

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon junkerr,EBADFD,77,9,9,9,9,6 .syscon junkerr,EBADFD,77,9,0,0,0,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon junkerr,EMEDIUMTYPE,124,0,0,86,86,0 .syscon errno,EMEDIUMTYPE,124,0,0,86,0,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon misc,EMPTY,0,0,0,0,0,0 .syscon termios,EMPTY,0,0,0,0,0,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon junkerr,EMULTIHOP,72,95,90,0,94,0 .syscon errno,EMULTIHOP,72,95,90,0,94,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon junkerr,ENODATA,61,96,0,0,89,0 .syscon errno,ENODATA,61,96,0,0,89,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon junkerr,ENOLINK,67,97,91,0,95,0 .syscon errno,ENOLINK,67,97,91,0,95,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon junkerr,ENOMEDIUM,123,0,0,85,85,0 .syscon errno,ENOMEDIUM,123,0,0,85,0,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon junkerr,ENOSR,63,98,0,0,90,0 .syscon errno,ENOSR,63,98,0,90,90,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon junkerr,ENOSTR,60,99,0,0,91,0 .syscon errno,ENOSTR,60,99,0,0,91,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon misc,ERA,0x02002c,45,45,0,0,0 .syscon termios,ERA,0x02002c,45,45,0,0,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon errno,ERESTART,85,0,0,0,-3,0 .syscon errno,ERESTART,85,-1,-1,-1,-3,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon misc,EXTA,14,0x4b00,0x4b00,0x4b00,0x4b00,0 .syscon termios,EXTA,14,0x4b00,0x4b00,0x4b00,0x4b00,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon misc,EXTB,15,0x9600,0x9600,0x9600,0x9600,0 .syscon termios,EXTB,15,0x9600,0x9600,0x9600,0x9600,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon fcntl,F_GETLK,5,7,11,7,7,0 .syscon fcntl,F_GETLK,5,7,11,7,7,5

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon fcntl,F_GETLK64,5,0,0,0,0,0 .syscon compat,F_GETLK64,5,7,11,7,7,5

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon fcntl,F_SETLK,6,8,12,8,8,0 .syscon fcntl,F_SETLK,6,8,12,8,8,6

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon fcntl,F_SETLK64,6,0,0,0,0,0 .syscon compat,F_SETLK64,6,8,12,8,8,6

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon fcntl,F_SETLKW,7,9,13,9,9,0 .syscon fcntl,F_SETLKW,7,9,13,9,9,7

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon fcntl,F_SETLKW64,7,0,0,0,0,0 .syscon compat,F_SETLKW64,7,9,13,9,9,7

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon fcntl,F_UNLCK,2,2,2,2,2,0 .syscon fcntl,F_UNLCK,2,2,2,2,2,2

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon fcntl,F_WRLCK,1,3,3,3,3,0 .syscon fcntl,F_WRLCK,1,3,3,3,3,1

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon misc,INADDR_ALLHOSTS_GROUP,0xe0000001,0xe0000001,0xe0000001,0xe0000001,0xe0000001,0

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon misc,INADDR_ALLRTRS_GROUP,0xe0000002,0xe0000002,0xe0000002,0,0,0

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon misc,INADDR_ANY,0,0,0,0,0,0

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon misc,INADDR_BROADCAST,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon misc,INADDR_LOOPBACK,0x7f000001,0x7f000001,0x7f000001,0x7f000001,0x7f000001,0x7f000001

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon misc,INADDR_MAX_LOCAL_GROUP,0xe00000ff,0xe00000ff,0xe00000ff,0xe00000ff,0xe00000ff,0

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon misc,INADDR_NONE,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon misc,INADDR_UNSPEC_GROUP,0xe0000000,0xe0000000,0xe0000000,0xe0000000,0xe0000000,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon termios,IUCLC,0b0000001000000000,0,0,0b0001000000000000,0b0001000000000000,0b0000001000000000 .syscon termios,IUCLC,0b0000001000000000,0,0,0b0001000000000000,0,0b0000001000000000

View file

@ -1,2 +0,0 @@
#include "libc/sysv/consts/syscon.internal.h"
.syscon misc,LITTLE_ENDIAN,0x04d2,0x04d2,0x04d2,0x04d2,0x04d2,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon mmap,MAP_CONCEAL,0,0,0x20000,0x8000,0x8000,0 .syscon mmap,MAP_CONCEAL,0,0,0,0x8000,0,0

View file

@ -1,2 +1,2 @@
#include "libc/sysv/consts/syscon.internal.h" #include "libc/sysv/consts/syscon.internal.h"
.syscon mmap,MAP_TYPE,15,0,0,0,0,0 .syscon mmap,MAP_TYPE,15,15,15,15,15,15

Some files were not shown because too many files have changed in this diff Show more