Serenity Operating System
at portability 483 lines 16 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 35extern "C" { 36struct timeval; 37struct timespec; 38struct sockaddr; 39struct siginfo; 40typedef u32 socklen_t; 41} 42 43namespace Kernel { 44 45#define ENUMERATE_SYSCALLS \ 46 __ENUMERATE_SYSCALL(sleep) \ 47 __ENUMERATE_SYSCALL(yield) \ 48 __ENUMERATE_SYSCALL(open) \ 49 __ENUMERATE_SYSCALL(close) \ 50 __ENUMERATE_SYSCALL(read) \ 51 __ENUMERATE_SYSCALL(lseek) \ 52 __ENUMERATE_SYSCALL(kill) \ 53 __ENUMERATE_SYSCALL(getuid) \ 54 __ENUMERATE_SYSCALL(exit) \ 55 __ENUMERATE_SYSCALL(getgid) \ 56 __ENUMERATE_SYSCALL(getpid) \ 57 __ENUMERATE_SYSCALL(waitid) \ 58 __ENUMERATE_SYSCALL(mmap) \ 59 __ENUMERATE_SYSCALL(munmap) \ 60 __ENUMERATE_SYSCALL(get_dir_entries) \ 61 __ENUMERATE_SYSCALL(getcwd) \ 62 __ENUMERATE_SYSCALL(gettimeofday) \ 63 __ENUMERATE_SYSCALL(gethostname) \ 64 __ENUMERATE_SYSCALL(chdir) \ 65 __ENUMERATE_SYSCALL(uname) \ 66 __ENUMERATE_SYSCALL(set_mmap_name) \ 67 __ENUMERATE_SYSCALL(readlink) \ 68 __ENUMERATE_SYSCALL(write) \ 69 __ENUMERATE_SYSCALL(ttyname_r) \ 70 __ENUMERATE_SYSCALL(stat) \ 71 __ENUMERATE_SYSCALL(getsid) \ 72 __ENUMERATE_SYSCALL(setsid) \ 73 __ENUMERATE_SYSCALL(getpgid) \ 74 __ENUMERATE_SYSCALL(setpgid) \ 75 __ENUMERATE_SYSCALL(getpgrp) \ 76 __ENUMERATE_SYSCALL(fork) \ 77 __ENUMERATE_SYSCALL(execve) \ 78 __ENUMERATE_SYSCALL(geteuid) \ 79 __ENUMERATE_SYSCALL(getegid) \ 80 __ENUMERATE_SYSCALL(getdtablesize) \ 81 __ENUMERATE_SYSCALL(dup) \ 82 __ENUMERATE_SYSCALL(dup2) \ 83 __ENUMERATE_SYSCALL(sigaction) \ 84 __ENUMERATE_SYSCALL(getppid) \ 85 __ENUMERATE_SYSCALL(umask) \ 86 __ENUMERATE_SYSCALL(getgroups) \ 87 __ENUMERATE_SYSCALL(setgroups) \ 88 __ENUMERATE_SYSCALL(sigreturn) \ 89 __ENUMERATE_SYSCALL(sigprocmask) \ 90 __ENUMERATE_SYSCALL(sigpending) \ 91 __ENUMERATE_SYSCALL(pipe) \ 92 __ENUMERATE_SYSCALL(killpg) \ 93 __ENUMERATE_SYSCALL(setuid) \ 94 __ENUMERATE_SYSCALL(setgid) \ 95 __ENUMERATE_SYSCALL(alarm) \ 96 __ENUMERATE_SYSCALL(fstat) \ 97 __ENUMERATE_SYSCALL(access) \ 98 __ENUMERATE_SYSCALL(fcntl) \ 99 __ENUMERATE_SYSCALL(ioctl) \ 100 __ENUMERATE_SYSCALL(mkdir) \ 101 __ENUMERATE_SYSCALL(times) \ 102 __ENUMERATE_SYSCALL(utime) \ 103 __ENUMERATE_SYSCALL(sync) \ 104 __ENUMERATE_SYSCALL(ptsname_r) \ 105 __ENUMERATE_SYSCALL(select) \ 106 __ENUMERATE_SYSCALL(unlink) \ 107 __ENUMERATE_SYSCALL(poll) \ 108 __ENUMERATE_SYSCALL(rmdir) \ 109 __ENUMERATE_SYSCALL(chmod) \ 110 __ENUMERATE_SYSCALL(usleep) \ 111 __ENUMERATE_SYSCALL(socket) \ 112 __ENUMERATE_SYSCALL(bind) \ 113 __ENUMERATE_SYSCALL(accept) \ 114 __ENUMERATE_SYSCALL(listen) \ 115 __ENUMERATE_SYSCALL(connect) \ 116 __ENUMERATE_SYSCALL(create_shared_buffer) \ 117 __ENUMERATE_SYSCALL(share_buffer_with) \ 118 __ENUMERATE_SYSCALL(get_shared_buffer) \ 119 __ENUMERATE_SYSCALL(release_shared_buffer) \ 120 __ENUMERATE_SYSCALL(link) \ 121 __ENUMERATE_SYSCALL(chown) \ 122 __ENUMERATE_SYSCALL(fchmod) \ 123 __ENUMERATE_SYSCALL(symlink) \ 124 __ENUMERATE_SYSCALL(get_shared_buffer_size) \ 125 __ENUMERATE_SYSCALL(seal_shared_buffer) \ 126 __ENUMERATE_SYSCALL(sendto) \ 127 __ENUMERATE_SYSCALL(recvfrom) \ 128 __ENUMERATE_SYSCALL(getsockopt) \ 129 __ENUMERATE_SYSCALL(setsockopt) \ 130 __ENUMERATE_SYSCALL(create_thread) \ 131 __ENUMERATE_SYSCALL(gettid) \ 132 __ENUMERATE_SYSCALL(donate) \ 133 __ENUMERATE_SYSCALL(rename) \ 134 __ENUMERATE_SYSCALL(ftruncate) \ 135 __ENUMERATE_SYSCALL(systrace) \ 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(share_buffer_globally) \ 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_nanosleep) \ 163 __ENUMERATE_SYSCALL(join_thread) \ 164 __ENUMERATE_SYSCALL(module_load) \ 165 __ENUMERATE_SYSCALL(module_unload) \ 166 __ENUMERATE_SYSCALL(detach_thread) \ 167 __ENUMERATE_SYSCALL(set_thread_name) \ 168 __ENUMERATE_SYSCALL(get_thread_name) \ 169 __ENUMERATE_SYSCALL(madvise) \ 170 __ENUMERATE_SYSCALL(purge) \ 171 __ENUMERATE_SYSCALL(set_shared_buffer_volatile) \ 172 __ENUMERATE_SYSCALL(profiling_enable) \ 173 __ENUMERATE_SYSCALL(profiling_disable) \ 174 __ENUMERATE_SYSCALL(get_kernel_info_page) \ 175 __ENUMERATE_SYSCALL(futex) \ 176 __ENUMERATE_SYSCALL(set_thread_boost) \ 177 __ENUMERATE_SYSCALL(set_process_boost) \ 178 __ENUMERATE_SYSCALL(chroot) \ 179 __ENUMERATE_SYSCALL(pledge) \ 180 __ENUMERATE_SYSCALL(unveil) \ 181 __ENUMERATE_SYSCALL(perf_event) \ 182 __ENUMERATE_SYSCALL(shutdown) 183 184namespace Syscall { 185 186enum Function { 187#undef __ENUMERATE_SYSCALL 188#undef __ENUMERATE_REMOVED_SYSCALL 189#define __ENUMERATE_REMOVED_SYSCALL(x) SC_##x, 190#define __ENUMERATE_SYSCALL(x) SC_##x, 191 ENUMERATE_SYSCALLS 192#undef __ENUMERATE_SYSCALL 193#undef __ENUMERATE_REMOVED_SYSCALL 194 __Count 195}; 196 197inline constexpr const char* to_string(Function function) 198{ 199 switch (function) { 200#undef __ENUMERATE_SYSCALL 201#undef __ENUMERATE_REMOVED_SYSCALL 202#define __ENUMERATE_REMOVED_SYSCALL(x) \ 203 case SC_##x: \ 204 return #x " (removed)"; 205#define __ENUMERATE_SYSCALL(x) \ 206 case SC_##x: \ 207 return #x; 208 ENUMERATE_SYSCALLS 209#undef __ENUMERATE_SYSCALL 210#undef __ENUMERATE_REMOVED_SYSCALL 211 default: 212 break; 213 } 214 return "Unknown"; 215} 216 217#ifdef __serenity__ 218struct StringArgument { 219 const char* characters { nullptr }; 220 size_t length { 0 }; 221}; 222 223template<typename DataType, typename SizeType> 224struct MutableBufferArgument { 225 DataType* data { nullptr }; 226 SizeType size { 0 }; 227}; 228 229template<typename DataType, typename SizeType> 230struct ImmutableBufferArgument { 231 const DataType* data { nullptr }; 232 SizeType size { 0 }; 233}; 234 235struct StringListArgument { 236 StringArgument* strings { nullptr }; 237 size_t length { 0 }; 238}; 239 240struct SC_mmap_params { 241 uint32_t addr; 242 uint32_t size; 243 uint32_t alignment; 244 int32_t prot; 245 int32_t flags; 246 int32_t fd; 247 int32_t offset; // FIXME: 64-bit off_t? 248 StringArgument name; 249}; 250 251struct SC_open_params { 252 int dirfd; 253 StringArgument path; 254 int options; 255 u16 mode; 256}; 257 258struct SC_select_params { 259 int nfds; 260 fd_set* readfds; 261 fd_set* writefds; 262 fd_set* exceptfds; 263 struct timeval* timeout; 264}; 265 266struct SC_clock_nanosleep_params { 267 int clock_id; 268 int flags; 269 const struct timespec* requested_sleep; 270 struct timespec* remaining_sleep; 271}; 272 273struct SC_sendto_params { 274 int sockfd; 275 ImmutableBufferArgument<void, size_t> data; 276 int flags; 277 const sockaddr* addr; 278 socklen_t addr_length; 279}; 280 281struct SC_recvfrom_params { 282 int sockfd; 283 MutableBufferArgument<void, size_t> buffer; 284 int flags; 285 sockaddr* addr; 286 socklen_t* addr_length; 287}; 288 289struct SC_getsockopt_params { 290 int sockfd; 291 int level; 292 int option; 293 void* value; 294 socklen_t* value_size; 295}; 296 297struct SC_setsockopt_params { 298 int sockfd; 299 int level; 300 int option; 301 const void* value; 302 socklen_t value_size; 303}; 304 305struct SC_getsockname_params { 306 int sockfd; 307 sockaddr* addr; 308 socklen_t* addrlen; 309}; 310 311struct SC_getpeername_params { 312 int sockfd; 313 sockaddr* addr; 314 socklen_t* addrlen; 315}; 316 317struct SC_futex_params { 318 i32* userspace_address; 319 int futex_op; 320 i32 val; 321 const timespec* timeout; 322}; 323 324struct SC_setkeymap_params { 325 const char* map; 326 const char* shift_map; 327 const char* alt_map; 328 const char* altgr_map; 329}; 330 331struct SC_create_thread_params { 332 unsigned int m_detach_state = 0; // JOINABLE or DETACHED 333 int m_schedule_priority = 30; // THREAD_PRIORITY_NORMAL 334 // FIXME: Implment guard pages in create_thread (unreadable pages at "overflow" end of stack) 335 // "If an implementation rounds up the value of guardsize to a multiple of {PAGESIZE}, 336 // a call to pthread_attr_getguardsize() specifying attr shall store in the guardsize 337 // parameter the guard size specified by the previous pthread_attr_setguardsize() function call" 338 // ... ok, if you say so posix. Guess we get to lie to people about guard page size 339 unsigned int m_guard_page_size = 0; // Rounded up to PAGE_SIZE 340 unsigned int m_reported_guard_page_size = 0; // The lie we tell callers 341 unsigned int m_stack_size = 4 * MB; // Default PTHREAD_STACK_MIN 342 void* m_stack_location = nullptr; // nullptr means any, o.w. process virtual address 343}; 344 345struct SC_realpath_params { 346 StringArgument path; 347 MutableBufferArgument<char, size_t> buffer; 348}; 349 350struct SC_set_mmap_name_params { 351 void* addr; 352 size_t size; 353 StringArgument name; 354}; 355 356struct SC_execve_params { 357 StringArgument path; 358 StringListArgument arguments; 359 StringListArgument environment; 360}; 361 362struct SC_readlink_params { 363 StringArgument path; 364 MutableBufferArgument<char, size_t> buffer; 365}; 366 367struct SC_link_params { 368 StringArgument old_path; 369 StringArgument new_path; 370}; 371 372struct SC_chown_params { 373 StringArgument path; 374 u32 uid; 375 u32 gid; 376}; 377 378struct SC_mknod_params { 379 StringArgument path; 380 u16 mode; 381 u32 dev; 382}; 383 384struct SC_symlink_params { 385 StringArgument target; 386 StringArgument linkpath; 387}; 388 389struct SC_rename_params { 390 StringArgument old_path; 391 StringArgument new_path; 392}; 393 394struct SC_mount_params { 395 StringArgument source; 396 StringArgument target; 397 StringArgument fs_type; 398 int flags; 399}; 400 401struct SC_pledge_params { 402 StringArgument promises; 403 StringArgument execpromises; 404}; 405 406struct SC_unveil_params { 407 StringArgument path; 408 StringArgument permissions; 409}; 410 411struct SC_waitid_params { 412 int idtype; 413 int id; 414 struct siginfo* infop; 415 int options; 416}; 417 418struct SC_stat_params { 419 StringArgument path; 420 struct stat* statbuf; 421 bool follow_symlinks; 422}; 423 424void initialize(); 425int sync(); 426 427inline u32 invoke(Function function) 428{ 429 u32 result; 430 asm volatile("int $0x82" 431 : "=a"(result) 432 : "a"(function) 433 : "memory"); 434 return result; 435} 436 437template<typename T1> 438inline u32 invoke(Function function, T1 arg1) 439{ 440 u32 result; 441 asm volatile("int $0x82" 442 : "=a"(result) 443 : "a"(function), "d"((u32)arg1) 444 : "memory"); 445 return result; 446} 447 448template<typename T1, typename T2> 449inline u32 invoke(Function function, T1 arg1, T2 arg2) 450{ 451 u32 result; 452 asm volatile("int $0x82" 453 : "=a"(result) 454 : "a"(function), "d"((u32)arg1), "c"((u32)arg2) 455 : "memory"); 456 return result; 457} 458 459template<typename T1, typename T2, typename T3> 460inline u32 invoke(Function function, T1 arg1, T2 arg2, T3 arg3) 461{ 462 u32 result; 463 asm volatile("int $0x82" 464 : "=a"(result) 465 : "a"(function), "d"((u32)arg1), "c"((u32)arg2), "b"((u32)arg3) 466 : "memory"); 467 return result; 468} 469#endif 470 471} 472 473#undef __ENUMERATE_SYSCALL 474#define __ENUMERATE_SYSCALL(x) using Syscall::SC_##x; 475#define __ENUMERATE_REMOVED_SYSCALL(x) 476ENUMERATE_SYSCALLS 477#undef __ENUMERATE_SYSCALL 478#undef __ENUMERATE_REMOVED_SYSCALL 479#define syscall Syscall::invoke 480 481} 482 483using namespace Kernel;