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