1 //===-- sanitizer_syscall_linux_x86_64.inc ----------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Implementations of internal_syscall and internal_iserror for Linux/x86_64. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #define SYSCALL(name) __NR_ ## name 15 16 static uptr internal_syscall(u64 nr) { 17 u64 retval; 18 asm volatile("syscall" : "=a"(retval) : "a"(nr) : "rcx", "r11", 19 "memory", "cc"); 20 return retval; 21 } 22 23 template <typename T1> 24 static uptr internal_syscall(u64 nr, T1 arg1) { 25 u64 retval; 26 asm volatile("syscall" : "=a"(retval) : "a"(nr), "D"((u64)arg1) : 27 "rcx", "r11", "memory", "cc"); 28 return retval; 29 } 30 31 template <typename T1, typename T2> 32 static uptr internal_syscall(u64 nr, T1 arg1, T2 arg2) { 33 u64 retval; 34 asm volatile("syscall" : "=a"(retval) : "a"(nr), "D"((u64)arg1), 35 "S"((u64)arg2) : "rcx", "r11", "memory", "cc"); 36 return retval; 37 } 38 39 template <typename T1, typename T2, typename T3> 40 static uptr internal_syscall(u64 nr, T1 arg1, T2 arg2, T3 arg3) { 41 u64 retval; 42 asm volatile("syscall" : "=a"(retval) : "a"(nr), "D"((u64)arg1), 43 "S"((u64)arg2), "d"((u64)arg3) : "rcx", "r11", "memory", "cc"); 44 return retval; 45 } 46 47 template <typename T1, typename T2, typename T3, typename T4> 48 static uptr internal_syscall(u64 nr, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { 49 u64 retval; 50 asm volatile("mov %5, %%r10;" 51 "syscall" : "=a"(retval) : "a"(nr), "D"((u64)arg1), 52 "S"((u64)arg2), "d"((u64)arg3), "r"((u64)arg4) : 53 "rcx", "r11", "r10", "memory", "cc"); 54 return retval; 55 } 56 57 template <typename T1, typename T2, typename T3, typename T4, typename T5> 58 static uptr internal_syscall(u64 nr, T1 arg1, T2 arg2, T3 arg3, T4 arg4, 59 T5 arg5) { 60 u64 retval; 61 asm volatile("mov %5, %%r10;" 62 "mov %6, %%r8;" 63 "syscall" : "=a"(retval) : "a"(nr), "D"((u64)arg1), 64 "S"((u64)arg2), "d"((u64)arg3), "r"((u64)arg4), "r"((u64)arg5) : 65 "rcx", "r11", "r10", "r8", "memory", "cc"); 66 return retval; 67 } 68 69 template <typename T1, typename T2, typename T3, typename T4, typename T5, 70 typename T6> 71 static uptr internal_syscall(u64 nr, T1 arg1, T2 arg2, T3 arg3, T4 arg4, 72 T5 arg5, T6 arg6) { 73 u64 retval; 74 asm volatile("mov %5, %%r10;" 75 "mov %6, %%r8;" 76 "mov %7, %%r9;" 77 "syscall" : "=a"(retval) : "a"(nr), "D"((u64)arg1), 78 "S"((u64)arg2), "d"((u64)arg3), "r"((u64)arg4), "r"((u64)arg5), 79 "r"((u64)arg6) : "rcx", "r11", "r10", "r8", "r9", 80 "memory", "cc"); 81 return retval; 82 } 83 84 bool internal_iserror(uptr retval, int *rverrno) { 85 if (retval >= (uptr)-4095) { 86 if (rverrno) 87 *rverrno = -retval; 88 return true; 89 } 90 return false; 91 } 92