mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 03:27:39 +00:00
Incorporate more small improvements
This commit is contained in:
parent
1d4eb08fa1
commit
f83eb440f7
20 changed files with 121 additions and 256 deletions
2
Makefile
2
Makefile
|
@ -269,7 +269,7 @@ CHECKS = $(foreach x,$(PKGS),$($(x)_CHECKS))
|
|||
|
||||
bins: $(BINS)
|
||||
check: $(CHECKS)
|
||||
test: $(TESTS) aarch64
|
||||
test: $(TESTS)
|
||||
depend: o/$(MODE)/depend
|
||||
tags: TAGS HTAGS
|
||||
|
||||
|
|
|
@ -176,7 +176,7 @@ void *Worker(void *id) {
|
|||
// inherited by the accepted sockets, but using them also has the
|
||||
// side-effect that the listening socket fails with EAGAIN, every
|
||||
// several seconds. we can use that to our advantage to check for
|
||||
// the ctrl-c shutdowne event; otherwise, we retry the accept call
|
||||
// the ctrl-c shutdowne event; otherwise we retry the accept call
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -91,6 +91,6 @@ int close(int fd) {
|
|||
__releasefd(fd);
|
||||
}
|
||||
}
|
||||
STRACE("%s(%d) → %d% m", "close", fd, rc);
|
||||
STRACE("close(%d) → %d% m", fd, rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -34,14 +34,6 @@ forceinline bool __isfdkind(int fd, int kind) {
|
|||
return 0 <= fd && fd < g_fds.n && g_fds.p[fd].kind == kind;
|
||||
}
|
||||
|
||||
forceinline size_t _clampio(size_t size) {
|
||||
if (!IsTrustworthy()) {
|
||||
return MIN(size, 0x7ffff000);
|
||||
} else {
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
int sys_close_nt(struct Fd *, int) _Hide;
|
||||
int _check_interrupts(bool, struct Fd *) _Hide;
|
||||
int sys_openat_metal(int, const char *, int, unsigned);
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
/*-*- 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/nt/struct/overlapped.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
textwindows struct NtOverlapped *_offset2overlap(int64_t handle,
|
||||
int64_t opt_offset,
|
||||
struct NtOverlapped *mem) {
|
||||
if (opt_offset == -1) return NULL;
|
||||
bzero(mem, sizeof(struct NtOverlapped));
|
||||
mem->Pointer = (void *)(uintptr_t)opt_offset;
|
||||
return mem;
|
||||
}
|
|
@ -26,6 +26,7 @@
|
|||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/calls/wincrash.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/enum/filetype.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/files.h"
|
||||
|
@ -37,13 +38,10 @@
|
|||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
static textwindows ssize_t sys_read_nt_impl(struct Fd *fd, void *data,
|
||||
size_t size, ssize_t offset) {
|
||||
bool32 ok;
|
||||
int64_t p;
|
||||
uint32_t got, avail;
|
||||
struct NtOverlapped overlap;
|
||||
size_t size, int64_t offset) {
|
||||
|
||||
// our terrible polling mechanism
|
||||
// try to poll rather than block
|
||||
uint32_t avail;
|
||||
if (GetFileType(fd->handle) == kNtFileTypePipe) {
|
||||
for (;;) {
|
||||
if (!PeekNamedPipe(fd->handle, 0, 0, 0, &avail, 0)) break;
|
||||
|
@ -63,19 +61,28 @@ static textwindows ssize_t sys_read_nt_impl(struct Fd *fd, void *data,
|
|||
POLLTRACE("sys_read_nt ready to read");
|
||||
}
|
||||
|
||||
if (offset != -1) {
|
||||
// windows changes the file pointer even if overlapped is passed
|
||||
_npassert(SetFilePointerEx(fd->handle, 0, &p, SEEK_CUR));
|
||||
// perform the read i/o operation
|
||||
bool32 ok;
|
||||
uint32_t got;
|
||||
size = MIN(size, 0x7ffff000);
|
||||
if (offset == -1) {
|
||||
// perform simple blocking read
|
||||
ok = ReadFile(fd->handle, data, size, &got, 0);
|
||||
} else {
|
||||
// perform pread()-style read at particular file offset
|
||||
int64_t position;
|
||||
// save file pointer which windows clobbers, even for overlapped i/o
|
||||
if (!SetFilePointerEx(fd->handle, 0, &position, SEEK_CUR)) {
|
||||
return __winerr(); // fd probably isn't seekable?
|
||||
}
|
||||
struct NtOverlapped overlap = {0};
|
||||
overlap.Pointer = (void *)(uintptr_t)offset;
|
||||
ok = ReadFile(fd->handle, data, size, 0, &overlap);
|
||||
if (!ok && GetLastError() == kNtErrorIoPending) ok = true;
|
||||
if (ok) ok = GetOverlappedResult(fd->handle, &overlap, &got, true);
|
||||
// restore file pointer which windows clobbers, even on error
|
||||
_unassert(SetFilePointerEx(fd->handle, position, 0, SEEK_SET));
|
||||
}
|
||||
|
||||
ok = ReadFile(fd->handle, data, _clampio(size), &got,
|
||||
_offset2overlap(fd->handle, offset, &overlap));
|
||||
|
||||
if (offset != -1) {
|
||||
// windows clobbers file pointer even on error
|
||||
_npassert(SetFilePointerEx(fd->handle, p, 0, SEEK_SET));
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
return got;
|
||||
}
|
||||
|
@ -93,7 +100,7 @@ static textwindows ssize_t sys_read_nt_impl(struct Fd *fd, void *data,
|
|||
}
|
||||
|
||||
textwindows ssize_t sys_read_nt(struct Fd *fd, const struct iovec *iov,
|
||||
size_t iovlen, ssize_t opt_offset) {
|
||||
size_t iovlen, int64_t opt_offset) {
|
||||
ssize_t rc;
|
||||
uint32_t size;
|
||||
size_t i, total;
|
||||
|
|
|
@ -13,7 +13,7 @@ int64_t sys_vmsplice(int, const struct iovec *, int64_t, uint32_t) _Hide;
|
|||
int64_t sys_writev(int32_t, const struct iovec *, int32_t) _Hide;
|
||||
size_t __iovec_size(const struct iovec *, size_t) _Hide;
|
||||
ssize_t WritevUninterruptible(int, struct iovec *, int);
|
||||
ssize_t sys_read_nt(struct Fd *, const struct iovec *, size_t, ssize_t) _Hide;
|
||||
ssize_t sys_read_nt(struct Fd *, const struct iovec *, size_t, int64_t) _Hide;
|
||||
ssize_t sys_readv_metal(struct Fd *, const struct iovec *, int) _Hide;
|
||||
ssize_t sys_readv_nt(struct Fd *, const struct iovec *, int) _Hide;
|
||||
ssize_t sys_readv_serial(struct Fd *, const struct iovec *, int) _Hide;
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_CALLS_WINCRASH_INTERNAL_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_WINCRASH_INTERNAL_H_
|
||||
#include "libc/nt/struct/ntexceptionpointers.h"
|
||||
#include "libc/nt/struct/overlapped.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
unsigned __wincrash_nt(struct NtExceptionPointers *);
|
||||
struct NtOverlapped *_offset2overlap(int64_t, int64_t,
|
||||
struct NtOverlapped *) _Hide;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -16,20 +16,20 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/sig.internal.h"
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/calls/struct/iovec.internal.h"
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/calls/wincrash.internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/nt/struct/overlapped.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sysv/consts/sicode.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
|
@ -37,26 +37,31 @@
|
|||
|
||||
static textwindows ssize_t sys_write_nt_impl(int fd, void *data, size_t size,
|
||||
ssize_t offset) {
|
||||
|
||||
// perform the write i/o operation
|
||||
bool32 ok;
|
||||
int64_t h, p;
|
||||
uint32_t err, sent;
|
||||
struct NtOverlapped overlap;
|
||||
|
||||
h = g_fds.p[fd].handle;
|
||||
|
||||
if (offset != -1) {
|
||||
// windows changes the file pointer even if overlapped is passed
|
||||
SetFilePointerEx(h, 0, &p, SEEK_CUR);
|
||||
uint32_t sent;
|
||||
int64_t handle;
|
||||
handle = g_fds.p[fd].handle;
|
||||
size = MIN(size, 0x7ffff000);
|
||||
if (offset == -1) {
|
||||
// perform simple blocking write
|
||||
ok = WriteFile(handle, data, size, &sent, 0);
|
||||
} else {
|
||||
// perform pwrite()-style write at particular file offset
|
||||
int64_t position;
|
||||
// save file pointer which windows clobbers, even for overlapped i/o
|
||||
if (!SetFilePointerEx(handle, 0, &position, SEEK_CUR)) {
|
||||
return __winerr(); // fd probably isn't seekable?
|
||||
}
|
||||
struct NtOverlapped overlap = {0};
|
||||
overlap.Pointer = (void *)(uintptr_t)offset;
|
||||
ok = WriteFile(handle, data, size, 0, &overlap);
|
||||
if (!ok && GetLastError() == kNtErrorIoPending) ok = true;
|
||||
if (ok) ok = GetOverlappedResult(handle, &overlap, &sent, true);
|
||||
// restore file pointer which windows clobbers, even on error
|
||||
_unassert(SetFilePointerEx(handle, position, 0, SEEK_SET));
|
||||
}
|
||||
|
||||
ok = WriteFile(h, data, _clampio(size), &sent,
|
||||
_offset2overlap(h, offset, &overlap));
|
||||
|
||||
if (offset != -1) {
|
||||
// windows clobbers file pointer even on error
|
||||
SetFilePointerEx(h, p, 0, SEEK_SET);
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
return sent;
|
||||
}
|
||||
|
@ -86,8 +91,6 @@ textwindows ssize_t sys_write_nt(int fd, const struct iovec *iov, size_t iovlen,
|
|||
ssize_t opt_offset) {
|
||||
ssize_t rc;
|
||||
size_t i, total;
|
||||
uint32_t size, wrote;
|
||||
struct NtOverlapped overlap;
|
||||
if (opt_offset < -1) return einval();
|
||||
while (iovlen && !iov[0].iov_len) iov++, iovlen--;
|
||||
if (iovlen) {
|
||||
|
|
104
libc/errno.h
104
libc/errno.h
|
@ -4,25 +4,35 @@
|
|||
COSMOPOLITAN_C_START_
|
||||
|
||||
/**
|
||||
* @fileoverview System error codes.
|
||||
* @see libc/sysv/consts.sh for numbers
|
||||
* @fileoverview System Five error codes.
|
||||
*
|
||||
* This file defines the `errno` global variable. When system calls
|
||||
* (e.g. read(), write(), etc.) fail they return -1 to indicate the
|
||||
* failure, and that is *the only* error return value. System calls
|
||||
* also update `errno` too whenever -1 is returned (otherwise errno
|
||||
* isn't changed) to be a non-zero value holding one of the numbers
|
||||
* below, in order to indicate why the system call failed.
|
||||
*
|
||||
* There is only one exception to the above rule; some system calls
|
||||
* are documented with the `@returnserrno` tag, which means they'll
|
||||
* return the error number rather than stuffing it in a global. You
|
||||
* can usually spot these system calls easily since most of them'll
|
||||
* have names like `posix_foo()` or `pthread_bar()`.
|
||||
*
|
||||
* @see libc/sysv/consts.sh for assigned numbers
|
||||
* @see libc/sysv/dos2errno.sh for multimapped numbers
|
||||
*/
|
||||
|
||||
#if defined(__GNUC__) && defined(__x86_64__) && defined(__MNO_RED_ZONE__) && \
|
||||
!defined(__STRICT_ANSI__) && !defined(__cplusplus)
|
||||
#define errno \
|
||||
(*({ \
|
||||
errno_t *_ep; \
|
||||
asm("call\t__errno_location" : "=a"(_ep) : /* no inputs */ : "cc"); \
|
||||
_ep; \
|
||||
}))
|
||||
#elif defined(__GNUC__) && defined(__aarch64__) && \
|
||||
!defined(__STRICT_ANSI__) && !defined(__cplusplus)
|
||||
#define errno \
|
||||
(*({ \
|
||||
errno_t *_ep; \
|
||||
asm("sub\t%0,x28,#1092" : "=r"(_ep)); \
|
||||
_ep; \
|
||||
#if defined(__GNUC__) && defined(__aarch64__) && !defined(__STRICT_ANSI__) && \
|
||||
!defined(__cplusplus)
|
||||
/* this header is included by 700+ files; therefore we */
|
||||
/* hand-roll &__get_tls()->tib_errno to avoid #include */
|
||||
/* cosmopolitan uses x28 as the tls register b/c apple */
|
||||
#define errno \
|
||||
(*({ \
|
||||
errno_t *__ep; \
|
||||
asm("sub\t%0,x28,#1092" : "=r"(__ep)); \
|
||||
__ep; \
|
||||
}))
|
||||
#else
|
||||
#define errno (*__errno_location())
|
||||
|
@ -493,7 +503,7 @@ extern const errno_t ENOMEDIUM;
|
|||
extern const errno_t EMEDIUMTYPE;
|
||||
|
||||
/**
|
||||
* Inappropriate file type or format. (BSD only)
|
||||
* Inappropriate file type or format.
|
||||
*/
|
||||
extern const errno_t EFTYPE;
|
||||
|
||||
|
@ -513,7 +523,6 @@ extern const errno_t EPROGUNAVAIL;
|
|||
extern const errno_t EPWROFF;
|
||||
extern const errno_t ERPCMISMATCH;
|
||||
extern const errno_t ESHLIBVERS;
|
||||
|
||||
extern const errno_t EADV;
|
||||
extern const errno_t EBADE;
|
||||
extern const errno_t EBADFD;
|
||||
|
@ -558,35 +567,20 @@ extern const errno_t EXFULL;
|
|||
#define EACCES EACCES
|
||||
#define EADDRINUSE EADDRINUSE
|
||||
#define EADDRNOTAVAIL EADDRNOTAVAIL
|
||||
#define EADV EADV
|
||||
#define EAFNOSUPPORT EAFNOSUPPORT
|
||||
#define EAGAIN EAGAIN
|
||||
#define EALREADY EALREADY
|
||||
#define EAUTH EAUTH
|
||||
#define EBADARCH EBADARCH
|
||||
#define EBADE EBADE
|
||||
#define EBADEXEC EBADEXEC
|
||||
#define EBADF EBADF
|
||||
#define EBADFD EBADFD
|
||||
#define EBADMACHO EBADMACHO
|
||||
#define EBADMSG EBADMSG
|
||||
#define EBADR EBADR
|
||||
#define EBADRPC EBADRPC
|
||||
#define EBADRQC EBADRQC
|
||||
#define EBADSLT EBADSLT
|
||||
#define EBUSY EBUSY
|
||||
#define ECANCELED ECANCELED
|
||||
#define ECHILD ECHILD
|
||||
#define ECHRNG ECHRNG
|
||||
#define ECOMM ECOMM
|
||||
#define ECONNABORTED ECONNABORTED
|
||||
#define ECONNREFUSED ECONNREFUSED
|
||||
#define ECONNRESET ECONNRESET
|
||||
#define EDEADLK EDEADLK
|
||||
#define EDESTADDRREQ EDESTADDRREQ
|
||||
#define EDEVERR EDEVERR
|
||||
#define EDOM EDOM
|
||||
#define EDOTDOT EDOTDOT
|
||||
#define EDQUOT EDQUOT
|
||||
#define EEXIST EEXIST
|
||||
#define EFAULT EFAULT
|
||||
|
@ -594,7 +588,6 @@ extern const errno_t EXFULL;
|
|||
#define EFTYPE EFTYPE
|
||||
#define EHOSTDOWN EHOSTDOWN
|
||||
#define EHOSTUNREACH EHOSTUNREACH
|
||||
#define EHWPOISON EHWPOISON
|
||||
#define EIDRM EIDRM
|
||||
#define EILSEQ EILSEQ
|
||||
#define EINPROGRESS EINPROGRESS
|
||||
|
@ -603,20 +596,6 @@ extern const errno_t EXFULL;
|
|||
#define EIO EIO
|
||||
#define EISCONN EISCONN
|
||||
#define EISDIR EISDIR
|
||||
#define EISNAM EISNAM
|
||||
#define EKEYEXPIRED EKEYEXPIRED
|
||||
#define EKEYREJECTED EKEYREJECTED
|
||||
#define EKEYREVOKED EKEYREVOKED
|
||||
#define EL2HLT EL2HLT
|
||||
#define EL2NSYNC EL2NSYNC
|
||||
#define EL3HLT EL3HLT
|
||||
#define EL3RST EL3RST
|
||||
#define ELIBACC ELIBACC
|
||||
#define ELIBBAD ELIBBAD
|
||||
#define ELIBEXEC ELIBEXEC
|
||||
#define ELIBMAX ELIBMAX
|
||||
#define ELIBSCN ELIBSCN
|
||||
#define ELNRNG ELNRNG
|
||||
#define ELOOP ELOOP
|
||||
#define EMEDIUMTYPE EMEDIUMTYPE
|
||||
#define EMFILE EMFILE
|
||||
|
@ -624,29 +603,21 @@ extern const errno_t EXFULL;
|
|||
#define EMSGSIZE EMSGSIZE
|
||||
#define EMULTIHOP EMULTIHOP
|
||||
#define ENAMETOOLONG ENAMETOOLONG
|
||||
#define ENAVAIL ENAVAIL
|
||||
#define ENEEDAUTH ENEEDAUTH
|
||||
#define ENETDOWN ENETDOWN
|
||||
#define ENETRESET ENETRESET
|
||||
#define ENETUNREACH ENETUNREACH
|
||||
#define ENFILE ENFILE
|
||||
#define ENOANO ENOANO
|
||||
#define ENOATTR ENOATTR
|
||||
#define ENOBUFS ENOBUFS
|
||||
#define ENOCSI ENOCSI
|
||||
#define ENODATA ENODATA
|
||||
#define ENODEV ENODEV
|
||||
#define ENOENT ENOENT
|
||||
#define ENOEXEC ENOEXEC
|
||||
#define ENOKEY ENOKEY
|
||||
#define ENOLCK ENOLCK
|
||||
#define ENOLINK ENOLINK
|
||||
#define ENOMEDIUM ENOMEDIUM
|
||||
#define ENOMEM ENOMEM
|
||||
#define ENOMSG ENOMSG
|
||||
#define ENONET ENONET
|
||||
#define ENOPKG ENOPKG
|
||||
#define ENOPOLICY ENOPOLICY
|
||||
#define ENOPROTOOPT ENOPROTOOPT
|
||||
#define ENOSPC ENOSPC
|
||||
#define ENOSR ENOSR
|
||||
|
@ -656,12 +627,10 @@ extern const errno_t EXFULL;
|
|||
#define ENOTCONN ENOTCONN
|
||||
#define ENOTDIR ENOTDIR
|
||||
#define ENOTEMPTY ENOTEMPTY
|
||||
#define ENOTNAM ENOTNAM
|
||||
#define ENOTRECOVERABLE ENOTRECOVERABLE
|
||||
#define ENOTSOCK ENOTSOCK
|
||||
#define ENOTSUP ENOTSUP
|
||||
#define ENOTTY ENOTTY
|
||||
#define ENOTUNIQ ENOTUNIQ
|
||||
#define ENXIO ENXIO
|
||||
#define EOPNOTSUPP EOPNOTSUPP
|
||||
#define EOVERFLOW EOVERFLOW
|
||||
|
@ -669,43 +638,28 @@ extern const errno_t EXFULL;
|
|||
#define EPERM EPERM
|
||||
#define EPFNOSUPPORT EPFNOSUPPORT
|
||||
#define EPIPE EPIPE
|
||||
#define EPROCLIM EPROCLIM
|
||||
#define EPROCUNAVAIL EPROCUNAVAIL
|
||||
#define EPROGMISMATCH EPROGMISMATCH
|
||||
#define EPROGUNAVAIL EPROGUNAVAIL
|
||||
#define EPROTO EPROTO
|
||||
#define EPROTONOSUPPORT EPROTONOSUPPORT
|
||||
#define EPROTOTYPE EPROTOTYPE
|
||||
#define EPWROFF EPWROFF
|
||||
#define ERANGE ERANGE
|
||||
#define EREMCHG EREMCHG
|
||||
#define EREMOTE EREMOTE
|
||||
#define EREMOTEIO EREMOTEIO
|
||||
#define ERESTART ERESTART
|
||||
#define ERFKILL ERFKILL
|
||||
#define EROFS EROFS
|
||||
#define ERPCMISMATCH ERPCMISMATCH
|
||||
#define ESHLIBVERS ESHLIBVERS
|
||||
#define ESHUTDOWN ESHUTDOWN
|
||||
#define ESOCKTNOSUPPORT ESOCKTNOSUPPORT
|
||||
#define ESPIPE ESPIPE
|
||||
#define ESRCH ESRCH
|
||||
#define ESRMNT ESRMNT
|
||||
#define ESTALE ESTALE
|
||||
#define ESTRPIPE ESTRPIPE
|
||||
#define ETIME ETIME
|
||||
#define ETIMEDOUT ETIMEDOUT
|
||||
#define ETOOMANYREFS ETOOMANYREFS
|
||||
#define ETXTBSY ETXTBSY
|
||||
#define EUCLEAN EUCLEAN
|
||||
#define EUNATCH EUNATCH
|
||||
#define EUSERS EUSERS
|
||||
#define EWOULDBLOCK EAGAIN
|
||||
#define EXDEV EXDEV
|
||||
#define EXFULL EXFULL
|
||||
|
||||
extern errno_t __errno;
|
||||
errno_t *__errno_location(void);
|
||||
errno_t *__errno_location(void) dontthrow pureconst;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -3298,6 +3298,7 @@ imp 'WSCWriteNameSpaceOrder32' WSCWriteNameSpaceOrder32 ws2_32 162
|
|||
imp 'WSCWriteProviderOrder' WSCWriteProviderOrder ws2_32 163
|
||||
imp 'WSCWriteProviderOrder32' WSCWriteProviderOrder32 ws2_32 164
|
||||
imp 'WSCWriteProviderOrderEx' WSCWriteProviderOrderEx ws2_32 165
|
||||
imp '__sys_socket_nt' socket ws2_32 0 3
|
||||
imp '__sys_accept_nt' accept ws2_32 1 3 # we're using WSAAccept()
|
||||
imp '__sys_bind_nt' bind ws2_32 2 3
|
||||
imp '__sys_closesocket_nt' closesocket ws2_32 3 1
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "libc/runtime/internal.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/symbols.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
|
@ -349,14 +350,20 @@ textwindows int sys_fork_nt(uint32_t dwCreationFlags) {
|
|||
}
|
||||
} else {
|
||||
rc = 0;
|
||||
// re-apply code morphing for thread-local storage
|
||||
if (tib && _weaken(__set_tls) && _weaken(__morph_tls)) {
|
||||
_weaken(__set_tls)(tib);
|
||||
_weaken(__morph_tls)();
|
||||
__tls_enabled_set(true);
|
||||
}
|
||||
// re-apply code morphing for synchronization nops
|
||||
if (threaded && !__threaded && _weaken(__enable_threads)) {
|
||||
_weaken(__enable_threads)();
|
||||
}
|
||||
// re-apply code morphing for function tracing
|
||||
if (ftrace_stackdigs) {
|
||||
_weaken(__hook)(_weaken(ftrace_hook), _weaken(GetSymbolTable)());
|
||||
}
|
||||
}
|
||||
if (untrackpid != -1) {
|
||||
__releasefd(untrackpid);
|
||||
|
|
|
@ -119,4 +119,4 @@ ftrace_hook:
|
|||
1: ret
|
||||
|
||||
#endif /* __x86_64__ */
|
||||
.endfn ftrace_hook,globl
|
||||
.endfn ftrace_hook,globl,hidden
|
||||
|
|
|
@ -23,8 +23,6 @@
|
|||
#include "libc/runtime/stack.h"
|
||||
#include "libc/runtime/symbols.internal.h"
|
||||
|
||||
void ftrace_hook(void);
|
||||
|
||||
textstartup int ftrace_install(void) {
|
||||
if (GetSymbolTable()) {
|
||||
ftrace_stackdigs = LengthInt64Thousands(GetStackSize());
|
||||
|
|
|
@ -33,6 +33,7 @@ extern unsigned char _tls_content[] __attribute__((__weak__));
|
|||
|
||||
void _init(void) _Hide;
|
||||
int ftrace_init(void) _Hide;
|
||||
void ftrace_hook(void) _Hide;
|
||||
void __morph_tls(void) _Hide;
|
||||
void __enable_tls(void) _Hide;
|
||||
void __enable_threads(void) _Hide;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#define ShouldUseMsabiAttribute() 1
|
||||
#include "ape/sections.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/dce.h"
|
||||
|
@ -36,24 +37,7 @@
|
|||
|
||||
__msabi extern typeof(VirtualProtect) *const __imp_VirtualProtect;
|
||||
|
||||
#ifdef __aarch64__
|
||||
static privileged void __aarch64_sigprocmask(int how, const sigset_t *set,
|
||||
sigset_t *oldset) {
|
||||
register int r0 asm("x0") = how;
|
||||
register long r1 asm("x1") = (long)set;
|
||||
register long r2 asm("x2") = (long)oldset;
|
||||
register long r3 asm("x3") = 8;
|
||||
register long r8 asm("x8") = __NR_sigprocmask;
|
||||
register long r16 asm("x16") = __NR_sigprocmask;
|
||||
asm volatile("svc\t0"
|
||||
: "+r"(r0)
|
||||
: "r"(r1), "r"(r2), "r"(r3), "r"(r8), "r"(r16)
|
||||
: "memory");
|
||||
}
|
||||
#endif
|
||||
|
||||
static privileged void __morph_mprotect(void *addr, size_t size, int prot,
|
||||
int ntprot) {
|
||||
__funline void __morph_mprotect(void *addr, size_t size, int prot, int ntprot) {
|
||||
#ifdef __x86_64__
|
||||
bool cf;
|
||||
int ax, dx;
|
||||
|
@ -69,8 +53,11 @@ static privileged void __morph_mprotect(void *addr, size_t size, int prot,
|
|||
if (ax == -EPERM) {
|
||||
kprintf("error: need pledge(prot_exec) permission to code morph\n");
|
||||
}
|
||||
if (ax < 0) {
|
||||
kprintf("error: __morph_mprotect(%p, %#zx, %d) failed: errno=%d\n", addr,
|
||||
size, prot, -ax);
|
||||
}
|
||||
#endif
|
||||
if (ax) notpossible;
|
||||
} else {
|
||||
__imp_VirtualProtect(addr, size, ntprot, &op);
|
||||
}
|
||||
|
@ -97,27 +84,6 @@ privileged void __morph_begin(sigset_t *save) {
|
|||
bool cf;
|
||||
intptr_t dx;
|
||||
sigset_t ss = {{-1, -1}};
|
||||
#ifdef __x86_64__
|
||||
if (IsOpenbsd()) {
|
||||
asm volatile(CFLAG_ASM("syscall")
|
||||
: CFLAG_CONSTRAINT(cf), "=a"(ax), "=d"(dx)
|
||||
: "1"(__NR_sigprocmask), "D"(SIG_BLOCK), "S"(-1u)
|
||||
: "rcx", "r8", "r9", "r10", "r11", "memory");
|
||||
save->__bits[0] = ax & 0xffffffff;
|
||||
if (cf) notpossible;
|
||||
} else if (!IsWindows() && !IsMetal()) {
|
||||
asm volatile("mov\t$8,%%r10d\n\t"
|
||||
"syscall"
|
||||
: "=a"(ax), "=d"(dx)
|
||||
: "0"(__NR_sigprocmask), "D"(SIG_BLOCK), "S"(&ss), "1"(save)
|
||||
: "rcx", "r8", "r9", "r10", "r11", "memory", "cc");
|
||||
if (ax) notpossible;
|
||||
}
|
||||
#elif defined(__aarch64__)
|
||||
__aarch64_sigprocmask(SIG_BLOCK, &ss, save);
|
||||
#else
|
||||
#error "unsupported architecture"
|
||||
#endif
|
||||
__morph_mprotect(__executable_start, __privileged_start - __executable_start,
|
||||
PROT_READ | PROT_WRITE, kNtPageWritecopy);
|
||||
}
|
||||
|
@ -131,24 +97,4 @@ privileged void __morph_end(sigset_t *save) {
|
|||
bool cf;
|
||||
__morph_mprotect(__executable_start, __privileged_start - __executable_start,
|
||||
PROT_READ | PROT_EXEC, kNtPageExecuteRead);
|
||||
#ifdef __x86_64__
|
||||
if (IsOpenbsd()) {
|
||||
asm volatile(CFLAG_ASM("syscall")
|
||||
: CFLAG_CONSTRAINT(cf), "=a"(ax), "=d"(dx)
|
||||
: "1"(__NR_sigprocmask), "D"(SIG_SETMASK), "S"(save->__bits[0])
|
||||
: "rcx", "r8", "r9", "r10", "r11", "memory");
|
||||
if (cf) notpossible;
|
||||
} else if (!IsWindows() && !IsMetal()) {
|
||||
asm volatile("mov\t$8,%%r10d\n\t"
|
||||
"syscall"
|
||||
: "=a"(ax), "=d"(dx)
|
||||
: "0"(__NR_sigprocmask), "D"(SIG_SETMASK), "S"(save), "1"(0L)
|
||||
: "rcx", "r8", "r9", "r10", "r11", "memory", "cc");
|
||||
if (ax) notpossible;
|
||||
}
|
||||
#elif defined(__aarch64__)
|
||||
__aarch64_sigprocmask(SIG_SETMASK, save, 0);
|
||||
#else
|
||||
#error "unsupported architecture"
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -100,8 +100,14 @@ static struct SymbolTable *OpenSymbolTableImpl(const char *filename) {
|
|||
for (j = i = 0; i < m; ++i) {
|
||||
sym = symtab + (stp[i] & 0x7fffffff);
|
||||
x = stp[i] >> 32;
|
||||
if (j && x == t->symbols[j - 1].x) --j;
|
||||
if (j && t->symbols[j - 1].y >= x) t->symbols[j - 1].y = x - 1;
|
||||
if (j && x == t->symbols[j - 1].x) {
|
||||
// when two symbols have an identical address value, favor the
|
||||
// symbol that was defined earlier in the elf data structures.
|
||||
continue;
|
||||
}
|
||||
if (j && t->symbols[j - 1].y >= x) {
|
||||
t->symbols[j - 1].y = x - 1;
|
||||
}
|
||||
t->names[j] = sym->st_name;
|
||||
t->symbols[j].x = x;
|
||||
if (sym->st_size) {
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/errno.h"
|
||||
#include "libc/thread/tls.h"
|
||||
|
||||
/**
|
||||
* Global variable for last error.
|
||||
|
@ -31,3 +32,14 @@
|
|||
* @see __errno_location() stable abi
|
||||
*/
|
||||
errno_t __errno;
|
||||
|
||||
/**
|
||||
* Returns address of `errno` variable.
|
||||
*/
|
||||
errno_t *__errno_location(void) {
|
||||
if (__tls_enabled) {
|
||||
return &__get_tls()->tib_errno;
|
||||
} else {
|
||||
return &__errno;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
/*-*- 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/thread/tls2.h"
|
||||
|
||||
extern errno_t __errno;
|
||||
|
||||
/**
|
||||
* Returns address of errno variable.
|
||||
*/
|
||||
nocallersavedregisters errno_t *(__errno_location)(void) {
|
||||
if (!__tls_enabled) return &__errno;
|
||||
return &__get_tls_privileged()->tib_errno;
|
||||
}
|
|
@ -40,7 +40,6 @@ LIBC_SYSV_A_FILES := \
|
|||
libc/sysv/restorert.S \
|
||||
libc/sysv/syscall.S \
|
||||
libc/sysv/systemfive.S \
|
||||
libc/sysv/errno_location.greg.c \
|
||||
libc/sysv/sysret.c \
|
||||
libc/sysv/errno.c \
|
||||
libc/sysv/errfun.S \
|
||||
|
|
Loading…
Reference in a new issue