Get TEST_LIBC_STR passing on AARCH64

It's now possible to run commands like:

    make -j8 m=aarch64 o/aarch64/test/libc/str

Which will cross-compile and run the test suites in a qemu-aarch64
binary that's vendored in the third_party/qemu/ folder within your
x86_64 build environment.
This commit is contained in:
Justine Tunney 2023-05-12 18:09:23 -07:00
parent 45186c74ac
commit 414667b1c9
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
24 changed files with 657 additions and 61 deletions

View file

@ -20,8 +20,6 @@
#include "libc/macros.internal.h"
#include "libc/str/str.h"
#ifdef __x86_64__
static int FindPromise(const char *name) {
int i;
for (i = 0; i < ARRAYLEN(kPledge); ++i) {
@ -66,5 +64,3 @@ int ParsePromises(const char *promises, unsigned long *out) {
}
return rc;
}
#endif /* __x86_64__ */

View file

@ -35,7 +35,6 @@
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/pr.h"
#include "libc/sysv/consts/prot.h"
#ifdef __x86_64__
/**
* @fileoverview OpenBSD pledge() Polyfill Payload for GNU/Systemd
@ -76,6 +75,18 @@
#define PLEDGE(pledge) pledge, ARRAYLEN(pledge)
#define OFF(f) offsetof(struct seccomp_data, f)
#ifdef __x86_64__
#define MCONTEXT_SYSCALL_RESULT_REGISTER rax
#define MCONTEXT_INSTRUCTION_POINTER rip
#define ARCHITECTURE AUDIT_ARCH_X86_64
#elif defined(__aarch64__)
#define MCONTEXT_SYSCALL_RESULT_REGISTER regs[0]
#define MCONTEXT_INSTRUCTION_POINTER pc
#define ARCHITECTURE AUDIT_ARCH_AARCH64
#else
#error "unsupported architecture"
#endif
struct Filter {
size_t n;
struct sock_filter p[700];
@ -93,10 +104,16 @@ static const struct thatispacked SyscallName {
{__NR_linux_close, "close"}, //
{__NR_linux_stat, "stat"}, //
{__NR_linux_fstat, "fstat"}, //
#ifdef __NR_linux_lstat //
{__NR_linux_lstat, "lstat"}, //
#endif //
#ifdef __NR_linux_poll //
{__NR_linux_poll, "poll"}, //
#endif //
{__NR_linux_ppoll, "ppoll"}, //
#ifdef __NR_linux_brk //
{__NR_linux_brk, "brk"}, //
#endif //
{__NR_linux_sigreturn, "sigreturn"}, //
{__NR_linux_lseek, "lseek"}, //
{__NR_linux_mmap, "mmap"}, //
@ -110,9 +127,15 @@ static const struct thatispacked SyscallName {
{__NR_linux_pwrite, "pwrite"}, //
{__NR_linux_readv, "readv"}, //
{__NR_linux_writev, "writev"}, //
#ifdef __NR_linux_access //
{__NR_linux_access, "access"}, //
#endif //
#ifdef __NR_linux_pipe //
{__NR_linux_pipe, "pipe"}, //
#endif //
#ifdef __NR_linux_select //
{__NR_linux_select, "select"}, //
#endif //
{__NR_linux_pselect6, "pselect6"}, //
{__NR_linux_sched_yield, "sched_yield"}, //
{__NR_linux_mremap, "mremap"}, //
@ -122,12 +145,18 @@ static const struct thatispacked SyscallName {
{__NR_linux_shmat, "shmat"}, //
{__NR_linux_shmctl, "shmctl"}, //
{__NR_linux_dup, "dup"}, //
#ifdef __NR_linux_dup2 //
{__NR_linux_dup2, "dup2"}, //
#endif //
#ifdef __NR_linux_pause //
{__NR_linux_pause, "pause"}, //
#endif //
{__NR_linux_nanosleep, "nanosleep"}, //
{__NR_linux_getitimer, "getitimer"}, //
{__NR_linux_setitimer, "setitimer"}, //
#ifdef __NR_linux_alarm //
{__NR_linux_alarm, "alarm"}, //
#endif //
{__NR_linux_getpid, "getpid"}, //
{__NR_linux_sendfile, "sendfile"}, //
{__NR_linux_socket, "socket"}, //
@ -145,8 +174,12 @@ static const struct thatispacked SyscallName {
{__NR_linux_socketpair, "socketpair"}, //
{__NR_linux_setsockopt, "setsockopt"}, //
{__NR_linux_getsockopt, "getsockopt"}, //
#ifdef __NR_linux_fork //
{__NR_linux_fork, "fork"}, //
#endif //
#ifdef __NR_linux_vfork //
{__NR_linux_vfork, "vfork"}, //
#endif //
{__NR_linux_execve, "execve"}, //
{__NR_linux_wait4, "wait4"}, //
{__NR_linux_kill, "kill"}, //
@ -173,19 +206,39 @@ static const struct thatispacked SyscallName {
{__NR_linux_getcwd, "getcwd"}, //
{__NR_linux_chdir, "chdir"}, //
{__NR_linux_fchdir, "fchdir"}, //
#ifdef __NR_linux_rename //
{__NR_linux_rename, "rename"}, //
#endif //
#ifdef __NR_linux_mkdir //
{__NR_linux_mkdir, "mkdir"}, //
#endif //
#ifdef __NR_linux_rmdir //
{__NR_linux_rmdir, "rmdir"}, //
#endif //
#ifdef __NR_linux_creat //
{__NR_linux_creat, "creat"}, //
#endif //
#ifdef __NR_linux_link //
{__NR_linux_link, "link"}, //
#endif //
{__NR_linux_unlink, "unlink"}, //
#ifdef __NR_linux_symlink //
{__NR_linux_symlink, "symlink"}, //
#endif //
#ifdef __NR_linux_readlink //
{__NR_linux_readlink, "readlink"}, //
#endif //
#ifdef __NR_linux_chmod //
{__NR_linux_chmod, "chmod"}, //
#endif //
{__NR_linux_fchmod, "fchmod"}, //
#ifdef __NR_linux_chown //
{__NR_linux_chown, "chown"}, //
#endif //
{__NR_linux_fchown, "fchown"}, //
#ifdef __NR_linux_lchown //
{__NR_linux_lchown, "lchown"}, //
#endif //
{__NR_linux_umask, "umask"}, //
{__NR_linux_gettimeofday, "gettimeofday"}, //
{__NR_linux_getrlimit, "getrlimit"}, //
@ -197,7 +250,9 @@ static const struct thatispacked SyscallName {
{__NR_linux_getuid, "getuid"}, //
{__NR_linux_getgid, "getgid"}, //
{__NR_linux_getppid, "getppid"}, //
#ifdef __NR_linux_getpgrp //
{__NR_linux_getpgrp, "getpgrp"}, //
#endif //
{__NR_linux_setsid, "setsid"}, //
{__NR_linux_getsid, "getsid"}, //
{__NR_linux_getpgid, "getpgid"}, //
@ -217,7 +272,9 @@ static const struct thatispacked SyscallName {
{__NR_linux_sigpending, "sigpending"}, //
{__NR_linux_sigsuspend, "sigsuspend"}, //
{__NR_linux_sigaltstack, "sigaltstack"}, //
#ifdef __NR_linux_mknod //
{__NR_linux_mknod, "mknod"}, //
#endif //
{__NR_linux_mknodat, "mknodat"}, //
{__NR_linux_statfs, "statfs"}, //
{__NR_linux_fstatfs, "fstatfs"}, //
@ -242,8 +299,12 @@ static const struct thatispacked SyscallName {
{__NR_linux_sigtimedwait, "sigtimedwait"}, //
{__NR_linux_sigqueueinfo, "sigqueueinfo"}, //
{__NR_linux_personality, "personality"}, //
#ifdef __NR_linux_ustat //
{__NR_linux_ustat, "ustat"}, //
#endif //
#ifdef __NR_linux_sysfs //
{__NR_linux_sysfs, "sysfs"}, //
#endif //
{__NR_linux_sched_setparam, "sched_setparam"}, //
{__NR_linux_sched_getparam, "sched_getparam"}, //
{__NR_linux_sched_setscheduler, "sched_setscheduler"}, //
@ -252,19 +313,29 @@ static const struct thatispacked SyscallName {
{__NR_linux_sched_get_priority_min, "sched_get_priority_min"}, //
{__NR_linux_sched_rr_get_interval, "sched_rr_get_interval"}, //
{__NR_linux_vhangup, "vhangup"}, //
#ifdef __NR_linux_modify_ldt //
{__NR_linux_modify_ldt, "modify_ldt"}, //
#endif //
{__NR_linux_pivot_root, "pivot_root"}, //
#ifdef __NR_linux__sysctl //
{__NR_linux__sysctl, "_sysctl"}, //
#endif //
{__NR_linux_prctl, "prctl"}, //
#ifdef __NR_linux_arch_prctl //
{__NR_linux_arch_prctl, "arch_prctl"}, //
#endif //
{__NR_linux_adjtimex, "adjtimex"}, //
{__NR_linux_umount2, "umount2"}, //
{__NR_linux_swapon, "swapon"}, //
{__NR_linux_swapoff, "swapoff"}, //
{__NR_linux_sethostname, "sethostname"}, //
{__NR_linux_setdomainname, "setdomainname"}, //
#ifdef __NR_linux_iopl //
{__NR_linux_iopl, "iopl"}, //
#endif //
#ifdef __NR_linux_ioperm //
{__NR_linux_ioperm, "ioperm"}, //
#endif //
{__NR_linux_init_module, "init_module"}, //
{__NR_linux_delete_module, "delete_module"}, //
{__NR_linux_gettid, "gettid"}, //
@ -289,11 +360,17 @@ static const struct thatispacked SyscallName {
{__NR_linux_io_submit, "io_submit"}, //
{__NR_linux_io_cancel, "io_cancel"}, //
{__NR_linux_lookup_dcookie, "lookup_dcookie"}, //
#ifdef __NR_linux_epoll_create //
{__NR_linux_epoll_create, "epoll_create"}, //
#endif //
#ifdef __NR_linux_epoll_wait //
{__NR_linux_epoll_wait, "epoll_wait"}, //
#endif //
{__NR_linux_epoll_ctl, "epoll_ctl"}, //
{__NR_linux_getdents, "getdents"}, //
#ifdef __NR_linux_oldgetdents //
{__NR_linux_oldgetdents, "oldgetdents"}, //
#endif //
{__NR_linux_set_tid_address, "set_tid_address"}, //
{__NR_linux_restart_syscall, "restart_syscall"}, //
{__NR_linux_semtimedop, "semtimedop"}, //
@ -324,15 +401,23 @@ static const struct thatispacked SyscallName {
{__NR_linux_keyctl, "keyctl"}, //
{__NR_linux_ioprio_set, "ioprio_set"}, //
{__NR_linux_ioprio_get, "ioprio_get"}, //
#ifdef __NR_linux_inotify_init //
{__NR_linux_inotify_init, "inotify_init"}, //
#endif //
#ifdef __NR_linux_inotify_add_watch //
{__NR_linux_inotify_add_watch, "inotify_add_watch"}, //
#endif //
#ifdef __NR_linux_inotify_rm_watch //
{__NR_linux_inotify_rm_watch, "inotify_rm_watch"}, //
#endif //
{__NR_linux_openat, "openat"}, //
{__NR_linux_mkdirat, "mkdirat"}, //
{__NR_linux_fchownat, "fchownat"}, //
{__NR_linux_utime, "utime"}, //
{__NR_linux_utimes, "utimes"}, //
#ifdef __NR_linux_futimesat //
{__NR_linux_futimesat, "futimesat"}, //
#endif //
{__NR_linux_fstatat, "fstatat"}, //
{__NR_linux_unlinkat, "unlinkat"}, //
{__NR_linux_renameat, "renameat"}, //
@ -360,9 +445,13 @@ static const struct thatispacked SyscallName {
{__NR_linux_perf_event_open, "perf_event_open"}, //
{__NR_linux_inotify_init1, "inotify_init1"}, //
{__NR_linux_tgsigqueueinfo, "tgsigqueueinfo"}, //
#ifdef __NR_linux_signalfd //
{__NR_linux_signalfd, "signalfd"}, //
#endif //
{__NR_linux_signalfd4, "signalfd4"}, //
#ifdef __NR_linux_eventfd //
{__NR_linux_eventfd, "eventfd"}, //
#endif //
{__NR_linux_eventfd2, "eventfd2"}, //
{__NR_linux_timerfd_create, "timerfd_create"}, //
{__NR_linux_timerfd_settime, "timerfd_settime"}, //
@ -422,14 +511,24 @@ static const struct thatispacked SyscallName {
{__NR_linux_process_madvise, "process_madvise"}, //
{__NR_linux_epoll_pwait2, "epoll_pwait2"}, //
{__NR_linux_mount_setattr, "mount_setattr"}, //
#ifdef __NR_linux_quotactl_fd //
{__NR_linux_quotactl_fd, "quotactl_fd"}, //
#endif //
{__NR_linux_landlock_create_ruleset, "landlock_create_ruleset"}, //
{__NR_linux_landlock_add_rule, "landlock_add_rule"}, //
{__NR_linux_landlock_restrict_self, "landlock_restrict_self"}, //
#ifdef __NR_linux_memfd_secret //
{__NR_linux_memfd_secret, "memfd_secret"}, //
#endif //
#ifdef __NR_linux_process_mrelease //
{__NR_linux_process_mrelease, "process_mrelease"}, //
#endif //
#ifdef __NR_linux_futex_waitv //
{__NR_linux_futex_waitv, "futex_waitv"}, //
#endif //
#ifdef __NR_linux_set_mempolicy_home_node //
{__NR_linux_set_mempolicy_home_node, "set_mempolicy_home_node"}, //
#endif //
};
static const uint16_t kPledgeDefault[] = {
@ -464,7 +563,9 @@ static const uint16_t kPledgeStdio[] = {
__NR_linux_preadv, //
__NR_linux_preadv2, //
__NR_linux_dup, //
#ifdef __NR_linux_dup2 //
__NR_linux_dup2, //
#endif //
__NR_linux_dup3, //
__NR_linux_fchdir, //
__NR_linux_fcntl | STDIO, //
@ -476,7 +577,9 @@ static const uint16_t kPledgeStdio[] = {
__NR_linux_getrandom, //
__NR_linux_getgroups, //
__NR_linux_getpgid, //
#ifdef __NR_linux_getpgrp //
__NR_linux_getpgrp, //
#endif //
__NR_linux_getpid, //
__NR_linux_gettid, //
__NR_linux_getuid, //
@ -500,7 +603,9 @@ static const uint16_t kPledgeStdio[] = {
__NR_linux_splice, //
__NR_linux_lseek, //
__NR_linux_tee, //
#ifdef __NR_linux_brk //
__NR_linux_brk, //
#endif //
__NR_linux_msync, //
__NR_linux_mmap | NOEXEC, //
__NR_linux_mremap, //
@ -509,33 +614,53 @@ static const uint16_t kPledgeStdio[] = {
__NR_linux_madvise, //
__NR_linux_fadvise, //
__NR_linux_mprotect | NOEXEC, //
#ifdef __NR_linux_arch_prctl //
__NR_linux_arch_prctl, //
#endif //
__NR_linux_migrate_pages, //
__NR_linux_sync_file_range, //
__NR_linux_set_tid_address, //
__NR_linux_membarrier, //
__NR_linux_nanosleep, //
#ifdef __NR_linux_pipe //
__NR_linux_pipe, //
#endif //
__NR_linux_pipe2, //
#ifdef __NR_linux_poll //
__NR_linux_poll, //
#endif //
__NR_linux_ppoll, //
#ifdef __NR_linux_select //
__NR_linux_select, //
#endif //
__NR_linux_pselect6, //
#ifdef __NR_linux_epoll_create //
__NR_linux_epoll_create, //
#endif //
__NR_linux_epoll_create1, //
__NR_linux_epoll_ctl, //
#ifdef __NR_linux_epoll_wait //
__NR_linux_epoll_wait, //
#endif //
__NR_linux_epoll_pwait, //
__NR_linux_epoll_pwait2, //
__NR_linux_recvfrom, //
__NR_linux_sendto | ADDRLESS, //
__NR_linux_ioctl | RESTRICT, //
#ifdef __NR_linux_alarm //
__NR_linux_alarm, //
#endif //
#ifdef __NR_linux_pause //
__NR_linux_pause, //
#endif //
__NR_linux_shutdown, //
#ifdef __NR_linux_eventfd //
__NR_linux_eventfd, //
#endif //
__NR_linux_eventfd2, //
#ifdef __NR_linux_signalfd //
__NR_linux_signalfd, //
#endif //
__NR_linux_signalfd4, //
__NR_linux_sigaction, //
__NR_linux_sigaltstack, //
@ -573,18 +698,26 @@ static const uint16_t kPledgeRpath[] = {
__NR_linux_open | READONLY, //
__NR_linux_openat | READONLY, //
__NR_linux_stat, //
#ifdef __NR_linux_lstat //
__NR_linux_lstat, //
#endif //
__NR_linux_fstat, //
__NR_linux_fstatat, //
#ifdef __NR_linux_access //
__NR_linux_access, //
#endif //
__NR_linux_faccessat, //
__NR_linux_faccessat2, //
#ifdef __NR_linux_readlink //
__NR_linux_readlink, //
#endif //
__NR_linux_readlinkat, //
__NR_linux_statfs, //
__NR_linux_fstatfs, //
__NR_linux_getdents, //
#ifdef __NR_linux_oldgetdents //
__NR_linux_oldgetdents, //
#endif //
};
static const uint16_t kPledgeWpath[] = {
@ -593,14 +726,20 @@ static const uint16_t kPledgeWpath[] = {
__NR_linux_openat | WRITEONLY, //
__NR_linux_stat, //
__NR_linux_fstat, //
#ifdef __NR_linux_lstat //
__NR_linux_lstat, //
#endif //
__NR_linux_fstatat, //
#ifdef __NR_linux_access //
__NR_linux_access, //
#endif //
__NR_linux_truncate, //
__NR_linux_faccessat, //
__NR_linux_faccessat2, //
__NR_linux_readlinkat, //
#ifdef __NR_linux_chmod //
__NR_linux_chmod | NOBITS, //
#endif //
__NR_linux_fchmod | NOBITS, //
__NR_linux_fchmodat | NOBITS, //
};
@ -608,33 +747,51 @@ static const uint16_t kPledgeWpath[] = {
static const uint16_t kPledgeCpath[] = {
__NR_linux_open | CREATONLY, //
__NR_linux_openat | CREATONLY, //
#ifdef __NR_linux_creat //
__NR_linux_creat | RESTRICT, //
#endif //
#ifdef __NR_linux_rename //
__NR_linux_rename, //
#endif //
__NR_linux_renameat, //
__NR_linux_renameat2, //
#ifdef __NR_linux_link //
__NR_linux_link, //
#endif //
__NR_linux_linkat, //
#ifdef __NR_linux_symlink //
__NR_linux_symlink, //
#endif //
__NR_linux_symlinkat, //
#ifdef __NR_linux_rmdir //
__NR_linux_rmdir, //
#endif //
__NR_linux_unlink, //
__NR_linux_unlinkat, //
#ifdef __NR_linux_mkdir //
__NR_linux_mkdir, //
#endif //
__NR_linux_mkdirat, //
};
static const uint16_t kPledgeDpath[] = {
#ifdef __NR_linux_mknod //
__NR_linux_mknod, //
#endif //
__NR_linux_mknodat, //
};
static const uint16_t kPledgeFattr[] = {
#ifdef __NR_linux_chmod //
__NR_linux_chmod | NOBITS, //
#endif //
__NR_linux_fchmod | NOBITS, //
__NR_linux_fchmodat | NOBITS, //
__NR_linux_utime, //
__NR_linux_utimes, //
#ifdef __NR_linux_futimesat //
__NR_linux_futimesat, //
#endif //
__NR_linux_utimensat, //
};
@ -695,8 +852,12 @@ static const uint16_t kPledgeSendfd[] = {
};
static const uint16_t kPledgeProc[] = {
#ifdef __NR_linux_fork //
__NR_linux_fork, //
#endif //
#ifdef __NR_linux_vfork //
__NR_linux_vfork, //
#endif //
__NR_linux_clone | RESTRICT, //
__NR_linux_kill, //
__NR_linux_tgkill, //
@ -733,9 +894,13 @@ static const uint16_t kPledgeId[] = {
};
static const uint16_t kPledgeChown[] = {
#ifdef __NR_linux_chown //
__NR_linux_chown, //
#endif //
__NR_linux_fchown, //
#ifdef __NR_linux_lchown //
__NR_linux_lchown, //
#endif //
__NR_linux_fchownat, //
};
@ -773,7 +938,9 @@ static const uint16_t kPledgeVminfo[] = {
// permissions. pledge() alone (without unveil() too) offers very
// little security here. consider using them together.
static const uint16_t kPledgeTmppath[] = {
#ifdef __NR_linux_lstat //
__NR_linux_lstat, //
#endif //
__NR_linux_unlink, //
__NR_linux_unlinkat, //
};
@ -806,12 +973,17 @@ const struct Pledges kPledge[PROMISE_LEN_] = {
static const struct sock_filter kPledgeStart[] = {
// make sure this isn't an i386 binary or something
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(arch)),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, AUDIT_ARCH_X86_64, 1, 0),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, ARCHITECTURE, 1, 0),
BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL_PROCESS),
// each filter assumes ordinal is already loaded into accumulator
BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)),
#ifdef __NR_linux_memfd_secret
// forbid some system calls with ENOSYS (rather than EPERM)
BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, __NR_linux_memfd_secret, 5, 0),
#else
BPF_JUMP(BPF_JMP | BPF_JGE | BPF_K, __NR_linux_landlock_restrict_self + 1,
5, 0),
#endif
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_rseq, 4, 0),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_memfd_create, 3, 0),
BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_linux_openat2, 2, 0),
@ -848,99 +1020,213 @@ static privileged char *HexCpy(char p[17], uint64_t x) {
}
static privileged int GetPid(void) {
int ax;
int res;
#ifdef __x86_64__
asm volatile("syscall"
: "=a"(ax)
: "=a"(res)
: "0"(__NR_linux_getpid)
: "rcx", "r11", "memory");
return ax;
#elif defined(__aarch64__)
register long res_x0 asm("x0");
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(__NR_linux_getpid)
: "x8", "memory");
res = res_x0;
#endif
return res;
}
static privileged int GetTid(void) {
int ax;
int res;
#ifdef __x86_64__
asm volatile("syscall"
: "=a"(ax)
: "=a"(res)
: "0"(__NR_linux_gettid)
: "rcx", "r11", "memory");
return ax;
#elif defined(__aarch64__)
register long res_x0 asm("x0");
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(__NR_linux_gettid)
: "x8", "memory");
res = res_x0;
#endif
return res;
}
static privileged void Log(const char *s, ...) {
int ax;
int res;
va_list va;
va_start(va, s);
do {
#ifdef __x86_64__
asm volatile("syscall"
: "=a"(ax)
: "=a"(res)
: "0"(__NR_linux_write), "D"(2), "S"(s), "d"(StrLen(s))
: "rcx", "r11", "memory");
#elif defined(__aarch64__)
register long r0 asm("x0") = 2;
register long r1 asm("x1") = (long)s;
register long r2 asm("x2") = StrLen(s);
register long res_x0 asm("x0");
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(__NR_linux_write), "r"(r0), "r"(r1), "r"(r2)
: "x8", "memory");
#endif
} while ((s = va_arg(va, const char *)));
va_end(va);
}
static privileged int Prctl(int op, long a, void *b, long c, long d) {
int rc;
#ifdef __x86_64__
asm volatile("mov\t%5,%%r10\n\t"
"mov\t%6,%%r8\n\t"
"syscall"
: "=a"(rc)
: "0"(__NR_linux_prctl), "D"(op), "S"(a), "d"(b), "g"(c), "g"(d)
: "rcx", "r8", "r10", "r11", "memory");
#elif defined(__aarch64__)
register long r0 asm("x0") = (long)op;
register long r1 asm("x1") = (long)a;
register long r2 asm("x2") = (long)b;
register long r3 asm("x3") = (long)c;
register long r4 asm("x4") = (long)d;
register long res_x0 asm("x0");
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(__NR_linux_prctl), "r"(r0), "r"(r1), "r"(r2), "r"(r3),
"r"(r4)
: "x8", "memory");
rc = res_x0;
#endif
return rc;
}
static privileged int SigAction(int sig, struct sigaction *act,
struct sigaction *old) {
int ax;
int res;
act->sa_flags |= Sa_Restorer;
act->sa_restorer = &__restore_rt;
#ifdef __x86_64__
asm volatile("mov\t%5,%%r10\n\t"
"syscall"
: "=a"(ax)
: "=a"(res)
: "0"(__NR_linux_sigaction), "D"(sig), "S"(act), "d"(old), "g"(8)
: "rcx", "r10", "r11", "memory");
return ax;
#elif defined(__aarch64__)
register long r0 asm("x0") = (long)sig;
register long r1 asm("x1") = (long)act;
register long r2 asm("x2") = (long)old;
register long r3 asm("x3") = (long)8;
register long res_x0 asm("x0");
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(__NR_linux_sigaction), "r"(r0), "r"(r1), "r"(r2), "r"(r3)
: "x8", "memory");
res = res_x0;
#endif
return res;
}
static privileged int SigProcMask(int how, int64_t set, int64_t *old) {
int ax;
int res;
#ifdef __x86_64__
asm volatile("mov\t%5,%%r10\n\t"
"syscall"
: "=a"(ax)
: "=a"(res)
: "0"(__NR_linux_sigprocmask), "D"(how), "S"(&set), "d"(old),
"g"(8)
: "rcx", "r10", "r11", "memory");
return ax;
#elif defined(__aarch64__)
register long r0 asm("x0") = (long)how;
register long r1 asm("x1") = (long)set;
register long r2 asm("x2") = (long)old;
register long r3 asm("x3") = (long)8;
register long res_x0 asm("x0");
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(__NR_linux_sigprocmask), "r"(r0), "r"(r1), "r"(r2), "r"(r3)
: "x8", "memory");
res = res_x0;
#endif
return res;
}
static privileged void KillThisProcess(void) {
int ax;
int res;
SigAction(Sigabrt, &(struct sigaction){0}, 0);
SigProcMask(Sig_Setmask, -1, 0);
#ifdef __x86_64__
asm volatile("syscall"
: "=a"(ax)
: "=a"(res)
: "0"(__NR_linux_kill), "D"(GetPid()), "S"(Sigabrt)
: "rcx", "r11", "memory");
#elif defined(__aarch64__)
{
register long r0 asm("x0") = (long)GetPid();
register long r1 asm("x1") = (long)Sigabrt;
register long res_x0 asm("x0");
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(__NR_linux_kill), "r"(r0), "r"(r1)
: "x8", "memory");
}
#endif
SigProcMask(Sig_Setmask, 0, 0);
#ifdef __x86_64__
asm volatile("syscall"
: "=a"(ax)
: "=a"(res)
: "0"(__NR_linux_exit_group), "D"(128 + Sigabrt)
: "rcx", "r11", "memory");
#elif defined(__aarch64__)
{
register long r0 asm("x0") = (long)(128 + Sigabrt);
register long res_x0 asm("x0");
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(__NR_linux_exit_group), "r"(r0)
: "x8", "memory");
}
#endif
}
static privileged void KillThisThread(void) {
int ax;
int res;
SigAction(Sigabrt, &(struct sigaction){0}, 0);
SigProcMask(Sig_Setmask, -1, 0);
#ifdef __x86_64__
asm volatile("syscall"
: "=a"(ax)
: "=a"(res)
: "0"(__NR_linux_tkill), "D"(GetTid()), "S"(Sigabrt)
: "rcx", "r11", "memory");
#elif defined(__aarch64__)
#endif
SigProcMask(Sig_Setmask, 0, 0);
#ifdef __x86_64__
asm volatile("syscall"
: /* no outputs */
: "a"(__NR_linux_exit), "D"(128 + Sigabrt)
: "rcx", "r11", "memory");
#elif defined(__aarch64__)
register long r0 asm("x0") = (long)(128 + Sigabrt);
register long res_x0 asm("x0");
asm volatile("mov\tx8,%1\n\t"
"svc\t0"
: "=r"(res_x0)
: "i"(__NR_linux_exit), "r"(r0)
: "x8", "memory");
#endif
}
static privileged const char *GetSyscallName(uint16_t n) {
@ -971,9 +1257,9 @@ static privileged void OnSigSys(int sig, siginfo_t *si, void *vctx) {
char ord[17], rip[17];
int i, ok, mode = si->si_errno;
ucontext_t *ctx = vctx;
ctx->uc_mcontext.rax = -Eperm;
ctx->uc_mcontext.MCONTEXT_SYSCALL_RESULT_REGISTER = -Eperm;
FixCpy(ord, si->si_syscall, 12);
HexCpy(rip, ctx->uc_mcontext.rip);
HexCpy(rip, ctx->uc_mcontext.MCONTEXT_INSTRUCTION_POINTER);
for (found = i = 0; i < ARRAYLEN(kPledge); ++i) {
if (HasSyscall(kPledge + i, si->si_syscall)) {
Log("error: pledge ", kPledge[i].name, " for ",
@ -999,7 +1285,6 @@ static privileged void OnSigSys(int sig, siginfo_t *si, void *vctx) {
}
static privileged void MonitorSigSys(void) {
int ax;
struct sigaction sa = {
.sa_sigaction = OnSigSys,
.sa_flags = Sa_Siginfo | Sa_Restart,
@ -1565,6 +1850,7 @@ static privileged void AllowOpenatCreatonly(struct Filter *f) {
AppendFilter(f, PLEDGE(fragment));
}
#ifdef __NR_linux_creat
// Then the mode parameter must not have:
//
// - S_ISVTX (01000 sticky)
@ -1583,6 +1869,7 @@ static privileged void AllowCreatRestrict(struct Filter *f) {
};
AppendFilter(f, PLEDGE(fragment));
}
#endif
// The second argument of fcntl() must be one of:
//
@ -1759,6 +2046,7 @@ static privileged void AllowPrctlStdio(struct Filter *f) {
AppendFilter(f, PLEDGE(fragment));
}
#ifdef __NR_linux_chmod
// The mode parameter of chmod() can't have the following:
//
// - S_ISVTX (01000 sticky)
@ -1777,6 +2065,7 @@ static privileged void AllowChmodNobits(struct Filter *f) {
};
AppendFilter(f, PLEDGE(fragment));
}
#endif
// The mode parameter of fchmod() can't have the following:
//
@ -1887,9 +2176,11 @@ static privileged void AppendPledge(struct Filter *f, //
case __NR_linux_mprotect | NOEXEC:
AllowMprotectNoexec(f);
break;
#ifdef __NR_linux_chmod
case __NR_linux_chmod | NOBITS:
AllowChmodNobits(f);
break;
#endif
case __NR_linux_fchmod | NOBITS:
AllowFchmodNobits(f);
break;
@ -1923,9 +2214,11 @@ static privileged void AppendPledge(struct Filter *f, //
case __NR_linux_getsockopt | RESTRICT:
AllowGetsockoptRestrict(f);
break;
#ifdef __NR_linux_creat
case __NR_linux_creat | RESTRICT:
AllowCreatRestrict(f);
break;
#endif
case __NR_linux_fcntl | STDIO:
AllowFcntlStdio(f);
break;
@ -2060,5 +2353,3 @@ privileged int sys_pledge_linux(unsigned long ipromises, int mode) {
return rc;
}
#endif

View file

@ -28,8 +28,6 @@
#include "libc/runtime/runtime.h"
#include "libc/sysv/errfuns.h"
#ifdef __x86_64__
/**
* Permits system operations, e.g.
*
@ -278,5 +276,3 @@ int pledge(const char *promises, const char *execpromises) {
STRACE("pledge(%#s, %#s) → %d% m", promises, execpromises, rc);
return rc;
}
#endif /* __x86_64__ */

View file

@ -1027,10 +1027,12 @@ static void __asan_trace(struct AsanTrace *bt, const struct StackFrame *bp) {
}
if (!__asan_checka(SHADOW(bp), sizeof(*bp) >> 3).kind) {
addr = bp->addr;
#ifdef __x86_64__
if (addr == (uintptr_t)_weaken(__gc) && (uintptr_t)_weaken(__gc)) {
do --gi;
while ((addr = garbage->p[gi].ret) == (uintptr_t)_weaken(__gc));
}
#endif
bt->p[i] = addr;
} else {
break;

View file

@ -3,7 +3,7 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
uint64_t _tpenc(int32_t) pureconst;
uint64_t _tpenc(uint32_t) pureconst;
#if defined(__x86_64__) && defined(__MNO_RED_ZONE__) && defined(__GNUC__) && \
!defined(__STRICT_ANSI__)

View file

@ -28,7 +28,7 @@ static const uint16_t kTpEnc[32 - 7] = {
5 | 0374 << 8, 5 | 0374 << 8, 5 | 0374 << 8, 5 | 0374 << 8, 5 | 0374 << 8,
};
uint64_t _tpenc(int32_t c) {
uint64_t _tpenc(uint32_t c) {
int e, n;
uint64_t w;
if (0 <= c && c <= 127) return c;

View file

@ -103,11 +103,13 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) {
return -1;
}
addr = frame->addr;
#ifdef __x86_64__
if (addr == (uintptr_t)_weaken(__gc)) {
do {
--gi;
} while ((addr = garbage->p[gi].ret) == (uintptr_t)_weaken(__gc));
}
#endif
argv[i++] = buf + j;
buf[j++] = '0';
buf[j++] = 'x';

View file

@ -67,11 +67,13 @@ noinstrument noasan int PrintBacktraceUsingSymbols(int fd,
break;
}
addr = frame->addr;
#ifdef __x86_64__
if (addr == (intptr_t)_weaken(__gc)) {
do {
--gi;
} while ((addr = garbage->p[gi].ret) == (intptr_t)_weaken(__gc));
}
#endif
if (addr) {
if (
#ifdef __x86_64__

View file

@ -184,7 +184,7 @@ relegated void __oncrash_arm64(int sig, struct siginfo *si, void *arg) {
" %s %s %s %s\n",
strong, reset, sig, kind, host, getpid(), gettid(),
program_invocation_name, names.sysname, names.version,
names.nodename, names.release, "yo");
names.nodename, names.release);
if (ctx) {
long pc;
char line[256];

View file

@ -25,8 +25,6 @@
#include "libc/str/str.h"
#include "libc/thread/tls.h"
#ifdef __x86_64__
forceinline bool PointerNotOwnedByParentStackFrame(struct StackFrame *frame,
struct StackFrame *parent,
void *ptr) {
@ -88,7 +86,9 @@ static void DeferFunction(struct StackFrame *frame, void *fn, void *arg) {
g->p[g->i].arg = (intptr_t)arg;
g->p[g->i].ret = frame->addr;
g->i++;
#ifdef __x86_64__
frame->addr = (intptr_t)__gc;
#endif
}
// the gnu extension macros for _gc / _defer point here
@ -146,5 +146,3 @@ void *(_defer)(void *fn, void *arg) {
DeferFunction(frame->next, fn, arg);
return arg;
}
#endif /* __x86_64__ */

View file

@ -33,11 +33,11 @@
// @param rax,rdx,xmm0,xmm1,st0,st1 is return value
// @see test/libc/runtime/gc_test.c
// @threadsafe
__gc: mov %fs:0,%rcx # __get_tls()
mov 0x18(%rcx),%rcx # tls::garbages
decl (%rcx) # ++g->i
mov (%rcx),%r8d # r8 = g->i
mov 8(%rcx),%r9 # r9 = g->p
__gc: mov %fs:0,%rcx // __get_tls()
mov 0x18(%rcx),%rcx // tls::garbages
decl (%rcx) // ++g->i
mov (%rcx),%r8d // r8 = g->i
mov 8(%rcx),%r9 // r9 = g->p
js 9f
shl $5,%r8
lea (%r9,%r8),%r8

View file

@ -18,6 +18,8 @@
*/
#include "libc/macros.internal.h"
#ifdef __x86_64__
.initbss 202,_init_kHalfCache3
// Half size of level 3 cache in bytes.
kHalfCache3:
@ -60,3 +62,14 @@ kHalfCache3:
4: shr %eax
stosq
.init.end 202,_init_kHalfCache3
#else
.rodata
.align 8
kHalfCache3:
.quad 4 * 1024 * 1024
.endobj kHalfCache3,globl
.previous
#endif /* __x86_64__ */

View file

@ -68,6 +68,8 @@ o/$(MODE)/libc/nexgen32e/setjmp.o: libc/nexgen32e/setjmp.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/nexgen32e/missingno.o: libc/nexgen32e/missingno.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
o/$(MODE)/libc/nexgen32e/khalfcache3.o: libc/nexgen32e/khalfcache3.S
@$(COMPILE) -AOBJECTIFY.S $(OBJECTIFY.S) $(OUTPUT_OPTION) -c $<
LIBC_NEXGEN32E_LIBS = $(foreach x,$(LIBC_NEXGEN32E_ARTIFACTS),$($(x)))
LIBC_NEXGEN32E_SRCS = $(foreach x,$(LIBC_NEXGEN32E_ARTIFACTS),$($(x)_SRCS))

View file

@ -30,5 +30,5 @@ int wcscmp(const wchar_t *a, const wchar_t *b) {
size_t i = 0;
if (a == b) return 0;
while (a[i] == b[i] && b[i]) ++i;
return (a[i] > b[i]) - (a[i] < b[i]);
return (int)a[i] < (int)b[i] ? -1 : (int)a[i] > (int)b[i];
}

View file

@ -30,5 +30,5 @@ int wcsncmp(const wchar_t *a, const wchar_t *b, size_t n) {
size_t i = 0;
if (!n-- || a == b) return 0;
while (i < n && a[i] == b[i] && b[i]) ++i;
return (a[i] > b[i]) - (a[i] < b[i]);
return (int)a[i] < (int)b[i] ? -1 : (int)a[i] > (int)b[i];
}

View file

@ -19,6 +19,7 @@
#include "libc/intrin/likely.h"
#include "libc/str/str.h"
#include "libc/str/unicode.h"
#include "libc/str/wcwidth_osx.internal.h"
extern const uint8_t kEastAsianWidth[];
extern const uint32_t kEastAsianWidthBits;
@ -34,7 +35,9 @@ int wcwidth(wchar_t c) {
return 1;
} else if (!c) {
return 0;
} else if ((0 < c && c < 32) || (0x7f <= c && c < 0xA0)) {
} else if ((uint32_t)c > 0x10FFFD || //
(0 < c && c < 32) || //
(0x7f <= c && c < 0xA0)) {
return -1;
} else if ((0 <= c && c < kCombiningCharsBits) &&
!!(kCombiningChars[c >> 3] & (1 << (c & 7)))) {
@ -45,15 +48,17 @@ int wcwidth(wchar_t c) {
return 1;
}
#else
if (!c) return 0;
if (c < 0 || iswcntrl(c)) return -1;
return 1 +
(c >= 0x1100 &&
(c <= 0x115f || c == 0x2329 || c == 0x232a ||
(c >= 0x2e80 && c <= 0xa4cf && c != 0x303f) ||
(c >= 0xac00 && c <= 0xd7a3) || (c >= 0xf900 && c <= 0xfaff) ||
(c >= 0xfe10 && c <= 0xfe19) || (c >= 0xfe30 && c <= 0xfe6f) ||
(c >= 0xff00 && c <= 0xff60) || (c >= 0xffe0 && c <= 0xffe6) ||
(c >= 0x20000 && c <= 0x2fffd) || (c >= 0x30000 && c <= 0x3fffd)));
int res;
if (LIKELY(32 <= c && c < 127)) return 1;
if (VERY_UNLIKELY((uint32_t)c >= 0x100000)) {
if ((uint32_t)c <= 0x10FFFD) return 1;
return -1;
}
res = _wcwidth_osx(c);
if (VERY_UNLIKELY(!res)) {
if (!c) return 0;
if (iswcntrl(c)) return -1;
}
return res;
#endif
}

238
libc/str/wcwidth_osx.c Normal file
View file

@ -0,0 +1,238 @@
// Copyright (c) 2012 Byron Lai
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#include "libc/macros.internal.h"
#include "libc/str/wcwidth_osx.internal.h"
const uint8_t kWcwidthOsxIndex1[] = {
0, 16, 26, 33, 34, 50, 56, 72, 88, 104, 107, 107, 107, 107,
115, 127, 143, 143, 143, 143, 143, 156, 160, 164, 178, 178, 178, 178,
178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178,
178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178,
178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178,
178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178,
178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178,
178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178,
178, 178, 178, 178, 178, 178, 178, 178, 194, 194, 194, 194, 194, 194,
194, 195, 211, 211, 211, 211, 211, 211, 211, 212,
};
const uint16_t kWcwidthOsxIndex2[] = {
0, 8, 22, 38, 54, 70, 86, 102, 118, 134, 150, 163, 179, 195, 211,
227, 243, 256, 272, 284, 299, 305, 321, 336, 352, 368, 376, 376, 376, 376,
376, 376, 379, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393, 393,
393, 393, 393, 393, 396, 412, 412, 424, 439, 455, 471, 487, 487, 487, 487,
487, 487, 487, 487, 487, 487, 487, 490, 504, 504, 504, 504, 520, 520, 520,
520, 520, 520, 520, 520, 520, 520, 520, 520, 529, 544, 559, 575, 591, 607,
623, 629, 645, 661, 664, 664, 664, 664, 664, 664, 664, 664, 664, 664, 680,
685, 701, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705, 705,
705, 705, 705, 721, 737, 753, 764, 780, 780, 780, 780, 780, 780, 780, 780,
796, 801, 801, 801, 801, 801, 801, 801, 817, 817, 817, 817, 817, 817, 817,
817, 817, 817, 817, 817, 817, 817, 817, 817, 827, 834, 834, 834, 834, 834,
834, 834, 834, 834, 834, 834, 834, 834, 834, 834, 834, 850, 866, 867, 867,
867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 867, 883,
883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883, 883,
884, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900, 900,
900, 900, 901,
};
const uint32_t kWcwidthOsxIndex3[] = {
0, 32, 32, 33, 64, 96, 96, 96, 96, 96, 96, 96,
96, 96, 96, 96, 128, 128, 128, 144, 175, 205, 208, 208,
208, 208, 237, 247, 247, 247, 247, 275, 292, 316, 340, 351,
381, 402, 428, 457, 478, 510, 527, 527, 537, 564, 582, 600,
619, 632, 632, 658, 690, 711, 738, 738, 738, 738, 738, 738,
738, 738, 767, 773, 804, 834, 866, 889, 920, 951, 980, 1003,
1034, 1065, 1094, 1117, 1148, 1180, 1210, 1233, 1263, 1294, 1323, 1355,
1384, 1410, 1441, 1464, 1495, 1527, 1559, 1582, 1611, 1643, 1673, 1696,
1727, 1759, 1791, 1817, 1849, 1881, 1912, 1927, 1958, 1986, 2017, 2049,
2081, 2111, 2143, 2169, 2195, 2214, 2240, 2252, 2282, 2303, 2335, 2354,
2380, 2406, 2412, 2442, 2468, 2484, 2516, 2516, 2522, 2554, 2554, 2554,
2554, 2554, 2586, 2586, 2609, 2641, 2664, 2680, 2710, 2734, 2749, 2773,
2778, 2810, 2813, 2845, 2845, 2856, 2887, 2888, 2888, 2888, 2888, 2888,
2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2888, 2897, 2929,
2961, 2961, 2976, 3008, 3040, 3072, 3104, 3136, 3148, 3178, 3210, 3242,
3274, 3274, 3282, 3314, 3337, 3348, 3348, 3380, 3409, 3441, 3459, 3491,
3513, 3535, 3565, 3574, 3606, 3606, 3606, 3606, 3606, 3606, 3606, 3634,
3646, 3676, 3697, 3729, 3750, 3776, 3776, 3808, 3816, 3830, 3843, 3875,
3875, 3875, 3875, 3907, 3907, 3907, 3907, 3907, 3907, 3939, 3964, 3996,
3996, 3996, 3996, 3996, 3996, 3996, 3996, 4006, 4038, 4064, 4095, 4127,
4138, 4154, 4183, 4215, 4239, 4254, 4286, 4306, 4338, 4360, 4376, 4408,
4408, 4424, 4443, 4466, 4482, 4482, 4482, 4482, 4482, 4482, 4482, 4482,
4482, 4505, 4516, 4516, 4516, 4516, 4516, 4540, 4572, 4597, 4629, 4661,
4661, 4661, 4661, 4661, 4661, 4661, 4661, 4661, 4661, 4661, 4661, 4661,
4663, 4695, 4723, 4727, 4758, 4782, 4802, 4833, 4844, 4868, 4888, 4904,
4904, 4904, 4904, 4904, 4904, 4904, 4904, 4904, 4904, 4904, 4904, 4904,
4904, 4904, 4904, 4923, 4944, 4944, 4944, 4944, 4944, 4976, 4993, 5009,
5024, 5056, 5056, 5056, 5077, 5102, 5128, 5144, 5170, 5202, 5234, 5234,
5266, 5281, 5298, 5298, 5330, 5357, 5357, 5369, 5401, 5401, 5401, 5401,
5401, 5401, 5411, 5433, 5465, 5487, 5519, 5520, 5529, 5556, 5556, 5556,
5588, 5606, 5623, 5623, 5640, 5656, 5664, 5680, 5696, 5728, 5756, 5772,
5772, 5772, 5772, 5773, 5805, 5805, 5805, 5805, 5805, 5805, 5805, 5805,
5805, 5805, 5805, 5805, 5805, 5805, 5805, 5805, 5815, 5847, 5847, 5847,
5847, 5847, 5847, 5847, 5847, 5847, 5847, 5847, 5847, 5847, 5847, 5847,
5847, 5851, 5879, 5879, 5911, 5911, 5911, 5911, 5911, 5911, 5911, 5911,
5911, 5911, 5911, 5911, 5911, 5911, 5911, 5911, 5930, 5946, 5971, 5978,
6010, 6010, 6010, 6010, 6010, 6010, 6010, 6010, 6030, 6062, 6094, 6122,
6146, 6146, 6146, 6178, 6178, 6178, 6178, 6197, 6210, 6210, 6215, 6245,
6272, 6304, 6312, 6344, 6344, 6371, 6397, 6429, 6429, 6441, 6473, 6473,
6473, 6473, 6473, 6505, 6514, 6546, 6578, 6578, 6578, 6578, 6578, 6578,
6578, 6578, 6578, 6578, 6578, 6578, 6578, 6610, 6610, 6610, 6610, 6610,
6610, 6610, 6610, 6610, 6610, 6610, 6610, 6610, 6610, 6610, 6610, 6638,
6642, 6642, 6642, 6642, 6642, 6642, 6642, 6642, 6642, 6642, 6642, 6642,
6642, 6642, 6642, 6642, 6674, 6674, 6674, 6674, 6674, 6674, 6674, 6674,
6674, 6674, 6674, 6674, 6674, 6674, 6674, 6674, 6690, 6722, 6722, 6722,
6722, 6722, 6722, 6722, 6722, 6740, 6756, 6777, 6793, 6793, 6799, 6825,
6857, 6888, 6920, 6926, 6926, 6940, 6958, 6977, 6977, 6977, 6977, 6977,
6977, 6977, 6977, 6977, 6977, 7009, 7025, 7041, 7059, 7083, 7099, 7129,
7157, 7173, 7198, 7220, 7220, 7220, 7223, 7254, 7255, 7255, 7286, 7287,
7288, 7319, 7351, 7383, 7388, 7419, 7449, 7481, 7481, 7481, 7486, 7518,
7530, 7553, 7553, 7574, 7602, 7618, 7634, 7664, 7664, 7664, 7664, 7696,
7728, 7743, 7760, 7792, 7819, 7840, 7851, 7883, 7914, 7942, 7964, 7996,
7996, 7996, 7996, 7998, 8018, 8028, 8028, 8028, 8028, 8028, 8028, 8028,
8028, 8028, 8028, 8028, 8028, 8028, 8028, 8028, 8028, 8060, 8070, 8102,
8102, 8102, 8102, 8102, 8102, 8134, 8166, 8166, 8166, 8166, 8166, 8166,
8166, 8198, 8223, 8255, 8280, 8280, 8280, 8280, 8280, 8280, 8280, 8280,
8280, 8280, 8280, 8280, 8280, 8280, 8280, 8280, 8312, 8312, 8312, 8312,
8312, 8312, 8312, 8312, 8312, 8312, 8312, 8312, 8312, 8312, 8312, 8312,
8329, 8344, 8344, 8344, 8344, 8376, 8376, 8376, 8405, 8425, 8425, 8425,
8425, 8425, 8425, 8425, 8425, 8425, 8425, 8425, 8425, 8425, 8425, 8425,
8425, 8457, 8457, 8457, 8457, 8457, 8457, 8457, 8467, 8499, 8524, 8533,
8558, 8587, 8609, 8623, 8653, 8685, 8685, 8715, 8721, 8721, 8721, 8721,
8721, 8753, 8753, 8762, 8767, 8785, 8785, 8785, 8785, 8817, 8817, 8828,
8850, 8853, 8885, 8914, 8919, 8945, 8975, 9007, 9025, 9025, 9025, 9025,
9025, 9051, 9059, 9059, 9059, 9059, 9059, 9059, 9059, 9059, 9079, 9093,
9125, 9125, 9125, 9125, 9125, 9125, 9125, 9125, 9125, 9125, 9125, 9125,
9125, 9125, 9125, 9125, 9157, 9177, 9193, 9193, 9205, 9225, 9225, 9225,
9225, 9225, 9225, 9225, 9225, 9225, 9225, 9225, 9225, 9225, 9225, 9225,
9225, 9257, 9257, 9257, 9257, 9257, 9257, 9257, 9257, 9257, 9257, 9257,
9257, 9257, 9257, 9257, 9257, 9266, 9289, 9289, 9289, 9289, 9289, 9289,
9289, 9289, 9289, 9289, 9289, 9289, 9289, 9289, 9289, 9289, 9321, 9321,
9321, 9321, 9321, 9321, 9321, 9321, 9321, 9321, 9321, 9321, 9321, 9321,
9321, 9321, 9323, 9353, 9353, 9353, 9353, 9353, 9353, 9353, 9353, 9353,
9353, 9353, 9353, 9353, 9353, 9353, 9353, 9385, 9385, 9385, 9385, 9385,
9385, 9385, 9385, 9385, 9385, 9385, 9385, 9385, 9385, 9385, 9385, 9387,
9419, 9419, 9419, 9419, 9419, 9419, 9419, 9419, 9419, 9419, 9419, 9419,
9419, 9419, 9419, 9419, 9421,
};
const uint32_t kWcwidthOsx[] = {
0x00000000, 0x00000000, 0x55555555, 0x55555555, 0x00000000, 0x00000000,
0x55555555, 0x55555555, 0x00000000, 0x00000000, 0x15505555, 0x54455540,
0x15555555, 0x55555555, 0x55555555, 0x55554000, 0x55555555, 0x00001555,
0x55555500, 0x54155555, 0x55555555, 0x14555555, 0x00000000, 0x04000000,
0x54000041, 0x01555555, 0x00001550, 0x00555550, 0x55505550, 0x55555555,
0x00015555, 0x50000000, 0x45555555, 0x55555555, 0x15555555, 0x04140000,
0x55555550, 0x55551055, 0x00005555, 0x55550000, 0x55555555, 0x00005555,
0x00000040, 0x55555550, 0x55555555, 0x55400005, 0x00000005, 0x00000000,
0x55555550, 0x15555555, 0x54000150, 0x55000101, 0x55555055, 0x54000155,
0x15554505, 0x55555414, 0x40455545, 0x40015015, 0x40001141, 0x54014500,
0x55555555, 0x15544005, 0x55554140, 0x14555455, 0x00140145, 0x00400000,
0x40011540, 0x15415555, 0x55440000, 0x55545455, 0x45554555, 0x01501551,
0x01014400, 0x05000000, 0x04555550, 0x45000000, 0x54141555, 0x55455555,
0x50155145, 0x00505040, 0x51401000, 0x55555505, 0x10000000, 0x54540555,
0x50144501, 0x55540540, 0x50140155, 0x40010151, 0x55550000, 0x01555555,
0x45555150, 0x55555545, 0x54555551, 0x00550405, 0x40000000, 0x54154001,
0x40001555, 0x55141555, 0x55545455, 0x55551555, 0x55405545, 0x00001454,
0x01440005, 0x05155554, 0x51400000, 0x55454555, 0x55515555, 0x54055555,
0x00545440, 0x40001000, 0x55555415, 0x15550155, 0x55555514, 0x55540555,
0x55155555, 0x55541155, 0x00150000, 0x00015554, 0x05400000, 0x55540000,
0x55555555, 0x00145555, 0x01555000, 0x55555400, 0x00000005, 0x00000000,
0x10450450, 0x55515400, 0x51411151, 0x10000145, 0x00004554, 0x14155554,
0x00000000, 0x40000000, 0x55555555, 0x55541555, 0x45555555, 0x55155544,
0x55555555, 0x00000015, 0x00550400, 0x00000000, 0x55500000, 0x15551554,
0x00000000, 0x40000000, 0x55555555, 0x15555555, 0x55105440, 0x55555555,
0x55555055, 0x55555555, 0x55500555, 0x55555555, 0x00055555, 0x55555500,
0x55555555, 0xaaaaaa01, 0xaaaaaaaa, 0x000800aa, 0x00000000, 0x55500000,
0x55555555, 0x15455555, 0x15445554, 0x55555554, 0x55555555, 0x55550551,
0x05515555, 0x50551555, 0x51555555, 0x55555555, 0x45555555, 0x55555415,
0x55555555, 0x55500155, 0x55555555, 0x54001555, 0x55555555, 0x01555555,
0x55550000, 0x55555555, 0x00005555, 0x55555554, 0x05555555, 0x55555554,
0x55555555, 0x00000001, 0x51555555, 0x00000005, 0x55555555, 0x00001405,
0x55555555, 0x00000005, 0x51555555, 0x00000001, 0x55555555, 0x55555555,
0x55500010, 0x50000014, 0x55501555, 0x55500055, 0x55500055, 0x55510155,
0x55500055, 0x55555555, 0x00055555, 0x55555550, 0x55555555, 0x00000045,
0x00000000, 0x55555500, 0x55555555, 0x00005501, 0x00055514, 0x55555404,
0x55555555, 0x00005541, 0x55555540, 0x55555555, 0x55540015, 0x40015555,
0x54015555, 0x55555555, 0x41555555, 0x00000505, 0x00000000, 0x55555000,
0x55555555, 0x45440045, 0x55005555, 0x00555555, 0x05555400, 0x55555554,
0x55555555, 0x55555501, 0x00000000, 0x00000000, 0x55555555, 0x55555555,
0x55555540, 0x55555555, 0x00000015, 0x00000000, 0x55555540, 0x55555555,
0x50000015, 0x55555555, 0x00000015, 0x55000000, 0x55555555, 0x50555555,
0x55555055, 0x55555555, 0x05550555, 0x44445555, 0x55555555, 0x41555555,
0x55555555, 0x15555555, 0x05555555, 0x55554555, 0x54541555, 0x55554555,
0x55554005, 0x50001555, 0x55555555, 0x05555555, 0x50000010, 0x55555550,
0x00001551, 0x55555550, 0x00005555, 0x00000000, 0x00010000, 0x55550000,
0x55555555, 0x55405555, 0x55555555, 0x00155555, 0x55555550, 0x55555555,
0x555555a5, 0x55555555, 0x00000055, 0x55000000, 0x55555555, 0x00555555,
0x00000000, 0x55555400, 0x00000000, 0x55555400, 0x55555555, 0x55554155,
0x55555555, 0x00001555, 0x00000000, 0x55154000, 0x55555550, 0x55554555,
0x45555555, 0x55510154, 0x55555551, 0x55555555, 0x55555501, 0x55555455,
0x55550115, 0x55555555, 0x55405555, 0x00000000, 0x00000000, 0x55555555,
0x55555555, 0x55555554, 0x55555555, 0x05555554, 0x55555555, 0x55555555,
0x50000000, 0x55555555, 0x05555555, 0x55550000, 0x55555555, 0x00005555,
0x00000004, 0x55555550, 0x00015555, 0x55515550, 0x55515551, 0x55555551,
0x55555555, 0x00000005, 0x00000000, 0xaaaaaaa0, 0xa8aaaaaa, 0xaaaaaaaa,
0x02aaaaaa, 0xaaa80000, 0xaaaaaaaa, 0x0002aaaa, 0xaaa80000, 0xaaa802aa,
0xaaaaaaaa, 0x8002aaaa, 0x1aaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaa00,
0xaaaaaaaa, 0xaaa800aa, 0xaaaaaaaa, 0xaaaa80aa, 0xaaaaaaaa, 0xaaaa2aaa,
0xaaaaaaaa, 0x00000000, 0xaaaaaaaa, 0x2aaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa,
0xaa000000, 0xaaaaaaaa, 0xa8aaaaaa, 0xaaaaaaaa, 0x02aaaaaa, 0xaaaa8000,
0xaaaaaaaa, 0x00002aaa, 0x00000000, 0xaaaa8000, 0xaaaaaaaa, 0xaaa02aaa,
0xaaaaaaaa, 0x000aaaaa, 0x00000000, 0x55500000, 0x55555555, 0x00055555,
0x50000000, 0x55555555, 0x05555555, 0x55555555, 0x55500005, 0x55555555,
0x00000005, 0x00000000, 0x55555550, 0x55555555, 0x00000005, 0x00000000,
0x55151550, 0x55555554, 0x00554155, 0x00000000, 0x55555555, 0x55555555,
0x55550000, 0x55555555, 0x00005555, 0x01555554, 0x00000000, 0x54000000,
0x55555555, 0x01555555, 0x00010000, 0x00000000, 0x55540000, 0x55555555,
0x00015555, 0x55555550, 0x50555550, 0x00000005, 0x00000000, 0xaaaaaaa0,
0xaaaaaaaa, 0x0000000a, 0x00000000, 0x55555550, 0x55555555, 0x00000005,
0xaaaaaaa0, 0xaaaaaaaa, 0xaaaaaa0a, 0xaaaaaaaa, 0xaaa800aa, 0xaaaaaaaa,
0x0002aaaa, 0x00000000, 0x55540000, 0x55000000, 0x55551001, 0x15555555,
0x51451155, 0x55555555, 0x05555555, 0x00000000, 0x55555554, 0x55555555,
0x00000001, 0x55555554, 0x55555555, 0x55555541, 0x55555555, 0x00000015,
0x55400000, 0x00015555, 0xaaa80000, 0x0054002a, 0xaaaaa800, 0xaaa8aaaa,
0x500aa2aa, 0x55555515, 0x55555555, 0xaaaa8055, 0xaaaaaaaa, 0x55556aaa,
0x55555555, 0x15541555, 0x15541554, 0x4aaa8054, 0x00000555, 0x55554140,
0x55555515, 0x55451555, 0x55415555, 0x00015555, 0x00000000, 0x55540000,
0x55555555, 0x50015555, 0x55555401, 0x05555555, 0x55555554, 0x55555555,
0x55555001, 0x00000005, 0x00000000, 0x55555550, 0x55555555, 0x00000000,
0x00000000, 0x55555555, 0x01555555, 0x55555555, 0x55555555, 0x00000000,
0x00000000, 0x55555555, 0x15555555, 0x55400000, 0x00155555, 0x00000000,
0x55400000, 0x55555555, 0x55515555, 0x55555555, 0x50055555, 0x00555555,
0x00000000, 0x55000000, 0x55555555, 0x00555555, 0x00000000, 0x55000000,
0x55555105, 0x14555555, 0x00000410, 0x00000000, 0x55555000, 0x55555555,
0x00000400, 0x00000000, 0x00001000, 0x45455000, 0x55555555, 0x40000015,
0x40001555, 0x00005555, 0x00000000, 0x55550000, 0x55555555, 0x00005555,
0x00000000, 0x55550000, 0x55555555, 0x00005555, 0x00015400, 0x00000000,
0x55540000, 0x55555555, 0x00015555, 0x55555540, 0x55555555, 0x55555415,
0x55555555, 0x55550155, 0x50000001, 0x55554000, 0x40155555, 0x55555555,
0x01555555, 0x00000000, 0x54000000, 0x55555555, 0x01555555, 0x00000001,
0x00000000, 0x55555554, 0x55555555, 0x00000001, 0x00000000, 0x55555554,
0x55555555, 0x55555551, 0x55555555, 0x50504145, 0x15555545, 0x55554551,
0x55555555, 0x50551555, 0x45554555, 0x55555555, 0x45515555, 0x55540455,
0x55555554, 0x55555555, 0x55555541, 0x55555555, 0x55555415, 0x55555555,
0x00000155, 0x00000000, 0x55555400, 0x55555555, 0x55540155, 0x55555555,
0x00015555, 0x00000000, 0xaaa80000, 0xaaaaaaaa, 0x0002aaaa, 0x00000000,
0xaaa80000, 0xaaaaaaaa, 0x0002aaaa, 0x00000000, 0x55540000, 0x55555555,
0x55415555, 0x55555555, 0x00155555,
};

View file

@ -0,0 +1,22 @@
#ifndef COSMOPOLITAN_LIBC_STR_WCWIDTH_OSX_H_
#define COSMOPOLITAN_LIBC_STR_WCWIDTH_OSX_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
extern const uint32_t kWcwidthOsx[591];
extern const uint8_t kWcwidthOsxIndex1[136];
extern const uint16_t kWcwidthOsxIndex2[228];
extern const uint32_t kWcwidthOsxIndex3[917];
static inline int _wcwidth_osx(uint32_t codePoint) {
uint32_t a, b, c, d;
a = kWcwidthOsxIndex1[codePoint >> 13];
b = kWcwidthOsxIndex2[a + ((codePoint >> 9) & 0xf)];
c = kWcwidthOsxIndex3[b + ((codePoint >> 5) & 0xf)];
d = c + (codePoint & 0x1f);
return (kWcwidthOsx[d >> 4] >> ((d & 0xf) << 1)) & 3;
}
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_STR_WCWIDTH_OSX_H_ */

View file

@ -7,7 +7,11 @@
#define __AUDIT_ARCH_CONVENTION_MASK 0x30000000
#define __AUDIT_ARCH_CONVENTION_MIPS64_N32 0x20000000
#define AUDIT_ARCH_X86_64 (EM_X86_64 | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
#define AUDIT_ARCH_I386 (EM_386 | __AUDIT_ARCH_LE)
#define AUDIT_ARCH_X86_64 (EM_X86_64 | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
#define AUDIT_ARCH_I386 (EM_386 | __AUDIT_ARCH_LE)
#define AUDIT_ARCH_AARCH64 (EM_AARCH64 | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
#define AUDIT_ARCH_PPC64LE (EM_PPC64 | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
#define AUDIT_ARCH_RISCV64 (EM_RISCV | __AUDIT_ARCH_64BIT | __AUDIT_ARCH_LE)
#define AUDIT_ARCH_S390X (EM_S390 | __AUDIT_ARCH_64BIT)
#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_AUDIT_H_ */

View file

@ -360,6 +360,7 @@
#define __NR_linux_stat 0x004f
#define __NR_linux_fstat 0x0050
#define __NR_linux_ppoll 0x0049
#define __NR_linux_sigreturn 0x008b
#define __NR_linux_lseek 0x003e
#define __NR_linux_mmap 0x00de
#define __NR_linux_msync 0x00e3

View file

@ -46,6 +46,8 @@ TEST(_longsort, test) {
ASSERT_EQ(0, memcmp(b, a, n * sizeof(long)));
}
#ifdef __x86_64__
TEST(vqsort_int64_avx2, test) {
if (!X86_HAVE(AVX2)) return;
size_t n = 5000;
@ -93,6 +95,8 @@ TEST(vqsort_int64_sse2, test) {
ASSERT_EQ(0, memcmp(b, a, n * sizeof(long)));
}
#endif /* __x86_64__ */
TEST(radix_sort_int64, test) {
size_t n = 5000;
long *a = gc(calloc(n, sizeof(long)));
@ -111,6 +115,7 @@ BENCH(_longsort, bench) {
long *p2 = gc(malloc(n * sizeof(long)));
rngset(p1, n * sizeof(long), 0, 0);
EZBENCH2("_longsort", memcpy(p2, p1, n * sizeof(long)), _longsort(p2, n));
#ifdef __x86_64__
if (X86_HAVE(AVX2)) {
EZBENCH2("vqsort_int64_avx2", memcpy(p2, p1, n * sizeof(long)),
vqsort_int64_avx2(p2, n));
@ -125,6 +130,7 @@ BENCH(_longsort, bench) {
}
EZBENCH2("vqsort_int64_sse2", memcpy(p2, p1, n * sizeof(long)),
vqsort_int64_sse2(p2, n));
#endif /* __x86_64__ */
EZBENCH2("radix_sort_int64", memcpy(p2, p1, n * sizeof(long)),
radix_sort_int64(p2, n));
EZBENCH2("qsort(long)", memcpy(p2, p1, n * sizeof(long)),
@ -150,6 +156,8 @@ TEST(_intsort, test) {
ASSERT_EQ(0, memcmp(b, a, n * sizeof(int)));
}
#ifdef __x86_64__
TEST(vqsort_int32_avx2, test) {
if (!X86_HAVE(AVX2)) return;
size_t n = 5000;
@ -197,6 +205,8 @@ TEST(vqsort_int32_sse2, test) {
ASSERT_EQ(0, memcmp(b, a, n * sizeof(int)));
}
#endif /* __x86_64__ */
TEST(radix_sort_int32, test) {
size_t n = 5000;
int *a = gc(calloc(n, sizeof(int)));
@ -215,6 +225,7 @@ BENCH(_intsort, bench) {
int *p2 = gc(malloc(n * sizeof(int)));
rngset(p1, n * sizeof(int), 0, 0);
EZBENCH2("_intsort", memcpy(p2, p1, n * sizeof(int)), _intsort(p2, n));
#ifdef __x86_64__
if (X86_HAVE(AVX2)) {
EZBENCH2("vqsort_int32_avx2", memcpy(p2, p1, n * sizeof(int)),
vqsort_int32_avx2(p2, n));
@ -229,6 +240,7 @@ BENCH(_intsort, bench) {
}
EZBENCH2("vqsort_int32_sse2", memcpy(p2, p1, n * sizeof(int)),
vqsort_int32_sse2(p2, n));
#endif /* __x86_64__ */
EZBENCH2("djbsort", memcpy(p2, p1, n * sizeof(int)), djbsort(p2, n));
EZBENCH2("radix_sort_int32", memcpy(p2, p1, n * sizeof(int)),
radix_sort_int32(p2, n));

View file

@ -472,6 +472,8 @@ TEST(wcscmp, testTwosComplementBane) {
TEST(wcsncmp, testTwosComplementBane) {
wchar_t *B1 = malloc(4);
wchar_t *B2 = malloc(4);
B1[1] = L'\0';
B2[1] = L'\0';
EXPECT_EQ(wcsncmp(memcpy(B1, "\x00\x00\x00\x80", 4),
memcpy(B2, "\x00\x00\x00\x80", 4), 1),
0);

View file

@ -26,6 +26,9 @@
TEST(wcwidth, test) {
ASSERT_EQ(0, wcwidth(0));
ASSERT_EQ(-1, wcwidth(1));
ASSERT_EQ(-1, wcwidth(-7));
ASSERT_EQ(1, wcwidth(0x10FFFD));
ASSERT_EQ(-1, wcwidth(0x10FFFD + 1));
}
TEST(strwidth, testCjkWidesAndCombiningLowLines_withThompsonPikeEncoding) {

View file

@ -1,4 +1,5 @@
#include "libc/calls/calls.h"
#include "libc/intrin/kprintf.h"
#include "libc/str/str.h"
// hello world with minimal build system dependencies
@ -8,5 +9,11 @@ static ssize_t Write(int fd, const char *s) {
}
int main(int argc, char *argv[]) {
wchar_t B1[8];
wchar_t B2[8];
B1[1] = L'\0';
B2[1] = L'\0';
Write(1, "hello world\n");
kprintf("%x\n", wcscmp(memcpy(B1, "\xff\xff\xff\x7f", 4),
memcpy(B2, "\x00\x00\x00\x80", 4)));
}