| 1 | module builtin |
| 2 | |
| 3 | struct LinuxMmapArgs { |
| 4 | addr usize |
| 5 | len usize |
| 6 | prot usize |
| 7 | flags usize |
| 8 | fd usize |
| 9 | offset usize |
| 10 | } |
| 11 | |
| 12 | fn split_int_errno(rc_in usize) (i64, Errno) { |
| 13 | rc := isize(rc_in) |
| 14 | if rc < 0 { |
| 15 | return i64(-1), unsafe { Errno(-rc) } |
| 16 | } |
| 17 | return i64(rc), Errno.enoerror |
| 18 | } |
| 19 | |
| 20 | // 3 sys_read |
| 21 | fn sys_read(fd i64, buf &u8, count u64) (i64, Errno) { |
| 22 | return split_int_errno(sys_call3(3, usize(fd), usize(buf), usize(count))) |
| 23 | } |
| 24 | |
| 25 | // 4 sys_write |
| 26 | pub fn sys_write(fd i64, buf &u8, count u64) (i64, Errno) { |
| 27 | return split_int_errno(sys_call3(4, usize(fd), usize(buf), usize(count))) |
| 28 | } |
| 29 | |
| 30 | // 5 sys_open |
| 31 | fn sys_open(filename &u8, flags i64, mode int) (i64, Errno) { |
| 32 | return split_int_errno(sys_call3(5, usize(filename), usize(flags), usize(mode))) |
| 33 | } |
| 34 | |
| 35 | // 6 sys_close |
| 36 | fn sys_close(fd i64) Errno { |
| 37 | return unsafe { Errno(-isize(sys_call1(6, usize(fd)))) } |
| 38 | } |
| 39 | |
| 40 | // 90 sys_mmap |
| 41 | fn sys_mmap(addr &u8, len u64, prot MemProt, flags MapFlags, fildes i64, off u64) (&u8, Errno) { |
| 42 | args := LinuxMmapArgs{ |
| 43 | addr: usize(addr) |
| 44 | len: usize(len) |
| 45 | prot: usize(prot) |
| 46 | flags: usize(flags) |
| 47 | fd: usize(fildes) |
| 48 | offset: usize(off) |
| 49 | } |
| 50 | rc := sys_call1(90, usize(&args)) |
| 51 | a, e := split_int_errno(rc) |
| 52 | return unsafe { &u8(usize(a)) }, e |
| 53 | } |
| 54 | |
| 55 | // 91 sys_munmap |
| 56 | fn sys_munmap(addr voidptr, len u64) Errno { |
| 57 | return unsafe { Errno(-isize(sys_call2(91, usize(addr), usize(len)))) } |
| 58 | } |
| 59 | |
| 60 | // 163 sys_mremap |
| 61 | fn sys_mremap(old_addr voidptr, old_len u64, new_len u64, flags u64) (&u8, Errno) { |
| 62 | rc := sys_call4(163, usize(old_addr), usize(old_len), usize(new_len), usize(flags)) |
| 63 | a, e := split_int_errno(rc) |
| 64 | return unsafe { &u8(usize(a)) }, e |
| 65 | } |
| 66 | |
| 67 | // 42 sys_pipe |
| 68 | fn sys_pipe(filedes &int) Errno { |
| 69 | return unsafe { Errno(isize(sys_call1(42, usize(filedes)))) } |
| 70 | } |
| 71 | |
| 72 | // 158 sys_sched_yield |
| 73 | fn sys_sched_yield() Errno { |
| 74 | return unsafe { Errno(isize(sys_call0(158))) } |
| 75 | } |
| 76 | |
| 77 | // 219 sys_madvise |
| 78 | fn sys_madvise(addr voidptr, len u64, advice int) Errno { |
| 79 | return unsafe { Errno(isize(sys_call3(219, usize(addr), usize(len), usize(advice)))) } |
| 80 | } |
| 81 | |
| 82 | // 20 sys_getpid |
| 83 | fn sys_getpid() int { |
| 84 | return int(sys_call0(20)) |
| 85 | } |
| 86 | |
| 87 | // 2 sys_fork |
| 88 | fn sys_fork() int { |
| 89 | return int(sys_call0(2)) |
| 90 | } |
| 91 | |
| 92 | // 190 sys_vfork |
| 93 | fn sys_vfork() int { |
| 94 | return int(sys_call0(190)) |
| 95 | } |
| 96 | |
| 97 | // 63 sys_dup2 |
| 98 | fn sys_dup2(oldfd int, newfd int) (i64, Errno) { |
| 99 | return split_int_errno(sys_call2(63, usize(oldfd), usize(newfd))) |
| 100 | } |
| 101 | |
| 102 | // 11 sys_execve |
| 103 | fn sys_execve(filename &u8, argv []&u8, envp []&u8) int { |
| 104 | return int(sys_call3(11, usize(filename), usize(argv.data), usize(envp.data))) |
| 105 | } |
| 106 | |
| 107 | // 1 sys_exit |
| 108 | @[noreturn] |
| 109 | fn sys_exit(ec int) { |
| 110 | sys_call1(1, usize(ec)) |
| 111 | for {} |
| 112 | } |
| 113 | |
| 114 | // 199 sys_getuid32 |
| 115 | fn sys_getuid() int { |
| 116 | return int(sys_call0(199)) |
| 117 | } |
| 118 | |
| 119 | // 284 sys_waitid |
| 120 | fn sys_waitid(which WiWhich, pid int, infop &int, options int, ru voidptr) Errno { |
| 121 | return unsafe { |
| 122 | Errno(isize(sys_call5(284, usize(which), usize(pid), usize(infop), usize(options), |
| 123 | usize(ru)))) |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | fn sys_call0(scn usize) usize { |
| 128 | mut res := usize(0) |
| 129 | asm volatile i386 { |
| 130 | mov eax, scn |
| 131 | int 0x80 |
| 132 | mov res, eax |
| 133 | ; =r (res) |
| 134 | ; r (scn) |
| 135 | ; eax |
| 136 | memory |
| 137 | } |
| 138 | return res |
| 139 | } |
| 140 | |
| 141 | fn sys_call1(scn usize, arg1 usize) usize { |
| 142 | mut res := usize(0) |
| 143 | asm volatile i386 { |
| 144 | mov eax, scn |
| 145 | mov ebx, arg1 |
| 146 | int 0x80 |
| 147 | mov res, eax |
| 148 | ; =r (res) |
| 149 | ; r (scn) |
| 150 | r (arg1) |
| 151 | ; eax |
| 152 | ebx |
| 153 | memory |
| 154 | } |
| 155 | return res |
| 156 | } |
| 157 | |
| 158 | fn sys_call2(scn usize, arg1 usize, arg2 usize) usize { |
| 159 | mut res := usize(0) |
| 160 | asm volatile i386 { |
| 161 | mov eax, scn |
| 162 | mov ebx, arg1 |
| 163 | mov ecx, arg2 |
| 164 | int 0x80 |
| 165 | mov res, eax |
| 166 | ; =r (res) |
| 167 | ; r (scn) |
| 168 | r (arg1) |
| 169 | r (arg2) |
| 170 | ; eax |
| 171 | ebx |
| 172 | ecx |
| 173 | memory |
| 174 | } |
| 175 | return res |
| 176 | } |
| 177 | |
| 178 | fn sys_call3(scn usize, arg1 usize, arg2 usize, arg3 usize) usize { |
| 179 | mut res := usize(0) |
| 180 | asm volatile i386 { |
| 181 | mov eax, scn |
| 182 | mov ebx, arg1 |
| 183 | mov ecx, arg2 |
| 184 | mov edx, arg3 |
| 185 | int 0x80 |
| 186 | mov res, eax |
| 187 | ; =r (res) |
| 188 | ; r (scn) |
| 189 | r (arg1) |
| 190 | r (arg2) |
| 191 | r (arg3) |
| 192 | ; eax |
| 193 | ebx |
| 194 | ecx |
| 195 | edx |
| 196 | memory |
| 197 | } |
| 198 | return res |
| 199 | } |
| 200 | |
| 201 | fn sys_call4(scn usize, arg1 usize, arg2 usize, arg3 usize, arg4 usize) usize { |
| 202 | mut res := usize(0) |
| 203 | asm volatile i386 { |
| 204 | mov eax, scn |
| 205 | mov ebx, arg1 |
| 206 | mov ecx, arg2 |
| 207 | mov edx, arg3 |
| 208 | mov esi, arg4 |
| 209 | int 0x80 |
| 210 | mov res, eax |
| 211 | ; =r (res) |
| 212 | ; r (scn) |
| 213 | r (arg1) |
| 214 | r (arg2) |
| 215 | r (arg3) |
| 216 | r (arg4) |
| 217 | ; eax |
| 218 | ebx |
| 219 | ecx |
| 220 | edx |
| 221 | esi |
| 222 | memory |
| 223 | } |
| 224 | return res |
| 225 | } |
| 226 | |
| 227 | fn sys_call5(scn usize, arg1 usize, arg2 usize, arg3 usize, arg4 usize, arg5 usize) usize { |
| 228 | mut res := usize(0) |
| 229 | asm volatile i386 { |
| 230 | mov eax, scn |
| 231 | mov ebx, arg1 |
| 232 | mov ecx, arg2 |
| 233 | mov edx, arg3 |
| 234 | mov esi, arg4 |
| 235 | mov edi, arg5 |
| 236 | int 0x80 |
| 237 | mov res, eax |
| 238 | ; =r (res) |
| 239 | ; r (scn) |
| 240 | r (arg1) |
| 241 | r (arg2) |
| 242 | r (arg3) |
| 243 | r (arg4) |
| 244 | r (arg5) |
| 245 | ; eax |
| 246 | ebx |
| 247 | ecx |
| 248 | edx |
| 249 | esi |
| 250 | edi |
| 251 | memory |
| 252 | } |
| 253 | return res |
| 254 | } |
| 255 | |
| 256 | asm i386 { |
| 257 | .globl _start |
| 258 | _start: |
| 259 | call main |
| 260 | mov eax, 1 |
| 261 | xor ebx, ebx |
| 262 | int 0x80 |
| 263 | ret |
| 264 | } |
| 265 | |