Home | History | Annotate | Download | only in sanitizer_common
      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