aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas <nbnoll@eml.cc>2021-11-15 15:10:35 -0800
committerNicholas <nbnoll@eml.cc>2021-11-15 15:10:35 -0800
commit0b8cebc1f074626f3c3e43a26152a3034ada7153 (patch)
tree8eb1cae101b089680830ad89606ee618357f9bd6
parente9ff1c6fbbbac9ece2604876ab589ac282360446 (diff)
Feat: prototype of self-hosted library
This is very much a work in progress. Still ruminating on the structure of the library. It feels right but I want a more "social" presence - namely the ability to link to a libc seemlessly. The solution is most likely weak aliasing that musl uses - but musl itself weak aliases global symbols, e.g malloc. We would have to define weak internal symbols that musl defines as strong links but this knows too much about the internals of musl...
-rw-r--r--sys/linux/amd64/bits.h18
-rw-r--r--sys/linux/amd64/internal/syscall.h452
-rw-r--r--sys/rt/amd64/crt1.s21
-rw-r--r--sys/rt/amd64/crti.s17
-rw-r--r--sys/rt/amd64/crtn.s9
-rw-r--r--sys/rt/boot.c34
-rw-r--r--sys/rt/env.c3
-rw-r--r--sys/rt/exit.c15
-rw-r--r--sys/rt/include/rt.h12
-rw-r--r--sys/src/chdir.c7
-rw-r--r--sys/src/close.c7
-rw-r--r--sys/src/dup.c7
-rw-r--r--sys/src/internal.h21
-rw-r--r--sys/src/mmap.c1
-rw-r--r--sys/src/open.c7
-rw-r--r--sys/src/read.c7
-rw-r--r--sys/src/write.c7
17 files changed, 645 insertions, 0 deletions
diff --git a/sys/linux/amd64/bits.h b/sys/linux/amd64/bits.h
new file mode 100644
index 0000000..e72e4e8
--- /dev/null
+++ b/sys/linux/amd64/bits.h
@@ -0,0 +1,18 @@
+#pragma once
+
+/* base types */
+#define INT8 char
+#define INT16 short
+#define INT32 int
+#define INT64 long
+#define ADDR long
+
+/* ABI */
+#define PAGESIZE 4096
+#define INTPTR_MIN INT64_MIN
+#define INTPTR_MAX INT64_MAX
+#define UINTPTR_MAX UINT64_MAX
+#define PTRDIFF_MIN INT64_MIN
+#define PTRDIFF_MAX INT64_MAX
+#define SIZE_MAX UINT64_MAX
+#define LONG_MAX 0x7fffffffffffffffL
diff --git a/sys/linux/amd64/internal/syscall.h b/sys/linux/amd64/internal/syscall.h
new file mode 100644
index 0000000..a06e3ba
--- /dev/null
+++ b/sys/linux/amd64/internal/syscall.h
@@ -0,0 +1,452 @@
+#pragma once
+
+#define ·Read 0
+#define ·Write 1
+#define ·Open 2
+#define ·Close 3
+#define ·Stat 4
+#define ·Fstat 5
+#define ·Lstat 6
+#define ·Poll 7
+#define ·Lseek 8
+#define ·Mmap 9
+#define ·Mprotect 10
+#define ·Munmap 11
+#define ·Brk 12
+#define ·RtSigAction 13
+#define ·RtSigProcmask 14
+#define ·RtSigReturn 15
+#define ·IoCtl 16
+#define ·PRead64 17
+#define ·PWrite64 18
+#define ·Readv 19
+#define ·Writev 20
+#define ·Access 21
+#define ·Pipe 22
+#define ·Select 23
+#define ·SchedYield 24
+#define ·MRemap 25
+#define ·MSync 26
+#define ·MIncore 27
+#define ·MAdvise 28
+#define ·ShmGet 29
+#define ·ShmAt 30
+#define ·ShmCtl 31
+#define ·Dup 32
+#define ·Dup2 33
+#define ·Pause 34
+#define ·Nanosleep 35
+#define ·GetItimer 36
+#define ·Alarm 37
+#define ·SetItimer 38
+#define ·GetPid 39
+#define ·SendFile 40
+#define ·Socket 41
+#define ·Connect 42
+#define ·Accept 43
+#define ·SendTo 44
+#define ·RecvFrom 45
+#define ·SendMsg 46
+#define ·RecvMsg 47
+#define ·Shutdown 48
+#define ·Bind 49
+#define ·Listen 50
+#define ·GetSockName 51
+#define ·GetPeerName 52
+#define ·SocketPair 53
+#define ·SetSockOpt 54
+#define ·GetSockOpt 55
+#define ·Clone 56
+#define ·Fork 57
+#define ·Vfork 58
+#define ·Execve 59
+#define ·Exit 60
+#define ·Wait4 61
+#define ·Kill 62
+#define ·Uname 63
+#define ·SemGet 64
+#define ·SemOp 65
+#define ·SemCtl 66
+#define ·ShmDt 67
+#define ·MsgGet 68
+#define ·MsgSnd 69
+#define ·MsgRcv 70
+#define ·MsgCtl 71
+#define ·Fcntl 72
+#define ·FLock 73
+#define ·FSync 74
+#define ·FDataSync 75
+#define ·Truncate 76
+#define ·FTruncate 77
+#define ·GetDents 78
+#define ·GetCwd 79
+#define ·Chdir 80
+#define ·Fchdir 81
+#define ·Rename 82
+#define ·Mkdir 83
+#define ·Rmdir 84
+#define ·Create 85
+#define ·Link 86
+#define ·Unlink 87
+#define ·Symlink 88
+#define ·Readlink 89
+#define ·Chmod 90
+#define ·Fchmod 91
+#define ·Chown 92
+#define ·FChown 93
+#define ·LChown 94
+#define ·UMask 95
+#define ·GetTimeOfDay 96
+#define ·GetRLimit 97
+#define ·GetRUsage 98
+#define ·SysInfo 99
+#define ·Times 100
+#define ·PTrace 101
+#define ·GetUID 102
+#define ·SysLog 103
+#define ·GetGid 104
+#define ·SetUid 105
+#define ·SetGid 106
+#define ·GetEuid 107
+#define ·GetEgid 108
+#define ·SetPgid 109
+#define ·GetPpid 110
+#define ·GetPgrp 111
+#define ·SetSid 112
+#define ·SetReuid 113
+#define ·SetRegid 114
+#define ·GetGroups 115
+#define ·SetGroups 116
+#define ·SetResuid 117
+#define ·GetResuid 118
+#define ·SetResgid 119
+#define ·GetResgid 120
+#define ·GetPgid 121
+#define ·SetFsuid 122
+#define ·SetFsgid 123
+#define ·GetSid 124
+#define ·CapGet 125
+#define ·CapSet 126
+#define ·RtSigPending 127
+#define ·RtSigTimedWait 128
+#define ·RtSigQueueInfo 129
+#define ·RtSigSuspend 130
+#define ·SignaltStack 131
+#define ·UTime 132
+#define ·MkNod 133
+#define ·UseLib 134
+#define ·Personality 135
+#define ·UStat 136
+#define ·StatFs 137
+#define ·FstatFs 138
+#define ·SysFs 139
+#define ·GetPriority 140
+#define ·SetPriority 141
+#define ·SchedSetParam 142
+#define ·SchedGetParam 143
+#define ·SchedSetScheduler 144
+#define ·SchedGetScheduler 145
+#define ·SchedGetPriorityMax 146
+#define ·SchedGetPriorityMin 147
+#define ·SchedRrGetInterval 148
+#define ·MLock 149
+#define ·MUnlock 150
+#define ·MLockAll 151
+#define ·MUnlockAll 152
+#define ·VHangup 153
+#define ·ModifyLdt 154
+#define ·PivotRoot 155
+#define ·Sysctl 156
+#define ·Prctl 157
+#define ·ArchPrctl 158
+#define ·AdjTimex 159
+#define ·SetRLimit 160
+#define ·Chroot 161
+#define ·Sync 162
+#define ·Acct 163
+#define ·Settimeofday 164
+#define ·Mount 165
+#define ·Umount2 166
+#define ·Swapon 167
+#define ·Swapoff 168
+#define ·Reboot 169
+#define ·SetHostName 170
+#define ·SetDomainName 171
+#define ·Iopl 172
+#define ·Ioperm 173
+#define ·CreateModule 174
+#define ·InitModule 175
+#define ·DeleteModule 176
+#define ·GetKernelSyms 177
+#define ·QueryModule 178
+#define ·QuotaCtl 179
+#define ·NfsServCtl 180
+#define ·GetPmsg 181
+#define ·PutPmsg 182
+#define ·AfsSyscall 183
+#define ·TuxCall 184
+#define ·Security 185
+#define ·Gettid 186
+#define ·Readahead 187
+#define ·SetXattr 188
+#define ·LsetXattr 189
+#define ·FsetXattr 190
+#define ·GetXattr 191
+#define ·LgetXattr 192
+#define ·FgetXattr 193
+#define ·ListXattr 194
+#define ·LlistXattr 195
+#define ·FlistXattr 196
+#define ·RemoveXattr 197
+#define ·LremoveXattr 198
+#define ·FremoveXattr 199
+#define ·TKill 200
+#define ·Time 201
+#define ·Futex 202
+#define ·SchedSetAffinity 203
+#define ·SchedGetAffinity 204
+#define ·SetThreadArea 205
+#define ·IoSetup 206
+#define ·IoDestroy 207
+#define ·IoGetEvents 208
+#define ·IoSubmit 209
+#define ·IoCancel 210
+#define ·GetThreadArea 211
+#define ·LookupDCookie 212
+#define ·EpollCreate 213
+#define ·EpollCtlOld 214
+#define ·EpollWaitOld 215
+#define ·RemapFilePages 216
+#define ·Getdents64 217
+#define ·SetTidAddress 218
+#define ·RestartSyscall 219
+#define ·SemtimeDop 220
+#define ·Fadvise64 221
+#define ·TimerCreate 222
+#define ·TimerSetTime 223
+#define ·TimerGetTime 224
+#define ·TimerGetOverrun 225
+#define ·TimerDelete 226
+#define ·ClockSetTime 227
+#define ·ClockGetTime 228
+#define ·ClockGetRes 229
+#define ·ClockNanosleep 230
+#define ·ExitGroup 231
+#define ·EpollWait 232
+#define ·EpollCtl 233
+#define ·Tgkill 234
+#define ·Utimes 235
+#define ·Vserver 236
+#define ·Mbind 237
+#define ·SetMemPolicy 238
+#define ·GetMemPolicy 239
+#define ·MqOpen 240
+#define ·MqUnlink 241
+#define ·MqTimedSend 242
+#define ·MqTimedReceive 243
+#define ·MqNotify 244
+#define ·MqGetSetAttr 245
+#define ·KexecLoad 246
+#define ·Waitid 247
+#define ·AddKey 248
+#define ·RequestKey 249
+#define ·Keyctl 250
+#define ·IoprioSet 251
+#define ·IoprioGet 252
+#define ·InotifyInit 253
+#define ·InotifyAddWatch 254
+#define ·InotifyRmWatch 255
+#define ·MigratePages 256
+#define ·OpenAt 257
+#define ·MkdirAt 258
+#define ·MkNodAt 259
+#define ·FchownAt 260
+#define ·FutimesAt 261
+#define ·NewfstatAt 262
+#define ·UnlinkAt 263
+#define ·RenameAt 264
+#define ·LinkAt 265
+#define ·SymlinkAt 266
+#define ·ReadlinkAt 267
+#define ·FchmodAt 268
+#define ·FaccessAt 269
+#define ·Pselect6 270
+#define ·Ppoll 271
+#define ·Unshare 272
+#define ·SetRobustList 273
+#define ·GetRobustList 274
+#define ·Splice 275
+#define ·Tee 276
+#define ·SyncFileRange 277
+#define ·Vmsplice 278
+#define ·MovePages 279
+#define ·UtimensAt 280
+#define ·EpollPwait 281
+#define ·SignalFd 282
+#define ·TimerFdCreate 283
+#define ·EventFd 284
+#define ·Fallocate 285
+#define ·TimerFdSetTime 286
+#define ·TimerFdGetTime 287
+#define ·Accept4 288
+#define ·SignalFd4 289
+#define ·EventFd2 290
+#define ·EpollCreate1 291
+#define ·Dup3 292
+#define ·Pipe2 293
+#define ·InotifyInit1 294
+#define ·Preadv 295
+#define ·Pwritev 296
+#define ·RtTgSigQueueInfo 297
+#define ·PerfEventOpen 298
+#define ·RecvmMsg 299
+#define ·FanotifyInit 300
+#define ·FanotifyMark 301
+#define ·Prlimit64 302
+#define ·NameToHandleAt 303
+#define ·OpenByHandleAt 304
+#define ·ClockAdjtime 305
+#define ·SyncFs 306
+#define ·SendmMsg 307
+#define ·SetNs 308
+#define ·GetCpu 309
+#define ·ProcessVmReadv 310
+#define ·ProcessVmWritev 311
+#define ·Kcmp 312
+#define ·FinitModule 313
+#define ·SchedSetattr 314
+#define ·SchedGetattr 315
+#define ·Renameat2 316
+#define ·Seccomp 317
+#define ·Getrandom 318
+#define ·MemfdCreate 319
+#define ·KexecFileLoad 320
+#define ·Bpf 321
+#define ·ExecveAt 322
+#define ·UserFaultFd 323
+#define ·MemBarrier 324
+#define ·Mlock2 325
+#define ·CopyFileRange 326
+#define ·Preadv2 327
+#define ·Pwritev2 328
+#define ·PkeyMprotect 329
+#define ·PkeyAlloc 330
+#define ·PkeyFree 331
+#define ·Statx 332
+#define ·IoPgetEvents 333
+#define ·Rseq 334
+#define ·PidfdSendSignal 424
+#define ·IoUringSetup 425
+#define ·IoUringEnter 426
+#define ·IoUringRegister 427
+#define ·OpenTree 428
+#define ·MoveMount 429
+#define ·FsOpen 430
+#define ·FsConfig 431
+#define ·FsMount 432
+#define ·FsPick 433
+#define ·PidFdOpen 434
+#define ·Clone3 435
+#define ·CloseRange 436
+#define ·OpenAt2 437
+#define ·PidFdGetFd 438
+#define ·FaccessAt2 439
+#define ·ProcessMadvise 440
+
+/*
+ * x86-64 linux ABI
+ * syscall rdi rsi rdx r10 r8 r9
+ * return value in rax
+ *
+ * the syntax for extended GNU inline assembly
+ * asm([instructions] : [output operands] : [input operands] : [clobbers] )
+ * operands are written as "constrants"(symbol)
+ * available constraints are:
+ * 'r': any register
+ * 'a': eax, 'b': ebx, 'c': ecx, 'd': edx, 'S', esi, 'D' edi
+ * '=': write only, previous value is discarded
+ */
+#define sysarg(x) ((long)(x))
+
+static inline long
+_syscall0(long n)
+{
+ ulong ret;
+ asm volatile("syscall" : "=a"(ret)
+ : "a"(n)
+ : "rcx", "r11", "memory"
+ );
+ return ret;
+}
+
+static inline long
+_syscall1(long n, long a1)
+{
+ ulong ret;
+ asm volatile("syscall" : "=a"(ret)
+ : "a"(n), "D"(a1)
+ : "rcx", "r11", "memory"
+ );
+ return ret;
+}
+
+static inline long
+_syscall2(long n, long a1, long a2)
+{
+ ulong ret;
+ asm volatile("syscall" : "=a"(ret)
+ : "a"(n), "D"(a1), "S"(a2)
+ : "rcx", "r11", "memory"
+ );
+ return ret;
+}
+
+static inline long
+_syscall3(long n, long a1, long a2, long a3)
+{
+ ulong ret;
+ asm volatile("syscall" : "=a"(ret)
+ : "a"(n), "D"(a1), "S"(a2), "d"(a3)
+ : "rcx", "r11", "memory"
+ );
+ return ret;
+}
+
+static inline long
+_syscall4(long n, long a1, long a2, long a3, long a4)
+{
+ ulong ret;
+ register long r10 asm("r10") = a4;
+ asm volatile("syscall" : "=a"(ret)
+ : "a"(n), "D"(a1), "S"(a2), "d"(a3), "r"(r10)
+ : "rcx", "r11", "memory"
+ );
+ return ret;
+}
+
+static inline long
+_syscall5(long n, long a1, long a2, long a3, long a4, long a5)
+{
+ ulong ret;
+ register long r10 asm("r10") = a4;
+ register long r8 asm("r8") = a5;
+ asm volatile("syscall" : "=a"(ret)
+ : "a"(n), "D"(a1), "S"(a2), "d"(a3), "r"(r10), "r"(r8)
+ : "rcx", "r11", "memory"
+ );
+ return ret;
+}
+
+static inline long
+_syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6)
+{
+ ulong ret;
+ register long r10 __asm__("r10") = a4;
+ register long r8 __asm__("r8") = a5;
+ register long r9 __asm__("r9") = a6;
+ asm volatile("syscall" : "=a"(ret)
+ : "a"(n), "D"(a1), "S"(a2), "d"(a3), "r"(r10), "r"(r8), "r"(r9)
+ : "rcx", "r11", "memory"
+ );
+ return ret;
+}
diff --git a/sys/rt/amd64/crt1.s b/sys/rt/amd64/crt1.s
new file mode 100644
index 0000000..aaad0ba
--- /dev/null
+++ b/sys/rt/amd64/crt1.s
@@ -0,0 +1,21 @@
+global _start
+
+; NOTE: assumes program loader has put argc, argv, envc, envp on stack
+section .text
+_start:
+ xor rbp,rbp ; base pointer undefined: set to 0
+ mov r9,rdx ; 6th arg: function to register with atexit()
+ pop rsi ; 2nd arg: argc
+ mov rdx,rsp ; 3rd arg: argv
+ and rsp,$-16 ; align stack pointer to 16 bytes
+ mov $_fini,r8 ; 5th arg: fini
+ mov $_init,rcx ; 4th arg: init
+ mov $main,rdi ; 1st arg: main
+
+ call rt·boot ; int boot(
+ ; int(*main)(int,char*[],char*[]),
+ ; int argc,
+ ; char *argv[],
+ ; init, fini, atexit);
+
+.loop: jmp .loop ; should never reach...
diff --git a/sys/rt/amd64/crti.s b/sys/rt/amd64/crti.s
new file mode 100644
index 0000000..eeba8b1
--- /dev/null
+++ b/sys/rt/amd64/crti.s
@@ -0,0 +1,17 @@
+global _init
+global _fini
+
+section .init
+_init:
+ ; call pushes an 8 byte return address on the stack
+ ; 64 bit ABI requires stack to be aligned to 16 bytes
+ ; we realign with another 8 byte address
+ push rbp
+ mov rbp, rsp
+ ;; compiler inserts the rest here
+
+section .fini
+_fini:
+ push rbp ; see above
+ mov rbp, rsp
+ ;; compiler inserts the rest here
diff --git a/sys/rt/amd64/crtn.s b/sys/rt/amd64/crtn.s
new file mode 100644
index 0000000..45d1a29
--- /dev/null
+++ b/sys/rt/amd64/crtn.s
@@ -0,0 +1,9 @@
+section .init
+ ;; compiler inserts here
+ pop rbp ;; undo our push
+ ret
+
+section .fini
+ ;; compiler inserts here
+ pop rbp ;; undo our push
+ ret
diff --git a/sys/rt/boot.c b/sys/rt/boot.c
new file mode 100644
index 0000000..197e861
--- /dev/null
+++ b/sys/rt/boot.c
@@ -0,0 +1,34 @@
+#include <rt.h>
+
+int
+rt·boot(
+ int (*main)(int,char **,char **), int argc, char **argv,
+ int (*init)(int, char **, char **), void (*fini)(void),
+ void (*exit)(void)
+)
+{
+ char **envp = argv+argc+1;
+ rt·environ = envp;
+
+ if(exit)
+ rt·context.exit = exit;
+
+ if(fini)
+ rt·context.fini = fini;
+
+ if(init){
+ rt·context.init = init;
+ init(argc, argv, envp);
+ }
+
+ /* XXX:
+ * we could call __libc_start_main of musl here:
+ * this would give us the normal C runtime along with ours
+ * which would allow seamless linking to other libraries
+ * or we can implement a compatibility layer
+ */
+ rt·exit(main(argc, argv, envp));
+
+ /* should never get here */
+ return 0;
+}
diff --git a/sys/rt/env.c b/sys/rt/env.c
new file mode 100644
index 0000000..ddd559d
--- /dev/null
+++ b/sys/rt/env.c
@@ -0,0 +1,3 @@
+#include <rt.h>
+
+char *rt·environ = 0;
diff --git a/sys/rt/exit.c b/sys/rt/exit.c
new file mode 100644
index 0000000..55a684a
--- /dev/null
+++ b/sys/rt/exit.c
@@ -0,0 +1,15 @@
+#include <rt.h>
+#include <sys.h>
+
+void
+rt·exit(int code)
+{
+ if(rt·context.fini)
+ rt·context.fini();
+ if(rt·context.exit)
+ rt·context.exit();
+
+ /* call exit syscalls here */
+
+ for(;;);
+}
diff --git a/sys/rt/include/rt.h b/sys/rt/include/rt.h
new file mode 100644
index 0000000..dd1598b
--- /dev/null
+++ b/sys/rt/include/rt.h
@@ -0,0 +1,12 @@
+#pragma once
+
+extern struct rt·context
+{
+ void (*init)(void);
+ void (*fini)(void);
+ void (*exit)(void);
+} rt·context;
+
+extern char **rt·environ;
+
+void rt·exit(int code);
diff --git a/sys/src/chdir.c b/sys/src/chdir.c
new file mode 100644
index 0000000..fd1385d
--- /dev/null
+++ b/sys/src/chdir.c
@@ -0,0 +1,7 @@
+#include "internal.h"
+
+int
+sys·chdir(char *path)
+{
+ return syscall(·Chdir, path);
+}
diff --git a/sys/src/close.c b/sys/src/close.c
new file mode 100644
index 0000000..88b1e2b
--- /dev/null
+++ b/sys/src/close.c
@@ -0,0 +1,7 @@
+#include "internal.h"
+
+int
+sys·close(int fd)
+{
+ return syscall(·Close, fd);
+}
diff --git a/sys/src/dup.c b/sys/src/dup.c
new file mode 100644
index 0000000..0943f52
--- /dev/null
+++ b/sys/src/dup.c
@@ -0,0 +1,7 @@
+#include "internal.h"
+
+int
+sys·dup(int fd)
+{
+ return syscall(·Dup, fd);
+}
diff --git a/sys/src/internal.h b/sys/src/internal.h
new file mode 100644
index 0000000..2bb1422
--- /dev/null
+++ b/sys/src/internal.h
@@ -0,0 +1,21 @@
+#pragma once
+
+#include <u.h>
+#include <internal/syscall.h>
+
+#define syscall1(n,a1) _syscall1(n,sysarg(a1))
+#define syscall2(n,a1,a2) _syscall2(n,sysarg(a1),sysarg(a2))
+#define syscall3(n,a1,a2,a3) _syscall3(n,sysarg(a1),sysarg(a2),sysarg(a3))
+#define syscall4(n,a1,a2,a3,a4) _syscall4(n,sysarg(a1),sysarg(a2),sysarg(a3),sysarg(a4))
+#define syscall5(n,a1,a2,a3,a4,a5) _syscall5(n,sysarg(a1),sysarg(a2),sysarg(a3),sysarg(a4),sysarg(a5))
+#define syscall6(n,a1,a2,a3,a4,a5,a6) _syscall6(n,sysarg(a1),sysarg(a2),sysarg(a3),sysarg(a4),sysarg(a5),sysarg(a6))
+#define syscall7(n,a1,a2,a3,a4,a5,a6,a7) _syscall7(n,sysarg(a1),sysarg(a2),sysarg(a3),sysarg(a4),sysarg(a5),sysarg(a6),sysarg(a7))
+
+#define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n
+#define __SYSCALL_NARGS(...) __SYSCALL_NARGS_X(__VA_ARGS__,7,6,5,4,3,2,1,0,)
+#define __SYSCALL_CONCAT_X(a,b) a##b
+#define __SYSCALL_CONCAT(a,b) __SYSCALL_CONCAT_X(a,b)
+#define __SYSCALL_DISP(b,...) __SYSCALL_CONCAT(b,__SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__)
+
+#define syscall(...) __SYSCALL_DISP(syscall,__VA_ARGS__)
+
diff --git a/sys/src/mmap.c b/sys/src/mmap.c
new file mode 100644
index 0000000..fb5c5f4
--- /dev/null
+++ b/sys/src/mmap.c
@@ -0,0 +1 @@
+#include "internal.h"
diff --git a/sys/src/open.c b/sys/src/open.c
new file mode 100644
index 0000000..02d2ca8
--- /dev/null
+++ b/sys/src/open.c
@@ -0,0 +1,7 @@
+#include "internal.h"
+
+int
+sys·open(char *path, int flag, int mode)
+{
+ return syscall(·Open, flag, mode);
+}
diff --git a/sys/src/read.c b/sys/src/read.c
new file mode 100644
index 0000000..3aa3e29
--- /dev/null
+++ b/sys/src/read.c
@@ -0,0 +1,7 @@
+#include "internal.h"
+
+intptr
+sys·read(int fd, intptr len, void *buf)
+{
+ return syscall(·Read, fd, buf, len);
+}
diff --git a/sys/src/write.c b/sys/src/write.c
new file mode 100644
index 0000000..c1faff5
--- /dev/null
+++ b/sys/src/write.c
@@ -0,0 +1,7 @@
+#include "internal.h"
+
+intptr
+sys·write(int fd, intptr size, intptr len, void *buf)
+{
+ return syscall(·Write, fd, buf, size*len);
+}