mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-06 08:56:22 +00:00
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:
parent
919b6fec10
commit
690be544da
228 changed files with 3653 additions and 3015 deletions
Binary file not shown.
|
@ -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"
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
31
libc/calls/fcntl-sysv.c
Normal 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;
|
||||||
|
}
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
164
libc/calls/metaflock.c
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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_
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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_ */
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
168
libc/log/ubsan.c
168
libc/log/ubsan.c
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
7
libc/nt/enum/lockfile.h
Normal 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_ */
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 >
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
2
libc/sysv/calls/__sys_fcntl.s
Normal file
2
libc/sysv/calls/__sys_fcntl.s
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
.include "o/libc/sysv/macros.internal.inc"
|
||||||
|
.scall __sys_fcntl,0x05c05c05c205c048,globl,hidden
|
|
@ -1,2 +0,0 @@
|
||||||
.include "o/libc/sysv/macros.internal.inc"
|
|
||||||
.scall sys_fcntl,0x05c05c05c205c048,globl,hidden
|
|
2342
libc/sysv/consts.sh
2342
libc/sysv/consts.sh
File diff suppressed because it is too large
Load diff
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon gai,AI_ADDRCONFIG,0x20,0x0400,0x0400,0x40,0x40,0x0400
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon gai,AI_ALL,0x10,0x0100,0x0100,0,0,0x0100
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon gai,AI_CANONNAME,2,2,2,2,2,2
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon gai,AI_NUMERICHOST,4,4,4,4,4,4
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon gai,AI_NUMERICSERV,0x0400,0x1000,8,0x10,0x10,8
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon gai,AI_PASSIVE,1,1,1,1,1,1
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon gai,AI_V4MAPPED,8,0x0800,0x0800,0,0,0x0800
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon misc,BIG_ENDIAN,0x10e1,0x10e1,0x10e1,0x10e1,0x10e1,0
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon misc,BLK_BYTECOUNT,2,2,2,2,2,0
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon misc,BLK_EOF,0x40,0x40,0x40,0x40,0x40,0
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon misc,BLK_EOR,0x80,0x80,0x80,0x80,0x80,0
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon misc,BLK_ERRORS,0x20,0x20,0x20,0x20,0x20,0
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon misc,BLK_RESTART,0x10,0x10,0x10,0x10,0x10,0
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon misc,INADDR_ALLHOSTS_GROUP,0xe0000001,0xe0000001,0xe0000001,0xe0000001,0xe0000001,0
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon misc,INADDR_ALLRTRS_GROUP,0xe0000002,0xe0000002,0xe0000002,0,0,0
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon misc,INADDR_ANY,0,0,0,0,0,0
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon misc,INADDR_BROADCAST,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon misc,INADDR_LOOPBACK,0x7f000001,0x7f000001,0x7f000001,0x7f000001,0x7f000001,0x7f000001
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon misc,INADDR_MAX_LOCAL_GROUP,0xe00000ff,0xe00000ff,0xe00000ff,0xe00000ff,0xe00000ff,0
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon misc,INADDR_NONE,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon misc,INADDR_UNSPEC_GROUP,0xe0000000,0xe0000000,0xe0000000,0xe0000000,0xe0000000,0
|
|
|
@ -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
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
|
||||||
.syscon misc,LITTLE_ENDIAN,0x04d2,0x04d2,0x04d2,0x04d2,0x04d2,0
|
|
|
@ -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
|
||||||
|
|
|
@ -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
Loading…
Add table
Reference in a new issue