commit 873099fe3bd1eed3a6fc6d043caefad035a348f1
parent 97cbdab969488853362d591e656fa19c06afe8c6
Author: Drew DeVault <sir@cmpwn.com>
Date: Mon, 28 Dec 2020 14:21:01 -0500
Add bare-bones runtime to rt/
Diffstat:
10 files changed, 742 insertions(+), 0 deletions(-)
diff --git a/rt/+linux/syscall+x86_64.s b/rt/+linux/syscall+x86_64.s
@@ -0,0 +1,63 @@
+.text
+.global sys.syscall0
+sys.syscall0:
+ movq %rdi, %rax
+ syscall
+ ret
+
+.global sys.syscall1
+sys.syscall1:
+ movq %rdi, %rax
+ movq %rsi, %rdi
+ syscall
+ ret
+
+.global sys.syscall2
+sys.syscall2:
+ movq %rdi, %rax
+ movq %rsi, %rdi
+ movq %rdx, %rsi
+ syscall
+ ret
+
+.global sys.syscall3
+sys.syscall3:
+ movq %rdi, %rax
+ movq %rsi, %rdi
+ movq %rdx, %rsi
+ movq %rcx, %rdx
+ syscall
+ ret
+
+.global sys.syscall4
+sys.syscall4:
+ movq %rdi, %rax
+ movq %r8, %r10
+ movq %rsi, %rdi
+ movq %rdx, %rsi
+ movq %rcx, %rdx
+ syscall
+ ret
+
+.global sys.syscall5
+sys.syscall5:
+ movq %rdi, %rax
+ movq %r8, %r10
+ movq %rsi, %rdi
+ movq %r9, %r8
+ movq %rdx, %rsi
+ movq %rcx, %rdx
+ syscall
+ ret
+
+.global sys.syscall6
+sys.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/+linux/syscallno+x86_64.ha b/rt/+linux/syscallno+x86_64.ha
@@ -0,0 +1,345 @@
+export def SYS_read: u64 = 0;
+export def SYS_write: u64 = 1;
+export def SYS_open: u64 = 2;
+export def SYS_close: u64 = 3;
+export def SYS_stat: u64 = 4;
+export def SYS_fstat: u64 = 5;
+export def SYS_lstat: u64 = 6;
+export def SYS_poll: u64 = 7;
+export def SYS_lseek: u64 = 8;
+export def SYS_mmap: u64 = 9;
+export def SYS_mprotect: u64 = 10;
+export def SYS_munmap: u64 = 11;
+export def SYS_brk: u64 = 12;
+export def SYS_rt_sigaction: u64 = 13;
+export def SYS_rt_sigprocmask: u64 = 14;
+export def SYS_rt_sigreturn: u64 = 15;
+export def SYS_ioctl: u64 = 16;
+export def SYS_pread64: u64 = 17;
+export def SYS_pwrite64: u64 = 18;
+export def SYS_readv: u64 = 19;
+export def SYS_writev: u64 = 20;
+export def SYS_access: u64 = 21;
+export def SYS_pipe: u64 = 22;
+export def SYS_select: u64 = 23;
+export def SYS_sched_yield: u64 = 24;
+export def SYS_mremap: u64 = 25;
+export def SYS_msync: u64 = 26;
+export def SYS_mincore: u64 = 27;
+export def SYS_madvise: u64 = 28;
+export def SYS_shmget: u64 = 29;
+export def SYS_shmat: u64 = 30;
+export def SYS_shmctl: u64 = 31;
+export def SYS_dup: u64 = 32;
+export def SYS_dup2: u64 = 33;
+export def SYS_pause: u64 = 34;
+export def SYS_nanosleep: u64 = 35;
+export def SYS_getitimer: u64 = 36;
+export def SYS_alarm: u64 = 37;
+export def SYS_setitimer: u64 = 38;
+export def SYS_getpid: u64 = 39;
+export def SYS_sendfile: u64 = 40;
+export def SYS_socket: u64 = 41;
+export def SYS_connect: u64 = 42;
+export def SYS_accept: u64 = 43;
+export def SYS_sendto: u64 = 44;
+export def SYS_recvfrom: u64 = 45;
+export def SYS_sendmsg: u64 = 46;
+export def SYS_recvmsg: u64 = 47;
+export def SYS_shutdown: u64 = 48;
+export def SYS_bind: u64 = 49;
+export def SYS_listen: u64 = 50;
+export def SYS_getsockname: u64 = 51;
+export def SYS_getpeername: u64 = 52;
+export def SYS_socketpair: u64 = 53;
+export def SYS_setsockopt: u64 = 54;
+export def SYS_getsockopt: u64 = 55;
+export def SYS_clone: u64 = 56;
+export def SYS_fork: u64 = 57;
+export def SYS_vfork: u64 = 58;
+export def SYS_execve: u64 = 59;
+export def SYS_exit: u64 = 60;
+export def SYS_wait4: u64 = 61;
+export def SYS_kill: u64 = 62;
+export def SYS_uname: u64 = 63;
+export def SYS_semget: u64 = 64;
+export def SYS_semop: u64 = 65;
+export def SYS_semctl: u64 = 66;
+export def SYS_shmdt: u64 = 67;
+export def SYS_msgget: u64 = 68;
+export def SYS_msgsnd: u64 = 69;
+export def SYS_msgrcv: u64 = 70;
+export def SYS_msgctl: u64 = 71;
+export def SYS_fcntl: u64 = 72;
+export def SYS_flock: u64 = 73;
+export def SYS_fsync: u64 = 74;
+export def SYS_fdatasync: u64 = 75;
+export def SYS_truncate: u64 = 76;
+export def SYS_ftruncate: u64 = 77;
+export def SYS_getdents: u64 = 78;
+export def SYS_getcwd: u64 = 79;
+export def SYS_chdir: u64 = 80;
+export def SYS_fchdir: u64 = 81;
+export def SYS_rename: u64 = 82;
+export def SYS_mkdir: u64 = 83;
+export def SYS_rmdir: u64 = 84;
+export def SYS_creat: u64 = 85;
+export def SYS_link: u64 = 86;
+export def SYS_unlink: u64 = 87;
+export def SYS_symlink: u64 = 88;
+export def SYS_readlink: u64 = 89;
+export def SYS_chmod: u64 = 90;
+export def SYS_fchmod: u64 = 91;
+export def SYS_chown: u64 = 92;
+export def SYS_fchown: u64 = 93;
+export def SYS_lchown: u64 = 94;
+export def SYS_umask: u64 = 95;
+export def SYS_gettimeofday: u64 = 96;
+export def SYS_getrlimit: u64 = 97;
+export def SYS_getrusage: u64 = 98;
+export def SYS_sysinfo: u64 = 99;
+export def SYS_times: u64 = 100;
+export def SYS_ptrace: u64 = 101;
+export def SYS_getuid: u64 = 102;
+export def SYS_syslog: u64 = 103;
+export def SYS_getgid: u64 = 104;
+export def SYS_setuid: u64 = 105;
+export def SYS_setgid: u64 = 106;
+export def SYS_geteuid: u64 = 107;
+export def SYS_getegid: u64 = 108;
+export def SYS_setpgid: u64 = 109;
+export def SYS_getppid: u64 = 110;
+export def SYS_getpgrp: u64 = 111;
+export def SYS_setsid: u64 = 112;
+export def SYS_setreuid: u64 = 113;
+export def SYS_setregid: u64 = 114;
+export def SYS_getgroups: u64 = 115;
+export def SYS_setgroups: u64 = 116;
+export def SYS_setresuid: u64 = 117;
+export def SYS_getresuid: u64 = 118;
+export def SYS_setresgid: u64 = 119;
+export def SYS_getresgid: u64 = 120;
+export def SYS_getpgid: u64 = 121;
+export def SYS_setfsuid: u64 = 122;
+export def SYS_setfsgid: u64 = 123;
+export def SYS_getsid: u64 = 124;
+export def SYS_capget: u64 = 125;
+export def SYS_capset: u64 = 126;
+export def SYS_rt_sigpending: u64 = 127;
+export def SYS_rt_sigtimedwait: u64 = 128;
+export def SYS_rt_sigqueueinfo: u64 = 129;
+export def SYS_rt_sigsuspend: u64 = 130;
+export def SYS_sigaltstack: u64 = 131;
+export def SYS_utime: u64 = 132;
+export def SYS_mknod: u64 = 133;
+export def SYS_uselib: u64 = 134;
+export def SYS_personality: u64 = 135;
+export def SYS_ustat: u64 = 136;
+export def SYS_statfs: u64 = 137;
+export def SYS_fstatfs: u64 = 138;
+export def SYS_sysfs: u64 = 139;
+export def SYS_getpriority: u64 = 140;
+export def SYS_setpriority: u64 = 141;
+export def SYS_sched_setparam: u64 = 142;
+export def SYS_sched_getparam: u64 = 143;
+export def SYS_sched_setscheduler: u64 = 144;
+export def SYS_sched_getscheduler: u64 = 145;
+export def SYS_sched_get_priority_max: u64 = 146;
+export def SYS_sched_get_priority_min: u64 = 147;
+export def SYS_sched_rr_get_interval: u64 = 148;
+export def SYS_mlock: u64 = 149;
+export def SYS_munlock: u64 = 150;
+export def SYS_mlockall: u64 = 151;
+export def SYS_munlockall: u64 = 152;
+export def SYS_vhangup: u64 = 153;
+export def SYS_modify_ldt: u64 = 154;
+export def SYS_pivot_root: u64 = 155;
+export def SYS__sysctl: u64 = 156;
+export def SYS_prctl: u64 = 157;
+export def SYS_arch_prctl: u64 = 158;
+export def SYS_adjtimex: u64 = 159;
+export def SYS_setrlimit: u64 = 160;
+export def SYS_chroot: u64 = 161;
+export def SYS_sync: u64 = 162;
+export def SYS_acct: u64 = 163;
+export def SYS_settimeofday: u64 = 164;
+export def SYS_mount: u64 = 165;
+export def SYS_umount2: u64 = 166;
+export def SYS_swapon: u64 = 167;
+export def SYS_swapoff: u64 = 168;
+export def SYS_reboot: u64 = 169;
+export def SYS_sethostname: u64 = 170;
+export def SYS_setdomainname: u64 = 171;
+export def SYS_iopl: u64 = 172;
+export def SYS_ioperm: u64 = 173;
+export def SYS_create_module: u64 = 174;
+export def SYS_init_module: u64 = 175;
+export def SYS_delete_module: u64 = 176;
+export def SYS_get_kernel_syms: u64 = 177;
+export def SYS_query_module: u64 = 178;
+export def SYS_quotactl: u64 = 179;
+export def SYS_nfsservctl: u64 = 180;
+export def SYS_getpmsg: u64 = 181;
+export def SYS_putpmsg: u64 = 182;
+export def SYS_afs_syscall: u64 = 183;
+export def SYS_tuxcall: u64 = 184;
+export def SYS_security: u64 = 185;
+export def SYS_gettid: u64 = 186;
+export def SYS_readahead: u64 = 187;
+export def SYS_setxattr: u64 = 188;
+export def SYS_lsetxattr: u64 = 189;
+export def SYS_fsetxattr: u64 = 190;
+export def SYS_getxattr: u64 = 191;
+export def SYS_lgetxattr: u64 = 192;
+export def SYS_fgetxattr: u64 = 193;
+export def SYS_listxattr: u64 = 194;
+export def SYS_llistxattr: u64 = 195;
+export def SYS_flistxattr: u64 = 196;
+export def SYS_removexattr: u64 = 197;
+export def SYS_lremovexattr: u64 = 198;
+export def SYS_fremovexattr: u64 = 199;
+export def SYS_tkill: u64 = 200;
+export def SYS_time: u64 = 201;
+export def SYS_futex: u64 = 202;
+export def SYS_sched_setaffinity: u64 = 203;
+export def SYS_sched_getaffinity: u64 = 204;
+export def SYS_set_thread_area: u64 = 205;
+export def SYS_io_setup: u64 = 206;
+export def SYS_io_destroy: u64 = 207;
+export def SYS_io_getevents: u64 = 208;
+export def SYS_io_submit: u64 = 209;
+export def SYS_io_cancel: u64 = 210;
+export def SYS_get_thread_area: u64 = 211;
+export def SYS_lookup_dcookie: u64 = 212;
+export def SYS_epoll_create: u64 = 213;
+export def SYS_epoll_ctl_old: u64 = 214;
+export def SYS_epoll_wait_old: u64 = 215;
+export def SYS_remap_file_pages: u64 = 216;
+export def SYS_getdents64: u64 = 217;
+export def SYS_set_tid_address: u64 = 218;
+export def SYS_restart_syscall: u64 = 219;
+export def SYS_semtimedop: u64 = 220;
+export def SYS_fadvise64: u64 = 221;
+export def SYS_timer_create: u64 = 222;
+export def SYS_timer_settime: u64 = 223;
+export def SYS_timer_gettime: u64 = 224;
+export def SYS_timer_getoverrun: u64 = 225;
+export def SYS_timer_delete: u64 = 226;
+export def SYS_clock_settime: u64 = 227;
+export def SYS_clock_gettime: u64 = 228;
+export def SYS_clock_getres: u64 = 229;
+export def SYS_clock_nanosleep: u64 = 230;
+export def SYS_exit_group: u64 = 231;
+export def SYS_epoll_wait: u64 = 232;
+export def SYS_epoll_ctl: u64 = 233;
+export def SYS_tgkill: u64 = 234;
+export def SYS_utimes: u64 = 235;
+export def SYS_vserver: u64 = 236;
+export def SYS_mbind: u64 = 237;
+export def SYS_set_mempolicy: u64 = 238;
+export def SYS_get_mempolicy: u64 = 239;
+export def SYS_mq_open: u64 = 240;
+export def SYS_mq_unlink: u64 = 241;
+export def SYS_mq_timedsend: u64 = 242;
+export def SYS_mq_timedreceive: u64 = 243;
+export def SYS_mq_notify: u64 = 244;
+export def SYS_mq_getsetattr: u64 = 245;
+export def SYS_kexec_load: u64 = 246;
+export def SYS_waitid: u64 = 247;
+export def SYS_add_key: u64 = 248;
+export def SYS_request_key: u64 = 249;
+export def SYS_keyctl: u64 = 250;
+export def SYS_ioprio_set: u64 = 251;
+export def SYS_ioprio_get: u64 = 252;
+export def SYS_inotify_init: u64 = 253;
+export def SYS_inotify_add_watch: u64 = 254;
+export def SYS_inotify_rm_watch: u64 = 255;
+export def SYS_migrate_pages: u64 = 256;
+export def SYS_openat: u64 = 257;
+export def SYS_mkdirat: u64 = 258;
+export def SYS_mknodat: u64 = 259;
+export def SYS_fchownat: u64 = 260;
+export def SYS_futimesat: u64 = 261;
+export def SYS_newfstatat: u64 = 262;
+export def SYS_unlinkat: u64 = 263;
+export def SYS_renameat: u64 = 264;
+export def SYS_linkat: u64 = 265;
+export def SYS_symlinkat: u64 = 266;
+export def SYS_readlinkat: u64 = 267;
+export def SYS_fchmodat: u64 = 268;
+export def SYS_faccessat: u64 = 269;
+export def SYS_pselect6: u64 = 270;
+export def SYS_ppoll: u64 = 271;
+export def SYS_unshare: u64 = 272;
+export def SYS_set_robust_list: u64 = 273;
+export def SYS_get_robust_list: u64 = 274;
+export def SYS_splice: u64 = 275;
+export def SYS_tee: u64 = 276;
+export def SYS_sync_file_range: u64 = 277;
+export def SYS_vmsplice: u64 = 278;
+export def SYS_move_pages: u64 = 279;
+export def SYS_utimensat: u64 = 280;
+export def SYS_epoll_pwait: u64 = 281;
+export def SYS_signalfd: u64 = 282;
+export def SYS_timerfd_create: u64 = 283;
+export def SYS_eventfd: u64 = 284;
+export def SYS_fallocate: u64 = 285;
+export def SYS_timerfd_settime: u64 = 286;
+export def SYS_timerfd_gettime: u64 = 287;
+export def SYS_accept4: u64 = 288;
+export def SYS_signalfd4: u64 = 289;
+export def SYS_eventfd2: u64 = 290;
+export def SYS_epoll_create1: u64 = 291;
+export def SYS_dup3: u64 = 292;
+export def SYS_pipe2: u64 = 293;
+export def SYS_inotify_init1: u64 = 294;
+export def SYS_preadv: u64 = 295;
+export def SYS_pwritev: u64 = 296;
+export def SYS_rt_tgsigqueueinfo: u64 = 297;
+export def SYS_perf_event_open: u64 = 298;
+export def SYS_recvmmsg: u64 = 299;
+export def SYS_fanotify_init: u64 = 300;
+export def SYS_fanotify_mark: u64 = 301;
+export def SYS_prlimit64: u64 = 302;
+export def SYS_name_to_handle_at: u64 = 303;
+export def SYS_open_by_handle_at: u64 = 304;
+export def SYS_clock_adjtime: u64 = 305;
+export def SYS_syncfs: u64 = 306;
+export def SYS_sendmmsg: u64 = 307;
+export def SYS_setns: u64 = 308;
+export def SYS_getcpu: u64 = 309;
+export def SYS_process_vm_readv: u64 = 310;
+export def SYS_process_vm_writev: u64 = 311;
+export def SYS_kcmp: u64 = 312;
+export def SYS_finit_module: u64 = 313;
+export def SYS_sched_setattr: u64 = 314;
+export def SYS_sched_getattr: u64 = 315;
+export def SYS_renameat2: u64 = 316;
+export def SYS_seccomp: u64 = 317;
+export def SYS_getrandom: u64 = 318;
+export def SYS_memfd_create: u64 = 319;
+export def SYS_kexec_file_load: u64 = 320;
+export def SYS_bpf: u64 = 321;
+export def SYS_execveat: u64 = 322;
+export def SYS_userfaultfd: u64 = 323;
+export def SYS_membarrier: u64 = 324;
+export def SYS_mlock2: u64 = 325;
+export def SYS_copy_file_range: u64 = 326;
+export def SYS_preadv2: u64 = 327;
+export def SYS_pwritev2: u64 = 328;
+export def SYS_pkey_mprotect: u64 = 329;
+export def SYS_pkey_alloc: u64 = 330;
+export def SYS_pkey_free: u64 = 331;
+export def SYS_statx: u64 = 332;
+export def SYS_io_pgetevents: u64 = 333;
+export def SYS_rseq: u64 = 334;
+export def SYS_pidfd_send_signal: u64 = 424;
+export def SYS_io_uring_setup: u64 = 425;
+export def SYS_io_uring_enter: u64 = 426;
+export def SYS_io_uring_register: u64 = 427;
+export def SYS_open_tree: u64 = 428;
+export def SYS_move_mount: u64 = 429;
+export def SYS_fsopen: u64 = 430;
+export def SYS_fsconfig: u64 = 431;
+export def SYS_fsmount: u64 = 432;
+export def SYS_fspick: u64 = 433;
diff --git a/rt/+linux/syscalls.ha b/rt/+linux/syscalls.ha
@@ -0,0 +1,105 @@
+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: *void, count: size) size =
+ syscall3(SYS_write, fd: u64, buf: uintptr: u64, count: u64): size;
+
+export fn mmap(
+ addr: nullable *void,
+ length: size,
+ prot: uint,
+ flags: uint,
+ fd: int,
+ offs: size
+) *void = {
+ let r: i64 = syscall6(SYS_mmap, addr: uintptr: u64,
+ length: u64, prot: u64, flags: u64, fd: u64, offs: u64): i64;
+ return if (r: int == -EPERM && addr: uintptr == null
+ && (flags & MAP_ANON) > 0u && (flags & MAP_FIXED) == 0u) {
+ (-ENOMEM): uintptr: *void; // Fix up incorrect EPERM from kernel
+ } else r: uintptr: *void;
+};
+
+export def MAP_SHARED: uint = 0x01;
+export def MAP_PRIVATE: uint = 0x02;
+export def MAP_SHARED_VALIDATE: uint = 0x03;
+export def MAP_FIXED: uint = 0x10;
+export def MAP_ANON: uint = 0x20;
+export def MAP_NORESERVE: uint = 0x4000;
+export def MAP_GROWSDOWN: uint = 0x0100;
+export def MAP_DENYWRITE: uint = 0x0800;
+export def MAP_EXECUTABLE: uint = 0x1000;
+export def MAP_LOCKED: uint = 0x2000;
+export def MAP_POPULATE: uint = 0x8000;
+export def MAP_NONBLOCK: uint = 0x10000;
+export def MAP_STACK: uint = 0x20000;
+export def MAP_HUGETLB: uint = 0x40000;
+export def MAP_SYNC: uint = 0x80000;
+export def MAP_FIXED_NOREPLACE: uint = 0x100000;
+export def MAP_FILE: uint = 0;
+export def MAP_HUGE_SHIFT: uint = 26;
+export def MAP_HUGE_MASK: uint = 0x3f;
+export def MAP_HUGE_64KB: uint = 16 << 26;
+export def MAP_HUGE_512KB: uint = 19 << 26;
+export def MAP_HUGE_1MB: uint = 20 << 26;
+export def MAP_HUGE_2MB: uint = 21 << 26;
+export def MAP_HUGE_8MB: uint = 23 << 26;
+export def MAP_HUGE_16MB: uint = 24 << 26;
+export def MAP_HUGE_32MB: uint = 25 << 26;
+export def MAP_HUGE_256MB: uint = 28 << 26;
+export def MAP_HUGE_512MB: uint = 29 << 26;
+export def MAP_HUGE_1GB: uint = 30 << 26;
+export def MAP_HUGE_2GB: uint = 31 << 26;
+export def MAP_HUGE_16GB: uint = 34u << 26u;
+
+export def PROT_NONE: uint = 0;
+export def PROT_READ: uint = 1;
+export def PROT_WRITE: uint = 2;
+export def PROT_EXEC: uint = 4;
+export def PROT_GROWSDOWN: uint = 0x01000000;
+export def PROT_GROWSUP: uint = 0x02000000;
+
+export fn getpid int = syscall0(SYS_getpid): int;
+
+export fn exit @noreturn(status: int) void = syscall1(SYS_exit, status: u64);
+
+export fn kill(pid: int, signal: int) int =
+ syscall2(SYS_kill, pid: u64, signal: u64): int;
+
+export def SIGHUP: int = 1;
+export def SIGINT: int = 2;
+export def SIGQUIT: int = 3;
+export def SIGILL: int = 4;
+export def SIGTRAP: int = 5;
+export def SIGABRT: int = 6;
+export def SIGBUS: int = 7;
+export def SIGFPE: int = 8;
+export def SIGKILL: int = 9;
+export def SIGUSR1: int = 10;
+export def SIGSEGV: int = 11;
+export def SIGUSR2: int = 12;
+export def SIGPIPE: int = 13;
+export def SIGALRM: int = 14;
+export def SIGTERM: int = 15;
+export def SIGSTKFLT: int = 16;
+export def SIGCHLD: int = 17;
+export def SIGCONT: int = 18;
+export def SIGSTOP: int = 19;
+export def SIGTSTP: int = 20;
+export def SIGTTIN: int = 21;
+export def SIGTTOU: int = 22;
+export def SIGURG: int = 23;
+export def SIGXCPU: int = 24;
+export def SIGXFSZ: int = 25;
+export def SIGVTALRM: int = 26;
+export def SIGPROF: int = 27;
+export def SIGWINCH: int = 28;
+export def SIGIO: int = 29;
+export def SIGPOLL: int = 29;
+export def SIGPWR: int = 30;
+export def SIGSYS: int = 31;
diff --git a/rt/COPYING b/rt/COPYING
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/rt/README b/rt/README
@@ -0,0 +1,2 @@
+This is a basic Hare runtime. It is capable of running the harec test suite, but
+not much else.
diff --git a/rt/assert.ha b/rt/assert.ha
@@ -0,0 +1,12 @@
+export fn abort @noreturn void = kill(getpid(), SIGABRT);
+
+export @symbol("sys.assert") fn assert_(cond: bool, msg: str) void = {
+ if (!cond) {
+ const prefix = "Assertion failed: ";
+ write(2, prefix: *char, len(prefix));
+ write(2, msg: *char, len(msg));
+ write(2, "\n": *char, 1);
+ abort();
+ };
+};
+
diff --git a/rt/malloc.ha b/rt/malloc.ha
@@ -0,0 +1,29 @@
+def PAGE_SIZE: uint = 4096u;
+
+export fn malloc(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: nullable *void;
+};
+
+export fn must_malloc(n: size) *void = {
+ let p = malloc(n);
+ assert(p != null, "out of memory");
+ return p: *void;
+};
+
+export @symbol("sys.free") fn _free() void = {
+ // no-op
+ return;
+};
+
+export fn realloc() nullable *void = {
+ assert(false, "realloc: not supported");
+ return null;
+};
+
+export fn must_realloc() *void = {
+ assert(false, "must_realloc: not supported");
+ return null;
+};
diff --git a/rt/memcmp.ha b/rt/memcmp.ha
@@ -0,0 +1,9 @@
+export fn memcmp(a: *void, b: *void, amt: size) bool {
+ let _a = a: *[*]u8, _b = b: *[*]u8;
+ for (let i = 0z; i < amt; i += 1) {
+ if (a[i] != b[i]) {
+ return false;
+ };
+ };
+ return true;
+};
diff --git a/rt/memcpy.ha b/rt/memcpy.ha
@@ -0,0 +1,6 @@
+export fn memcpy(dest: *void, src: *void, amt: size) void = {
+ let a = dest: *[*]u8, b = src: *[*]u8;
+ for (let i = 0z; i < amt; i += 1) {
+ a[i] = b[i];
+ };
+};
diff --git a/rt/memset.ha b/rt/memset.ha
@@ -0,0 +1,6 @@
+export fn memzero(ptr: *void, amt: size) void = {
+ let a = ptr: *[*]u8;
+ for (let i = 0z; i < amt; i += 1) {
+ a[i] = 0u8;
+ };
+};