Serenity Operating System
at hosted 493 lines 15 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#pragma once 28 29#include <AK/Types.h> 30 31#ifdef __serenity__ 32# include <LibC/fd_set.h> 33#endif 34 35constexpr int syscall_vector = 0x82; 36 37extern "C" { 38struct timeval; 39struct timespec; 40struct sockaddr; 41struct siginfo; 42typedef u32 socklen_t; 43} 44 45namespace Kernel { 46 47#define ENUMERATE_SYSCALLS \ 48 __ENUMERATE_SYSCALL(sleep) \ 49 __ENUMERATE_SYSCALL(yield) \ 50 __ENUMERATE_SYSCALL(open) \ 51 __ENUMERATE_SYSCALL(close) \ 52 __ENUMERATE_SYSCALL(read) \ 53 __ENUMERATE_SYSCALL(lseek) \ 54 __ENUMERATE_SYSCALL(kill) \ 55 __ENUMERATE_SYSCALL(getuid) \ 56 __ENUMERATE_SYSCALL(exit) \ 57 __ENUMERATE_SYSCALL(getgid) \ 58 __ENUMERATE_SYSCALL(getpid) \ 59 __ENUMERATE_SYSCALL(waitid) \ 60 __ENUMERATE_SYSCALL(mmap) \ 61 __ENUMERATE_SYSCALL(munmap) \ 62 __ENUMERATE_SYSCALL(get_dir_entries) \ 63 __ENUMERATE_SYSCALL(getcwd) \ 64 __ENUMERATE_SYSCALL(gettimeofday) \ 65 __ENUMERATE_SYSCALL(gethostname) \ 66 __ENUMERATE_SYSCALL(chdir) \ 67 __ENUMERATE_SYSCALL(uname) \ 68 __ENUMERATE_SYSCALL(set_mmap_name) \ 69 __ENUMERATE_SYSCALL(readlink) \ 70 __ENUMERATE_SYSCALL(write) \ 71 __ENUMERATE_SYSCALL(ttyname_r) \ 72 __ENUMERATE_SYSCALL(stat) \ 73 __ENUMERATE_SYSCALL(getsid) \ 74 __ENUMERATE_SYSCALL(setsid) \ 75 __ENUMERATE_SYSCALL(getpgid) \ 76 __ENUMERATE_SYSCALL(setpgid) \ 77 __ENUMERATE_SYSCALL(getpgrp) \ 78 __ENUMERATE_SYSCALL(fork) \ 79 __ENUMERATE_SYSCALL(execve) \ 80 __ENUMERATE_SYSCALL(geteuid) \ 81 __ENUMERATE_SYSCALL(getegid) \ 82 __ENUMERATE_SYSCALL(getdtablesize) \ 83 __ENUMERATE_SYSCALL(dup) \ 84 __ENUMERATE_SYSCALL(dup2) \ 85 __ENUMERATE_SYSCALL(sigaction) \ 86 __ENUMERATE_SYSCALL(getppid) \ 87 __ENUMERATE_SYSCALL(umask) \ 88 __ENUMERATE_SYSCALL(getgroups) \ 89 __ENUMERATE_SYSCALL(setgroups) \ 90 __ENUMERATE_SYSCALL(sigreturn) \ 91 __ENUMERATE_SYSCALL(sigprocmask) \ 92 __ENUMERATE_SYSCALL(sigpending) \ 93 __ENUMERATE_SYSCALL(pipe) \ 94 __ENUMERATE_SYSCALL(killpg) \ 95 __ENUMERATE_SYSCALL(setuid) \ 96 __ENUMERATE_SYSCALL(setgid) \ 97 __ENUMERATE_SYSCALL(alarm) \ 98 __ENUMERATE_SYSCALL(fstat) \ 99 __ENUMERATE_SYSCALL(access) \ 100 __ENUMERATE_SYSCALL(fcntl) \ 101 __ENUMERATE_SYSCALL(ioctl) \ 102 __ENUMERATE_SYSCALL(mkdir) \ 103 __ENUMERATE_SYSCALL(times) \ 104 __ENUMERATE_SYSCALL(utime) \ 105 __ENUMERATE_SYSCALL(sync) \ 106 __ENUMERATE_SYSCALL(ptsname_r) \ 107 __ENUMERATE_SYSCALL(select) \ 108 __ENUMERATE_SYSCALL(unlink) \ 109 __ENUMERATE_SYSCALL(poll) \ 110 __ENUMERATE_SYSCALL(rmdir) \ 111 __ENUMERATE_SYSCALL(chmod) \ 112 __ENUMERATE_SYSCALL(usleep) \ 113 __ENUMERATE_SYSCALL(socket) \ 114 __ENUMERATE_SYSCALL(bind) \ 115 __ENUMERATE_SYSCALL(accept) \ 116 __ENUMERATE_SYSCALL(listen) \ 117 __ENUMERATE_SYSCALL(connect) \ 118 __ENUMERATE_SYSCALL(shbuf_create) \ 119 __ENUMERATE_SYSCALL(shbuf_allow_pid) \ 120 __ENUMERATE_SYSCALL(shbuf_get) \ 121 __ENUMERATE_SYSCALL(shbuf_release) \ 122 __ENUMERATE_SYSCALL(link) \ 123 __ENUMERATE_SYSCALL(chown) \ 124 __ENUMERATE_SYSCALL(fchmod) \ 125 __ENUMERATE_SYSCALL(symlink) \ 126 __ENUMERATE_SYSCALL(shbuf_seal) \ 127 __ENUMERATE_SYSCALL(sendto) \ 128 __ENUMERATE_SYSCALL(recvfrom) \ 129 __ENUMERATE_SYSCALL(getsockopt) \ 130 __ENUMERATE_SYSCALL(setsockopt) \ 131 __ENUMERATE_SYSCALL(create_thread) \ 132 __ENUMERATE_SYSCALL(gettid) \ 133 __ENUMERATE_SYSCALL(donate) \ 134 __ENUMERATE_SYSCALL(rename) \ 135 __ENUMERATE_SYSCALL(ftruncate) \ 136 __ENUMERATE_SYSCALL(exit_thread) \ 137 __ENUMERATE_SYSCALL(mknod) \ 138 __ENUMERATE_SYSCALL(writev) \ 139 __ENUMERATE_SYSCALL(beep) \ 140 __ENUMERATE_SYSCALL(getsockname) \ 141 __ENUMERATE_SYSCALL(getpeername) \ 142 __ENUMERATE_SYSCALL(sched_setparam) \ 143 __ENUMERATE_SYSCALL(sched_getparam) \ 144 __ENUMERATE_SYSCALL(fchown) \ 145 __ENUMERATE_SYSCALL(halt) \ 146 __ENUMERATE_SYSCALL(reboot) \ 147 __ENUMERATE_SYSCALL(mount) \ 148 __ENUMERATE_SYSCALL(umount) \ 149 __ENUMERATE_SYSCALL(dump_backtrace) \ 150 __ENUMERATE_SYSCALL(dbgputch) \ 151 __ENUMERATE_SYSCALL(dbgputstr) \ 152 __ENUMERATE_SYSCALL(watch_file) \ 153 __ENUMERATE_SYSCALL(shbuf_allow_all) \ 154 __ENUMERATE_SYSCALL(set_process_icon) \ 155 __ENUMERATE_SYSCALL(mprotect) \ 156 __ENUMERATE_SYSCALL(realpath) \ 157 __ENUMERATE_SYSCALL(get_process_name) \ 158 __ENUMERATE_SYSCALL(fchdir) \ 159 __ENUMERATE_SYSCALL(getrandom) \ 160 __ENUMERATE_SYSCALL(setkeymap) \ 161 __ENUMERATE_SYSCALL(clock_gettime) \ 162 __ENUMERATE_SYSCALL(clock_settime) \ 163 __ENUMERATE_SYSCALL(clock_nanosleep) \ 164 __ENUMERATE_SYSCALL(join_thread) \ 165 __ENUMERATE_SYSCALL(module_load) \ 166 __ENUMERATE_SYSCALL(module_unload) \ 167 __ENUMERATE_SYSCALL(detach_thread) \ 168 __ENUMERATE_SYSCALL(set_thread_name) \ 169 __ENUMERATE_SYSCALL(get_thread_name) \ 170 __ENUMERATE_SYSCALL(madvise) \ 171 __ENUMERATE_SYSCALL(purge) \ 172 __ENUMERATE_SYSCALL(shbuf_set_volatile) \ 173 __ENUMERATE_SYSCALL(profiling_enable) \ 174 __ENUMERATE_SYSCALL(profiling_disable) \ 175 __ENUMERATE_SYSCALL(get_kernel_info_page) \ 176 __ENUMERATE_SYSCALL(futex) \ 177 __ENUMERATE_SYSCALL(set_thread_boost) \ 178 __ENUMERATE_SYSCALL(set_process_boost) \ 179 __ENUMERATE_SYSCALL(chroot) \ 180 __ENUMERATE_SYSCALL(pledge) \ 181 __ENUMERATE_SYSCALL(unveil) \ 182 __ENUMERATE_SYSCALL(perf_event) \ 183 __ENUMERATE_SYSCALL(shutdown) \ 184 __ENUMERATE_SYSCALL(get_stack_bounds) \ 185 __ENUMERATE_SYSCALL(ptrace) 186 187namespace Syscall { 188 189enum Function { 190#undef __ENUMERATE_SYSCALL 191#undef __ENUMERATE_REMOVED_SYSCALL 192#define __ENUMERATE_REMOVED_SYSCALL(x) SC_##x, 193#define __ENUMERATE_SYSCALL(x) SC_##x, 194 ENUMERATE_SYSCALLS 195#undef __ENUMERATE_SYSCALL 196#undef __ENUMERATE_REMOVED_SYSCALL 197 __Count 198}; 199 200inline constexpr const char* to_string(Function function) 201{ 202 switch (function) { 203#undef __ENUMERATE_SYSCALL 204#undef __ENUMERATE_REMOVED_SYSCALL 205#define __ENUMERATE_REMOVED_SYSCALL(x) \ 206 case SC_##x: \ 207 return #x " (removed)"; 208#define __ENUMERATE_SYSCALL(x) \ 209 case SC_##x: \ 210 return #x; 211 ENUMERATE_SYSCALLS 212#undef __ENUMERATE_SYSCALL 213#undef __ENUMERATE_REMOVED_SYSCALL 214 default: 215 break; 216 } 217 return "Unknown"; 218} 219 220#ifdef __serenity__ 221struct StringArgument { 222 const char* characters { nullptr }; 223 size_t length { 0 }; 224}; 225 226template<typename DataType, typename SizeType> 227struct MutableBufferArgument { 228 DataType* data { nullptr }; 229 SizeType size { 0 }; 230}; 231 232template<typename DataType, typename SizeType> 233struct ImmutableBufferArgument { 234 const DataType* data { nullptr }; 235 SizeType size { 0 }; 236}; 237 238struct StringListArgument { 239 StringArgument* strings { nullptr }; 240 size_t length { 0 }; 241}; 242 243struct SC_mmap_params { 244 uint32_t addr; 245 uint32_t size; 246 uint32_t alignment; 247 int32_t prot; 248 int32_t flags; 249 int32_t fd; 250 int32_t offset; // FIXME: 64-bit off_t? 251 StringArgument name; 252}; 253 254struct SC_open_params { 255 int dirfd; 256 StringArgument path; 257 int options; 258 u16 mode; 259}; 260 261struct SC_select_params { 262 int nfds; 263 fd_set* readfds; 264 fd_set* writefds; 265 fd_set* exceptfds; 266 struct timeval* timeout; 267}; 268 269struct SC_clock_nanosleep_params { 270 int clock_id; 271 int flags; 272 const struct timespec* requested_sleep; 273 struct timespec* remaining_sleep; 274}; 275 276struct SC_sendto_params { 277 int sockfd; 278 ImmutableBufferArgument<void, size_t> data; 279 int flags; 280 const sockaddr* addr; 281 socklen_t addr_length; 282}; 283 284struct SC_recvfrom_params { 285 int sockfd; 286 MutableBufferArgument<void, size_t> buffer; 287 int flags; 288 sockaddr* addr; 289 socklen_t* addr_length; 290}; 291 292struct SC_getsockopt_params { 293 int sockfd; 294 int level; 295 int option; 296 void* value; 297 socklen_t* value_size; 298}; 299 300struct SC_setsockopt_params { 301 int sockfd; 302 int level; 303 int option; 304 const void* value; 305 socklen_t value_size; 306}; 307 308struct SC_getsockname_params { 309 int sockfd; 310 sockaddr* addr; 311 socklen_t* addrlen; 312}; 313 314struct SC_getpeername_params { 315 int sockfd; 316 sockaddr* addr; 317 socklen_t* addrlen; 318}; 319 320struct SC_futex_params { 321 i32* userspace_address; 322 int futex_op; 323 i32 val; 324 const timespec* timeout; 325}; 326 327struct SC_setkeymap_params { 328 const char* map; 329 const char* shift_map; 330 const char* alt_map; 331 const char* altgr_map; 332}; 333 334struct SC_create_thread_params { 335 unsigned int m_detach_state = 0; // JOINABLE or DETACHED 336 int m_schedule_priority = 30; // THREAD_PRIORITY_NORMAL 337 // FIXME: Implment guard pages in create_thread (unreadable pages at "overflow" end of stack) 338 // "If an implementation rounds up the value of guardsize to a multiple of {PAGESIZE}, 339 // a call to pthread_attr_getguardsize() specifying attr shall store in the guardsize 340 // parameter the guard size specified by the previous pthread_attr_setguardsize() function call" 341 // ... ok, if you say so posix. Guess we get to lie to people about guard page size 342 unsigned int m_guard_page_size = 0; // Rounded up to PAGE_SIZE 343 unsigned int m_reported_guard_page_size = 0; // The lie we tell callers 344 unsigned int m_stack_size = 4 * MB; // Default PTHREAD_STACK_MIN 345 void* m_stack_location = nullptr; // nullptr means any, o.w. process virtual address 346}; 347 348struct SC_realpath_params { 349 StringArgument path; 350 MutableBufferArgument<char, size_t> buffer; 351}; 352 353struct SC_set_mmap_name_params { 354 void* addr; 355 size_t size; 356 StringArgument name; 357}; 358 359struct SC_execve_params { 360 StringArgument path; 361 StringListArgument arguments; 362 StringListArgument environment; 363}; 364 365struct SC_readlink_params { 366 StringArgument path; 367 MutableBufferArgument<char, size_t> buffer; 368}; 369 370struct SC_link_params { 371 StringArgument old_path; 372 StringArgument new_path; 373}; 374 375struct SC_chown_params { 376 StringArgument path; 377 u32 uid; 378 u32 gid; 379}; 380 381struct SC_mknod_params { 382 StringArgument path; 383 u16 mode; 384 u32 dev; 385}; 386 387struct SC_symlink_params { 388 StringArgument target; 389 StringArgument linkpath; 390}; 391 392struct SC_rename_params { 393 StringArgument old_path; 394 StringArgument new_path; 395}; 396 397struct SC_mount_params { 398 int source_fd; 399 StringArgument target; 400 StringArgument fs_type; 401 int flags; 402}; 403 404struct SC_pledge_params { 405 StringArgument promises; 406 StringArgument execpromises; 407}; 408 409struct SC_unveil_params { 410 StringArgument path; 411 StringArgument permissions; 412}; 413 414struct SC_waitid_params { 415 int idtype; 416 int id; 417 struct siginfo* infop; 418 int options; 419}; 420 421struct SC_stat_params { 422 StringArgument path; 423 struct stat* statbuf; 424 bool follow_symlinks; 425}; 426 427struct SC_ptrace_params { 428 int request; 429 pid_t pid; 430 u8* addr; 431 int data; 432}; 433 434void initialize(); 435int sync(); 436 437inline u32 invoke(Function function) 438{ 439 u32 result; 440 asm volatile("int $0x82" 441 : "=a"(result) 442 : "a"(function) 443 : "memory"); 444 return result; 445} 446 447template<typename T1> 448inline u32 invoke(Function function, T1 arg1) 449{ 450 u32 result; 451 asm volatile("int $0x82" 452 : "=a"(result) 453 : "a"(function), "d"((u32)arg1) 454 : "memory"); 455 return result; 456} 457 458template<typename T1, typename T2> 459inline u32 invoke(Function function, T1 arg1, T2 arg2) 460{ 461 u32 result; 462 asm volatile("int $0x82" 463 : "=a"(result) 464 : "a"(function), "d"((u32)arg1), "c"((u32)arg2) 465 : "memory"); 466 return result; 467} 468 469template<typename T1, typename T2, typename T3> 470inline u32 invoke(Function function, T1 arg1, T2 arg2, T3 arg3) 471{ 472 u32 result; 473 asm volatile("int $0x82" 474 : "=a"(result) 475 : "a"(function), "d"((u32)arg1), "c"((u32)arg2), "b"((u32)arg3) 476 : "memory"); 477 return result; 478} 479#endif 480 481} 482 483#undef __ENUMERATE_SYSCALL 484#define __ENUMERATE_SYSCALL(x) using Syscall::SC_##x; 485#define __ENUMERATE_REMOVED_SYSCALL(x) 486ENUMERATE_SYSCALLS 487#undef __ENUMERATE_SYSCALL 488#undef __ENUMERATE_REMOVED_SYSCALL 489#define syscall Syscall::invoke 490 491} 492 493using namespace Kernel;