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