~sircmpwn/hare-dev

NetBSD support for harec v2 SUPERSEDED

Andreas R: 1
 NetBSD support for harec

 11 files changed, 806 insertions(+), 1 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~sircmpwn/hare-dev/patches/36677/mbox | git am -3
Learn more about email & git

[PATCH v2] NetBSD support for harec Export this patch

---
added NetBSD build manifest, NetBSD README.md build status
 .builds/netbsd.yml          |  21 ++
 README.md                   |   1 +
 rt/+netbsd/errno.ha         |  98 ++++++++
 rt/+netbsd/segmalloc.ha     |  10 +
 rt/+netbsd/start+x86_64.s   |  16 ++
 rt/+netbsd/syscall+x86_64.s |  69 ++++++
 rt/+netbsd/syscallno.ha     | 429 ++++++++++++++++++++++++++++++++++++
 rt/+netbsd/syscalls.ha      |  84 +++++++
 rt/configure                |  27 ++-
 rt/hare+netbsd.sc           |  47 ++++
 tests/configure             |   5 +
 11 files changed, 806 insertions(+), 1 deletion(-)
 create mode 100644 .builds/netbsd.yml
 create mode 100644 rt/+netbsd/errno.ha
 create mode 100644 rt/+netbsd/segmalloc.ha
 create mode 100644 rt/+netbsd/start+x86_64.s
 create mode 100644 rt/+netbsd/syscall+x86_64.s
 create mode 100644 rt/+netbsd/syscallno.ha
 create mode 100644 rt/+netbsd/syscalls.ha
 create mode 100644 rt/hare+netbsd.sc

diff --git a/.builds/netbsd.yml b/.builds/netbsd.yml
new file mode 100644
index 0000000..2d8e4e9
--- /dev/null
+++ b/.builds/netbsd.yml
@@ -0,0 +1,21 @@
image: netbsd/9.x
sources:
- https://git.sr.ht/~sircmpwn/harec
- git://c9x.me/qbe.git
packages:
- binutils
tasks:
- qbe: |
    cd qbe
    make PREFIX=/usr
    sudo make install PREFIX=/usr
- prepare: |
    mkdir harec/build
    cd harec/build
    ../configure
- build: |
    cd harec/build
    make -j2
- tests: |
    cd harec/build
    make check
diff --git a/README.md b/README.md
index 7daf284..c4189cb 100644
--- a/README.md
+++ b/README.md
@@ -8,6 +8,7 @@ POSIX-compatible systems.
<dl>
  <dt>Linux (x86_64)</dt><dd><a href="https://builds.sr.ht/~sircmpwn/harec/commits/master/alpine.yml"><img src="https://builds.sr.ht/~sircmpwn/harec/commits/master/alpine.yml.svg" alt="Build status for Linux" /></a></dd>
  <dt>FreeBSD (x86_64)</dt><dd><a href="https://builds.sr.ht/~sircmpwn/harec/commits/master/freebsd.yml"><img src="https://builds.sr.ht/~sircmpwn/harec/commits/master/freebsd.yml.svg" alt="Build status for FreeBSD" /></a></dd>
  <dt>NetBSD (x86_64)</dt><dd><a href="https://builds.sr.ht/~sircmpwn/harec/commits/master/netbsd.yml"><img src="https://builds.sr.ht/~sircmpwn/harec/commits/master/netbsd.yml.svg" alt="Build status for NetBSD" /></a></dd>
</dl>

## Building
diff --git a/rt/+netbsd/errno.ha b/rt/+netbsd/errno.ha
new file mode 100644
index 0000000..35d9db7
--- /dev/null
+++ b/rt/+netbsd/errno.ha
@@ -0,0 +1,98 @@
export def EPERM: int = 1;
export def ENOENT: int = 2;
export def ESRCH: int = 3;
export def EINTR: int = 4;
export def EIO: int = 5;
export def ENXIO: int = 6;
export def E2BIG: int = 7;
export def ENOEXEC: int = 8;
export def EBADF: int = 9;
export def ECHILD: int = 10;
export def EDEADLK: int = 11;
export def ENOMEM: int = 12;
export def EACCES: int = 13;
export def EFAULT: int = 14;
export def ENOTBLK: int = 15;
export def EBUSY: int = 16;
export def EEXIST: int = 17;
export def EXDEV: int = 18;
export def ENODEV: int = 19;
export def ENOTDIR: int = 20;
export def EISDIR: int = 21;
export def EINVAL: int = 22;
export def ENFILE: int = 23;
export def EMFILE: int = 24;
export def ENOTTY: int = 25;
export def ETXTBSY: int = 26;
export def EFBIG: int = 27;
export def ENOSPC: int = 28;
export def ESPIPE: int = 29;
export def EROFS: int = 30;
export def EMLINK: int = 31;
export def EPIPE: int = 32;
export def EDOM: int = 33;
export def ERANGE: int = 34;
export def EAGAIN: int = 35;
export def EWOULDBLOCK: int = EAGAIN;
export def EINPROGRESS: int = 36;
export def EALREADY: int = 37;
export def ENOTSOCK: int = 38;
export def EDESTADDRREQ: int = 39;
export def EMSGSIZE: int = 40;
export def EPROTOTYPE: int = 41;
export def ENOPROTOOPT: int = 42;
export def EPROTONOSUPPORT: int = 43;
export def ESOCKTNOSUPPORT: int = 44;
export def EOPNOTSUPP: int = 45;
export def EPFNOSUPPORT: int = 46;
export def EAFNOSUPPORT: int = 47;
export def EADDRINUSE: int = 48;
export def EADDRNOTAVAIL: int = 49;
export def ENETDOWN: int = 50;
export def ENETUNREACH: int = 51;
export def ENETRESET: int = 52;
export def ECONNABORTED: int = 53;
export def ECONNRESET: int = 54;
export def ENOBUFS: int = 55;
export def EISCONN: int = 56;
export def ENOTCONN: int = 57;
export def ESHUTDOWN: int = 58;
export def ETOOMANYREFS: int = 59;
export def ETIMEDOUT: int = 60;
export def ECONNREFUSED: int = 61;
export def ELOOP: int = 62;
export def ENAMETOOLONG: int = 63;
export def EHOSTDOWN: int = 64;
export def EHOSTUNREACH: int = 65;
export def ENOTEMPTY: int = 66;
export def EPROCLIM: int = 67;
export def EUSERS: int = 68;
export def EDQUOT: int = 69;
export def ESTALE: int = 70;
export def EREMOTE: int = 71;
export def EBADRPC: int = 72;
export def ERPCMISMATCH: int = 73;
export def EPROGUNAVAIL: int = 74;
export def EPROGMISMATCH: int = 75;
export def EPROCUNAVAIL: int = 76;
export def ENOLCK: int = 77;
export def ENOSYS: int = 78;
export def EFTYPE: int = 79;
export def EAUTH: int = 80;
export def ENEEDAUTH: int = 81;
export def EIDRM: int = 82;
export def ENOMSG: int = 83;
export def EOVERFLOW: int = 84;
export def EILSEQ: int = 85;
export def ENOTSUP: int = 86;
export def ECANCELED: int = 87;
export def EBADMSG: int = 88;
export def ENODATA: int = 89;
export def ENOSR: int = 90;
export def ENOSTR: int = 91;
export def ETIME: int = 92;
export def ENOATTR: int = 93;
export def EMULTIHOP: int = 94;
export def ENOLINK: int = 95;
export def EPROTO: int = 96;
export def ELAST: int = 96;
diff --git a/rt/+netbsd/segmalloc.ha b/rt/+netbsd/segmalloc.ha
new file mode 100644
index 0000000..e3844b4
--- /dev/null
+++ b/rt/+netbsd/segmalloc.ha
@@ -0,0 +1,10 @@
// Allocates a segment.
fn segmalloc(n: size) nullable *void = {
	let p: *void = mmap(null, n,
		PROT_READ | PROT_WRITE,
		MAP_PRIVATE | MAP_ANON, -1, 0);
	return if (p: uintptr: int == -ENOMEM) null else p;
};

// Frees a segment allocated with segmalloc.
fn segfree(p: *void, s: size) int = munmap(p, s);
diff --git a/rt/+netbsd/start+x86_64.s b/rt/+netbsd/start+x86_64.s
new file mode 100644
index 0000000..f5c3fc0
--- /dev/null
+++ b/rt/+netbsd/start+x86_64.s
@@ -0,0 +1,16 @@
.section ".note.netbsd.ident", "a"
	.long   2f-1f
	.long   4f-3f
	.long   1
1:      .asciz "NetBSD"
2:      .p2align 2
3:      .long   199905
4:      .p2align 2

.text
.global _start
_start:
	xor %rbp, %rbp
	movq %rsp, %rdi
	andq $-16, %rsp
	call rt.start_ha
diff --git a/rt/+netbsd/syscall+x86_64.s b/rt/+netbsd/syscall+x86_64.s
new file mode 100644
index 0000000..786f272
--- /dev/null
+++ b/rt/+netbsd/syscall+x86_64.s
@@ -0,0 +1,69 @@
.section .text.rt.syscall0
.global rt.syscall0
rt.syscall0:
	movq %rdi, %rax
	syscall
	ret

.section .text.rt.syscall1
.global rt.syscall1
rt.syscall1:
	movq %rdi, %rax
	movq %rsi, %rdi
	syscall
	ret

.section .text.rt.syscall2
.global rt.syscall2
rt.syscall2:
	movq %rdi, %rax
	movq %rsi, %rdi
	movq %rdx, %rsi
	syscall
	ret

.section .text.rt.syscall3
.global rt.syscall3
rt.syscall3:
	movq %rdi, %rax
	movq %rsi, %rdi
	movq %rdx, %rsi
	movq %rcx, %rdx
	syscall
	ret

.section .text.rt.syscall4
.global rt.syscall4
rt.syscall4:
	movq %rdi, %rax
	movq %r8, %r10
	movq %rsi, %rdi
	movq %rdx, %rsi
	movq %rcx, %rdx
	syscall
	ret

.section .text.rt.syscall5
.global rt.syscall5
rt.syscall5:
	movq %rdi, %rax
	movq %r8, %r10
	movq %rsi, %rdi
	movq %r9, %r8
	movq %rdx, %rsi
	movq %rcx, %rdx
	syscall
	ret

.section .text.rt.syscall6
.global rt.syscall6
rt.syscall6:
	movq %rdi, %rax
	movq %r8, %r10
	movq %rsi, %rdi
	movq %r9, %r8
	movq %rdx, %rsi
	movq 8(%rsp), %r9
	movq %rcx, %rdx
	syscall
	ret
diff --git a/rt/+netbsd/syscallno.ha b/rt/+netbsd/syscallno.ha
new file mode 100644
index 0000000..b8d3ac7
--- /dev/null
+++ b/rt/+netbsd/syscallno.ha
@@ -0,0 +1,429 @@
export def SYS_syscall: u64 = 0;
export def SYS_exit: u64 = 1;
export def SYS_fork: u64 = 2;
export def SYS_read: u64 = 3;
export def SYS_write: u64 = 4;
export def SYS_open: u64 = 5;
export def SYS_close: u64 = 6;
export def SYS_compat_50_wait4: u64 = 7;
export def SYS_compat_43_ocreat: u64 = 8;
export def SYS_link: u64 = 9;
export def SYS_unlink: u64 = 10;
export def SYS_chdir: u64 = 12;
export def SYS_fchdir: u64 = 13;
export def SYS_compat_50_mknod: u64 = 14;
export def SYS_chmod: u64 = 15;
export def SYS_chown: u64 = 16;
export def SYS_break: u64 = 17;
export def SYS_compat_20_getfsstat: u64 = 18;
export def SYS_compat_43_olseek: u64 = 19;
export def SYS_getpid: u64 = 20;
export def SYS_compat_40_mount: u64 = 21;
export def SYS_unmount: u64 = 22;
export def SYS_setuid: u64 = 23;
export def SYS_getuid: u64 = 24;
export def SYS_geteuid: u64 = 25;
export def SYS_ptrace: u64 = 26;
export def SYS_recvmsg: u64 = 27;
export def SYS_sendmsg: u64 = 28;
export def SYS_recvfrom: u64 = 29;
export def SYS_accept: u64 = 30;
export def SYS_getpeername: u64 = 31;
export def SYS_getsockname: u64 = 32;
export def SYS_access: u64 = 33;
export def SYS_chflags: u64 = 34;
export def SYS_fchflags: u64 = 35;
export def SYS_sync: u64 = 36;
export def SYS_kill: u64 = 37;
export def SYS_compat_43_stat43: u64 = 38;
export def SYS_getppid: u64 = 39;
export def SYS_compat_43_lstat43: u64 = 40;
export def SYS_dup: u64 = 41;
export def SYS_pipe: u64 = 42;
export def SYS_getegid: u64 = 43;
export def SYS_profil: u64 = 44;
export def SYS_ktrace: u64 = 45;
export def SYS_compat_13_sigaction13: u64 = 46;
export def SYS_getgid: u64 = 47;
export def SYS_compat_13_sigprocmask13: u64 = 48;
export def SYS___getlogin: u64 = 49;
export def SYS___setlogin: u64 = 50;
export def SYS_acct: u64 = 51;
export def SYS_compat_13_sigpending13: u64 = 52;
export def SYS_compat_13_sigaltstack13: u64 = 53;
export def SYS_ioctl: u64 = 54;
export def SYS_compat_12_oreboot: u64 = 55;
export def SYS_revoke: u64 = 56;
export def SYS_symlink: u64 = 57;
export def SYS_readlink: u64 = 58;
export def SYS_execve: u64 = 59;
export def SYS_umask: u64 = 60;
export def SYS_chroot: u64 = 61;
export def SYS_compat_43_fstat43: u64 = 62;
export def SYS_compat_43_ogetkerninfo: u64 = 63;
export def SYS_compat_43_ogetpagesize: u64 = 64;
export def SYS_compat_12_msync: u64 = 65;
export def SYS_vfork: u64 = 66;
export def SYS_compat_43_ommap: u64 = 71;
export def SYS_vadvise: u64 = 72;
export def SYS_munmap: u64 = 73;
export def SYS_mprotect: u64 = 74;
export def SYS_madvise: u64 = 75;
export def SYS_mincore: u64 = 78;
export def SYS_getgroups: u64 = 79;
export def SYS_setgroups: u64 = 80;
export def SYS_getpgrp: u64 = 81;
export def SYS_setpgid: u64 = 82;
export def SYS_compat_50_setitimer: u64 = 83;
export def SYS_compat_43_owait: u64 = 84;
export def SYS_compat_12_oswapon: u64 = 85;
export def SYS_compat_50_getitimer: u64 = 86;
export def SYS_compat_43_ogethostname: u64 = 87;
export def SYS_compat_43_osethostname: u64 = 88;
export def SYS_compat_43_ogetdtablesize: u64 = 89;
export def SYS_dup2: u64 = 90;
export def SYS_fcntl: u64 = 92;
export def SYS_compat_50_select: u64 = 93;
export def SYS_fsync: u64 = 95;
export def SYS_setpriority: u64 = 96;
export def SYS_compat_30_socket: u64 = 97;
export def SYS_connect: u64 = 98;
export def SYS_compat_43_oaccept: u64 = 99;
export def SYS_getpriority: u64 = 100;
export def SYS_compat_43_osend: u64 = 101;
export def SYS_compat_43_orecv: u64 = 102;
export def SYS_compat_13_sigreturn13: u64 = 103;
export def SYS_bind: u64 = 104;
export def SYS_setsockopt: u64 = 105;
export def SYS_listen: u64 = 106;
export def SYS_compat_43_osigvec: u64 = 108;
export def SYS_compat_43_osigblock: u64 = 109;
export def SYS_compat_43_osigsetmask: u64 = 110;
export def SYS_compat_13_sigsuspend13: u64 = 111;
export def SYS_compat_43_osigstack: u64 = 112;
export def SYS_compat_43_orecvmsg: u64 = 113;
export def SYS_compat_43_osendmsg: u64 = 114;
export def SYS_compat_50_gettimeofday: u64 = 116;
export def SYS_compat_50_getrusage: u64 = 117;
export def SYS_getsockopt: u64 = 118;
export def SYS_readv: u64 = 120;
export def SYS_writev: u64 = 121;
export def SYS_compat_50_settimeofday: u64 = 122;
export def SYS_fchown: u64 = 123;
export def SYS_fchmod: u64 = 124;
export def SYS_compat_43_orecvfrom: u64 = 125;
export def SYS_setreuid: u64 = 126;
export def SYS_setregid: u64 = 127;
export def SYS_rename: u64 = 128;
export def SYS_compat_43_otruncate: u64 = 129;
export def SYS_compat_43_oftruncate: u64 = 130;
export def SYS_flock: u64 = 131;
export def SYS_mkfifo: u64 = 132;
export def SYS_sendto: u64 = 133;
export def SYS_shutdown: u64 = 134;
export def SYS_socketpair: u64 = 135;
export def SYS_mkdir: u64 = 136;
export def SYS_rmdir: u64 = 137;
export def SYS_compat_50_utimes: u64 = 138;
export def SYS_compat_50_adjtime: u64 = 140;
export def SYS_compat_43_ogetpeername: u64 = 141;
export def SYS_compat_43_ogethostid: u64 = 142;
export def SYS_compat_43_osethostid: u64 = 143;
export def SYS_compat_43_ogetrlimit: u64 = 144;
export def SYS_compat_43_osetrlimit: u64 = 145;
export def SYS_compat_43_okillpg: u64 = 146;
export def SYS_setsid: u64 = 147;
export def SYS_compat_50_quotactl: u64 = 148;
export def SYS_compat_43_oquota: u64 = 149;
export def SYS_compat_43_ogetsockname: u64 = 150;
export def SYS_nfssvc: u64 = 155;
export def SYS_compat_43_ogetdirentries: u64 = 156;
export def SYS_compat_20_statfs: u64 = 157;
export def SYS_compat_20_fstatfs: u64 = 158;
export def SYS_compat_30_getfh: u64 = 161;
export def SYS_compat_09_ogetdomainname: u64 = 162;
export def SYS_compat_09_osetdomainname: u64 = 163;
export def SYS_compat_09_ouname: u64 = 164;
export def SYS_sysarch: u64 = 165;
export def SYS_compat_10_osemsys: u64 = 169;
export def SYS_compat_10_omsgsys: u64 = 170;
export def SYS_compat_10_oshmsys: u64 = 171;
export def SYS_pread: u64 = 173;
export def SYS_pwrite: u64 = 174;
export def SYS_compat_30_ntp_gettime: u64 = 175;
export def SYS_ntp_adjtime: u64 = 176;
export def SYS_setgid: u64 = 181;
export def SYS_setegid: u64 = 182;
export def SYS_seteuid: u64 = 183;
export def SYS_lfs_bmapv: u64 = 184;
export def SYS_lfs_markv: u64 = 185;
export def SYS_lfs_segclean: u64 = 186;
export def SYS_compat_50_lfs_segwait: u64 = 187;
export def SYS_compat_12_stat12: u64 = 188;
export def SYS_compat_12_fstat12: u64 = 189;
export def SYS_compat_12_lstat12: u64 = 190;
export def SYS_pathconf: u64 = 191;
export def SYS_fpathconf: u64 = 192;
export def SYS_getsockopt2: u64 = 193;
export def SYS_getrlimit: u64 = 194;
export def SYS_setrlimit: u64 = 195;
export def SYS_compat_12_getdirentries: u64 = 196;
export def SYS_mmap: u64 = 197;
export def SYS___syscall: u64 = 198;
export def SYS_lseek: u64 = 199;
export def SYS_truncate: u64 = 200;
export def SYS_ftruncate: u64 = 201;
export def SYS___sysctl: u64 = 202;
export def SYS_mlock: u64 = 203;
export def SYS_munlock: u64 = 204;
export def SYS_undelete: u64 = 205;
export def SYS_compat_50_futimes: u64 = 206;
export def SYS_getpgid: u64 = 207;
export def SYS_reboot: u64 = 208;
export def SYS_poll: u64 = 209;
export def SYS_afssys: u64 = 210;
export def SYS_compat_14___semctl: u64 = 220;
export def SYS_semget: u64 = 221;
export def SYS_semop: u64 = 222;
export def SYS_semconfig: u64 = 223;
export def SYS_compat_14_msgctl: u64 = 224;
export def SYS_msgget: u64 = 225;
export def SYS_msgsnd: u64 = 226;
export def SYS_msgrcv: u64 = 227;
export def SYS_shmat: u64 = 228;
export def SYS_compat_14_shmctl: u64 = 229;
export def SYS_shmdt: u64 = 230;
export def SYS_shmget: u64 = 231;
export def SYS_compat_50_clock_gettime: u64 = 232;
export def SYS_compat_50_clock_settime: u64 = 233;
export def SYS_compat_50_clock_getres: u64 = 234;
export def SYS_timer_create: u64 = 235;
export def SYS_timer_delete: u64 = 236;
export def SYS_compat_50_timer_settime: u64 = 237;
export def SYS_compat_50_timer_gettime: u64 = 238;
export def SYS_timer_getoverrun: u64 = 239;
export def SYS_compat_50_nanosleep: u64 = 240;
export def SYS_fdatasync: u64 = 241;
export def SYS_mlockall: u64 = 242;
export def SYS_munlockall: u64 = 243;
export def SYS_compat_50___sigtimedwait: u64 = 244;
export def SYS_sigqueueinfo: u64 = 245;
export def SYS_modctl: u64 = 246;
export def SYS__ksem_init: u64 = 247;
export def SYS__ksem_open: u64 = 248;
export def SYS__ksem_unlink: u64 = 249;
export def SYS__ksem_close: u64 = 250;
export def SYS__ksem_post: u64 = 251;
export def SYS__ksem_wait: u64 = 252;
export def SYS__ksem_trywait: u64 = 253;
export def SYS__ksem_getvalue: u64 = 254;
export def SYS__ksem_destroy: u64 = 255;
export def SYS__ksem_timedwait: u64 = 256;
export def SYS_mq_open: u64 = 257;
export def SYS_mq_close: u64 = 258;
export def SYS_mq_unlink: u64 = 259;
export def SYS_mq_getattr: u64 = 260;
export def SYS_mq_setattr: u64 = 261;
export def SYS_mq_notify: u64 = 262;
export def SYS_mq_send: u64 = 263;
export def SYS_mq_receive: u64 = 264;
export def SYS_compat_50_mq_timedsend: u64 = 265;
export def SYS_compat_50_mq_timedreceive: u64 = 266;
export def SYS___posix_rename: u64 = 270;
export def SYS_swapctl: u64 = 271;
export def SYS_compat_30_getdents: u64 = 272;
export def SYS_minherit: u64 = 273;
export def SYS_lchmod: u64 = 274;
export def SYS_lchown: u64 = 275;
export def SYS_compat_50_lutimes: u64 = 276;
export def SYS___msync13: u64 = 277;
export def SYS_compat_30___stat13: u64 = 278;
export def SYS_compat_30___fstat13: u64 = 279;
export def SYS_compat_30___lstat13: u64 = 280;
export def SYS___sigaltstack14: u64 = 281;
export def SYS___vfork14: u64 = 282;
export def SYS___posix_chown: u64 = 283;
export def SYS___posix_fchown: u64 = 284;
export def SYS___posix_lchown: u64 = 285;
export def SYS_getsid: u64 = 286;
export def SYS___clone: u64 = 287;
export def SYS_fktrace: u64 = 288;
export def SYS_preadv: u64 = 289;
export def SYS_pwritev: u64 = 290;
export def SYS_compat_16___sigaction14: u64 = 291;
export def SYS___sigpending14: u64 = 292;
export def SYS___sigprocmask14: u64 = 293;
export def SYS___sigsuspend14: u64 = 294;
export def SYS_compat_16___sigreturn14: u64 = 295;
export def SYS___getcwd: u64 = 296;
export def SYS_fchroot: u64 = 297;
export def SYS_compat_30_fhopen: u64 = 298;
export def SYS_compat_30_fhstat: u64 = 299;
export def SYS_compat_20_fhstatfs: u64 = 300;
export def SYS_compat_50_____semctl13: u64 = 301;
export def SYS_compat_50___msgctl13: u64 = 302;
export def SYS_compat_50___shmctl13: u64 = 303;
export def SYS_lchflags: u64 = 304;
export def SYS_issetugid: u64 = 305;
export def SYS_utrace: u64 = 306;
export def SYS_getcontext: u64 = 307;
export def SYS_setcontext: u64 = 308;
export def SYS__lwp_create: u64 = 309;
export def SYS__lwp_exit: u64 = 310;
export def SYS__lwp_self: u64 = 311;
export def SYS__lwp_wait: u64 = 312;
export def SYS__lwp_suspend: u64 = 313;
export def SYS__lwp_continue: u64 = 314;
export def SYS__lwp_wakeup: u64 = 315;
export def SYS__lwp_getprivate: u64 = 316;
export def SYS__lwp_setprivate: u64 = 317;
export def SYS__lwp_kill: u64 = 318;
export def SYS__lwp_detach: u64 = 319;
export def SYS_compat_50__lwp_park: u64 = 320;
export def SYS__lwp_unpark: u64 = 321;
export def SYS__lwp_unpark_all: u64 = 322;
export def SYS__lwp_setname: u64 = 323;
export def SYS__lwp_getname: u64 = 324;
export def SYS__lwp_ctl: u64 = 325;
export def SYS_compat_60_sa_register: u64 = 330;
export def SYS_compat_60_sa_stacks: u64 = 331;
export def SYS_compat_60_sa_enable: u64 = 332;
export def SYS_compat_60_sa_setconcurrency: u64 = 333;
export def SYS_compat_60_sa_yield: u64 = 334;
export def SYS_compat_60_sa_preempt: u64 = 335;
export def SYS___sigaction_sigtramp: u64 = 340;
export def SYS_rasctl: u64 = 343;
export def SYS_kqueue: u64 = 344;
export def SYS_compat_50_kevent: u64 = 345;
export def SYS__sched_setparam: u64 = 346;
export def SYS__sched_getparam: u64 = 347;
export def SYS__sched_setaffinity: u64 = 348;
export def SYS__sched_getaffinity: u64 = 349;
export def SYS_sched_yield: u64 = 350;
export def SYS__sched_protect: u64 = 351;
export def SYS_fsync_range: u64 = 354;
export def SYS_uuidgen: u64 = 355;
export def SYS_getvfsstat: u64 = 356;
export def SYS_statvfs1: u64 = 357;
export def SYS_fstatvfs1: u64 = 358;
export def SYS_compat_30_fhstatvfs1: u64 = 359;
export def SYS_extattrctl: u64 = 360;
export def SYS_extattr_set_file: u64 = 361;
export def SYS_extattr_get_file: u64 = 362;
export def SYS_extattr_delete_file: u64 = 363;
export def SYS_extattr_set_fd: u64 = 364;
export def SYS_extattr_get_fd: u64 = 365;
export def SYS_extattr_delete_fd: u64 = 366;
export def SYS_extattr_set_link: u64 = 367;
export def SYS_extattr_get_link: u64 = 368;
export def SYS_extattr_delete_link: u64 = 369;
export def SYS_extattr_list_fd: u64 = 370;
export def SYS_extattr_list_file: u64 = 371;
export def SYS_extattr_list_link: u64 = 372;
export def SYS_compat_50_pselect: u64 = 373;
export def SYS_compat_50_pollts: u64 = 374;
export def SYS_setxattr: u64 = 375;
export def SYS_lsetxattr: u64 = 376;
export def SYS_fsetxattr: u64 = 377;
export def SYS_getxattr: u64 = 378;
export def SYS_lgetxattr: u64 = 379;
export def SYS_fgetxattr: u64 = 380;
export def SYS_listxattr: u64 = 381;
export def SYS_llistxattr: u64 = 382;
export def SYS_flistxattr: u64 = 383;
export def SYS_removexattr: u64 = 384;
export def SYS_lremovexattr: u64 = 385;
export def SYS_fremovexattr: u64 = 386;
export def SYS_compat_50___stat30: u64 = 387;
export def SYS_compat_50___fstat30: u64 = 388;
export def SYS_compat_50___lstat30: u64 = 389;
export def SYS___getdents30: u64 = 390;
export def SYS_compat_30___fhstat30: u64 = 392;
export def SYS_compat_50___ntp_gettime30: u64 = 393;
export def SYS___socket30: u64 = 394;
export def SYS___getfh30: u64 = 395;
export def SYS___fhopen40: u64 = 396;
export def SYS___fhstatvfs140: u64 = 397;
export def SYS_compat_50___fhstat40: u64 = 398;
export def SYS_aio_cancel: u64 = 399;
export def SYS_aio_error: u64 = 400;
export def SYS_aio_fsync: u64 = 401;
export def SYS_aio_read: u64 = 402;
export def SYS_aio_return: u64 = 403;
export def SYS_compat_50_aio_suspend: u64 = 404;
export def SYS_aio_write: u64 = 405;
export def SYS_lio_listio: u64 = 406;
export def SYS___mount50: u64 = 410;
export def SYS_mremap: u64 = 411;
export def SYS_pset_create: u64 = 412;
export def SYS_pset_destroy: u64 = 413;
export def SYS_pset_assign: u64 = 414;
export def SYS__pset_bind: u64 = 415;
export def SYS___posix_fadvise50: u64 = 416;
export def SYS___select50: u64 = 417;
export def SYS___gettimeofday50: u64 = 418;
export def SYS___settimeofday50: u64 = 419;
export def SYS___utimes50: u64 = 420;
export def SYS___adjtime50: u64 = 421;
export def SYS___lfs_segwait50: u64 = 422;
export def SYS___futimes50: u64 = 423;
export def SYS___lutimes50: u64 = 424;
export def SYS___setitimer50: u64 = 425;
export def SYS___getitimer50: u64 = 426;
export def SYS___clock_gettime50: u64 = 427;
export def SYS___clock_settime50: u64 = 428;
export def SYS___clock_getres50: u64 = 429;
export def SYS___nanosleep50: u64 = 430;
export def SYS_____sigtimedwait50: u64 = 431;
export def SYS___mq_timedsend50: u64 = 432;
export def SYS___mq_timedreceive50: u64 = 433;
export def SYS_compat_60__lwp_park: u64 = 434;
export def SYS___kevent50: u64 = 435;
export def SYS___pselect50: u64 = 436;
export def SYS___pollts50: u64 = 437;
export def SYS___aio_suspend50: u64 = 438;
export def SYS___stat50: u64 = 439;
export def SYS___fstat50: u64 = 440;
export def SYS___lstat50: u64 = 441;
export def SYS_____semctl50: u64 = 442;
export def SYS___shmctl50: u64 = 443;
export def SYS___msgctl50: u64 = 444;
export def SYS___getrusage50: u64 = 445;
export def SYS___timer_settime50: u64 = 446;
export def SYS___timer_gettime50: u64 = 447;
export def SYS___ntp_gettime50: u64 = 448;
export def SYS___wait450: u64 = 449;
export def SYS___mknod50: u64 = 450;
export def SYS___fhstat50: u64 = 451;
export def SYS_pipe2: u64 = 453;
export def SYS_dup3: u64 = 454;
export def SYS_kqueue1: u64 = 455;
export def SYS_paccept: u64 = 456;
export def SYS_linkat: u64 = 457;
export def SYS_renameat: u64 = 458;
export def SYS_mkfifoat: u64 = 459;
export def SYS_mknodat: u64 = 460;
export def SYS_mkdirat: u64 = 461;
export def SYS_faccessat: u64 = 462;
export def SYS_fchmodat: u64 = 463;
export def SYS_fchownat: u64 = 464;
export def SYS_fexecve: u64 = 465;
export def SYS_fstatat: u64 = 466;
export def SYS_utimensat: u64 = 467;
export def SYS_openat: u64 = 468;
export def SYS_readlinkat: u64 = 469;
export def SYS_symlinkat: u64 = 470;
export def SYS_unlinkat: u64 = 471;
export def SYS_futimens: u64 = 472;
export def SYS___quotactl: u64 = 473;
export def SYS_posix_spawn: u64 = 474;
export def SYS_recvmmsg: u64 = 475;
export def SYS_sendmmsg: u64 = 476;
export def SYS_clock_nanosleep: u64 = 477;
export def SYS____lwp_park60: u64 = 478;
export def SYS_posix_fallocate: u64 = 479;
export def SYS_fdiscard: u64 = 480;
export def SYS_wait6: u64 = 481;
export def SYS_clock_getcpuclockid2: u64 = 482;
export def SYS_MAXSYSCALL: u64 = 483;
export def SYS_NSYSENT: u64 = 512;
diff --git a/rt/+netbsd/syscalls.ha b/rt/+netbsd/syscalls.ha
new file mode 100644
index 0000000..ae0cf04
--- /dev/null
+++ b/rt/+netbsd/syscalls.ha
@@ -0,0 +1,84 @@
fn syscall0(_: u64) u64;
fn syscall1(_: u64, _: u64) u64;
fn syscall2(_: u64, _: u64, _: u64) u64;
fn syscall3(_: u64, _: u64, _: u64, _: u64) u64;
fn syscall4(_: u64, _: u64, _: u64, _: u64, _: u64) u64;
fn syscall5(_: u64, _: u64, _: u64, _: u64, _: u64, _: u64) u64;
fn syscall6(_: u64, _: u64, _: u64, _: u64, _: u64, _: u64, _: u64) u64;

export fn write(fd: int, buf: *const void, count: size) size =
	syscall3(SYS_write, fd: u64, buf: uintptr: u64, count: u64): size;

export fn close(fd: int) int = syscall1(SYS_close, fd: u64): int;

export fn dup2(old: int, new: int) int =
	syscall2(SYS_dup2, old: u64, new: u64): int;

export fn getpid() int = syscall0(SYS_getpid): int;

export def EXIT_SUCCESS: int = 0;
export def EXIT_FAILURE: int = 1;

export @noreturn fn exit(status: int) void = { syscall1(SYS_exit, status: u64); };

export fn fork() int = syscall0(SYS_fork): int;

export fn execve(
	path: *const char,
	argv: *[*]nullable *const char,
	envp: *[*]nullable *const char,
) int = syscall3(SYS_execve,
	path: uintptr: u64,
	argv: uintptr: u64,
	envp: uintptr: u64): int;

export fn wait4(pid: int, status: *int, options: int, rusage: nullable *void) void = {
	syscall4(SYS_compat_50_wait4, pid: u64, status: uintptr: u64,
		options: u64, rusage: uintptr: u64);
};

export fn wifexited(status: int) bool = wtermsig(status) == 0;
export fn wexitstatus(status: int) int = (status & 0xff00) >> 8;

