diff options
author | Ori Bernstein <ori@eigenstate.org> | 2017-02-15 22:50:13 -0800 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2017-02-15 22:50:13 -0800 |
commit | bf2829b82ba77f1f9fd5586e4216995366cf7aed (patch) | |
tree | 844d5e26db35942d43dc454f495b1982b6b21999 | |
parent | f2e6c0069b510391b2a309868ed3b049bf95167a (diff) | |
download | mc-bf2829b82ba77f1f9fd5586e4216995366cf7aed.tar.gz |
Add assembly start code for netbsd.
Seems to work so far.
-rw-r--r-- | mk/c.mk | 2 | ||||
-rw-r--r-- | rt/abort-netbsd.s | 42 | ||||
-rw-r--r-- | rt/start-netbsd.s | 86 |
3 files changed, 129 insertions, 1 deletions
@@ -9,7 +9,7 @@ _LIBINCPATHS=$(addprefix -I, $(dir $(DEPS))) $(_PCHDRS) _LIBPATHS=$(addprefix -l, $(patsubst lib%.a,%,$(notdir $(DEPS)))) $(_PCLIBS) # yeah, I should probably remove -Werror, but it's nice for developing alone. -CFLAGS += -Wall -Wextra -Werror -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -g -O0 +CFLAGS += -Wall -Wextra -Werror -Wno-unused-parameter -Wno-missing-field-initializers -Wno-sign-compare -Wno-char-subscripts -g -O0 CFLAGS += -MMD -MP -MF .deps/$(subst /,-,$*).d LIB ?= $(INSTLIB) diff --git a/rt/abort-netbsd.s b/rt/abort-netbsd.s new file mode 100644 index 0000000..a4b12bb --- /dev/null +++ b/rt/abort-netbsd.s @@ -0,0 +1,42 @@ +.text + +.globl _rt$abort_oob +.globl __rt$abort_oob +_rt$abort_oob: +__rt$abort_oob: + /* format pc */ + movq (%rsp),%rax + movq $15,%rdx + leaq .digitchars(%rip),%r8 + leaq .pcstr(%rip),%r9 +.loop: + movq %rax, %rcx + andq $0xf, %rcx + movb (%r8,%rcx),%r10b + movb %r10b,(%r9,%rdx) + subq $1, %rdx + shrq $4, %rax + jnz .loop + /* write abort message */ + movq $4, %rax /* write(fd=%rdi, msg=%rsi, len=%rdx) */ + movq $2, %rdi /* fd */ + leaq .msg(%rip), %rsi /* msg */ + movq $(.msgend-.msg), %rdx /* length */ + syscall + /* kill self */ + movq $20,%rax /* getpid */ + syscall + movq %rax, %rdi /* save pid */ + movq $37, %rax /* kill(pid=%rdi, sig=%rsi) */ + movq $6, %rsi + syscall +.data +.msg: /* pc name: */ + .ascii "0x" +.pcstr: + .ascii "0000000000000000" + .ascii ": out of bounds access\n" +.msgend: + +.digitchars: + .ascii "0123456789abcdef" diff --git a/rt/start-netbsd.s b/rt/start-netbsd.s new file mode 100644 index 0000000..d78559e --- /dev/null +++ b/rt/start-netbsd.s @@ -0,0 +1,86 @@ +.section .note.netbsd.ident + .long 7 + .long 4 + .long 1 + .ascii "NetBSD\0" + .p2align 2 + .long 200000000 + +.data + +/* sys._environment : byte[:][:] */ +.globl sys$__environment +sys$__environment: + .envbase: + .quad 0 /* env size */ + .envlen: + .quad 0 /* env ptr */ + +.globl sys$__cenvp +sys$__cenvp: + .quad 0 + +.text +/* + * The entry point for the whole program. + * This is called by the OS. In order, it: + * - Sets up all argc entries as slices + * - Sets up all envp entries as slices + * - Converts argc/argv to a slice + * - Stashes envp in sys._environment + * - Stashes a raw envp copy in __cenvp (for syscalls to use) + * - Calls main() + */ +.globl _start +_start: + /* turn args into a slice */ + movq %rsp,%rbp + + /* stack allocate sizeof(byte[:])*(argc + len(envp)) */ + movq (%rbp),%rax + leaq 16(%rbp,%rax,8), %rbx /* argp = argv + 8*argc + 8 */ + call count + addq %r9,%rax + imulq $16,%rax + subq %rax,%rsp + movq %rsp, %rdx /* saved args[:] */ + + /* stack allocate sizeof(byte[:])*(argc + len(envp)) */ + movq (%rbp),%rax + leaq 16(%rbp,%rax,8), %rbx /* argp = argv + 8*argc + 8 */ + call count + addq %r9,%rax + imulq $16,%rax + subq %rax,%rsp + movq %rsp, %rdx /* saved args[:] */ + + /* convert envp to byte[:][:] for sys._environment */ + movq (%rbp),%rax + leaq 16(%rbp,%rax,8), %rbx /* envp = argv + 8*argc + 8 */ + /* store envp for some syscalls to use without converting */ + movq %rbx,sys$__cenvp(%rip) + movq %r9,%rax + movq %rsp, %rcx + movq %r9,.envlen(%rip) + movq %rdx,.envbase(%rip) + call cvt + movq %rcx,%rdx + + /* convert argc, argv to byte[:][:] for args. */ + movq (%rbp), %rax /* argc */ + leaq 8(%rbp), %rbx /* argv */ + movq (%rbp), %rsi /* saved argc */ + call cvt + pushq %rsi + pushq %rdx + + xorq %rbp,%rbp + /* call pre-main initializers */ + call __init__ + /* enter the main program */ + call main + /* exit(0) */ + xorq %rdi,%rdi + movq $1,%rax + syscall + |