Add x86_64-linux-gnu emulator

I wanted a tiny scriptable meltdown proof way to run userspace programs
and visualize how program execution impacts memory. It helps to explain
how things like Actually Portable Executable works. It can show you how
the GCC generated code is going about manipulating matrices and more. I
didn't feel fully comfortable with Qemu and Bochs because I'm not smart
enough to understand them. I wanted something like gVisor but with much
stronger levels of assurances. I wanted a single binary that'll run, on
all major operating systems with an embedded GPL barrier ZIP filesystem
that is tiny enough to transpile to JavaScript and run in browsers too.

https://justine.storage.googleapis.com/emulator625.mp4
This commit is contained in:
Justine Tunney 2020-08-25 04:23:25 -07:00
parent 467504308a
commit f4f4caab0e
1052 changed files with 65667 additions and 7825 deletions

View file

@ -29,4 +29,4 @@ abort: push %bp
mov %sp,%bp
rlcall panic
int3
.endfn abort,weak,protected
.endfn abort,weak

View file

@ -18,9 +18,9 @@
02110-1301 USA
*/
#include "libc/macros.h"
.align 16
.text.likely
.source __FILE__
.privileged
.alignfunc
/ Returns 𝑥+𝑦, aborting on overflow.
/

View file

@ -18,9 +18,9 @@
02110-1301 USA
*/
#include "libc/macros.h"
.align 16
.text.likely
.source __FILE__
.privileged
.alignfunc
/ Returns 𝑥+𝑦, aborting on overflow.
/

View file

@ -18,9 +18,9 @@
02110-1301 USA
*/
#include "libc/macros.h"
.align 16
.text.likely
.source __FILE__
.privileged
.alignfunc
/ Returns 𝑥+𝑦, aborting on overflow.
/
@ -30,8 +30,9 @@
/ @see -ftrapv
__addvti3:
mov %rdi,%rax
add %rsi,%rax
adc %rdi,%rdx
add %rdx,%rax
mov %rsi,%rdx
adc %rcx,%rdx
jo 1f
ret
1: push %rbp

View file

@ -28,6 +28,7 @@
/ @mode long,legacy,real
/ @noreturn
__assert_fail:
int3
push %bp
mov %sp,%bp
rlcall panic

View file

@ -24,7 +24,6 @@
/ Returns address of errno variable.
/ @note this isn't a universal definition
__errno_location:
.leafprologue
lea errno(%rip),%rax
.leafepilogue
ezlea errno,ax
ret
.endfn __errno_location,globl,hidden

View file

@ -32,6 +32,7 @@
/ @noreturn
_exit: push %bp
mov %sp,%bp
.weak _Exit
rlcall _Exit
int3
.endfn _exit,weak,protected
.endfn _exit,weak

View file

@ -34,15 +34,13 @@
__privileged_start = 0
__test_start = 0
__ro = 0
__piro_start = 0
__relo_start = 0
__relo_end = 0
__piro_end = 0
.globl _base
.globl ape.xlm
.globl __piro_start
.globl __relo_start
.globl __relo_end
.globl __piro_end
.globl __privileged_start
.globl __ro
.globl __test_start
@ -54,9 +52,8 @@
.weak _base
.weak ape.xlm
.weak __piro_start
.weak __relo_start
.weak __relo_end
.weak __piro_end
.weak __privileged_start
.weak __ro
.weak __test_start

View file

@ -18,9 +18,9 @@
02110-1301 USA
*/
#include "libc/macros.h"
.align 16
.text.likely
.source __FILE__
.privileged
.alignfunc
/ Returns 𝑥*𝑦, aborting on overflow.
/
@ -31,6 +31,11 @@
__mulvdi3:
mov %rdi,%rax
imul %rsi
jc __on_arithmetic_overflow
jc 1f
ret
1: push %rbp
mov %rsp,%rbp
call __on_arithmetic_overflow
pop %rbp
ret
.endfn __mulvdi3,globl

View file