export fn wtermsig(status: int) int = status & 0x7f;
export fn wifsignaled(status: int) bool =
	wtermsig(status) != 0o177 && wtermsig(status) != 0 && status != 0x13;

export fn kill(pid: int, signal: int) int =
	syscall2(SYS_kill, pid: u64, signal: u64): int;

export fn pipe2(pipefd: *[2]int, flags: int) int =
	syscall2(SYS_pipe2, pipefd: uintptr: u64, flags: u64): int;

export def MAP_SHARED: uint = 0x0001;
export def MAP_PRIVATE: uint = 0x0002;
export def MAP_FIXED: uint = 0x0010;
export def __MAP_NOREPLACE: uint = 0x0800;
export def MAP_ANON: uint = 0x1000;
export def MAP_ANONYMOUS: uint = MAP_ANON;
export def __MAP_NOFAULT: uint = 0x2000;
export def MAP_STACK: uint = 0x4000;
export def MAP_CONCEAL: uint = 0x8000;

def PROT_NONE: uint = 0x00;
def PROT_READ: uint = 0x01;
def PROT_WRITE: uint = 0x02;
def PROT_EXEC: uint = 0x04;

export fn mmap(
	addr: nullable *void,
	length: size,
	prot: uint,
	flags: uint,
	fd: int,
	offs: size
) *void = {
	return syscall6(SYS_mmap, addr: uintptr: u64, length: u64, prot: u64,
		flags: u64, fd: u64, offs: u64): uintptr: *void;
};

