mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-24 23:09:02 +00:00
Get threads working well on MacOS Arm64
- Now using 10x better GCD semaphores - We now generate Linux-like thread ids - We now use fast system clock / sleep libraries - The APE M1 loader now generates Linux-like stacks
This commit is contained in:
parent
b5eab2b0b7
commit
bcf9af94bf
2037 changed files with 4664 additions and 4451 deletions
ape
libc
calls
clock_gettime-m1.cclock_gettime.cclock_nanosleep-xnu.cgettimeofday-m1.cgettimeofday.cnanosleep-xnu.c
dce.hstruct
intrin
log
runtime
sysv
consts.sh
consts
ABORTED_COMMAND.SACCT_BYTEORDER.SACCT_COMM.SACK.SACORE.SAFORK.SAF_ALG.SAF_APPLETALK.SAF_ASH.SAF_ATMPVC.SAF_ATMSVC.SAF_AX25.SAF_BLUETOOTH.SAF_BRIDGE.SAF_CAIF.SAF_CAN.SAF_ECONET.SAF_FILE.SAF_IB.SAF_IEEE802154.SAF_INET.SAF_INET6.SAF_IPX.SAF_IRDA.SAF_ISDN.SAF_IUCV.SAF_KCM.SAF_KEY.SAF_LINK.SAF_LLC.SAF_LOCAL.SAF_MAX.SAF_MPLS.SAF_NETBEUI.SAF_NETLINK.SAF_NETROM.SAF_NFC.SAF_PACKET.SAF_PHONET.SAF_PPPOX.SAF_RDS.SAF_ROSE.SAF_ROUTE.SAF_RXRPC.SAF_SECURITY.SAF_SNA.SAF_TIPC.SAF_UNIX.SAF_UNSPEC.SAF_VSOCK.SAF_WANPIPE.SAF_X25.SAIO_ALLDONE.SAIO_CANCELED.SAIO_NOTCANCELED.SALG_SET_AEAD_ASSOCLEN.SALG_SET_AEAD_AUTHSIZE.SALG_SET_DRBG_ENTROPY.SALG_SET_IV.SALG_SET_KEY.SALG_SET_OP.SAREGTYPE.SAT_BASE.SAT_BASE_PLATFORM.SAT_CANARY.SAT_CANARYLEN.SAT_CLKTCK.SAT_DCACHEBSIZE.SAT_EACCESS.SAT_EGID.SAT_EHDRFLAGS.SAT_EMPTY_PATH.SAT_ENTRY.SAT_EUID.SAT_EXECFD.S
417
ape/ape-m1.c
417
ape/ape-m1.c
|
@ -16,86 +16,79 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include <time.h>
|
||||
#include <fcntl.h>
|
||||
#include <dispatch/dispatch.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <libkern/OSCacheControl.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/uio.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/mman.h>
|
||||
#include <libkern/OSCacheControl.h>
|
||||
#include <sys/random.h>
|
||||
#include <sys/uio.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define SYSLIB_MAGIC ('s' | 'l' << 8 | 'i' << 16 | 'b' << 24)
|
||||
#define SYSLIB_VERSION 0
|
||||
#define SYSLIB_MAGIC ('s' | 'l' << 8 | 'i' << 16 | 'b' << 24)
|
||||
#define SYSLIB_VERSION 1
|
||||
|
||||
struct Syslib {
|
||||
int magic;
|
||||
int version;
|
||||
void (*exit)(int) __attribute__((__noreturn__));
|
||||
long (*fork)(void);
|
||||
long (*read)(int, void *, size_t);
|
||||
long (*pread)(int, void *, size_t, off_t);
|
||||
long (*readv)(int, const struct iovec *, int);
|
||||
long (*write)(int, const void *, size_t);
|
||||
long (*pwrite)(int, const void *, size_t, off_t);
|
||||
long (*writev)(int, const struct iovec *, int);
|
||||
long (*openat)(int, const char *, int, ...);
|
||||
long (*pipe)(int[2]);
|
||||
long (*close)(int);
|
||||
long (*clock_gettime)(int, struct timespec *);
|
||||
long (*nanosleep)(const struct timespec *, struct timespec *);
|
||||
long (*mmap)(void *, size_t, int, int, int, off_t);
|
||||
long (*sigaction)(int, const struct sigaction *restrict, struct sigaction *restrict);
|
||||
int (*pthread_jit_write_protect_supported_np)(void);
|
||||
void (*pthread_jit_write_protect_np)(int);
|
||||
void (*sys_icache_invalidate)(void *, size_t);
|
||||
pthread_t (*pthread_self)(void);
|
||||
int (*pthread_create)(pthread_t *, const pthread_attr_t *, void *(*)(void *), void *);
|
||||
int (*pthread_detach)(pthread_t);
|
||||
int (*pthread_join)(pthread_t, void **);
|
||||
int (*pthread_create)(pthread_t *, const pthread_attr_t *, void *(*)(void *),
|
||||
void *);
|
||||
void (*pthread_exit)(void *);
|
||||
int (*pthread_kill)(pthread_t, int);
|
||||
int (*pthread_sigmask)(int, const sigset_t *restrict, sigset_t *restrict);
|
||||
int (*pthread_setname_np)(const char *);
|
||||
int (*pthread_key_create)(pthread_key_t *, void (*)(void *));
|
||||
int (*pthread_setspecific)(pthread_key_t, const void *);
|
||||
void *(*pthread_getspecific)(pthread_key_t);
|
||||
dispatch_semaphore_t (*dispatch_semaphore_create)(long);
|
||||
long (*dispatch_semaphore_signal)(dispatch_semaphore_t);
|
||||
long (*dispatch_semaphore_wait)(dispatch_semaphore_t, dispatch_time_t);
|
||||
dispatch_time_t (*dispatch_walltime)(const struct timespec *, int64_t);
|
||||
};
|
||||
|
||||
#define TROUBLESHOOT 0
|
||||
|
||||
#define ELFCLASS64 2
|
||||
#define ELFDATA2LSB 1
|
||||
#define EM_AARCH64 183
|
||||
#define ET_EXEC 2
|
||||
#define PT_LOAD 1
|
||||
#define PT_DYNAMIC 2
|
||||
#define EI_CLASS 4
|
||||
#define EI_DATA 5
|
||||
#define PF_X 1
|
||||
#define PF_W 2
|
||||
#define PF_R 4
|
||||
#define AT_PHDR 3
|
||||
#define AT_PHENT 4
|
||||
#define AT_PHNUM 5
|
||||
#define AT_PAGESZ 6
|
||||
#define AT_BASE 7
|
||||
#define AT_ENTRY 9
|
||||
#define AT_UID 11
|
||||
#define AT_EUID 12
|
||||
#define AT_GID 13
|
||||
#define AT_EGID 14
|
||||
#define AT_HWCAP 16
|
||||
#define AT_HWCAP2 16
|
||||
#define AT_SECURE 23
|
||||
#define AT_RANDOM 25
|
||||
#define AT_EXECFN 31
|
||||
#define ELFCLASS64 2
|
||||
#define ELFDATA2LSB 1
|
||||
#define EM_AARCH64 183
|
||||
#define ET_EXEC 2
|
||||
#define PT_LOAD 1
|
||||
#define PT_DYNAMIC 2
|
||||
#define EI_CLASS 4
|
||||
#define EI_DATA 5
|
||||
#define PF_X 1
|
||||
#define PF_W 2
|
||||
#define PF_R 4
|
||||
#define AT_PHDR 3
|
||||
#define AT_PHENT 4
|
||||
#define AT_PHNUM 5
|
||||
#define AT_PAGESZ 6
|
||||
#define AT_BASE 7
|
||||
#define AT_ENTRY 9
|
||||
#define AT_UID 11
|
||||
#define AT_EUID 12
|
||||
#define AT_GID 13
|
||||
#define AT_EGID 14
|
||||
#define AT_HWCAP 16
|
||||
#define AT_HWCAP2 16
|
||||
#define AT_SECURE 23
|
||||
#define AT_RANDOM 25
|
||||
#define AT_EXECFN 31
|
||||
|
||||
#define STACK_SIZE (8ul * 1024 * 1024)
|
||||
#define STACK_ALIGN (sizeof(long) * 2)
|
||||
#define AUXV_BYTES (sizeof(long) * 2 * 14)
|
||||
#define AUXV_BYTES (sizeof(long) * 2 * 15)
|
||||
|
||||
// from the xnu codebase
|
||||
#define _COMM_PAGE_START_ADDRESS 0x0000000FFFFFC000ul
|
||||
|
@ -104,14 +97,12 @@ struct Syslib {
|
|||
#define _COMM_PAGE_APRR_WRITE_DISABLE (_COMM_PAGE_START_ADDRESS + 0x118)
|
||||
|
||||
#define Min(X, Y) ((Y) > (X) ? (X) : (Y))
|
||||
#define Roundup(X, K) (((X) + (K) - 1) & -(K))
|
||||
#define Roundup(X, K) (((X) + (K)-1) & -(K))
|
||||
#define Rounddown(X, K) ((X) & -(K))
|
||||
|
||||
#define Read32(S) \
|
||||
((unsigned)(255 & (S)[3]) << 030 | \
|
||||
(unsigned)(255 & (S)[2]) << 020 | \
|
||||
(unsigned)(255 & (S)[1]) << 010 | \
|
||||
(unsigned)(255 & (S)[0]) << 000)
|
||||
#define Read32(S) \
|
||||
((unsigned)(255 & (S)[3]) << 030 | (unsigned)(255 & (S)[2]) << 020 | \
|
||||
(unsigned)(255 & (S)[1]) << 010 | (unsigned)(255 & (S)[0]) << 000)
|
||||
|
||||
#define Read64(S) \
|
||||
((unsigned long)(255 & (S)[7]) << 070 | \
|
||||
|
@ -123,13 +114,6 @@ struct Syslib {
|
|||
(unsigned long)(255 & (S)[1]) << 010 | \
|
||||
(unsigned long)(255 & (S)[0]) << 000)
|
||||
|
||||
struct PathSearcher {
|
||||
unsigned long namelen;
|
||||
const char *name;
|
||||
const char *syspath;
|
||||
char path[1024];
|
||||
};
|
||||
|
||||
struct ElfEhdr {
|
||||
unsigned char e_ident[16];
|
||||
unsigned short e_type;
|
||||
|
@ -168,10 +152,44 @@ union ElfPhdrBuf {
|
|||
char buf[0x1000];
|
||||
};
|
||||
|
||||
struct PathSearcher {
|
||||
unsigned long namelen;
|
||||
const char *name;
|
||||
const char *syspath;
|
||||
char path[1024];
|
||||
};
|
||||
|
||||
struct ApeLoader {
|
||||
union ElfEhdrBuf ehdr;
|
||||
struct PathSearcher ps;
|
||||
// this memory shall be discarded by the guest
|
||||
//////////////////////////////////////////////
|
||||
// this memory shall be known to guest program
|
||||
union {
|
||||
char argblock[ARG_MAX];
|
||||
long numblock[ARG_MAX / sizeof(long)];
|
||||
};
|
||||
union ElfPhdrBuf phdr;
|
||||
struct Syslib lib;
|
||||
char rando[16];
|
||||
};
|
||||
|
||||
static int ToLower(int c) {
|
||||
return 'A' <= c && c <= 'Z' ? c + ('a' - 'A') : c;
|
||||
}
|
||||
|
||||
static unsigned long StrLen(const char *s) {
|
||||
unsigned long n = 0;
|
||||
while (*s++) ++n;
|
||||
return n;
|
||||
}
|
||||
|
||||
static int StrCmp(const char *l, const char *r) {
|
||||
unsigned long i = 0;
|
||||
while (l[i] == r[i] && r[i]) ++i;
|
||||
return (l[i] & 255) - (r[i] & 255);
|
||||
}
|
||||
|
||||
static void *MemSet(void *a, int c, unsigned long n) {
|
||||
char *d = a;
|
||||
unsigned long i;
|
||||
|
@ -197,12 +215,6 @@ static void *MemMove(void *a, const void *b, unsigned long n) {
|
|||
return d;
|
||||
}
|
||||
|
||||
static unsigned long StrLen(const char *s) {
|
||||
unsigned long n = 0;
|
||||
while (*s++) ++n;
|
||||
return n;
|
||||
}
|
||||
|
||||
static const char *MemChr(const char *s, unsigned char c, unsigned long n) {
|
||||
for (; n; --n, ++s) {
|
||||
if ((*s & 255) == c) {
|
||||
|
@ -267,6 +279,7 @@ static void Perror(const char *c, int failed, const char *s) {
|
|||
Emit(": ");
|
||||
Emit(s);
|
||||
if (failed) {
|
||||
#include <sys/random.h>
|
||||
Emit(" failed errno=");
|
||||
Itoa(ibuf, errno);
|
||||
Emit(ibuf);
|
||||
|
@ -274,18 +287,12 @@ static void Perror(const char *c, int failed, const char *s) {
|
|||
Emit("\n");
|
||||
}
|
||||
|
||||
__attribute__((__noreturn__))
|
||||
static void Pexit(const char *c, int failed, const char *s) {
|
||||
__attribute__((__noreturn__)) static void Pexit(const char *c, int failed,
|
||||
const char *s) {
|
||||
Perror(c, failed, s);
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
static int StrCmp(const char *l, const char *r) {
|
||||
unsigned long i = 0;
|
||||
while (l[i] == r[i] && r[i]) ++i;
|
||||
return (l[i] & 255) - (r[i] & 255);
|
||||
}
|
||||
|
||||
static char EndsWithIgnoreCase(const char *p, unsigned long n, const char *s) {
|
||||
unsigned long i, m;
|
||||
if (n >= (m = StrLen(s))) {
|
||||
|
@ -347,8 +354,7 @@ static char FindCommand(struct PathSearcher *ps, const char *suffix) {
|
|||
return SearchPath(ps, suffix);
|
||||
}
|
||||
|
||||
static char *Commandv(struct PathSearcher *ps,
|
||||
const char *name,
|
||||
static char *Commandv(struct PathSearcher *ps, const char *name,
|
||||
const char *syspath) {
|
||||
ps->syspath = syspath ? syspath : "/bin:/usr/local/bin:/usr/bin";
|
||||
if (!(ps->namelen = StrLen((ps->name = name)))) return 0;
|
||||
|
@ -365,9 +371,9 @@ static void pthread_jit_write_protect_np_workaround(int enabled) {
|
|||
volatile int count = count_start;
|
||||
unsigned long *addr, *other, val, val2, reread = -1;
|
||||
addr = (unsigned long *)(!enabled ? _COMM_PAGE_APRR_WRITE_ENABLE
|
||||
: _COMM_PAGE_APRR_WRITE_DISABLE);
|
||||
: _COMM_PAGE_APRR_WRITE_DISABLE);
|
||||
other = (unsigned long *)(enabled ? _COMM_PAGE_APRR_WRITE_ENABLE
|
||||
: _COMM_PAGE_APRR_WRITE_DISABLE);
|
||||
: _COMM_PAGE_APRR_WRITE_DISABLE);
|
||||
switch (*(volatile unsigned char *)_COMM_PAGE_APRR_SUPPORT) {
|
||||
case 1:
|
||||
do {
|
||||
|
@ -416,15 +422,14 @@ static void pthread_jit_write_protect_np_workaround(int enabled) {
|
|||
Pexit("ape-m1", 0, "failed to set jit write protection");
|
||||
}
|
||||
|
||||
__attribute__((__noreturn__))
|
||||
static void Spawn(const char *exe,
|
||||
int fd, long *sp,
|
||||
struct ElfEhdr *e,
|
||||
struct ElfPhdr *p,
|
||||
struct Syslib *lib) {
|
||||
__attribute__((__noreturn__)) static void Spawn(const char *exe, int fd,
|
||||
long *sp, struct ElfEhdr *e,
|
||||
struct ElfPhdr *p,
|
||||
struct Syslib *lib) {
|
||||
int prot, flags;
|
||||
long code, codesize;
|
||||
unsigned long a, b, i;
|
||||
|
||||
code = 0;
|
||||
codesize = 0;
|
||||
for (i = e->e_phnum; i--;) {
|
||||
|
@ -460,8 +465,8 @@ static void Spawn(const char *exe,
|
|||
codesize = p[i].p_filesz;
|
||||
}
|
||||
if (p[i].p_filesz) {
|
||||
if (mmap((char *)p[i].p_vaddr, p[i].p_filesz, prot,
|
||||
flags, fd, p[i].p_offset) == MAP_FAILED) {
|
||||
if (mmap((char *)p[i].p_vaddr, p[i].p_filesz, prot, flags, fd,
|
||||
p[i].p_offset) == MAP_FAILED) {
|
||||
Pexit(exe, -1, "image mmap()");
|
||||
}
|
||||
if ((a = Min(-p[i].p_filesz & 0x3fff, p[i].p_memsz - p[i].p_filesz))) {
|
||||
|
@ -470,8 +475,8 @@ static void Spawn(const char *exe,
|
|||
}
|
||||
if ((b = Roundup(p[i].p_memsz, 0x4000)) >
|
||||
(a = Roundup(p[i].p_filesz, 0x4000))) {
|
||||
if (mmap((char *)p[i].p_vaddr + a, b - a,
|
||||
prot, flags | MAP_ANONYMOUS, -1, 0) == MAP_FAILED) {
|
||||
if (mmap((char *)p[i].p_vaddr + a, b - a, prot, flags | MAP_ANONYMOUS, -1,
|
||||
0) == MAP_FAILED) {
|
||||
Pexit(exe, -1, "bss mmap()");
|
||||
}
|
||||
}
|
||||
|
@ -521,41 +526,41 @@ static void Spawn(const char *exe,
|
|||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
static void TryElf(const char *exe, int fd, long *sp, long *bp, char *execfn,
|
||||
union ElfEhdrBuf *ehdr, union ElfPhdrBuf *phdr, struct Syslib *lib) {
|
||||
static void TryElf(struct ApeLoader *M, const char *exe, int fd, long *sp,
|
||||
long *bp, char *execfn) {
|
||||
unsigned long n;
|
||||
if (Read32(ehdr->buf) == Read32("\177ELF") &&
|
||||
ehdr->ehdr.e_type == ET_EXEC &&
|
||||
ehdr->ehdr.e_machine == EM_AARCH64 &&
|
||||
ehdr->ehdr.e_ident[EI_CLASS] == ELFCLASS64 &&
|
||||
ehdr->ehdr.e_ident[EI_DATA] == ELFDATA2LSB &&
|
||||
(n = ehdr->ehdr.e_phnum * sizeof(phdr->phdr)) <= sizeof(phdr->buf) &&
|
||||
pread(fd, phdr->buf, n, ehdr->ehdr.e_phoff) == n) {
|
||||
if (Read32(M->ehdr.buf) == Read32("\177ELF") &&
|
||||
M->ehdr.ehdr.e_type == ET_EXEC && M->ehdr.ehdr.e_machine == EM_AARCH64 &&
|
||||
M->ehdr.ehdr.e_ident[EI_CLASS] == ELFCLASS64 &&
|
||||
M->ehdr.ehdr.e_ident[EI_DATA] == ELFDATA2LSB &&
|
||||
(n = M->ehdr.ehdr.e_phnum * sizeof(M->phdr.phdr)) <=
|
||||
sizeof(M->phdr.buf) &&
|
||||
pread(fd, M->phdr.buf, n, M->ehdr.ehdr.e_phoff) == n) {
|
||||
long auxv[][2] = {
|
||||
{AT_PHDR, (long)&phdr->phdr}, //
|
||||
{AT_PHENT, ehdr->ehdr.e_phentsize}, //
|
||||
{AT_PHNUM, ehdr->ehdr.e_phnum}, //
|
||||
{AT_ENTRY, ehdr->ehdr.e_entry}, //
|
||||
{AT_PAGESZ, 0x4000}, //
|
||||
{AT_UID, getuid()}, //
|
||||
{AT_EUID, geteuid()}, //
|
||||
{AT_GID, getgid()}, //
|
||||
{AT_EGID, getegid()}, //
|
||||
{AT_HWCAP, 0xffb3ffffu}, //
|
||||
{AT_HWCAP2, 0x181}, //
|
||||
{AT_SECURE, issetugid()}, //
|
||||
{AT_EXECFN, (long)execfn}, //
|
||||
{0, 0}, //
|
||||
{AT_PHDR, (long)&M->phdr.phdr}, //
|
||||
{AT_PHENT, M->ehdr.ehdr.e_phentsize}, //
|
||||
{AT_PHNUM, M->ehdr.ehdr.e_phnum}, //
|
||||
{AT_ENTRY, M->ehdr.ehdr.e_entry}, //
|
||||
{AT_PAGESZ, 0x4000}, //
|
||||
{AT_UID, getuid()}, //
|
||||
{AT_EUID, geteuid()}, //
|
||||
{AT_GID, getgid()}, //
|
||||
{AT_EGID, getegid()}, //
|
||||
{AT_HWCAP, 0xffb3ffffu}, //
|
||||
{AT_HWCAP2, 0x181}, //
|
||||
{AT_SECURE, issetugid()}, //
|
||||
{AT_RANDOM, (long)M->rando}, //
|
||||
{AT_EXECFN, (long)execfn}, //
|
||||
{0, 0}, //
|
||||
};
|
||||
_Static_assert(sizeof(auxv) == AUXV_BYTES,
|
||||
"Please update the AUXV_BYTES constant");
|
||||
MemMove(bp, auxv, sizeof(auxv));
|
||||
Spawn(exe, fd, sp, &ehdr->ehdr, &phdr->phdr, lib);
|
||||
Spawn(exe, fd, sp, &M->ehdr.ehdr, &M->phdr.phdr, &M->lib);
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((__noinline__))
|
||||
static long sysret(long rc) {
|
||||
__attribute__((__noinline__)) static long sysret(long rc) {
|
||||
return rc == -1 ? -errno : rc;
|
||||
}
|
||||
|
||||
|
@ -563,47 +568,10 @@ static long sys_fork(void) {
|
|||
return sysret(fork());
|
||||
}
|
||||
|
||||
static long sys_read(int fd, void *p, size_t n) {
|
||||
return sysret(read(fd, p, n));
|
||||
}
|
||||
|
||||
static long sys_pread(int fd, void *p, size_t n, off_t o) {
|
||||
return sysret(pread(fd, p, n, o));
|
||||
}
|
||||
|
||||
static long sys_readv(int fd, const struct iovec *p, int n) {
|
||||
return sysret(readv(fd, p, n));
|
||||
}
|
||||
|
||||
static long sys_write(int fd, const void *p, size_t n) {
|
||||
return sysret(write(fd, p, n));
|
||||
}
|
||||
|
||||
static long sys_pwrite(int fd, const void *p, size_t n, off_t o) {
|
||||
return sysret(pwrite(fd, p, n, o));
|
||||
}
|
||||
|
||||
static long sys_writev(int fd, const struct iovec *p, int n) {
|
||||
return sysret(writev(fd, p, n));
|
||||
}
|
||||
|
||||
static long sys_openat(int dirfd, const char *path, int oflag, ...) {
|
||||
va_list va;
|
||||
unsigned mode;
|
||||
va_start(va, oflag);
|
||||
mode = va_arg(va, unsigned);
|
||||
va_end(va);
|
||||
return sysret(openat(dirfd, path, oflag, mode));
|
||||
}
|
||||
|
||||
static long sys_pipe(int pfds[2]) {
|
||||
return sysret(pipe(pfds));
|
||||
}
|
||||
|
||||
static long sys_close(int fd) {
|
||||
return sysret(close(fd));
|
||||
}
|
||||
|
||||
static long sys_clock_gettime(int clock, struct timespec *ts) {
|
||||
return sysret(clock_gettime(clock, ts));
|
||||
}
|
||||
|
@ -612,69 +580,62 @@ static long sys_nanosleep(const struct timespec *req, struct timespec *rem) {
|
|||
return sysret(nanosleep(req, rem));
|
||||
}
|
||||
|
||||
static long sys_mmap(void *addr, size_t size, int prot, int flags, int fd, off_t off) {
|
||||
static long sys_mmap(void *addr, size_t size, int prot, int flags, int fd,
|
||||
off_t off) {
|
||||
return sysret((long)mmap(addr, size, prot, flags, fd, off));
|
||||
}
|
||||
|
||||
static long sys_sigaction(int sig, const struct sigaction *restrict act,
|
||||
struct sigaction *restrict oact) {
|
||||
return sysret(sigaction(sig, act, oact));
|
||||
}
|
||||
|
||||
int loader(int argc, char **argv, char **envp) {
|
||||
int main(int argc, char **argv, char **envp) {
|
||||
long z;
|
||||
void *map;
|
||||
long *sp, *bp, *ip;
|
||||
int c, i, n, fd, rc;
|
||||
struct ApeLoader *M;
|
||||
unsigned char rando[24];
|
||||
char *p, *tp, *exe, *prog, *execfn;
|
||||
|
||||
struct {
|
||||
union ElfEhdrBuf ehdr;
|
||||
struct PathSearcher ps;
|
||||
// this memory shall be discarded by the guest
|
||||
//////////////////////////////////////////////
|
||||
// this memory shall be known to guest program
|
||||
union {
|
||||
char argblock[ARG_MAX];
|
||||
long numblock[ARG_MAX / sizeof(long)];
|
||||
};
|
||||
union ElfPhdrBuf phdr;
|
||||
struct Syslib lib;
|
||||
} M;
|
||||
// generate some hard random data
|
||||
if (getentropy(rando, sizeof(rando))) {
|
||||
Pexit(argv[0], -1, "getentropy");
|
||||
}
|
||||
|
||||
// expose some apple libraries
|
||||
M.lib.magic = SYSLIB_MAGIC;
|
||||
M.lib.version = SYSLIB_VERSION;
|
||||
M.lib.exit = _exit;
|
||||
M.lib.fork = sys_fork;
|
||||
M.lib.read = sys_read;
|
||||
M.lib.pread = sys_pread;
|
||||
M.lib.readv = sys_readv;
|
||||
M.lib.write = sys_write;
|
||||
M.lib.pwrite = sys_pwrite;
|
||||
M.lib.writev = sys_writev;
|
||||
M.lib.openat = sys_openat;
|
||||
M.lib.close = sys_close;
|
||||
M.lib.clock_gettime = sys_clock_gettime;
|
||||
M.lib.nanosleep = sys_nanosleep;
|
||||
M.lib.mmap = sys_mmap;
|
||||
M.lib.sigaction = sys_sigaction;
|
||||
M.lib.pthread_jit_write_protect_supported_np =
|
||||
// make the stack look like a linux one
|
||||
map = mmap((void *)(0x7f0000000000 | (long)rando[23] << 32), STACK_SIZE,
|
||||
PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||
if (map == MAP_FAILED) {
|
||||
Pexit(argv[0], -1, "stack mmap");
|
||||
}
|
||||
|
||||
// put argument block at top of allocated stack
|
||||
z = (long)map;
|
||||
z += STACK_SIZE - sizeof(struct ApeLoader);
|
||||
z &= -_Alignof(struct ApeLoader);
|
||||
M = (struct ApeLoader *)z;
|
||||
|
||||
// expose screwy apple libs
|
||||
M->lib.magic = SYSLIB_MAGIC;
|
||||
M->lib.version = SYSLIB_VERSION;
|
||||
M->lib.fork = sys_fork;
|
||||
M->lib.pipe = sys_pipe;
|
||||
M->lib.clock_gettime = sys_clock_gettime;
|
||||
M->lib.nanosleep = sys_nanosleep;
|
||||
M->lib.mmap = sys_mmap;
|
||||
M->lib.pthread_jit_write_protect_supported_np =
|
||||
pthread_jit_write_protect_supported_np;
|
||||
M.lib.pthread_jit_write_protect_np =
|
||||
pthread_jit_write_protect_np_workaround;
|
||||
M.lib.pthread_self = pthread_self;
|
||||
M.lib.pthread_create = pthread_create;
|
||||
M.lib.pthread_join = pthread_join;
|
||||
M.lib.pthread_exit = pthread_exit;
|
||||
M.lib.pthread_kill = pthread_kill;
|
||||
M.lib.pthread_sigmask = pthread_sigmask;
|
||||
M.lib.pthread_setname_np = pthread_setname_np;
|
||||
M.lib.pthread_key_create = pthread_key_create;
|
||||
M.lib.pthread_getspecific = pthread_getspecific;
|
||||
M.lib.pthread_setspecific = pthread_setspecific;
|
||||
M->lib.pthread_jit_write_protect_np = pthread_jit_write_protect_np_workaround;
|
||||
M->lib.pthread_create = pthread_create;
|
||||
M->lib.pthread_exit = pthread_exit;
|
||||
M->lib.pthread_kill = pthread_kill;
|
||||
M->lib.pthread_sigmask = pthread_sigmask;
|
||||
M->lib.pthread_setname_np = pthread_setname_np;
|
||||
M->lib.dispatch_semaphore_create = dispatch_semaphore_create;
|
||||
M->lib.dispatch_semaphore_signal = dispatch_semaphore_signal;
|
||||
M->lib.dispatch_semaphore_wait = dispatch_semaphore_wait;
|
||||
M->lib.dispatch_walltime = dispatch_walltime;
|
||||
|
||||
// copy system provided argument block
|
||||
bp = M.numblock;
|
||||
tp = M.argblock + sizeof(M.argblock);
|
||||
bp = M->numblock;
|
||||
tp = M->argblock + sizeof(M->argblock);
|
||||
*bp++ = argc;
|
||||
for (i = 0; i < argc; ++i) {
|
||||
tp -= (n = StrLen(argv[i]) + 1);
|
||||
|
@ -690,7 +651,7 @@ int loader(int argc, char **argv, char **envp) {
|
|||
*bp++ = 0;
|
||||
|
||||
// get arguments that point into our block
|
||||
sp = M.numblock;
|
||||
sp = M->numblock;
|
||||
argc = *sp;
|
||||
argv = (char **)(sp + 1);
|
||||
envp = (char **)(sp + 1 + argc + 1);
|
||||
|
@ -734,14 +695,18 @@ int loader(int argc, char **argv, char **envp) {
|
|||
bp = ip + n;
|
||||
sp = ip;
|
||||
|
||||
// relocate the guest's random numbers
|
||||
MemMove(M->rando, rando, sizeof(M->rando));
|
||||
MemSet(rando, 0, sizeof(rando));
|
||||
|
||||
// search for executable
|
||||
if (!(exe = Commandv(&M.ps, prog, GetEnv(envp, "PATH")))) {
|
||||
if (!(exe = Commandv(&M->ps, prog, GetEnv(envp, "PATH")))) {
|
||||
Pexit(prog, 0, "not found (maybe chmod +x)");
|
||||
} else if ((fd = openat(AT_FDCWD, exe, O_RDONLY)) < 0) {
|
||||
Pexit(exe, -1, "open");
|
||||
} else if ((rc = read(fd, M.ehdr.buf, sizeof(M.ehdr.buf))) < 0) {
|
||||
} else if ((rc = read(fd, M->ehdr.buf, sizeof(M->ehdr.buf))) < 0) {
|
||||
Pexit(exe, -1, "read");
|
||||
} else if (rc != sizeof(M.ehdr.buf)) {
|
||||
} else if (rc != sizeof(M->ehdr.buf)) {
|
||||
Pexit(exe, 0, "too small");
|
||||
}
|
||||
|
||||
|
@ -759,13 +724,14 @@ int loader(int argc, char **argv, char **envp) {
|
|||
// 3. shell script may have multiple lines producing elf headers
|
||||
// 4. all elf printf lines must exist in the first 4096 bytes of file
|
||||
// 5. elf program headers may appear anywhere in the binary
|
||||
if (Read64(M.ehdr.buf) == Read64("MZqFpD='") ||
|
||||
Read64(M.ehdr.buf) == Read64("jartsr='")) {
|
||||
for (p = M.ehdr.buf; p < M.ehdr.buf + sizeof(M.ehdr.buf); ++p) {
|
||||
if (Read64(M->ehdr.buf) == Read64("MZqFpD='") ||
|
||||
Read64(M->ehdr.buf) == Read64("jartsr='")) {
|
||||
for (p = M->ehdr.buf; p < M->ehdr.buf + sizeof(M->ehdr.buf); ++p) {
|
||||
if (Read64(p) != Read64("printf '")) {
|
||||
continue;
|
||||
}
|
||||
for (i = 0, p += 8; p + 3 < M.ehdr.buf + sizeof(M.ehdr.buf) && (c = *p++) != '\'';) {
|
||||
for (i = 0, p += 8;
|
||||
p + 3 < M->ehdr.buf + sizeof(M->ehdr.buf) && (c = *p++) != '\'';) {
|
||||
if (c == '\\') {
|
||||
if ('0' <= *p && *p <= '7') {
|
||||
c = *p++ - '0';
|
||||
|
@ -779,22 +745,13 @@ int loader(int argc, char **argv, char **envp) {
|
|||
}
|
||||
}
|
||||
}
|
||||
M.ehdr.buf[i++] = c;
|
||||
M->ehdr.buf[i++] = c;
|
||||
}
|
||||
if (i >= sizeof(M.ehdr.ehdr)) {
|
||||
TryElf(exe, fd, sp, bp, execfn, &M.ehdr, &M.phdr, &M.lib);
|
||||
if (i >= sizeof(M->ehdr.ehdr)) {
|
||||
TryElf(M, exe, fd, sp, bp, execfn);
|
||||
}
|
||||
}
|
||||
}
|
||||
TryElf(exe, fd, sp, bp, execfn, &M.ehdr, &M.phdr, &M.lib);
|
||||
TryElf(M, exe, fd, sp, bp, execfn);
|
||||
Pexit(exe, 0, "Not an acceptable APE/ELF executable for AARCH64");
|
||||
}
|
||||
|
||||
asm(".globl\t_main\n_main:\t"
|
||||
"stp\tx29,x30,[sp,#-16]!\n\t"
|
||||
"mov\tx29,sp\n\t"
|
||||
"mov\tx9,sp\n\t"
|
||||
"and\tsp,x9,#-(2*1024*1024)\n\t"
|
||||
"bl\t_loader\n\t"
|
||||
"ldp\tx29,x30,[sp],#16\n\t"
|
||||
"ret");
|
||||
|
|
26
libc/calls/clock_gettime-m1.c
Normal file
26
libc/calls/clock_gettime-m1.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*-*- 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 2022 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/struct/timespec.h"
|
||||
#include "libc/calls/struct/timespec.internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/runtime/syslib.internal.h"
|
||||
|
||||
int sys_clock_gettime_m1(int clock, struct timespec *ts) {
|
||||
return _sysret(__syslib->clock_gettime(clock, ts));
|
||||
}
|
|
@ -110,8 +110,15 @@ clock_gettime_f *__clock_gettime_get(bool *opt_out_isfast) {
|
|||
if (IsLinux() && (res = CGT_VDSO)) {
|
||||
isfast = true;
|
||||
} else if (IsXnu()) {
|
||||
isfast = false;
|
||||
#ifdef __x86_64__
|
||||
res = sys_clock_gettime_xnu;
|
||||
isfast = false;
|
||||
#elif defined(__aarch64__)
|
||||
res = sys_clock_gettime_m1;
|
||||
isfast = true;
|
||||
#else
|
||||
#error "unsupported architecture"
|
||||
#endif
|
||||
} else if (IsWindows()) {
|
||||
isfast = true;
|
||||
res = sys_clock_gettime_nt;
|
||||
|
|
|
@ -16,10 +16,13 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/calls/struct/timespec.internal.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/calls/struct/timeval.internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/runtime/syslib.internal.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/sysv/consts/timer.h"
|
||||
|
@ -27,23 +30,38 @@
|
|||
|
||||
int sys_clock_nanosleep_xnu(int clock, int flags, const struct timespec *req,
|
||||
struct timespec *rem) {
|
||||
int res;
|
||||
struct timeval now, abs, rel;
|
||||
#ifdef __x86_64__
|
||||
struct timeval abs, now, rel;
|
||||
if (clock == CLOCK_REALTIME) {
|
||||
if (flags & TIMER_ABSTIME) {
|
||||
abs = timespec_totimeval(*req);
|
||||
sys_gettimeofday_xnu(&now, 0, 0);
|
||||
if (timeval_cmp(abs, now) > 0) {
|
||||
rel = timeval_sub(abs, now);
|
||||
res = sys_select(0, 0, 0, 0, &rel);
|
||||
return sys_select(0, 0, 0, 0, &rel);
|
||||
} else {
|
||||
res = 0;
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
res = sys_nanosleep_xnu(req, rem);
|
||||
return sys_nanosleep_xnu(req, rem);
|
||||
}
|
||||
} else {
|
||||
res = enotsup();
|
||||
return enotsup();
|
||||
}
|
||||
return res;
|
||||
#else
|
||||
long res;
|
||||
struct timespec abs, now, rel;
|
||||
if (flags & TIMER_ABSTIME) {
|
||||
abs = *req;
|
||||
if (!(res = __syslib->clock_gettime(clock, &now))) {
|
||||
if (timespec_cmp(abs, now) > 0) {
|
||||
rel = timespec_sub(abs, now);
|
||||
res = __syslib->nanosleep(&rel, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
res = __syslib->nanosleep(req, rem);
|
||||
}
|
||||
return _sysret(res);
|
||||
#endif
|
||||
}
|
||||
|
|
35
libc/calls/gettimeofday-m1.c
Normal file
35
libc/calls/gettimeofday-m1.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/calls/struct/timeval.internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/runtime/syslib.internal.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
|
||||
axdx_t sys_gettimeofday_m1(struct timeval *tv, struct timezone *tz, void *wut) {
|
||||
axdx_t ad;
|
||||
struct timespec ts;
|
||||
ad.ax = _sysret(__syslib->clock_gettime(CLOCK_REALTIME, &ts));
|
||||
ad.dx = 0;
|
||||
if (!ad.ax && tv) {
|
||||
*tv = timespec_totimeval(ts);
|
||||
}
|
||||
return ad;
|
||||
}
|
|
@ -82,8 +82,15 @@ gettimeofday_f *__gettimeofday_get(bool *opt_out_isfast) {
|
|||
isfast = true;
|
||||
res = sys_gettimeofday_nt;
|
||||
} else if (IsXnu()) {
|
||||
isfast = false;
|
||||
#ifdef __x86_64__
|
||||
res = sys_gettimeofday_xnu;
|
||||
isfast = false;
|
||||
#elif defined(__aarch64__)
|
||||
res = sys_gettimeofday_m1;
|
||||
isfast = true;
|
||||
#else
|
||||
#error "unsupported architecture"
|
||||
#endif
|
||||
} else if (IsMetal()) {
|
||||
isfast = false;
|
||||
res = sys_gettimeofday_metal;
|
||||
|
|
|
@ -20,33 +20,32 @@
|
|||
#include "libc/calls/struct/timespec.internal.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/calls/struct/timeval.internal.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/runtime/syslib.internal.h"
|
||||
#include "libc/sock/internal.h"
|
||||
|
||||
// nanosleep() on xnu: a bloodbath of a polyfill
|
||||
// consider using clock_nanosleep(TIMER_ABSTIME)
|
||||
int sys_nanosleep_xnu(const struct timespec *req, struct timespec *rem) {
|
||||
#ifdef __x86_64__
|
||||
int rc;
|
||||
struct timeval wt, t1, t2, td;
|
||||
if (rem) sys_gettimeofday_xnu(&t1, 0, 0);
|
||||
wt = timespec_totimeval(*req); // rounds up
|
||||
rc = sys_select(0, 0, 0, 0, &wt);
|
||||
if (rem) {
|
||||
if (!rc) {
|
||||
if (rem && rc == -1 && errno == EINTR) {
|
||||
sys_gettimeofday_xnu(&t2, 0, 0);
|
||||
td = timeval_sub(t2, t1);
|
||||
if (timeval_cmp(td, wt) >= 0) {
|
||||
rem->tv_sec = 0;
|
||||
rem->tv_nsec = 0;
|
||||
} else if (rc == -1 && errno == EINTR) {
|
||||
// xnu select() doesn't modify timeout
|
||||
// so we need, yet another system call
|
||||
sys_gettimeofday_xnu(&t2, 0, 0);
|
||||
td = timeval_sub(t2, t1);
|
||||
if (timeval_cmp(td, wt) >= 0) {
|
||||
rem->tv_sec = 0;
|
||||
rem->tv_nsec = 0;
|
||||
} else {
|
||||
*rem = timeval_totimespec(timeval_sub(wt, td));
|
||||
}
|
||||
} else {
|
||||
*rem = timeval_totimespec(timeval_sub(wt, td));
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
#else
|
||||
return _sysret(__syslib->nanosleep(req, rem));
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ int __utimens(int, const char *, const struct timespec[2], int) _Hide;
|
|||
int sys_clock_getres(int, struct timespec *) _Hide;
|
||||
int sys_clock_gettime(int, struct timespec *) _Hide;
|
||||
int sys_clock_gettime_nt(int, struct timespec *) _Hide;
|
||||
int sys_clock_gettime_m1(int, struct timespec *) _Hide;
|
||||
int sys_clock_gettime_xnu(int, struct timespec *) _Hide;
|
||||
int sys_clock_nanosleep_nt(int, int, const struct timespec *, struct timespec *) _Hide;
|
||||
int sys_clock_nanosleep_openbsd(int, int, const struct timespec *, struct timespec *) _Hide;
|
||||
|
|
|
@ -9,6 +9,7 @@ axdx_t sys_gettimeofday(struct timeval *, struct timezone *, void *) _Hide;
|
|||
int sys_futimes(int, const struct timeval *) _Hide;
|
||||
int sys_lutimes(const char *, const struct timeval *) _Hide;
|
||||
int sys_utimes(const char *, const struct timeval *) _Hide;
|
||||
axdx_t sys_gettimeofday_m1(struct timeval *, struct timezone *, void *) _Hide;
|
||||
axdx_t sys_gettimeofday_xnu(struct timeval *, struct timezone *, void *) _Hide;
|
||||
axdx_t sys_gettimeofday_nt(struct timeval *, struct timezone *, void *) _Hide;
|
||||
int sys_utimes_nt(const char *, const struct timeval[2]) _Hide;
|
||||
|
|
|
@ -66,6 +66,12 @@
|
|||
#define IsAsan() 0
|
||||
#endif
|
||||
|
||||
#ifdef __aarch64__
|
||||
#define IsXnuSilicon() IsXnu()
|
||||
#else
|
||||
#define IsXnuSilicon() 0
|
||||
#endif
|
||||
|
||||
#if defined(__PIE__) || defined(__PIC__)
|
||||
#define IsPositionIndependent() 1
|
||||
#else
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/symbols.internal.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#include "libc/thread/tls.h"
|
||||
|
||||
relegated void __assert_fail(const char *expr, const char *file, int line) {
|
||||
int me, owner;
|
||||
|
@ -37,7 +38,7 @@ relegated void __assert_fail(const char *expr, const char *file, int line) {
|
|||
strace_enabled(-1);
|
||||
ftrace_enabled(-1);
|
||||
owner = 0;
|
||||
me = sys_gettid();
|
||||
me = __tls_enabled ? __get_tls()->tib_tid : sys_gettid();
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
|
||||
kprintf("%s:%d: assert(%s) failed (tid %d) %m\n", file, line, expr, me);
|
||||
if (__vforked ||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "libc/intrin/asmflag.h"
|
||||
#include "libc/nt/thread.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/syslib.internal.h"
|
||||
#include "libc/sysv/consts/nr.h"
|
||||
#include "libc/thread/tls.h"
|
||||
|
||||
|
@ -74,13 +75,16 @@ privileged wontreturn void _Exit1(int rc) {
|
|||
}
|
||||
notpossible;
|
||||
#elif defined(__aarch64__)
|
||||
register long r0 asm("x0") = rc;
|
||||
asm volatile("mov\tx8,%0\n\t"
|
||||
"mov\tx16,%1\n\t"
|
||||
"svc\t0"
|
||||
: /* no outputs */
|
||||
: "i"(93), "i"(0x169), "r"(r0)
|
||||
: "x8", "memory");
|
||||
if (IsLinux()) {
|
||||
register long r0 asm("x0") = rc;
|
||||
asm volatile("mov\tx8,%0\n\t"
|
||||
"svc\t0"
|
||||
: /* no outputs */
|
||||
: "i"(93), "r"(r0)
|
||||
: "x8", "memory");
|
||||
} else if (IsXnu()) {
|
||||
__syslib->pthread_exit(0);
|
||||
}
|
||||
notpossible;
|
||||
#else
|
||||
#error "arch unsupported"
|
||||
|
|
|
@ -227,8 +227,8 @@ privileged dontinline void klog(const char *b, size_t n) {
|
|||
register long r0 asm("x0") = (long)2;
|
||||
register long r1 asm("x1") = (long)b;
|
||||
register long r2 asm("x2") = (long)n;
|
||||
register long r8 asm("x8") = (long)__NR_write & 0x7ff;
|
||||
register long r16 asm("x16") = (long)__NR_write & 0x7ff;
|
||||
register long r8 asm("x8") = (long)__NR_write;
|
||||
register long r16 asm("x16") = (long)__NR_write;
|
||||
register long res_x0 asm("x0");
|
||||
asm volatile("svc\t0"
|
||||
: "=r"(res_x0)
|
||||
|
|
|
@ -90,13 +90,18 @@ sched_yield:
|
|||
|
||||
#elif defined(__aarch64__)
|
||||
|
||||
mov x0,#0
|
||||
mov x1,#0
|
||||
mov x2,#0
|
||||
mov x3,#0
|
||||
mov x8,#0x7c // sched_yield() for linux
|
||||
mov x16,#0x85d // select(0,0,0,0) for xnu
|
||||
stp x29,x30,[sp,-32]!
|
||||
mov x29,sp
|
||||
mov x3,0
|
||||
mov x2,0
|
||||
add x4,sp,16
|
||||
mov x1,0
|
||||
mov w0,0
|
||||
stp xzr,xzr,[sp,16]
|
||||
mov x8,#0x7c // sched_yield() for gnu/systemd
|
||||
mov x16,#0x5d // select(0,0,0,0,&blah) for xnu
|
||||
svc 0
|
||||
ldp x29,x30,[sp],32
|
||||
ret
|
||||
|
||||
#else
|
||||
|
|
|
@ -63,14 +63,15 @@ privileged int sys_gettid(void) {
|
|||
}
|
||||
return tid;
|
||||
#elif defined(__aarch64__)
|
||||
register long res_x0 asm("x0");
|
||||
// this can't be used on xnu
|
||||
if (!IsLinux()) notpossible;
|
||||
register long res asm("x0");
|
||||
asm volatile("mov\tx8,%1\n\t"
|
||||
"mov\tx16,%2\n\t"
|
||||
"svc\t0"
|
||||
: "=r"(res_x0)
|
||||
: "i"(178), "i"(186)
|
||||
: "=r"(res)
|
||||
: "i"(178)
|
||||
: "x8", "memory");
|
||||
return res_x0;
|
||||
return res;
|
||||
#else
|
||||
#error "arch unsupported"
|
||||
#endif
|
||||
|
|
|
@ -45,7 +45,7 @@ relegated wontreturn void __die(void) {
|
|||
int me, owner;
|
||||
static atomic_int once;
|
||||
owner = 0;
|
||||
me = sys_gettid();
|
||||
me = __tls_enabled ? __get_tls()->tib_tid : sys_gettid();
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
|
||||
if (__vforked ||
|
||||
atomic_compare_exchange_strong_explicit(
|
||||
|
|
|
@ -270,7 +270,7 @@ static wontreturn relegated noinstrument void __minicrash(int sig,
|
|||
"\n",
|
||||
kind, sig, __argv[0], ctx ? ctx->uc_mcontext.rip : 0,
|
||||
ctx ? ctx->uc_mcontext.rsp : 0, ctx ? ctx->uc_mcontext.rbp : 0, __pid,
|
||||
sys_gettid());
|
||||
__tls_enabled ? __get_tls()->tib_tid : sys_gettid());
|
||||
_Exitr(119);
|
||||
}
|
||||
|
||||
|
@ -302,7 +302,7 @@ relegated void __oncrash_amd64(int sig, struct siginfo *si, void *arg) {
|
|||
ftrace_enabled(-1);
|
||||
strace_enabled(-1);
|
||||
owner = 0;
|
||||
me = sys_gettid();
|
||||
me = __tls_enabled ? __get_tls()->tib_tid : sys_gettid();
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
|
||||
if (atomic_compare_exchange_strong_explicit(
|
||||
&once, &owner, me, memory_order_relaxed, memory_order_relaxed)) {
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/atomic.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
@ -53,6 +52,9 @@
|
|||
#include "libc/thread/tls2.h"
|
||||
#include "libc/thread/xnu.internal.h"
|
||||
|
||||
#define kMaxThreadIds 32768
|
||||
#define kMinThreadId 262144
|
||||
|
||||
#define __NR_thr_new 455
|
||||
#define __NR_clone_linux 56
|
||||
#define __NR__lwp_create 309
|
||||
|
@ -64,8 +66,11 @@
|
|||
#define LWP_SUSPENDED 0x00000080
|
||||
|
||||
struct CloneArgs {
|
||||
union {
|
||||
int tid;
|
||||
_Alignas(16) union {
|
||||
struct {
|
||||
int tid;
|
||||
int this;
|
||||
};
|
||||
uint32_t utid;
|
||||
int64_t tid64;
|
||||
};
|
||||
|
@ -77,6 +82,12 @@ struct CloneArgs {
|
|||
void *arg;
|
||||
};
|
||||
|
||||
static struct CloneArgs *AllocateCloneArgs(char *stk, size_t stksz) {
|
||||
return (struct CloneArgs *)(((uintptr_t)(stk + stksz) -
|
||||
sizeof(struct CloneArgs)) &
|
||||
-16);
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -108,7 +119,7 @@ WinThreadEntry(int rdi, // rcx
|
|||
int rc;
|
||||
if (wt->tls) __set_tls_win32(wt->tls);
|
||||
*wt->ctid = wt->tid;
|
||||
rc = WinThreadLaunch(wt->arg, wt->tid, wt->func, (intptr_t)wt & -16);
|
||||
rc = WinThreadLaunch(wt->arg, wt->tid, wt->func, (intptr_t)wt);
|
||||
// we can now clear ctid directly since we're no longer using our own
|
||||
// stack memory, which can now be safely free'd by the parent thread.
|
||||
*wt->ztid = 0;
|
||||
|
@ -124,9 +135,7 @@ static textwindows errno_t CloneWindows(int (*func)(void *, int), char *stk,
|
|||
void *tls, int *ptid, int *ctid) {
|
||||
int64_t h;
|
||||
struct CloneArgs *wt;
|
||||
wt = (struct CloneArgs *)(((intptr_t)(stk + stksz) -
|
||||
sizeof(struct CloneArgs)) &
|
||||
-alignof(struct CloneArgs));
|
||||
wt = AllocateCloneArgs(stk, stksz);
|
||||
wt->ctid = flags & CLONE_CHILD_SETTID ? ctid : &wt->tid;
|
||||
wt->ztid = flags & CLONE_CHILD_CLEARTID ? ctid : &wt->tid;
|
||||
wt->func = func;
|
||||
|
@ -155,7 +164,6 @@ void XnuThreadThunk(void *pthread, // rdi x0
|
|||
asm("XnuThreadThunk:\n\t"
|
||||
"xor\t%ebp,%ebp\n\t"
|
||||
"mov\t%r8,%rsp\n\t"
|
||||
"and\t$-16,%rsp\n\t"
|
||||
"push\t%rax\n\t"
|
||||
"jmp\tXnuThreadMain\n\t"
|
||||
".size\tXnuThreadThunk,.-XnuThreadThunk");
|
||||
|
@ -209,9 +217,7 @@ static errno_t CloneXnu(int (*fn)(void *), char *stk, size_t stksz, int flags,
|
|||
_npassert(sys_bsdthread_register(XnuThreadThunk, 0, 0, 0, 0, 0, 0) != -1);
|
||||
once = true;
|
||||
}
|
||||
wt = (struct CloneArgs *)(((intptr_t)(stk + stksz) -
|
||||
sizeof(struct CloneArgs)) &
|
||||
-alignof(struct CloneArgs));
|
||||
wt = AllocateCloneArgs(stk, stksz);
|
||||
wt->ptid = flags & CLONE_PARENT_SETTID ? ptid : &wt->tid;
|
||||
wt->ctid = flags & CLONE_CHILD_SETTID ? ctid : &wt->tid;
|
||||
wt->ztid = flags & CLONE_CHILD_CLEARTID ? ctid : &wt->tid;
|
||||
|
@ -248,9 +254,7 @@ static errno_t CloneFreebsd(int (*func)(void *, int), char *stk, size_t stksz,
|
|||
bool failed;
|
||||
int64_t tid;
|
||||
struct CloneArgs *wt;
|
||||
wt = (struct CloneArgs *)(((intptr_t)(stk + stksz) -
|
||||
sizeof(struct CloneArgs)) &
|
||||
-alignof(struct CloneArgs));
|
||||
wt = AllocateCloneArgs(stk, stksz);
|
||||
wt->ctid = flags & CLONE_CHILD_SETTID ? ctid : &wt->tid;
|
||||
wt->ztid = flags & CLONE_CHILD_CLEARTID ? ctid : &wt->tid;
|
||||
wt->tls = tls;
|
||||
|
@ -260,7 +264,7 @@ static errno_t CloneFreebsd(int (*func)(void *, int), char *stk, size_t stksz,
|
|||
.start_func = FreebsdThreadMain,
|
||||
.arg = wt,
|
||||
.stack_base = stk,
|
||||
.stack_size = (((intptr_t)wt - (intptr_t)stk) & -16) - 8,
|
||||
.stack_size = (uintptr_t)wt - (uintptr_t)stk,
|
||||
.tls_base = flags & CLONE_SETTLS ? tls : 0,
|
||||
.tls_size = 64,
|
||||
.child_tid = &wt->tid64,
|
||||
|
@ -346,8 +350,7 @@ static wontreturn void NetbsdThreadMain(void *arg, // rdi
|
|||
// we no longer use the stack after this point
|
||||
// %eax = int __lwp_exit(void);
|
||||
asm volatile("movl\t$0,%2\n\t" // *wt->ztid = 0
|
||||
"syscall\n\t" // __lwp_exit()
|
||||
"ud2"
|
||||
"syscall" // __lwp_exit()
|
||||
: "=a"(ax), "=d"(dx), "=m"(*ztid)
|
||||
: "0"(310)
|
||||
: "rcx", "r11", "memory");
|
||||
|
@ -440,20 +443,18 @@ static int CloneNetbsd(int (*func)(void *, int), char *stk, size_t stksz,
|
|||
static void *SiliconThreadMain(void *arg) {
|
||||
register struct CloneArgs *wt asm("x21") = arg;
|
||||
asm volatile("ldr\tx28,%0" : /* no outputs */ : "m"(wt->tls));
|
||||
int tid = sys_gettid();
|
||||
*wt->ctid = tid;
|
||||
*wt->ptid = tid;
|
||||
*wt->ctid = wt->this;
|
||||
register long x0 asm("x0") = (long)wt->arg;
|
||||
register long x1 asm("x1") = (long)tid;
|
||||
register long x1 asm("x1") = (long)wt->tid;
|
||||
asm volatile("mov\tx19,x29\n\t" // save frame pointer
|
||||
"mov\tx20,sp\n\t" // save stack pointer
|
||||
"mov\tx29,#0\n\t" // reset backtrace
|
||||
"mov\tsp,x21\n\t" // switch stack
|
||||
"mov\tsp,%3\n\t" // switch stack
|
||||
"blr\t%2\n\t" // wt->func(wt->arg, tid)
|
||||
"mov\tx29,x19\n\t" // restore frame pointer
|
||||
"mov\tsp,x20" // restore stack pointer
|
||||
: "+r"(x0)
|
||||
: "r"(x1), "r"(wt->func)
|
||||
: "r"(x1), "r"(wt->func), "r"(wt)
|
||||
: "x19", "x20", "memory");
|
||||
*wt->ztid = 0;
|
||||
return 0;
|
||||
|
@ -462,18 +463,24 @@ static void *SiliconThreadMain(void *arg) {
|
|||
static errno_t CloneSilicon(int (*fn)(void *, int), char *stk, size_t stksz,
|
||||
int flags, void *arg, void *tls, int *ptid,
|
||||
int *ctid) {
|
||||
errno_t res;
|
||||
unsigned tid;
|
||||
pthread_t th;
|
||||
struct CloneArgs *wt;
|
||||
wt = (struct CloneArgs *)(((intptr_t)(stk + stksz) -
|
||||
sizeof(struct CloneArgs)) &
|
||||
-MAX(16, alignof(struct CloneArgs)));
|
||||
static atomic_uint tids;
|
||||
wt = AllocateCloneArgs(stk, stksz);
|
||||
tid = atomic_fetch_add_explicit(&tids, 1, memory_order_acq_rel);
|
||||
wt->this = tid = (tid & (kMaxThreadIds - 1)) + kMinThreadId;
|
||||
wt->ctid = flags & CLONE_CHILD_SETTID ? ctid : &wt->tid;
|
||||
wt->ptid = flags & CLONE_PARENT_SETTID ? ptid : &wt->tid;
|
||||
wt->ztid = flags & CLONE_CHILD_CLEARTID ? ctid : &wt->tid;
|
||||
wt->tls = flags & CLONE_SETTLS ? tls : 0;
|
||||
wt->func = fn;
|
||||
wt->arg = arg;
|
||||
return __syslib->pthread_create(&th, 0, SiliconThreadMain, wt);
|
||||
if (!(res = __syslib->pthread_create(&th, 0, SiliconThreadMain, wt)) &&
|
||||
(flags & CLONE_PARENT_SETTID)) {
|
||||
*ptid = tid;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* __aarch64__ */
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/syscall-sysv.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
|
@ -27,11 +28,16 @@
|
|||
#include "libc/runtime/stack.h"
|
||||
#include "libc/runtime/syslib.internal.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#include "libc/thread/tls.h"
|
||||
#ifndef __x86_64__
|
||||
|
||||
void __wipe(uintptr_t);
|
||||
/**
|
||||
* @fileoverview Cosmopolitan C Runtime, Second Edition
|
||||
*/
|
||||
|
||||
void __wipe(uintptr_t) _Hide;
|
||||
int main(int, char **, char **) __attribute__((__weak__));
|
||||
|
||||
typedef int init_f(int argc, char **argv, char **envp, unsigned long *auxv);
|
||||
|
@ -75,12 +81,14 @@ textstartup void cosmo(long *sp, struct Syslib *m1) {
|
|||
while (*auxv++) donothing;
|
||||
|
||||
// detect apple m1 environment
|
||||
if ((__syslib = m1)) {
|
||||
if (SupportsXnu() && (__syslib = m1)) {
|
||||
hostos = _HOSTXNU;
|
||||
magnums = syscon_xnu;
|
||||
} else {
|
||||
} else if (SupportsLinux()) {
|
||||
hostos = _HOSTLINUX;
|
||||
magnums = syscon_linux;
|
||||
} else {
|
||||
notpossible;
|
||||
}
|
||||
|
||||
// setup system magic numbers
|
||||
|
@ -88,6 +96,18 @@ textstartup void cosmo(long *sp, struct Syslib *m1) {
|
|||
*mp = *magnums++;
|
||||
}
|
||||
|
||||
// check system call abi compatibility
|
||||
if (SupportsXnu() && __syslib && __syslib->version < SYSLIB_VERSION) {
|
||||
sys_write(2, "need newer ape loader\n", 22);
|
||||
_Exit(127);
|
||||
}
|
||||
|
||||
// disable enosys trapping
|
||||
if (IsBsd()) {
|
||||
void *act[6] = {SIG_IGN};
|
||||
sys_sigaction(SIGSYS, act, 0, 8, 0);
|
||||
}
|
||||
|
||||
// needed by kisdangerous()
|
||||
__oldstack = (intptr_t)sp;
|
||||
__pid = sys_getpid().ax;
|
||||
|
@ -97,7 +117,7 @@ textstartup void cosmo(long *sp, struct Syslib *m1) {
|
|||
_mmi.p = _mmi.s;
|
||||
__mmi_lock_obj._type = PTHREAD_MUTEX_RECURSIVE;
|
||||
|
||||
// record system-provided stack to memory manager
|
||||
// record provided stack to memory manager
|
||||
_mmi.i = 1;
|
||||
_mmi.p->x = (uintptr_t)GetStackAddr() >> 16;
|
||||
_mmi.p->y = (uintptr_t)(GetStackAddr() + (GetStackSize() - FRAMESIZE)) >> 16;
|
||||
|
@ -106,6 +126,7 @@ textstartup void cosmo(long *sp, struct Syslib *m1) {
|
|||
|
||||
#if 0
|
||||
#if IsAsan()
|
||||
// TODO(jart): Figure out ASAN data model on AARCH64.
|
||||
__asan_init(argc, argv, envp, auxv);
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -66,5 +66,5 @@ void __enable_threads(void) {
|
|||
STRACE("__enable_threads()");
|
||||
FixupLockNops();
|
||||
#endif
|
||||
__threaded = sys_gettid();
|
||||
__threaded = __tls_enabled ? __get_tls()->tib_tid : sys_gettid();
|
||||
}
|
||||
|
|
|
@ -190,7 +190,7 @@ textstartup void __enable_tls(void) {
|
|||
tib->tib_strace = __strace;
|
||||
tib->tib_ftrace = __ftrace;
|
||||
tib->tib_pthread = (pthread_t)&_pthread_main;
|
||||
if (IsLinux()) {
|
||||
if (IsLinux() || IsXnuSilicon()) {
|
||||
// gnu/systemd guarantees pid==tid for the main thread so we can
|
||||
// avoid issuing a superfluous system call at startup in program
|
||||
tid = __pid;
|
||||
|
|
|
@ -39,28 +39,29 @@ int sys_fork(void) {
|
|||
|
||||
#elif defined(__aarch64__)
|
||||
|
||||
int flags = 17; // SIGCHLD
|
||||
void *child_stack = 0;
|
||||
void *parent_tidptr = 0;
|
||||
void *newtls = 0;
|
||||
void *child_tidptr = 0;
|
||||
register long r0 asm("x0") = (long)flags;
|
||||
register long r1 asm("x1") = (long)child_stack;
|
||||
register long r2 asm("x2") = (long)parent_tidptr;
|
||||
register long r3 asm("x3") = (long)newtls;
|
||||
register long r4 asm("x4") = (long)child_tidptr;
|
||||
register int res_x0 asm("x0");
|
||||
register int res_x1 asm("x1");
|
||||
asm volatile("mov\tx8,%2\n\t"
|
||||
"mov\tx16,%3\n\t"
|
||||
"svc\t0"
|
||||
: "=r"(res_x0), "=r"(res_x1)
|
||||
: "i"(220), "i"(2), "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4)
|
||||
: "x8", "x16", "memory");
|
||||
if (IsXnu() && res_x0 != -1) {
|
||||
res_x0 &= res_x1 - 1;
|
||||
if (IsLinux()) {
|
||||
int flags = 17; // SIGCHLD
|
||||
void *child_stack = 0;
|
||||
void *parent_tidptr = 0;
|
||||
void *newtls = 0;
|
||||
void *child_tidptr = 0;
|
||||
register long r0 asm("x0") = (long)flags;
|
||||
register long r1 asm("x1") = (long)child_stack;
|
||||
register long r2 asm("x2") = (long)parent_tidptr;
|
||||
register long r3 asm("x3") = (long)newtls;
|
||||
register long r4 asm("x4") = (long)child_tidptr;
|
||||
register int res_x0 asm("x0");
|
||||
asm volatile("mov\tx8,%1\n\t"
|
||||
"svc\t0"
|
||||
: "=r"(res_x0)
|
||||
: "i"(220), "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4)
|
||||
: "x8", "x16", "memory");
|
||||
return _sysret(res_x0);
|
||||
} else if (__syslib) {
|
||||
return _sysret(__syslib->fork());
|
||||
} else {
|
||||
return enosys();
|
||||
}
|
||||
return _sysret(res_x0);
|
||||
|
||||
#else
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ int _fork(uint32_t dwCreationFlags) {
|
|||
__pid = dx;
|
||||
if (__tls_enabled) {
|
||||
tib = __get_tls();
|
||||
tid = IsLinux() ? dx : sys_gettid();
|
||||
tid = IsLinux() || IsXnuSilicon() ? dx : sys_gettid();
|
||||
atomic_store_explicit(&tib->tib_tid, tid, memory_order_relaxed);
|
||||
if ((pt = (struct PosixThread *)tib->tib_pthread)) {
|
||||
atomic_store_explicit(&pt->ptid, tid, memory_order_relaxed);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_RUNTIME_SYSLIB_H_
|
||||
#define COSMOPOLITAN_LIBC_RUNTIME_SYSLIB_H_
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
|
@ -8,43 +7,41 @@
|
|||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
/**
|
||||
* @fileoverview System DSO interfaces provided by APE loader.
|
||||
*
|
||||
* These functions are owned by the platform C library. Regardless of
|
||||
* platform, POSIX APIs returning `long` will follow the Linux Kernel
|
||||
* `-errno` convention, and hence should be wrapped with `_sysret()`.
|
||||
*/
|
||||
|
||||
#define SYSLIB_MAGIC ('s' | 'l' << 8 | 'i' << 16 | 'b' << 24)
|
||||
#define SYSLIB_VERSION 0
|
||||
#define SYSLIB_VERSION 1
|
||||
|
||||
typedef uint64_t dispatch_time_t;
|
||||
typedef uint64_t dispatch_semaphore_t;
|
||||
|
||||
struct Syslib {
|
||||
int magic;
|
||||
int version;
|
||||
void (*exit)(int) wontreturn;
|
||||
long (*fork)(void);
|
||||
long (*read)(int, void *, size_t);
|
||||
long (*pread)(int, void *, size_t, int64_t);
|
||||
long (*readv)(int, const struct iovec *, int);
|
||||
long (*write)(int, const void *, size_t);
|
||||
long (*pwrite)(int, const void *, size_t, int64_t);
|
||||
long (*writev)(int, const struct iovec *, int);
|
||||
long (*openat)(int, const char *, int, ...);
|
||||
long (*pipe)(int[2]);
|
||||
long (*close)(int);
|
||||
long (*clock_gettime)(int, struct timespec *);
|
||||
long (*nanosleep)(const struct timespec *, struct timespec *);
|
||||
long (*mmap)(void *, size_t, int, int, int, int64_t);
|
||||
long (*sigaction)(int, const struct sigaction *restrict,
|
||||
struct sigaction *restrict);
|
||||
int (*pthread_jit_write_protect_supported_np)(void);
|
||||
void (*pthread_jit_write_protect_np)(int);
|
||||
void (*sys_icache_invalidate)(void *, size_t);
|
||||
pthread_t (*pthread_self)(void);
|
||||
int (*pthread_create)(pthread_t *, const pthread_attr_t *, void *(*)(void *),
|
||||
void *);
|
||||
int (*pthread_detach)(pthread_t);
|
||||
int (*pthread_join)(pthread_t, void **);
|
||||
void (*pthread_exit)(void *);
|
||||
int (*pthread_kill)(pthread_t, int);
|
||||
int (*pthread_sigmask)(int, const sigset_t *restrict, sigset_t *restrict);
|
||||
int (*pthread_setname_np)(const char *);
|
||||
int (*pthread_key_create)(pthread_key_t *, void (*)(void *));
|
||||
int (*pthread_setspecific)(pthread_key_t, const void *);
|
||||
void *(*pthread_getspecific)(pthread_key_t);
|
||||
dispatch_semaphore_t (*dispatch_semaphore_create)(long);
|
||||
long (*dispatch_semaphore_signal)(dispatch_semaphore_t);
|
||||
long (*dispatch_semaphore_wait)(dispatch_semaphore_t, dispatch_time_t);
|
||||
dispatch_time_t (*dispatch_walltime)(const struct timespec *, int64_t);
|
||||
};
|
||||
|
||||
extern struct Syslib *__syslib;
|
||||
|
|
4166
libc/sysv/consts.sh
4166
libc/sysv/consts.sh
File diff suppressed because it is too large
Load diff
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon misc,ABORTED_COMMAND,11,11,0,0,0,0,0
|
||||
.syscon misc,ABORTED_COMMAND,11,11,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon misc,ACCT_BYTEORDER,0,0,0,0,0,0,0
|
||||
.syscon misc,ACCT_BYTEORDER,0,0,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon misc,ACCT_COMM,0x10,0x10,0,0,0,0,0
|
||||
.syscon misc,ACCT_COMM,0x10,0x10,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon misc,ACK,4,4,4,4,4,4,0
|
||||
.syscon misc,ACK,4,4,4,4,4,4,4,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon misc,ACORE,0,0,8,8,8,8,0
|
||||
.syscon misc,ACORE,0,0,8,8,8,8,8,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon misc,AFORK,0,0,1,1,1,1,0
|
||||
.syscon misc,AFORK,0,0,1,1,1,1,1,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_ALG,38,38,0,0,0,0,0
|
||||
.syscon af,AF_ALG,38,38,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_APPLETALK,5,5,0x10,0x10,0x10,0x10,0x10
|
||||
.syscon af,AF_APPLETALK,5,5,0x10,0x10,0x10,0x10,0x10,0x10
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_ASH,18,18,0,0,0,0,0
|
||||
.syscon af,AF_ASH,18,18,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_ATMPVC,8,8,0,0,0,0,0
|
||||
.syscon af,AF_ATMPVC,8,8,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_ATMSVC,20,20,0,0,0,0,0
|
||||
.syscon af,AF_ATMSVC,20,20,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_AX25,3,3,0,0,0,0,0
|
||||
.syscon af,AF_AX25,3,3,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_BLUETOOTH,31,31,0,36,0x20,31,0
|
||||
.syscon af,AF_BLUETOOTH,31,31,0,0,36,0x20,31,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_BRIDGE,7,7,0,0,0,0,0
|
||||
.syscon af,AF_BRIDGE,7,7,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_CAIF,37,37,0,0,0,0,0
|
||||
.syscon af,AF_CAIF,37,37,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_CAN,29,29,0,0,0,35,0
|
||||
.syscon af,AF_CAN,29,29,0,0,0,0,35,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_ECONET,19,19,0,0,0,0,0
|
||||
.syscon af,AF_ECONET,19,19,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_FILE,1,1,0,0,0,0,0
|
||||
.syscon af,AF_FILE,1,1,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_IB,27,27,0,0,0,0,0
|
||||
.syscon af,AF_IB,27,27,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_IEEE802154,36,36,0,0,0,0,0
|
||||
.syscon af,AF_IEEE802154,36,36,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_INET,2,2,2,2,2,2,2
|
||||
.syscon af,AF_INET,2,2,2,2,2,2,2,2
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_INET6,10,10,30,28,24,24,23
|
||||
.syscon af,AF_INET6,10,10,30,30,28,24,24,23
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_IPX,4,4,23,23,23,23,6
|
||||
.syscon af,AF_IPX,4,4,23,23,23,23,23,6
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_IRDA,23,23,0,0,0,0,0
|
||||
.syscon af,AF_IRDA,23,23,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_ISDN,34,34,28,26,26,26,0
|
||||
.syscon af,AF_ISDN,34,34,28,28,26,26,26,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_IUCV,0x20,0x20,0,0,0,0,0
|
||||
.syscon af,AF_IUCV,0x20,0x20,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_KCM,41,41,0,0,0,0,0
|
||||
.syscon af,AF_KCM,41,41,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_KEY,15,15,0,0,30,0,0
|
||||
.syscon af,AF_KEY,15,15,0,0,0,30,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_LINK,0,0,18,18,18,18,0
|
||||
.syscon af,AF_LINK,0,0,18,18,18,18,18,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_LLC,26,26,0,0,0,0,0
|
||||
.syscon af,AF_LLC,26,26,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_LOCAL,1,1,1,1,1,1,1
|
||||
.syscon af,AF_LOCAL,1,1,1,1,1,1,1,1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_MAX,42,42,40,42,36,37,35
|
||||
.syscon af,AF_MAX,42,42,40,40,42,36,37,35
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_MPLS,28,28,0,0,33,33,0
|
||||
.syscon af,AF_MPLS,28,28,0,0,0,33,33,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_NETBEUI,13,13,0,0,0,0,0
|
||||
.syscon af,AF_NETBEUI,13,13,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_NETLINK,16,16,0,0,0,0,0
|
||||
.syscon af,AF_NETLINK,16,16,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_NETROM,6,6,0,0,0,0,0
|
||||
.syscon af,AF_NETROM,6,6,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_NFC,39,39,0,0,0,0,0
|
||||
.syscon af,AF_NFC,39,39,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_PACKET,17,17,0,0,0,0,0
|
||||
.syscon af,AF_PACKET,17,17,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_PHONET,35,35,0,0,0,0,0
|
||||
.syscon af,AF_PHONET,35,35,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_PPPOX,24,24,0,0,0,0,0
|
||||
.syscon af,AF_PPPOX,24,24,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_RDS,21,21,0,0,0,0,0
|
||||
.syscon af,AF_RDS,21,21,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_ROSE,11,11,0,0,0,0,0
|
||||
.syscon af,AF_ROSE,11,11,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_ROUTE,16,16,17,17,17,34,0
|
||||
.syscon af,AF_ROUTE,16,16,17,17,17,17,34,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_RXRPC,33,33,0,0,0,0,0
|
||||
.syscon af,AF_RXRPC,33,33,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_SECURITY,14,14,0,0,0,0,0
|
||||
.syscon af,AF_SECURITY,14,14,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_SNA,22,22,11,11,11,11,11
|
||||
.syscon af,AF_SNA,22,22,11,11,11,11,11,11
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_TIPC,30,30,0,0,0,0,0
|
||||
.syscon af,AF_TIPC,30,30,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_UNIX,1,1,1,1,1,1,1
|
||||
.syscon af,AF_UNIX,1,1,1,1,1,1,1,1
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_UNSPEC,0,0,0,0,0,0,0
|
||||
.syscon af,AF_UNSPEC,0,0,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_VSOCK,40,40,0,0,0,0,0
|
||||
.syscon af,AF_VSOCK,40,40,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_WANPIPE,25,25,0,0,0,0,0
|
||||
.syscon af,AF_WANPIPE,25,25,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon af,AF_X25,9,9,0,0,0,0,0
|
||||
.syscon af,AF_X25,9,9,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon misc,AIO_ALLDONE,2,2,1,3,0,0,0
|
||||
.syscon misc,AIO_ALLDONE,2,2,1,1,3,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon misc,AIO_CANCELED,0,0,2,1,0,0,0
|
||||
.syscon misc,AIO_CANCELED,0,0,2,2,1,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon misc,AIO_NOTCANCELED,1,1,4,2,0,0,0
|
||||
.syscon misc,AIO_NOTCANCELED,1,1,4,4,2,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon alg,ALG_SET_AEAD_ASSOCLEN,4,4,0,0,0,0,0
|
||||
.syscon alg,ALG_SET_AEAD_ASSOCLEN,4,4,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon alg,ALG_SET_AEAD_AUTHSIZE,5,5,0,0,0,0,0
|
||||
.syscon alg,ALG_SET_AEAD_AUTHSIZE,5,5,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon alg,ALG_SET_DRBG_ENTROPY,6,6,0,0,0,0,0
|
||||
.syscon alg,ALG_SET_DRBG_ENTROPY,6,6,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon alg,ALG_SET_IV,2,2,0,0,0,0,0
|
||||
.syscon alg,ALG_SET_IV,2,2,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon alg,ALG_SET_KEY,1,1,0,0,0,0,0
|
||||
.syscon alg,ALG_SET_KEY,1,1,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon alg,ALG_SET_OP,3,3,0,0,0,0,0
|
||||
.syscon alg,ALG_SET_OP,3,3,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon misc,AREGTYPE,0,0,0,0,0,0,0
|
||||
.syscon misc,AREGTYPE,0,0,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon auxv,AT_BASE,7,7,7,7,0,7,0
|
||||
.syscon auxv,AT_BASE,7,7,7,7,7,0,7,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon auxv,AT_BASE_PLATFORM,24,24,0,0,0,0,0
|
||||
.syscon auxv,AT_BASE_PLATFORM,24,24,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon auxv,AT_CANARY,0,0,0,16,0,0,0
|
||||
.syscon auxv,AT_CANARY,0,0,0,0,16,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon auxv,AT_CANARYLEN,0,0,0,17,0,0,0
|
||||
.syscon auxv,AT_CANARYLEN,0,0,0,0,17,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon auxv,AT_CLKTCK,17,17,0,0,0,0,0
|
||||
.syscon auxv,AT_CLKTCK,17,17,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon auxv,AT_DCACHEBSIZE,19,19,0,0,0,0,0
|
||||
.syscon auxv,AT_DCACHEBSIZE,19,19,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon at,AT_EACCESS,0x0200,0x0200,0x10,0x0100,1,0x100,0
|
||||
.syscon at,AT_EACCESS,0x0200,0x0200,0x10,0x10,0x0100,1,0x100,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon auxv,AT_EGID,14,14,14,0,0,2002,0
|
||||
.syscon auxv,AT_EGID,14,14,14,14,0,0,2002,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon auxv,AT_EHDRFLAGS,0,0,0,24,0,0,0
|
||||
.syscon auxv,AT_EHDRFLAGS,0,0,0,0,24,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon at,AT_EMPTY_PATH,0x1000,0x1000,0,0,0,0,0
|
||||
.syscon at,AT_EMPTY_PATH,0x1000,0x1000,0,0,0,0,0,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon auxv,AT_ENTRY,9,9,9,9,0,9,0
|
||||
.syscon auxv,AT_ENTRY,9,9,9,9,9,0,9,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon auxv,AT_EUID,12,12,12,0,0,2000,0
|
||||
.syscon auxv,AT_EUID,12,12,12,12,0,0,2000,0
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#include "libc/sysv/consts/syscon.internal.h"
|
||||
.syscon auxv,AT_EXECFD,2,2,0,2,0,2,0
|
||||
.syscon auxv,AT_EXECFD,2,2,0,0,2,0,2,0
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue