mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-16 15:40:31 +00:00
Support malloc() on bare metal
Your Actually Portable Executables now contains a simple virtual memory that works similarly to the Linux Kernel in the sense that it maps your physical memory to negative addresses. This is needed to support mmap() and malloc(). This functionality has zero code size impact. For example the MODE=tiny LIFE.COM executable is still only 12KB in size. The APE bootloader code has also been simplified to improve readibility and further elevate the elegance by which we're able to support so many platforms thereby enhancing verifiability so that we may engender trust in this bootloading process.
This commit is contained in:
parent
ac3b1dfb21
commit
edd9297eba
89 changed files with 900 additions and 1417 deletions
|
@ -1,23 +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 2021 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/efi.h"
|
||||
#include "libc/nt/efi.h"
|
||||
|
||||
EFI_HANDLE __efi_image_handle;
|
||||
EFI_SYSTEM_TABLE *__efi_system_table;
|
|
@ -1,12 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_CALLS_EFI_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_EFI_H_
|
||||
#include "libc/nt/efi.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern EFI_HANDLE __efi_image_handle;
|
||||
extern EFI_SYSTEM_TABLE *__efi_system_table;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_CALLS_EFI_H_ */
|
|
@ -31,9 +31,9 @@ int fstat(int fd, struct stat *st) {
|
|||
if (__isfdkind(fd, kFdZip)) {
|
||||
return weaken(__zipos_fstat)(
|
||||
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, st);
|
||||
} else if (!IsWindows() && !IsMetal() && !IsUefi()) {
|
||||
} else if (!IsWindows() && !IsMetal()) {
|
||||
return sys_fstat(fd, st);
|
||||
} else if (IsMetal() || IsUefi()) {
|
||||
} else if (IsMetal()) {
|
||||
return fstat_metal(fd, st);
|
||||
} else {
|
||||
if (!__isfdkind(fd, kFdFile)) return ebadf();
|
||||
|
|
|
@ -30,7 +30,7 @@ hidden textstartup void InitializeFileDescriptors(void) {
|
|||
fds = VEIL("r", &g_fds);
|
||||
pushmov(&fds->n, ARRAYLEN(fds->__init_p));
|
||||
fds->p = fds->__init_p;
|
||||
if (IsMetal() || IsUefi()) {
|
||||
if (IsMetal()) {
|
||||
pushmov(&fds->f, 3ull);
|
||||
fds->__init_p[STDIN_FILENO].kind = pushpop(kFdSerial);
|
||||
fds->__init_p[STDOUT_FILENO].kind = pushpop(kFdSerial);
|
||||
|
|
|
@ -197,7 +197,7 @@ u32 sys_getgid(void) hidden;
|
|||
u32 sys_getsid(int) hidden;
|
||||
u32 sys_gettid(void) hidden;
|
||||
u32 sys_getuid(void) hidden;
|
||||
void *sys_mmap(void *, u64, u32, u32, i64, i64, i64) hidden;
|
||||
void *__sys_mmap(void *, u64, u32, u32, i64, i64, i64) hidden;
|
||||
void *sys_mremap(void *, u64, u64, i32, void *) hidden;
|
||||
void sys_exit(int) hidden;
|
||||
|
||||
|
@ -295,12 +295,6 @@ unsigned __wincrash_nt(struct NtExceptionPointers *);
|
|||
|
||||
int fstat_metal(int, struct stat *);
|
||||
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § syscalls » uefi ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
int sys_nanosleep_uefi(const struct timespec *, struct timespec *);
|
||||
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § syscalls » drivers ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
|
|
@ -1,35 +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 2021 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/calls.h"
|
||||
#include "libc/calls/efi.h"
|
||||
#include "libc/nt/efi.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
int sys_nanosleep_uefi(const struct timespec *req, struct timespec *rem) {
|
||||
if (__efi_system_table->BootServices->Stall(
|
||||
req->tv_sec * 1000000 + req->tv_nsec / 1000) == EFI_SUCCESS) {
|
||||
if (rem) {
|
||||
rem->tv_sec = 0;
|
||||
rem->tv_nsec = 0;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
return eintr();
|
||||
}
|
||||
}
|
|
@ -29,12 +29,10 @@ int nanosleep(const struct timespec *req, struct timespec *rem) {
|
|||
if (req->tv_sec < 0 || !(0 <= req->tv_nsec && req->tv_nsec <= 999999999)) {
|
||||
return einval();
|
||||
}
|
||||
if (!IsWindows() && !IsMetal() && !IsUefi() && !IsXnu()) {
|
||||
if (!IsWindows() && !IsMetal() && !IsXnu()) {
|
||||
return sys_nanosleep(req, rem);
|
||||
} else if (IsXnu()) {
|
||||
return sys_nanosleep_xnu(req, rem);
|
||||
} else if (IsUefi()) {
|
||||
return sys_nanosleep_uefi(req, rem);
|
||||
} else if (IsMetal()) {
|
||||
return enosys(); /* TODO: Sleep on Metal */
|
||||
} else {
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "ape/lib/pc.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/nexgen32e/uart.internal.h"
|
||||
#include "libc/runtime/pc.internal.h"
|
||||
|
||||
static bool IsDataAvailable(struct Fd *fd) {
|
||||
return inb(fd->handle + UART_LSR) & UART_TTYDA;
|
||||
|
|
|
@ -36,8 +36,7 @@ ssize_t readv(int fd, const struct iovec *iov, int iovlen) {
|
|||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
return weaken(__zipos_read)(
|
||||
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, -1);
|
||||
} else if ((SupportsMetal() || SupportsUefi()) && fd < g_fds.n &&
|
||||
g_fds.p[fd].kind == kFdSerial) {
|
||||
} else if (SupportsMetal() && fd < g_fds.n && g_fds.p[fd].kind == kFdSerial) {
|
||||
return readv_serial(&g_fds.p[fd], iov, iovlen);
|
||||
} else if (!IsWindows()) {
|
||||
return sys_readv(fd, iov, iovlen);
|
||||
|
|
|
@ -144,7 +144,7 @@ int(sigaction)(int sig, const struct sigaction *act, struct sigaction *oldact) {
|
|||
sizeof(struct sigaction) > sizeof(struct sigaction_freebsd) &&
|
||||
sizeof(struct sigaction) > sizeof(struct sigaction_openbsd) &&
|
||||
sizeof(struct sigaction) > sizeof(struct sigaction_netbsd));
|
||||
if (IsMetal() || IsUefi()) return enosys(); /* TODO: Signals on Metal */
|
||||
if (IsMetal()) return enosys(); /* TODO: Signals on Metal */
|
||||
if (!(0 < sig && sig < NSIG)) return einval();
|
||||
if (sig == SIGKILL || sig == SIGSTOP) return einval();
|
||||
if (!act) {
|
||||
|
|
|
@ -16,9 +16,9 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "ape/lib/pc.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/nexgen32e/uart.internal.h"
|
||||
#include "libc/runtime/pc.internal.h"
|
||||
|
||||
ssize_t writev_serial(struct Fd *fd, const struct iovec *iov, int iovlen) {
|
||||
size_t i, j, wrote = 0;
|
||||
|
|
|
@ -39,8 +39,7 @@ ssize_t writev(int fd, const struct iovec *iov, int iovlen) {
|
|||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
return weaken(__zipos_write)(
|
||||
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, -1);
|
||||
} else if ((SupportsMetal() || SupportsUefi()) && fd < g_fds.n &&
|
||||
g_fds.p[fd].kind == kFdSerial) {
|
||||
} else if (SupportsMetal() && fd < g_fds.n && g_fds.p[fd].kind == kFdSerial) {
|
||||
return writev_serial(&g_fds.p[fd], iov, iovlen);
|
||||
} else if (!IsWindows()) {
|
||||
return sys_writev(fd, iov, iovlen);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue