Incorporate more small improvements

This commit is contained in:
Justine Tunney 2023-07-23 10:57:18 -07:00
parent 1d4eb08fa1
commit f83eb440f7
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
20 changed files with 121 additions and 256 deletions

View file

@ -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

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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;

View file

@ -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;

View file

@ -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) */

View file

@ -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) {

View file

@ -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) */

View file

@ -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

View file

@ -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);

View file

@ -119,4 +119,4 @@ ftrace_hook:
1: ret
#endif /* __x86_64__ */
.endfn ftrace_hook,globl
.endfn ftrace_hook,globl,hidden

View file

@ -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());

View file

@ -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;

View file

@ -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
}

View file

@ -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) {

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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 \