gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/syscalls/linux/rseq/syscalls.h (about) 1 // Copyright 2019 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef GVISOR_TEST_SYSCALLS_LINUX_RSEQ_SYSCALLS_H_ 16 #define GVISOR_TEST_SYSCALLS_LINUX_RSEQ_SYSCALLS_H_ 17 18 #include "test/syscalls/linux/rseq/types.h" 19 20 // Syscall numbers. 21 #if defined(__x86_64__) 22 constexpr int kExitGroup = 231; 23 constexpr int kFutex = 202; 24 constexpr int kGetpid = 39; 25 constexpr int kMembarrier = 324; 26 constexpr int kMmap = 9; 27 #elif defined(__aarch64__) 28 constexpr int kExitGroup = 94; 29 constexpr int kFutex = 98; 30 constexpr int kGetpid = 172; 31 constexpr int kMembarrier = 283; 32 constexpr int kMmap = 222; 33 #else 34 #error "Unknown architecture" 35 #endif 36 37 namespace gvisor { 38 namespace testing { 39 40 // Standalone system call interfaces. 41 // Note that these are all "raw" system call interfaces which encode 42 // errors by setting the return value to a small negative number. 43 // Use sys_errno() to check system call return values for errors. 44 45 // Maximum Linux error number. 46 constexpr int kMaxErrno = 4095; 47 48 // Errno values. 49 #define EPERM 1 50 #define EINTR 4 51 #define EAGAIN 11 52 #define EFAULT 14 53 #define EBUSY 16 54 #define EINVAL 22 55 56 // Get the error number from a raw system call return value. 57 // Returns a positive error number or 0 if there was no error. 58 static inline int sys_errno(uintptr_t rval) { 59 if (rval >= static_cast<uintptr_t>(-kMaxErrno)) { 60 return -static_cast<int>(rval); 61 } 62 return 0; 63 } 64 65 extern "C" uintptr_t raw_syscall(int number, ...); 66 67 extern "C" int clone(int (*fn)(void*), uintptr_t stack, int flags, void* arg, 68 uint32_t* child_tid); 69 70 // clone flags: 71 #define CLONE_VM 0x00000100 72 #define CLONE_FS 0x00000200 73 #define CLONE_FILES 0x00000400 74 #define CLONE_SIGHAND 0x00000800 75 #define CLONE_THREAD 0x00010000 76 #define CLONE_CHILD_CLEARTID 0x00200000 77 #define CLONE_CHILD_SETTID 0x01000000 78 79 static inline void sys_exit_group(int status) { 80 raw_syscall(kExitGroup, status); 81 } 82 83 static inline uintptr_t sys_futex(uint32_t* uaddr, int futex_op, uint32_t val, 84 const struct timespec* timeout) { 85 return raw_syscall(kFutex, uaddr, futex_op, val, timeout); 86 } 87 88 // futex ops: 89 #define FUTEX_WAIT 0 90 91 static inline int sys_getpid() { 92 return static_cast<int>(raw_syscall(kGetpid)); 93 } 94 95 static inline uintptr_t sys_membarrier(int cmd, unsigned int flags) { 96 return raw_syscall(kMembarrier, cmd, flags); 97 } 98 99 // membarrier commands: 100 #define MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ (1 << 7) 101 #define MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ (1 << 8) 102 103 static inline uintptr_t sys_mmap(void* addr, size_t length, int prot, int flags, 104 int fd, int64_t offset) { 105 return raw_syscall(kMmap, addr, length, prot, flags, fd, offset); 106 } 107 108 // mmap options: 109 #define PROT_READ 0x1 110 #define PROT_WRITE 0x2 111 #define MAP_PRIVATE 0x02 112 #define MAP_ANONYMOUS 0x20 113 #define MAP_STACK 0x020000 114 115 } // namespace testing 116 } // namespace gvisor 117 118 #endif // GVISOR_TEST_SYSCALLS_LINUX_RSEQ_SYSCALLS_H_