syscalls.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /*
  2. * Copyright (C) 2016 by Waldemar Brodkorb <wbx@uclibc-ng.org>
  3. * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  4. * ported from GNU libc
  5. */
  6. /* Copyright (C) 2005-2016 Free Software Foundation, Inc.
  7. This file is part of the GNU C Library.
  8. The GNU C Library is free software; you can redistribute it and/or
  9. modify it under the terms of the GNU Lesser General Public License as
  10. published by the Free Software Foundation; either version 2.1 of the
  11. License, or (at your option) any later version.
  12. The GNU C Library is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. Lesser General Public License for more details.
  16. You should have received a copy of the GNU Lesser General Public
  17. License along with the GNU C Library; if not, see
  18. <http://www.gnu.org/licenses/>. */
  19. #ifndef _BITS_SYSCALLS_H
  20. #define _BITS_SYSCALLS_H
  21. #ifndef _SYSCALL_H
  22. # error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
  23. #endif
  24. #ifndef __ASSEMBLER__
  25. #include <errno.h>
  26. /* For Linux we can use the system call table in the header file
  27. * /usr/include/asm/unistd.h
  28. * of the kernel. But these symbols do not follow the SYS_* syntax
  29. * so we have to redefine the `SYS_ify' macro here. */
  30. #undef SYS_ify
  31. #define SYS_ify(syscall_name) (__NR_##syscall_name)
  32. /* Define a macro which expands into the inline wrapper code for a system
  33. call. */
  34. # undef INLINE_SYSCALL
  35. # define INLINE_SYSCALL(name, nr, args...) \
  36. ({ unsigned long _sys_result = INTERNAL_SYSCALL (name, , nr, args); \
  37. if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (_sys_result, ), 0))\
  38. { \
  39. __set_errno (INTERNAL_SYSCALL_ERRNO (_sys_result, )); \
  40. _sys_result = (unsigned long) -1; \
  41. } \
  42. (long) _sys_result; })
  43. # undef INTERNAL_SYSCALL_DECL
  44. # define INTERNAL_SYSCALL_DECL(err) do { } while (0)
  45. #define INTERNAL_SYSCALL_RAW(name, err, nr, args...) \
  46. ({ long _sys_result; \
  47. { \
  48. LOAD_ARGS_##nr (args) \
  49. register long _x8 __asm__ ("x8") = (name); \
  50. __asm__ volatile ( \
  51. "svc 0 // syscall " # name \
  52. : "=r" (_x0) : "r"(_x8) ASM_ARGS_##nr : "memory"); \
  53. _sys_result = _x0; \
  54. } \
  55. _sys_result; })
  56. # undef INTERNAL_SYSCALL
  57. # define INTERNAL_SYSCALL(name, err, nr, args...) \
  58. INTERNAL_SYSCALL_RAW(SYS_ify(name), err, nr, args)
  59. # undef INTERNAL_SYSCALL_AARCH64
  60. # define INTERNAL_SYSCALL_AARCH64(name, err, nr, args...) \
  61. INTERNAL_SYSCALL_RAW(__ARM_NR_##name, err, nr, args)
  62. # undef INTERNAL_SYSCALL_ERROR_P
  63. # define INTERNAL_SYSCALL_ERROR_P(val, err) \
  64. ((unsigned long) (val) >= (unsigned long) -4095)
  65. # undef INTERNAL_SYSCALL_ERRNO
  66. # define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
  67. /* Macros for setting up inline __asm__ input regs */
  68. # define ASM_ARGS_0
  69. # define ASM_ARGS_1 , "r" (_x0)
  70. # define ASM_ARGS_2 ASM_ARGS_1, "r" (_x1)
  71. # define ASM_ARGS_3 ASM_ARGS_2, "r" (_x2)
  72. # define ASM_ARGS_4 ASM_ARGS_3, "r" (_x3)
  73. # define ASM_ARGS_5 ASM_ARGS_4, "r" (_x4)
  74. # define ASM_ARGS_6 ASM_ARGS_5, "r" (_x5)
  75. # define ASM_ARGS_7 ASM_ARGS_6, "r" (_x6)
  76. /* Macros for converting sys-call wrapper args into sys call args */
  77. # define LOAD_ARGS_0() \
  78. register long _x0 __asm__ ("x0");
  79. # define LOAD_ARGS_1(x0) \
  80. long _x0tmp; \
  81. LOAD_ARGS_0 () \
  82. _x0tmp = (long) (x0); \
  83. _x0 = _x0tmp;
  84. # define LOAD_ARGS_2(x0, x1) \
  85. register long _x1 __asm__ ("x1"); \
  86. long _x1tmp; \
  87. LOAD_ARGS_1 (x0) \
  88. _x1tmp = (long) (x1); \
  89. _x1 = _x1tmp;
  90. # define LOAD_ARGS_3(x0, x1, x2) \
  91. register long _x2 __asm__ ("x2"); \
  92. long _x2tmp; \
  93. LOAD_ARGS_2 (x0, x1) \
  94. _x2tmp = (long) (x2); \
  95. _x2 = _x2tmp;
  96. # define LOAD_ARGS_4(x0, x1, x2, x3) \
  97. register long _x3 __asm__ ("x3"); \
  98. long _x3tmp; \
  99. LOAD_ARGS_3 (x0, x1, x2) \
  100. _x3tmp = (long) (x3); \
  101. _x3 = _x3tmp;
  102. # define LOAD_ARGS_5(x0, x1, x2, x3, x4) \
  103. register long _x4 __asm__ ("x4"); \
  104. long _x4tmp; \
  105. LOAD_ARGS_4 (x0, x1, x2, x3) \
  106. _x4tmp = (long) (x4); \
  107. _x4 = _x4tmp;
  108. # define LOAD_ARGS_6(x0, x1, x2, x3, x4, x5) \
  109. register long _x5 __asm__ ("x5"); \
  110. long _x5tmp; \
  111. LOAD_ARGS_5 (x0, x1, x2, x3, x4) \
  112. _x5tmp = (long) (x5); \
  113. _x5 = _x5tmp;
  114. # define LOAD_ARGS_7(x0, x1, x2, x3, x4, x5, x6)\
  115. register long _x6 __asm__ ("x6"); \
  116. long _x6tmp; \
  117. LOAD_ARGS_6 (x0, x1, x2, x3, x4, x5) \
  118. _x6tmp = (long) (x6); \
  119. _x6 = _x6tmp;
  120. # undef INTERNAL_SYSCALL_NCS
  121. # define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \
  122. INTERNAL_SYSCALL_RAW (number, err, nr, args)
  123. #endif /* ! __ASSEMBLER__ */
  124. #endif /* _BITS_SYSCALLS_H */