export fn munmap(addr: *void, length: size) int =
	syscall2(SYS_munmap, addr: uintptr: u64, length: u64): int;

export def SIGABRT: int	= 6;
export def SIGCHLD: int	= 20;
diff --git a/rt/configure b/rt/configure
index d887ce3..ad0dd0b 100644
--- a/rt/configure
+++ b/rt/configure
@@ -53,7 +53,7 @@ rt() {
				amd64)
					arch=x86_64
					;;
				aarch64|riscv64)
					aarch64|riscv64)
					;;
				*)
					printf "unsupported OpenBSD arch %s\n" "$arch" >&2
@@ -75,6 +75,31 @@ rt() {
			rt: libhart.a rt/+openbsd/start+$arch.o
			EOF
			;;
		NetBSD)
			case $arch in
				amd64)
					arch=x86_64
					;;
				*)
					printf "unsupported NetBSD arch %s\n" "$arch" >&2
					;;
			esac
			rtstart=rt/+netbsd/start+$arch.o
			cat <<-EOF
			rtstart=rt/+netbsd/start+$arch.o

			libhart_srcs=\
				rt/+netbsd/errno.ha \
				rt/+netbsd/segmalloc.ha \
				rt/+netbsd/syscallno.ha \
				rt/+netbsd/syscalls.ha \

			libhart_objs=\
				rt/+netbsd/syscall+$arch.o

			rt: libhart.a rt/+netbsd/start+$arch.o
			EOF
			;;
		*)
			printf "rt not supported for %s\n" "$(uname)" >&2
			exit 1
