diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/linux/amd64/bits.h | 18 | ||||
-rw-r--r-- | sys/linux/amd64/internal/syscall.h | 452 | ||||
-rw-r--r-- | sys/rt/amd64/crt1.s | 21 | ||||
-rw-r--r-- | sys/rt/amd64/crti.s | 17 | ||||
-rw-r--r-- | sys/rt/amd64/crtn.s | 9 | ||||
-rw-r--r-- | sys/rt/boot.c | 34 | ||||
-rw-r--r-- | sys/rt/env.c | 3 | ||||
-rw-r--r-- | sys/rt/exit.c | 15 | ||||
-rw-r--r-- | sys/rt/include/rt.h | 12 | ||||
-rw-r--r-- | sys/src/chdir.c | 7 | ||||
-rw-r--r-- | sys/src/close.c | 7 | ||||
-rw-r--r-- | sys/src/dup.c | 7 | ||||
-rw-r--r-- | sys/src/internal.h | 21 | ||||
-rw-r--r-- | sys/src/mmap.c | 1 | ||||
-rw-r--r-- | sys/src/open.c | 7 | ||||
-rw-r--r-- | sys/src/read.c | 7 | ||||
-rw-r--r-- | sys/src/write.c | 7 |
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); +} |