ref: bf2829b82ba77f1f9fd5586e4216995366cf7aed
parent: f2e6c0069b510391b2a309868ed3b049bf95167a
author: Ori Bernstein <ori@eigenstate.org>
date: Wed Feb 15 17:50:13 EST 2017
Add assembly start code for netbsd. Seems to work so far.
--- a/mk/c.mk
+++ b/mk/c.mk
@@ -9,7 +9,7 @@
_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)
--- /dev/null
+++ b/rt/abort-netbsd.s
@@ -1,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"
--- /dev/null
+++ b/rt/start-netbsd.s
@@ -1,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
+