1251034Sed//===-- sanitizer_syscall_linux_x86_64.inc ----------------------*- C++ -*-===// 2251034Sed// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6251034Sed// 7251034Sed//===----------------------------------------------------------------------===// 8251034Sed// 9251034Sed// Implementations of internal_syscall and internal_iserror for Linux/x86_64. 10251034Sed// 11251034Sed//===----------------------------------------------------------------------===// 12251034Sed 13276789Sdim#define SYSCALL(name) __NR_ ## name 14276789Sdim 15251034Sedstatic uptr internal_syscall(u64 nr) { 16251034Sed u64 retval; 17274201Sdim asm volatile("syscall" : "=a"(retval) : "a"(nr) : "rcx", "r11", 18274201Sdim "memory", "cc"); 19251034Sed return retval; 20251034Sed} 21251034Sed 22251034Sedtemplate <typename T1> 23251034Sedstatic uptr internal_syscall(u64 nr, T1 arg1) { 24251034Sed u64 retval; 25251034Sed asm volatile("syscall" : "=a"(retval) : "a"(nr), "D"((u64)arg1) : 26274201Sdim "rcx", "r11", "memory", "cc"); 27251034Sed return retval; 28251034Sed} 29251034Sed 30251034Sedtemplate <typename T1, typename T2> 31251034Sedstatic uptr internal_syscall(u64 nr, T1 arg1, T2 arg2) { 32251034Sed u64 retval; 33251034Sed asm volatile("syscall" : "=a"(retval) : "a"(nr), "D"((u64)arg1), 34274201Sdim "S"((u64)arg2) : "rcx", "r11", "memory", "cc"); 35251034Sed return retval; 36251034Sed} 37251034Sed 38251034Sedtemplate <typename T1, typename T2, typename T3> 39251034Sedstatic uptr internal_syscall(u64 nr, T1 arg1, T2 arg2, T3 arg3) { 40251034Sed u64 retval; 41251034Sed asm volatile("syscall" : "=a"(retval) : "a"(nr), "D"((u64)arg1), 42274201Sdim "S"((u64)arg2), "d"((u64)arg3) : "rcx", "r11", "memory", "cc"); 43251034Sed return retval; 44251034Sed} 45251034Sed 46251034Sedtemplate <typename T1, typename T2, typename T3, typename T4> 47251034Sedstatic uptr internal_syscall(u64 nr, T1 arg1, T2 arg2, T3 arg3, T4 arg4) { 48251034Sed u64 retval; 49251034Sed asm volatile("mov %5, %%r10;" 50251034Sed "syscall" : "=a"(retval) : "a"(nr), "D"((u64)arg1), 51251034Sed "S"((u64)arg2), "d"((u64)arg3), "r"((u64)arg4) : 52274201Sdim "rcx", "r11", "r10", "memory", "cc"); 53251034Sed return retval; 54251034Sed} 55251034Sed 56251034Sedtemplate <typename T1, typename T2, typename T3, typename T4, typename T5> 57251034Sedstatic uptr internal_syscall(u64 nr, T1 arg1, T2 arg2, T3 arg3, T4 arg4, 58251034Sed T5 arg5) { 59251034Sed u64 retval; 60251034Sed asm volatile("mov %5, %%r10;" 61251034Sed "mov %6, %%r8;" 62251034Sed "syscall" : "=a"(retval) : "a"(nr), "D"((u64)arg1), 63251034Sed "S"((u64)arg2), "d"((u64)arg3), "r"((u64)arg4), "r"((u64)arg5) : 64274201Sdim "rcx", "r11", "r10", "r8", "memory", "cc"); 65251034Sed return retval; 66251034Sed} 67251034Sed 68251034Sedtemplate <typename T1, typename T2, typename T3, typename T4, typename T5, 69251034Sed typename T6> 70251034Sedstatic uptr internal_syscall(u64 nr, T1 arg1, T2 arg2, T3 arg3, T4 arg4, 71251034Sed T5 arg5, T6 arg6) { 72251034Sed u64 retval; 73251034Sed asm volatile("mov %5, %%r10;" 74251034Sed "mov %6, %%r8;" 75251034Sed "mov %7, %%r9;" 76251034Sed "syscall" : "=a"(retval) : "a"(nr), "D"((u64)arg1), 77251034Sed "S"((u64)arg2), "d"((u64)arg3), "r"((u64)arg4), "r"((u64)arg5), 78274201Sdim "r"((u64)arg6) : "rcx", "r11", "r10", "r8", "r9", 79274201Sdim "memory", "cc"); 80251034Sed return retval; 81251034Sed} 82251034Sed 83251034Sedbool internal_iserror(uptr retval, int *rverrno) { 84251034Sed if (retval >= (uptr)-4095) { 85251034Sed if (rverrno) 86251034Sed *rverrno = -retval; 87251034Sed return true; 88251034Sed } 89251034Sed return false; 90251034Sed} 91