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:
Justine Tunney 2021-02-23 20:23:19 -08:00
parent ac3b1dfb21
commit edd9297eba
89 changed files with 900 additions and 1417 deletions

View file

@ -0,0 +1,2 @@
.include "o/libc/sysv/macros.internal.inc"
.scall __sys_mmap,0x0c50c51dd20c5009,globl,hidden

View file

@ -1,2 +0,0 @@
.include "o/libc/sysv/macros.internal.inc"
.scall sys_mmap,0x0c50c51dd20c5009,globl,hidden

View file

@ -44,7 +44,7 @@ scall __sys_lstat 0x1b90280282154006 globl hidden # needs __stat2linux(); block
scall sys_poll 0x0d10fc0d120e6007 globl hidden
scall sys_ppoll 0xfff06d221ffff10f globl hidden # consider INTON/INTOFF tutorial in examples/unbourne.c
scall sys_lseek 0x0c70c71de20c7008 globl hidden # netbsd+openbsd:evilpad
scall sys_mmap 0x0c50c51dd20c5009 globl hidden # netbsd+openbsd:pad
scall __sys_mmap 0x0c50c51dd20c5009 globl hidden # netbsd+openbsd:pad
scall sys_msync 0x115100041204101a globl hidden
scall sys_mprotect 0x04a04a04a204a00a globl hidden
scall sys_munmap 0x049049049204900b globl hidden

View file

@ -104,7 +104,7 @@ __systemfive:
.privileged
.Lanchorpoint:
#if SupportsLinux() || SupportsMetal() || SupportsUefi()
#if SupportsLinux() || SupportsMetal()
systemfive_linux:
and $0xfff,%eax
cmp $0xfff,%eax
@ -198,10 +198,6 @@ systemfive_xnu:
testb $XNU,(%rdi) # @see libc/crt/crt.S
jnz _init_systemfive_xnu
#endif
#if SupportsUefi()
testb $UEFI,(%rdi) # @see ape/ape.S
jnz _init_systemfive_uefi
#endif
#if SupportsMetal()
testb $METAL,(%rdi) # @see ape/ape.S
jnz _init_systemfive_metal
@ -240,13 +236,6 @@ _init_systemfive_metal:
ezlea syscon_linux,si
jmp _init_systemfive_os
#endif
#if SupportsUefi()
_init_systemfive_uefi:
pushb systemfive_linux-.Lanchorpoint
push $UEFI
ezlea syscon_linux,si
jmp _init_systemfive_os
#endif
#if SupportsWindows()
_init_systemfive_windows:
pushb systemfive_enosys-.Lanchorpoint
@ -323,20 +312,22 @@ _init_systemfive_magnums:
// 𝑠𝑙𝑖𝑑𝑒
#if SupportsSystemv() && !defined(TINY)
_init_systemfive_stack: # determinism ftw!
#if SupportsWindows() || SupportsMetal() || SupportsUefi()
testb $WINDOWS|METAL|UEFI,__hostos(%rip)
#if SupportsWindows() || SupportsMetal()
testb $WINDOWS|METAL,__hostos(%rip)
jnz _init_systemfive_done
#endif
push %rdi
push %rsi
mov __NR_mmap,%eax
mov $0x700000000000-STACKSIZE,%rdi
mov $STACKSIZE,%esi
movabs $ape_stack_vaddr,%rdi
mov $ape_stack_memsz,%esi
mov $PROT_READ|PROT_WRITE,%edx
mov $MAP_PRIVATE|MAP_FIXED,%r10d
or MAP_ANONYMOUS,%r10d
or $-1,%r8d
xor %r9d,%r9d
push %rdi # vaddr of stack
push %rsi # size of stack
push %r9 # openbsd:pad
push %r9 # openbsd:align
#if SupportsOpenbsd()
@ -351,6 +342,8 @@ _init_systemfive_stack: # determinism ftw!
syscall
pop %r9
pop %r9
pop %r9 # size of stack
pop %r11 # vaddr of stack
jnc 2f
1: mov %eax,%edi
mov __NR_exit_group,%eax
@ -360,17 +353,23 @@ _init_systemfive_stack: # determinism ftw!
.weak _mmi
ezlea _mmi,cx
test %rcx,%rcx
push %r9 # save the stack size
jz 3f
lea -1(%r11,%r9),%r9 # need incl. interval
shr $16,%r11 # for the stack range
shr $16,%r9
movb $1,(%rcx) # _mmi.i
movl $(0x700000000000-STACKSIZE)>>16,8(%rcx) # _mmi.p[0].x
movl $(0x700000000000-1)>>16,12(%rcx) # _mmi.p[0].y
mov %r11d,8(%rcx) # _mmi.p[0].x
mov %r9d,12(%rcx) # _mmi.p[0].y
mov %edx,20(%rcx) # _mmi.p[0].prot
mov %r10d,24(%rcx) # _mmi.p[0].flags
3: pop %rsi
3: pop %r9 # restore stack size
pop %rsi
pop %rdi
leave
pop %rcx
lea STACKSIZE-16(%rax),%rsp # openbsd:stackbound
lea (%rax,%r9),%rsp
sub $ape_stack_align,%rsp # openbsd:stackbound
mov %rbp,(%rsp)
push %rcx
push %rbp
@ -414,7 +413,7 @@ syscon_end:
.type syscon_end,@object
.globl syscon_start
.globl syscon_end
#if SupportsLinux() || SupportsMetal() || SupportsUefi()
#if SupportsLinux() || SupportsMetal()
.section .sort.rodata.syscon.linux.1,"a",@progbits
.align 1
syscon_linux:/*
@ -468,3 +467,7 @@ syscon_windows:/*
.type syscon_windows,@object
.globl syscon_windows
#endif
.weak ape_stack_vaddr
.weak ape_stack_memsz
.weak ape_stack_align