os_linux_aarch64.c (4113B)
1 /* TODO: generate this whole file with a metaprogram */ 2 3 /* See LICENSE for license details. */ 4 #ifndef asm 5 #ifdef __asm 6 #define asm __asm 7 #else 8 #define asm __asm__ 9 #endif 10 #endif 11 12 typedef enum { 13 SYS_dup3 = 24, 14 SYS_inotify_init1 = 26, 15 SYS_inotify_add_watch = 27, 16 SYS_inotify_rm_watch = 28, 17 SYS_ioctl = 29, 18 SYS_ftruncate = 46, 19 SYS_openat = 56, 20 SYS_close = 57, 21 SYS_read = 63, 22 SYS_write = 64, 23 SYS_pwrite64 = 68, 24 SYS_pselect6 = 72, 25 SYS_exit = 93, 26 SYS_exit_group = 94, 27 SYS_futex = 98, 28 SYS_clock_gettime = 113, 29 SYS_setsid = 157, 30 SYS_prctl = 167, 31 SYS_munmap = 215, 32 SYS_clone = 220, 33 SYS_execve = 221, 34 SYS_mmap = 222, 35 SYS_mprotect = 226, 36 SYS_madvise = 233, 37 SYS_wait4 = 260, 38 SYS_memfd_create = 279, 39 SYS_statx = 291, 40 } AArch64Syscall; 41 42 #define SIGCHLD 17 43 44 /* NOTE(rnp): technically arm64 can have 4K, 16K or 64K pages but we will just assume 64K */ 45 #define PAGE_SIZE 65536 46 47 /* TODO: check that this is equivalent */ 48 typedef u64 sys_fd_set[16]; 49 50 function FORCE_INLINE u64 51 syscall0(AArch64Syscall n) 52 { 53 register i64 x8 asm("x8") = n; 54 register u64 x0 asm("x0"); 55 asm volatile ("svc 0" 56 : "=x"(x0) 57 : "x"(x8) 58 : "memory", "cc" 59 ); 60 return x0; 61 } 62 63 function FORCE_INLINE u64 64 syscall1(AArch64Syscall n, i64 a1) 65 { 66 register i64 x8 asm("x8") = n; 67 register u64 x0 asm("x0") = a1; 68 asm volatile ("svc 0" 69 : "+x"(x0) 70 : "x"(x8) 71 : "memory", "cc" 72 ); 73 return x0; 74 } 75 76 function FORCE_INLINE u64 77 syscall2(AArch64Syscall n, i64 a1, i64 a2) 78 { 79 register i64 x8 asm("x8") = n; 80 register u64 x0 asm("x0") = a1; 81 register i64 x1 asm("x1") = a2; 82 asm volatile ("svc 0" 83 : "+x"(x0) 84 : "x"(x8), "x"(x1) 85 : "memory", "cc" 86 ); 87 return x0; 88 } 89 90 function FORCE_INLINE u64 91 syscall3(AArch64Syscall n, i64 a1, i64 a2, i64 a3) 92 { 93 register i64 x8 asm("x8") = n; 94 register u64 x0 asm("x0") = a1; 95 register i64 x1 asm("x1") = a2; 96 register i64 x2 asm("x2") = a3; 97 asm volatile ("svc 0" 98 : "+x"(x0) 99 : "x"(x8), "x"(x1), "x"(x2) 100 : "memory", "cc" 101 ); 102 return x0; 103 } 104 105 function FORCE_INLINE u64 106 syscall4(AArch64Syscall n, i64 a1, i64 a2, i64 a3, i64 a4) 107 { 108 register i64 x8 asm("x8") = n; 109 register u64 x0 asm("x0") = a1; 110 register i64 x1 asm("x1") = a2; 111 register i64 x2 asm("x2") = a3; 112 register i64 x3 asm("x3") = a4; 113 asm volatile ("svc 0" 114 : "+x"(x0) 115 : "x"(x8), "x"(x1), "x"(x2), "x"(x3) 116 : "memory", "cc" 117 ); 118 return x0; 119 } 120 121 function FORCE_INLINE u64 122 syscall5(AArch64Syscall n, i64 a1, i64 a2, i64 a3, i64 a4, i64 a5) 123 { 124 register i64 x8 asm("x8") = n; 125 register u64 x0 asm("x0") = a1; 126 register i64 x1 asm("x1") = a2; 127 register i64 x2 asm("x2") = a3; 128 register i64 x3 asm("x3") = a4; 129 register i64 x4 asm("x4") = a5; 130 asm volatile ("svc 0" 131 : "+x"(x0) 132 : "x"(x8), "x"(x1), "x"(x2), "x"(x3), "x"(x4) 133 : "memory", "cc" 134 ); 135 return x0; 136 } 137 138 function FORCE_INLINE u64 139 syscall6(AArch64Syscall n, i64 a1, i64 a2, i64 a3, i64 a4, i64 a5, i64 a6) 140 { 141 register i64 x8 asm("x8") = n; 142 register u64 x0 asm("x0") = a1; 143 register i64 x1 asm("x1") = a2; 144 register i64 x2 asm("x2") = a3; 145 register i64 x3 asm("x3") = a4; 146 register i64 x4 asm("x4") = a5; 147 register i64 x5 asm("x5") = a6; 148 asm volatile ("svc 0" 149 : "+x"(x0) 150 : "x"(x8), "x"(x1), "x"(x2), "x"(x3), "x"(x4), "x"(x5) 151 : "memory", "cc" 152 ); 153 return x0; 154 } 155 156 __attribute__((naked)) 157 function i64 158 new_thread(void *stack_base) 159 { 160 asm volatile ( 161 "mov x8, #220\n" // SYS_clone 162 "mov x1, x0\n" // arg2 = new stack 163 "mov x0, #0xF00\n" // arg1 = clone flags (VM|FS|FILES|SIGHAND|THREAD|SYSVMEM) 164 "movk x0, #0x5, lsl #16\n" // no 32 bit immediates in general on arm 165 "svc 0\n" 166 "cbnz x0, 1f\n" // don't clobber syscall return in calling thread 167 "mov x0, sp\n" 168 "ldr x1, [sp]\n" // arm doesn't take the return address from the stack; 169 "blr x1\n" // we need to load it and branch to it 170 "1: ret" 171 ::: "x8", "x1", "memory", "cc" 172 ); 173 } 174 175 #include "os_linux_common.c"