diff --git a/rt/hare+netbsd.sc b/rt/hare+netbsd.sc
new file mode 100644
index 0000000..b62f920
--- /dev/null
+++ b/rt/hare+netbsd.sc
@@ -0,0 +1,47 @@
PHDRS {
	headers PT_PHDR PHDRS;
	text PT_LOAD FILEHDR PHDRS;
	data PT_LOAD;
	note PT_NOTE;
}
ENTRY(_start);
SECTIONS {
	. = 0x8000000;
	.text : {
		KEEP (*(.text))
		*(.text.*)
	} :text
	. = 0x80000000;
	.data : {
		KEEP (*(.data))
		*(.data.*)
	} :data

	.init_array : {
		PROVIDE_HIDDEN (__init_array_start = .);
		KEEP (*(.init_array))
		PROVIDE_HIDDEN (__init_array_end = .);
	} :data

	.fini_array : {
		PROVIDE_HIDDEN (__fini_array_start = .);
		KEEP (*(.fini_array))
		PROVIDE_HIDDEN (__fini_array_end = .);
	} :data

	.test_array : {
		PROVIDE_HIDDEN (__test_array_start = .);
		KEEP (*(.test_array))
		PROVIDE_HIDDEN (__test_array_end = .);
	} :data

	.note.openbsd.ident : {
		KEEP (*(.note.netbsd.ident))
		*(.note.netbsd.*)
	} :data :note

	.bss : {
		KEEP (*(.bss))
		*(.bss.*)
	} :data
}
diff --git a/tests/configure b/tests/configure
index d4b85e0..09864e3 100644
--- a/tests/configure
+++ b/tests/configure
@@ -8,6 +8,11 @@ then
	rtscript="rt/hare+openbsd.sc"
fi

if [ `uname -s` = "NetBSD" ]
then
	rtscript="rt/hare+netbsd.sc"
fi

tests() {
	# harec tests
	for t in \
-- 
2.30.2
Missing sign-off