mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-30 00:08:30 +00:00
Mint APE Loader v1.5
This change ports APE Loader to Linux AARCH64, so that Raspberry Pi users can run programs like redbean, without the executable needing to modify itself. Progress has also slipped into this change on the issue of making progress better conforming to user expectations and industry standards regarding which symbols we're allowed to declare
This commit is contained in:
parent
6843150e0c
commit
7e0a09feec
510 changed files with 1783 additions and 1483 deletions
|
@ -41,14 +41,14 @@ int sys_accept4(int server, struct sockaddr_storage *addr, int flags) {
|
|||
if ((client = __sys_accept(server, addr, &size, 0)) != -1) {
|
||||
// __sys_accept() has inconsistent flag inheritence across platforms
|
||||
// this is one of the issues that accept4() was invented for solving
|
||||
_unassert((file_mode = __sys_fcntl(client, F_GETFD)) != -1);
|
||||
_unassert(!__sys_fcntl(client, F_SETFD,
|
||||
((file_mode & ~FD_CLOEXEC) |
|
||||
(flags & SOCK_CLOEXEC ? FD_CLOEXEC : 0))));
|
||||
_unassert((file_mode = __sys_fcntl(client, F_GETFL)) != -1);
|
||||
_unassert(!__sys_fcntl(client, F_SETFL,
|
||||
((file_mode & ~O_NONBLOCK) |
|
||||
(flags & SOCK_NONBLOCK ? O_NONBLOCK : 0))));
|
||||
unassert((file_mode = __sys_fcntl(client, F_GETFD)) != -1);
|
||||
unassert(!__sys_fcntl(client, F_SETFD,
|
||||
((file_mode & ~FD_CLOEXEC) |
|
||||
(flags & SOCK_CLOEXEC ? FD_CLOEXEC : 0))));
|
||||
unassert((file_mode = __sys_fcntl(client, F_GETFL)) != -1);
|
||||
unassert(!__sys_fcntl(client, F_SETFL,
|
||||
((file_mode & ~O_NONBLOCK) |
|
||||
(flags & SOCK_NONBLOCK ? O_NONBLOCK : 0))));
|
||||
}
|
||||
}
|
||||
return client;
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
textwindows int sys_bind_nt(struct Fd *fd, const void *addr,
|
||||
uint32_t addrsize) {
|
||||
_npassert(fd->kind == kFdSocket);
|
||||
npassert(fd->kind == kFdSocket);
|
||||
if (__sys_bind_nt(fd->handle, addr, addrsize) != -1) {
|
||||
return 0;
|
||||
} else {
|
||||
|
|
|
@ -28,7 +28,7 @@ textwindows int sys_connect_nt(struct Fd *fd, const void *addr,
|
|||
uint32_t addrsize) {
|
||||
struct SockFd *sockfd;
|
||||
sockfd = (struct SockFd *)fd->extra;
|
||||
_npassert(fd->kind == kFdSocket);
|
||||
npassert(fd->kind == kFdSocket);
|
||||
return __winsockblock(
|
||||
fd->handle, _bsr(kNtFdConnect),
|
||||
WSAConnect(fd->handle, addr, addrsize, NULL, NULL, NULL, NULL),
|
||||
|
|
|
@ -383,7 +383,7 @@ static textwindows int afd_poll(int64_t afd_device_handle,
|
|||
struct NtIoStatusBlock *io_status_block) {
|
||||
NtStatus status;
|
||||
/* Blocking operation is not supported.*/
|
||||
_npassert(io_status_block);
|
||||
npassert(io_status_block);
|
||||
io_status_block->Status = kNtStatusPending;
|
||||
status =
|
||||
NtDeviceIoControlFile(afd_device_handle, 0, NULL, io_status_block,
|
||||
|
@ -563,7 +563,7 @@ static textwindows int ts_tree_add(struct TsTree *ts_tree,
|
|||
}
|
||||
|
||||
static textwindows void port__free(struct PortState *port) {
|
||||
_npassert(port);
|
||||
npassert(port);
|
||||
free(port);
|
||||
}
|
||||
|
||||
|
@ -591,7 +591,7 @@ err1:
|
|||
}
|
||||
|
||||
static textwindows int sock__cancel_poll(struct SockState *sock_state) {
|
||||
_npassert(sock_state->poll_status == kPollPending);
|
||||
npassert(sock_state->poll_status == kPollPending);
|
||||
if (afd_cancel_poll(poll_group_get_afd_device_handle(sock_state->poll_group),
|
||||
&sock_state->io_status_block) < 0) {
|
||||
return -1;
|
||||
|
@ -707,13 +707,13 @@ static textwindows void reflock__await_event(void *address) {
|
|||
static textwindows void reflock_ref(struct RefLock *reflock) {
|
||||
long state = InterlockedAdd(&reflock->state, REFLOCK__REF);
|
||||
/* Verify that the counter didn 't overflow and the lock isn' t destroyed.*/
|
||||
_npassert((state & REFLOCK__DESTROY_MASK) == 0);
|
||||
npassert((state & REFLOCK__DESTROY_MASK) == 0);
|
||||
}
|
||||
|
||||
static textwindows void reflock_unref(struct RefLock *reflock) {
|
||||
long state = InterlockedAdd(&reflock->state, -REFLOCK__REF);
|
||||
/* Verify that the lock was referenced and not already destroyed.*/
|
||||
_npassert((state & REFLOCK__DESTROY_MASK & ~REFLOCK__DESTROY) == 0);
|
||||
npassert((state & REFLOCK__DESTROY_MASK & ~REFLOCK__DESTROY) == 0);
|
||||
if (state == REFLOCK__DESTROY) reflock__signal_event(reflock);
|
||||
}
|
||||
|
||||
|
@ -749,10 +749,10 @@ static textwindows void reflock_unref_and_destroy(struct RefLock *reflock) {
|
|||
state = InterlockedAdd(&reflock->state, REFLOCK__DESTROY - REFLOCK__REF);
|
||||
ref_count = state & REFLOCK__REF_MASK;
|
||||
/* Verify that the lock was referenced and not already destroyed. */
|
||||
_npassert((state & REFLOCK__DESTROY_MASK) == REFLOCK__DESTROY);
|
||||
npassert((state & REFLOCK__DESTROY_MASK) == REFLOCK__DESTROY);
|
||||
if (ref_count != 0) reflock__await_event(reflock);
|
||||
state = InterlockedExchange(&reflock->state, REFLOCK__POISON);
|
||||
_npassert(state == REFLOCK__DESTROY);
|
||||
npassert(state == REFLOCK__DESTROY);
|
||||
}
|
||||
|
||||
static textwindows void ts_tree_node_unref_and_destroy(
|
||||
|
@ -780,13 +780,13 @@ static textwindows void poll_group_release(struct PollGroup *poll_group) {
|
|||
struct PortState *port_state = poll_group->port_state;
|
||||
struct Queue *poll_group_queue = port_get_poll_group_queue(port_state);
|
||||
poll_group->group_size--;
|
||||
_npassert(poll_group->group_size < MAX_GROUP_SIZE);
|
||||
npassert(poll_group->group_size < MAX_GROUP_SIZE);
|
||||
queue_move_to_end(poll_group_queue, &poll_group->queue_node);
|
||||
/* Poll groups are currently only freed when the epoll port is closed. */
|
||||
}
|
||||
|
||||
static textwindows void sock__free(struct SockState *sock_state) {
|
||||
_npassert(sock_state != NULL);
|
||||
npassert(sock_state != NULL);
|
||||
free(sock_state);
|
||||
}
|
||||
|
||||
|
@ -832,7 +832,7 @@ static textwindows void sock_force_delete(struct PortState *port_state,
|
|||
}
|
||||
|
||||
static textwindows void poll_group_delete(struct PollGroup *poll_group) {
|
||||
_npassert(poll_group->group_size == 0);
|
||||
npassert(poll_group->group_size == 0);
|
||||
CloseHandle(poll_group->afd_device_handle);
|
||||
queue_remove(&poll_group->queue_node);
|
||||
free(poll_group);
|
||||
|
@ -844,7 +844,7 @@ static textwindows int port_delete(struct PortState *port_state) {
|
|||
struct SockState *sock_state;
|
||||
struct PollGroup *poll_group;
|
||||
/* At this point the IOCP port should have been closed.*/
|
||||
_npassert(!port_state->iocp_handle);
|
||||
npassert(!port_state->iocp_handle);
|
||||
while ((tree_node = tree_root(&port_state->sock_tree)) != NULL) {
|
||||
sock_state = sock_state_from_tree_node(tree_node);
|
||||
sock_force_delete(port_state, sock_state);
|
||||
|
@ -857,14 +857,14 @@ static textwindows int port_delete(struct PortState *port_state) {
|
|||
poll_group = poll_group_from_queue_node(queue_node);
|
||||
poll_group_delete(poll_group);
|
||||
}
|
||||
_npassert(queue_is_empty(&port_state->sock_update_queue));
|
||||
npassert(queue_is_empty(&port_state->sock_update_queue));
|
||||
DeleteCriticalSection(&port_state->lock);
|
||||
port__free(port_state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static textwindows int64_t port_get_iocp_handle(struct PortState *port_state) {
|
||||
_npassert(port_state->iocp_handle);
|
||||
npassert(port_state->iocp_handle);
|
||||
return port_state->iocp_handle;
|
||||
}
|
||||
|
||||
|
@ -938,7 +938,7 @@ static textwindows uint32_t sock__afd_events_to_epoll_events(uint32_t a) {
|
|||
|
||||
static textwindows int sock_update(struct PortState *port_state,
|
||||
struct SockState *sock_state) {
|
||||
_npassert(!sock_state->delete_pending);
|
||||
npassert(!sock_state->delete_pending);
|
||||
if ((sock_state->poll_status == kPollPending) &&
|
||||
!(sock_state->user_events & KNOWN_EVENTS & ~sock_state->pending_events)) {
|
||||
/* All the events the user is interested in are already being
|
||||
|
|
|
@ -36,7 +36,7 @@ textwindows int sys_getsockopt_nt(struct Fd *fd, int level, int optname,
|
|||
uint32_t in_optlen;
|
||||
struct SockFd *sockfd;
|
||||
struct linger_nt linger;
|
||||
_npassert(fd->kind == kFdSocket);
|
||||
npassert(fd->kind == kFdSocket);
|
||||
sockfd = (struct SockFd *)fd->extra;
|
||||
|
||||
if (out_opt_optval && inout_optlen) {
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
/**
|
||||
* Information about underlying Windows Sockets implementation.
|
||||
*
|
||||
* Cosmopolitan automatically calls YOINK() on this symbol when its
|
||||
* Cosmopolitan automatically calls __yoink() on this symbol when its
|
||||
* Berkeley Socket wrappers are linked. The latest version of Winsock
|
||||
* was introduced alongside x64, so this should never fail.
|
||||
*/
|
||||
|
@ -43,7 +43,7 @@ static textwindows void WinSockCleanup(void) {
|
|||
NTTRACE("WSACleanup() → %d% lm", rc);
|
||||
}
|
||||
|
||||
textwindows noasan void WinSockInit(void) {
|
||||
textwindows dontasan void WinSockInit(void) {
|
||||
int rc;
|
||||
atexit(WinSockCleanup);
|
||||
NTTRACE("WSAStartup()");
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "libc/sock/syscall_fd.internal.h"
|
||||
|
||||
textwindows int sys_listen_nt(struct Fd *fd, int backlog) {
|
||||
_npassert(fd->kind == kFdSocket);
|
||||
npassert(fd->kind == kFdSocket);
|
||||
if (__sys_listen_nt(fd->handle, backlog) != -1) {
|
||||
return 0;
|
||||
} else {
|
||||
|
|
|
@ -323,7 +323,7 @@ int nointernet(void) {
|
|||
sigprocmask(SIG_SETMASK, &old, 0);
|
||||
return eperm();
|
||||
}
|
||||
_npassert(WIFSTOPPED(ws));
|
||||
npassert(WIFSTOPPED(ws));
|
||||
|
||||
// parent process becomes monitor of subprocess tree. all signals
|
||||
// continue to be blocked since we assume they'll also be sent to
|
||||
|
|
|
@ -49,6 +49,6 @@ textwindows ssize_t sys_recv_nt(struct Fd *fd, const struct iovec *iov,
|
|||
sockfd = (struct SockFd *)fd->extra;
|
||||
rc = __wsablock(fd, &overlapped, &flags, true, sockfd->rcvtimeo);
|
||||
}
|
||||
_unassert(WSACloseEvent(overlapped.hEvent));
|
||||
unassert(WSACloseEvent(overlapped.hEvent));
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -110,9 +110,9 @@ static dontinline textwindows ssize_t sys_sendfile_nt(
|
|||
if (rc != -1) {
|
||||
if (opt_in_out_inoffset) {
|
||||
*opt_in_out_inoffset = offset + rc;
|
||||
_npassert(SetFilePointerEx(ih, pos, 0, SEEK_SET));
|
||||
npassert(SetFilePointerEx(ih, pos, 0, SEEK_SET));
|
||||
} else {
|
||||
_npassert(SetFilePointerEx(ih, offset + rc, 0, SEEK_SET));
|
||||
npassert(SetFilePointerEx(ih, offset + rc, 0, SEEK_SET));
|
||||
}
|
||||
}
|
||||
WSACloseEvent(ov.hEvent);
|
||||
|
@ -141,7 +141,7 @@ static ssize_t sys_sendfile_bsd(int outfd, int infd,
|
|||
if (opt_in_out_inoffset) {
|
||||
*opt_in_out_inoffset += sbytes;
|
||||
} else {
|
||||
_npassert(lseek(infd, offset + sbytes, SEEK_SET) == offset + sbytes);
|
||||
npassert(lseek(infd, offset + sbytes, SEEK_SET) == offset + sbytes);
|
||||
}
|
||||
return sbytes;
|
||||
} else {
|
||||
|
|
|
@ -35,9 +35,9 @@
|
|||
* functions through weak reference. This ensure those symbols are not
|
||||
* stripped during final link.
|
||||
*/
|
||||
STATIC_YOINK("GetAdaptersAddresses");
|
||||
STATIC_YOINK("tprecode16to8");
|
||||
STATIC_YOINK("_dupsockfd");
|
||||
__static_yoink("GetAdaptersAddresses");
|
||||
__static_yoink("tprecode16to8");
|
||||
__static_yoink("_dupsockfd");
|
||||
|
||||
textwindows int sys_socket_nt(int family, int type, int protocol) {
|
||||
int64_t h;
|
||||
|
|
|
@ -47,8 +47,8 @@ textwindows int __wsablock(struct Fd *fd, struct NtOverlapped *overlapped,
|
|||
}
|
||||
if (fd->flags & O_NONBLOCK) {
|
||||
e = errno;
|
||||
_unassert(CancelIoEx(fd->handle, overlapped) ||
|
||||
WSAGetLastError() == kNtErrorNotFound);
|
||||
unassert(CancelIoEx(fd->handle, overlapped) ||
|
||||
WSAGetLastError() == kNtErrorNotFound);
|
||||
errno = e;
|
||||
} else {
|
||||
if (_check_interrupts(restartable, g_fds.p)) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
STATIC_YOINK("kNtWsaData"); // for winmain
|
||||
STATIC_YOINK("WSAGetLastError"); // for kprintf
|
||||
STATIC_YOINK("sys_closesocket_nt"); // for close
|
||||
STATIC_YOINK("sys_recv_nt"); // for readv
|
||||
STATIC_YOINK("sys_send_nt"); // for writev
|
||||
__static_yoink("kNtWsaData"); // for winmain
|
||||
__static_yoink("WSAGetLastError"); // for kprintf
|
||||
__static_yoink("sys_closesocket_nt"); // for close
|
||||
__static_yoink("sys_recv_nt"); // for readv
|
||||
__static_yoink("sys_send_nt"); // for writev
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue