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 static uptr internal_syscall(u64 nr) {
     15   u64 retval;
     16   asm volatile("syscall" : "=a"(retval) : "a"(nr) : "rcx", "r11");
     17   return retval;
     18 }
     19 
     20 template <typename T1>
     21 static uptr internal_syscall(u64 nr, T1 arg1) {
     22   u64 retval;
     23   asm volatile("syscall" : "=a"(retval) : "a"(nr), "D"((u64)arg1) :
     24                "rcx", "r11");
     25   return retval;
     26 }
     27 
     28 template <typename T1, typename T2>
     29 static uptr internal_syscall(u64 nr, T1 arg1, T2 arg2) {
     30   u64 retval;
     31   asm volatile("syscall" : "=a"(retval) : "a"(nr), "D"((u64)arg1),
     32                "S"((u64)arg2) : "rcx", "r11");
     33   return retval;
     34 }
     35 
     36 template <typename T1, typename T2, typename T3>
     37 static uptr internal_syscall(u64 nr, T1 arg1, T2 arg2, T3 arg3) {
     38   u64 retval;
     39   asm volatile("syscall" : "=a"(retval) : "a"(nr), "D"((u64)arg1),
     40                "S"((u64)arg2), "d"((u64)arg3) : "rcx", "r11");
     41   return retval;
     42 }
     43 
     44 template <typename T1, typename T2, typename T3, typename T4>
     45 static uptr internal_syscall(u64 nr, T1 arg1, T2 arg2, T3 arg3, T4 arg4) {
     46   u64 retval;
     47   asm volatile("mov %5, %%r10;"
     48                "syscall" : "=a"(retval) : "a"(nr), "D"((u64)arg1),
     49                "S"((u64)arg2), "d"((u64)arg3), "r"((u64)arg4) :
     50                "rcx", "r11", "r10");
     51   return retval;
     52 }
     53 
     54 template <typename T1, typename T2, typename T3, typename T4, typename T5>
     55 static uptr internal_syscall(u64 nr, T1 arg1, T2 arg2, T3 arg3, T4 arg4,
     56                              T5 arg5) {
     57   u64 retval;
     58   asm volatile("mov %5, %%r10;"
     59                "mov %6, %%r8;"
     60                "syscall" : "=a"(retval) : "a"(nr), "D"((u64)arg1),
     61                "S"((u64)arg2), "d"((u64)arg3), "r"((u64)arg4), "r"((u64)arg5) :
     62                "rcx", "r11", "r10", "r8");
     63   return retval;
     64 }
     65 
     66 template <typename T1, typename T2, typename T3, typename T4, typename T5,
     67           typename T6>
     68 static uptr internal_syscall(u64 nr, T1 arg1, T2 arg2, T3 arg3, T4 arg4,
     69                              T5 arg5, T6 arg6) {
     70   u64 retval;
     71   asm volatile("mov %5, %%r10;"
     72                "mov %6, %%r8;"
     73                "mov %7, %%r9;"
     74                "syscall" : "=a"(retval) : "a"(nr), "D"((u64)arg1),
     75                "S"((u64)arg2), "d"((u64)arg3), "r"((u64)arg4), "r"((u64)arg5),
     76                "r"((u64)arg6) : "rcx", "r11", "r10", "r8", "r9");
     77   return retval;
     78 }
     79 
     80 bool internal_iserror(uptr retval, int *rverrno) {
     81   if (retval >= (uptr)-4095) {
     82     if (rverrno)
     83       *rverrno = -retval;
     84     return true;
     85   }
     86   return false;
     87 }
     88