@ -18,9 +18,9 @@
02110-1301 USA
*/
#include "libc/macros.h"
.align 16
.text.likely
.source __FILE__
.privileged
.alignfunc
/ Returns 𝑥*𝑦, aborting on overflow.
/
@ -31,6 +31,11 @@
__mulvsi3:
mov %edi,%eax
imul %esi
jc __on_arithmetic_overflow
jc 1f
ret
1: push %rbp
mov %rsp,%rbp
call __on_arithmetic_overflow
pop %rbp
ret
.endfn __mulvsi3,globl

View file

@ -18,27 +18,119 @@
02110-1301 USA
*/
#include "libc/macros.h"
.align 16
.text.likely
.source __FILE__
.privileged
.alignfunc
/ Returns 𝑥*𝑦, aborting on overflow.
/
/ TODO(jart): is this ok?
/
/ @param rdi:rsi is int128 𝑥
/ @param rdx:rcx is int128 𝑦
/ @return rdx:rax is 𝑥*𝑦
/ @see -ftrapv
__mulvti3:
push %rbp
mov %rsp,%rbp
push %rbx
push %rbx
push %r12
push %r13
push %r14
push %r15
mov %rdx,%r10
mov %rdi,%rdx
xor %r11d,%r11d
mov %r10,%rax
sar $63,%rdx
sar $63,%rax
cmp %rsi,%rdx
jne 4f
cmp %rcx,%rax
jne 5f
mov %rdi,%rax
imul %r10
mov %rax,%r14
mov %rdx,%r8
jmp 2f
5: mov %r10,%r12
mov %rcx,%r13
mov %rcx,%r8
mov %rdi,%rbx
jmp 6f
4: cmp %rcx,%rax
jne 7f
mov %rdi,%r12
mov %rsi,%r13
mov %rsi,%r8
mov %r10,%rbx
6: mov %rdi,%rax
mul %r10
mov %rax,%r14
mov %rbx,%rax
mov %rdx,%r15
mul %r8
test %r8,%r8
jns 8f
xor %r8d,%r8d
sub %r8,%rax
sbb %rbx,%rdx
8: test %rbx,%rbx
jns 9f
sub %r12,%rax
sbb %r13,%rdx
9: mov %r15,%r8
xor %r9d,%r9d
add %rax,%r8
adc %rdx,%r9
mov %r8,%rdx
sar $63,%rdx
cmp %r9,%rdx
je 2f
imul %r10,%rsi
mov %rdi,%rax
imul %rdx,%rsi
imul %rdi,%rcx
add %rsi,%rcx
mul %rdx
jc 1f
add %rcx,%rdx
jo 1f
mul %r10
lea (%rsi,%rcx),%r8
add %rdx,%r8
mov %rax,%r14
jmp 3f
7: mov %rsi,%r8
mov %rcx,%rdx
mov %rdi,%rax
imul %rdi,%rdx
imul %r10,%r8
add %rdx,%r8
mul %r10
mov %rax,%r14
lea 1(%rsi),%rax
add %rdx,%r8
cmp $1,%rax
ja 3f
lea 1(%rcx),%rax
cmp $1,%rax
ja 3f
cmp %rcx,%rsi
jne 11f
cmp %r14,%r11
mov %r11,%rax
sbb %r8,%rax
jl 2f
jmp 3f
11: test %r8,%r8
js 2f
3: mov $1,%r11d
2: test %r11,%r11
je 1f
mov %r8,-8(%rbp)
call __on_arithmetic_overflow
mov -8(%rbp),%r8
1: mov %r14,%rax
mov %r8,%rdx
pop %r15
pop %r14
pop %r13
pop %r12
pop %rbx
leave
ret
1: jmp __on_arithmetic_overflow
.endfn __mulvti3,globl

View file

