platform_linux_amd64.c (3732B)
1 /* See LICENSE for license details. */ 2 #ifndef asm 3 #ifdef __asm 4 #define asm __asm 5 #else 6 #define asm __asm__ 7 #endif 8 #endif 9 10 /* TODO: X macro that defines all of these with the appropriate function/macro */ 11 #define SYS_read 0 12 #define SYS_write 1 13 #define SYS_close 3 14 #define SYS_mmap 9 15 #define SYS_mprotect 10 16 #define SYS_munmap 11 17 #define SYS_ioctl 16 18 #define SYS_pwrite64 18 19 #define SYS_madvise 28 20 #define SYS_clone 56 21 #define SYS_execve 59 22 #define SYS_wait4 61 23 #define SYS_ftruncate 77 24 #define SYS_setsid 112 25 #define SYS_prctl 157 26 #define SYS_futex 202 27 #define SYS_getdents64 217 28 #define SYS_clock_gettime 228 29 #define SYS_exit_group 231 30 #define SYS_inotify_add_watch 254 31 #define SYS_inotify_rm_watch 255 32 #define SYS_openat 257 33 #define SYS_pselect6 270 34 #define SYS_dup3 292 35 #define SYS_inotify_init1 294 36 #define SYS_memfd_create 319 37 #define SYS_statx 332 38 39 #define SIGCHLD 17 40 41 #define PAGE_SIZE 4096 42 43 typedef u64 sys_fd_set[16]; 44 45 #define DIRENT_RECLEN_OFF 16 46 #define DIRENT_TYPE_OFF 18 47 #define DIRENT_NAME_OFF 19 48 49 static FORCE_INLINE u64 50 syscall1(i64 n, i64 a1) 51 { 52 u64 result; 53 asm volatile ("syscall" 54 : "=a"(result) 55 : "a"(n), "D"(a1) 56 : "rcx", "r11", "memory" 57 ); 58 return result; 59 } 60 61 static FORCE_INLINE u64 62 syscall2(i64 n, i64 a1, i64 a2) 63 { 64 i64 result; 65 asm volatile ("syscall" 66 : "=a"(result) 67 : "a"(n), "D"(a1), "S"(a2) 68 : "rcx", "r11", "memory" 69 ); 70 return result; 71 } 72 73 static FORCE_INLINE u64 74 syscall3(i64 n, i64 a1, i64 a2, i64 a3) 75 { 76 u64 result; 77 asm volatile ("syscall" 78 : "=a"(result) 79 : "a"(n), "D"(a1), "S"(a2), "d"(a3) 80 : "rcx", "r11", "memory" 81 ); 82 return result; 83 } 84 85 static FORCE_INLINE u64 86 syscall4(i64 n, i64 a1, i64 a2, i64 a3, i64 a4) 87 { 88 u64 result; 89 register i64 r10 asm("r10") = a4; 90 asm volatile ("syscall" 91 : "=a"(result) 92 : "a"(n), "D"(a1), "S"(a2), "d"(a3), "r"(r10) 93 : "rcx", "r11", "memory" 94 ); 95 return result; 96 } 97 98 99 static FORCE_INLINE u64 100 syscall5(i64 n, i64 a1, i64 a2, i64 a3, i64 a4, i64 a5) 101 { 102 u64 result; 103 register i64 r10 asm("r10") = a4; 104 register i64 r8 asm("r8") = a5; 105 asm volatile ("syscall" 106 : "=a"(result) 107 : "a"(n), "D"(a1), "S"(a2), "d"(a3), "r"(r10), "r"(r8) 108 : "rcx", "r11", "memory" 109 ); 110 return result; 111 } 112 113 static FORCE_INLINE u64 114 syscall6(i64 n, i64 a1, i64 a2, i64 a3, i64 a4, i64 a5, i64 a6) 115 { 116 i64 result; 117 register i64 r10 asm("r10") = a4; 118 register i64 r8 asm("r8") = a5; 119 register i64 r9 asm("r9") = a6; 120 asm volatile ("syscall" 121 : "=a"(result) 122 : "a"(n), "D"(a1), "S"(a2), "d"(a3), "r"(r10), "r"(r8), "r"(r9) 123 : "rcx", "r11", "memory" 124 ); 125 return result; 126 } 127 128 /* NOTE: based on code from nullprogram (Chris Wellons) */ 129 __attribute__((naked)) 130 static i64 131 new_thread(void *stack_base) 132 { 133 asm volatile ( 134 "mov %%rdi, %%rsi\n" // arg2 = new stack 135 "mov $0x50F00, %%edi\n" // arg1 = clone flags (VM|FS|FILES|SIGHAND|THREAD|SYSVMEM) 136 "mov $56, %%eax\n" // SYS_clone 137 "syscall\n" 138 "test %%eax, %%eax\n" // don't mess with the calling thread's stack 139 "jne 1f\n" 140 "mov %%rsp, %%rdi\n" 141 "sub $8, %%rsp\n" // place a 0 return branch pointer on the child's stack 142 "push (%%rdi)\n" // push the entry point back onto the stack for use by ret 143 "1: ret\n" 144 ::: "rax", "rcx", "rsi", "rdi", "r11", "memory" 145 ); 146 } 147 148 #include "platform_linux_common.c" 149 150 #if 0 151 asm ( 152 ".intel_syntax noprefix\n" 153 ".global _start\n" 154 "_start:\n" 155 " mov edi, DWORD PTR [rsp]\n" 156 " lea rsi, [rsp+8]\n" 157 " lea rdx, [rsi+rdi*8+8]\n" 158 " call linux_main\n" 159 " ud2\n" 160 ".att_syntax\n" 161 ); 162 #endif