@ -18,9 +18,9 @@
02110-1301 USA
*/
#include "libc/macros.h"
.align 16
.text.likely
.source __FILE__
.privileged
.alignfunc
/ Returns -𝑥, aborting on overflow (two's complement bane).
/

View file

@ -18,9 +18,9 @@
02110-1301 USA
*/
#include "libc/macros.h"
.align 16
.text.likely
.source __FILE__
.privileged
.alignfunc
/ Returns -𝑥, aborting on overflow (two's complement bane).
/

View file

@ -18,9 +18,9 @@
02110-1301 USA
*/
#include "libc/macros.h"
.align 16
.text.likely
.source __FILE__
.privileged
.alignfunc
/ Returns -𝑥, aborting on overflow.
/
@ -31,11 +31,14 @@ __negvti2:
mov %rdi,%rax
mov %rsi,%rdx
neg %rax
not %rdx
cmc
adc $0,%rdx
/ TODO(jart): Make sure this is correct.
jo 1f
neg %rdx
jo 1f
ret
1: jmp __on_arithmetic_overflow
1: push %rbp
mov %rsp,%rbp
call __on_arithmetic_overflow
pop %rbp
ret
.endfn __negvti2,globl

View file

@ -18,12 +18,10 @@
02110-1301 USA
*/
#include "libc/macros.h"
.text.unlikely
.privileged
.source __FILE__
/ Arithmetic overflow handler.
/
/ @see libc/testlib/arithmeticoverflowhook.S
/ @see -ftrapv
__on_arithmetic_overflow:
push %rbp

View file

@ -30,4 +30,4 @@ panic: push %bp
cli
1: hlt
jmp 1b
.endfn panic,weak,protected
.endfn panic,weak

View file

@ -17,20 +17,10 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "ape/macros.h"
.real
.source __FILE__
.code16 # .code32 .code64
#include "libc/macros.h"
/ Thrice re-imagined Unix user process termination API stub.
/
/ @param edi is exit code ∈ [0,256)
/ @see libc/runtime/_exit.c
/ @mode long,legacy,real
/ @asyncsignalsafe
/ @noreturn
_Exit: push %bp
mov %sp,%bp
rlcall panic
int3
.endfn _Exit,weak,protected
/ See -mfunction-return=thunk
__x86_return_thunk:
ret
.endfn __x86_return_thunk,weak
.source __FILE__

View file

@ -0,0 +1,41 @@
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify │
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License. │
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of │
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software │
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/macros.h"
#include "libc/notice.inc"
.source __FILE__
/ Canary for -fstack-protector.
/
/ This global is referenced by synthetic code generated by GCC.
/ The -mstack-protector-guard=global flag might need to be passed.
/
/ @note this value is protected by piro
.initbss 200,_init___stack_chk_guard
__stack_chk_guard:
.quad 0
.endobj __stack_chk_guard,globl
.previous
.init.start 301,_init___stack_chk_guard
rdtsc
stosl
xchg %edx,%eax
stosl
.init.end 301,_init___stack_chk_guard

View file

@ -17,7 +17,7 @@ PKGS += LIBC_STUBS
LIBC_STUBS_ARTIFACTS += LIBC_STUBS_A
LIBC_STUBS = $(LIBC_STUBS_A)
LIBC_STUBS_A = o/libc/stubs/stubs.a
LIBC_STUBS_A = o/$(MODE)/libc/stubs/stubs.a
LIBC_STUBS_A_FILES := $(wildcard libc/stubs/*.S)
LIBC_STUBS_A_HDRS = \
@ -28,7 +28,7 @@ LIBC_STUBS_A_SRCS = \
LIBC_STUBS_A_OBJS = \
$(LIBC_STUBS_A_SRCS:%=o/$(MODE)/%.zip.o) \
$(LIBC_STUBS_A_SRCS:%.S=o/%.o)
$(LIBC_STUBS_A_SRCS:%.S=o/$(MODE)/%.o)
LIBC_STUBS_A_CHECKS = \
$(LIBC_STUBS_A).pkg \
@ -47,7 +47,7 @@ LIBC_STUBS_LIBS = $(foreach x,$(LIBC_STUBS_ARTIFACTS),$($(x)))
LIBC_STUBS_SRCS = $(foreach x,$(LIBC_STUBS_ARTIFACTS),$($(x)_SRCS))
LIBC_STUBS_CHECKS = $(foreach x,$(LIBC_STUBS_ARTIFACTS),$($(x)_CHECKS))
LIBC_STUBS_OBJS = $(foreach x,$(LIBC_STUBS_ARTIFACTS),$($(x)_OBJS))
$(LIBC_STUBS_OBJS): $(BUILD_FILES) libc/stubs/stubs.mk
.PHONY: o/libc/stubs
o/libc/stubs: $(LIBC_STUBS_CHECKS)
.PHONY: o/$(MODE)/libc/stubs
o/$(MODE)/libc/stubs: \
$(LIBC_STUBS_CHECKS)

View file

@ -18,9 +18,9 @@
02110-1301 USA
*/
#include "libc/macros.h"
.align 16
.text.likely
.source __FILE__
.privileged
.alignfunc
/ Returns 𝑥-𝑦, aborting on overflow.
/

View file

@ -18,9 +18,9 @@
02110-1301 USA
*/
#include "libc/macros.h"
.align 16
.text.likely
.source __FILE__
.privileged
.alignfunc
/ Returns 𝑥-𝑦, aborting on overflow.
/

View file

@ -18,9 +18,9 @@
02110-1301 USA
*/
#include "libc/macros.h"
.align 16
.text.likely
.source __FILE__
.privileged
.alignfunc
/ Returns 𝑥-𝑦, aborting on overflow.
/
@ -30,8 +30,9 @@
/ @see -ftrapv
__subvti3:
mov %rdi,%rax
sub %rsi,%rax
sbb %rdi,%rdx
sub %rdx,%rax
mov %rsi,%rdx
sbb %rcx,%rdx
jo 1f
ret
1: push %rbp

63
libc/stubs/sysv2nt.S Normal file
View file

@ -0,0 +1,63 @@
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify │
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License. │
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of │
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software │
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/macros.h"
.text.windows
/ Epilogues for calling functions w/ Microsoft x64 convention.
/
/ @param %rax is address of windows x64 function to call
/ @param %rsi is ignored
/ @param %rdx,%rcx,%r8,%r9,stack are params (unlimited)
/ @param %xmm0,%xmm1,%xmm2 are double params (limited to 3)
/ @return is in %rax, %xmm0, or %st
/ @note GCC 4.8+ and Clang can avoid this indirection
/ @note thunk that jumps here must setup frame
/ @note this is so much faster than nt2sysv()
__sysv2nt14:
pushq 72(%rbp)
pushq 64(%rbp)
__sysv2nt12:
pushq 56(%rbp)
pushq 48(%rbp)
__sysv2nt10:
pushq 40(%rbp)
pushq 32(%rbp)
__sysv2nt8:
pushq 24(%rbp)
pushq 16(%rbp)
__sysv2nt6:
push %r9
push %r8
__sysv2nt:
mov %rdx,%r8
mov %rcx,%r9
mov %rdi,%rcx
mov %rsi,%rdx
sub $32,%rsp
call *%rax
leave
ret
.endfn __sysv2nt,globl,hidden
.endfn __sysv2nt6,globl,hidden
.endfn __sysv2nt8,globl,hidden
.endfn __sysv2nt10,globl,hidden
.endfn __sysv2nt12,globl,hidden
.endfn __sysv2nt14,globl,hidden
.source __FILE__

View file

@ -18,9 +18,33 @@
02110-1301 USA
*/
#include "libc/macros.h"
#include "ape/relocations.h"
#include "libc/zip.h"
/ ZIP Central Directory.
.section .piro.data.sort.zip.3,"a",@progbits
.hidden __zip_start
.globl __zip_start
.type __zip_start,@object
.align kZipCdirAlign
__zip_start:
.endfn __zip_start,weak
.previous/*
...
decentralized content
...
*/.section .piro.data.sort.zip.5,"a",@progbits
.align kZipCdirAlign
__zip_end:
.endfn __zip_end,weak
.long kZipCdirHdrMagic # magic
.short 0 # disk
.short 0 # starting disk
.short v_zip_records # records on disk
.short v_zip_records # records
.long v_zip_cdirsize # size of central directory
.long RVA(__zip_start) # central directory offset
.short v_zip_commentsize # comment size
.endobj __zip_end,globl,hidden
.weak v_zip_records
.weak v_zip_cdirsize
.weak v_zip_commentsize
.previous