sanitizer_syscall_linux_hexagon.inc 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. //===-- sanitizer_syscall_linux_hexagon.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/hexagon.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #define SYSCALL(name) __NR_##name
  13. #define __internal_syscall_LL_E(x) \
  14. ((union { \
  15. long long ll; \
  16. long l[2]; \
  17. }){.ll = x}) \
  18. .l[0], \
  19. ((union { \
  20. long long ll; \
  21. long l[2]; \
  22. }){.ll = x}) \
  23. .l[1]
  24. #define __internal_syscall_LL_O(x) 0, __SYSCALL_LL_E((x))
  25. #define __asm_syscall(...) \
  26. do { \
  27. __asm__ __volatile__("trap0(#1)" : "=r"(r0) : __VA_ARGS__ : "memory"); \
  28. return r0; \
  29. } while (0)
  30. #define __internal_syscall0(n) (__internal_syscall)(n)
  31. static uptr __internal_syscall(long n) {
  32. register u32 r6 __asm__("r6") = n;
  33. register u32 r0 __asm__("r0");
  34. __asm_syscall("r"(r6));
  35. }
  36. #define __internal_syscall1(n, a1) (__internal_syscall)(n, (long)(a1))
  37. static uptr __internal_syscall(long n, long a) {
  38. register u32 r6 __asm__("r6") = n;
  39. register u32 r0 __asm__("r0") = a;
  40. __asm_syscall("r"(r6), "0"(r0));
  41. }
  42. #define __internal_syscall2(n, a1, a2) \
  43. (__internal_syscall)(n, (long)(a1), (long)(a2))
  44. static uptr __internal_syscall(long n, long a, long b) {
  45. register u32 r6 __asm__("r6") = n;
  46. register u32 r0 __asm__("r0") = a;
  47. register u32 r1 __asm__("r1") = b;
  48. __asm_syscall("r"(r6), "0"(r0), "r"(r1));
  49. }
  50. #define __internal_syscall3(n, a1, a2, a3) \
  51. (__internal_syscall)(n, (long)(a1), (long)(a2), (long)(a3))
  52. static uptr __internal_syscall(long n, long a, long b, long c) {
  53. register u32 r6 __asm__("r6") = n;
  54. register u32 r0 __asm__("r0") = a;
  55. register u32 r1 __asm__("r1") = b;
  56. register u32 r2 __asm__("r2") = c;
  57. __asm_syscall("r"(r6), "0"(r0), "r"(r1), "r"(r2));
  58. }
  59. #define __internal_syscall4(n, a1, a2, a3, a4) \
  60. (__internal_syscall)(n, (long)(a1), (long)(a2), (long)(a3), (long)(a4))
  61. static uptr __internal_syscall(long n, long a, long b, long c, long d) {
  62. register u32 r6 __asm__("r6") = n;
  63. register u32 r0 __asm__("r0") = a;
  64. register u32 r1 __asm__("r1") = b;
  65. register u32 r2 __asm__("r2") = c;
  66. register u32 r3 __asm__("r3") = d;
  67. __asm_syscall("r"(r6), "0"(r0), "r"(r1), "r"(r2), "r"(r3));
  68. }
  69. #define __internal_syscall5(n, a1, a2, a3, a4, a5) \
  70. (__internal_syscall)(n, (long)(a1), (long)(a2), (long)(a3), (long)(a4), \
  71. (long)(a5))
  72. static uptr __internal_syscall(long n, long a, long b, long c, long d, long e) {
  73. register u32 r6 __asm__("r6") = n;
  74. register u32 r0 __asm__("r0") = a;
  75. register u32 r1 __asm__("r1") = b;
  76. register u32 r2 __asm__("r2") = c;
  77. register u32 r3 __asm__("r3") = d;
  78. register u32 r4 __asm__("r4") = e;
  79. __asm_syscall("r"(r6), "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4));
  80. }
  81. #define __internal_syscall6(n, a1, a2, a3, a4, a5, a6) \
  82. (__internal_syscall)(n, (long)(a1), (long)(a2), (long)(a3), (long)(a4), \
  83. (long)(a5), (long)(a6))
  84. static uptr __internal_syscall(long n, long a, long b, long c, long d, long e,
  85. long f) {
  86. register u32 r6 __asm__("r6") = n;
  87. register u32 r0 __asm__("r0") = a;
  88. register u32 r1 __asm__("r1") = b;
  89. register u32 r2 __asm__("r2") = c;
  90. register u32 r3 __asm__("r3") = d;
  91. register u32 r4 __asm__("r4") = e;
  92. register u32 r5 __asm__("r5") = f;
  93. __asm_syscall("r"(r6), "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5));
  94. }
  95. #define __SYSCALL_NARGS_X(a1, a2, a3, a4, a5, a6, a7, a8, n, ...) n
  96. #define __SYSCALL_NARGS(...) \
  97. __SYSCALL_NARGS_X(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0, )
  98. #define __SYSCALL_CONCAT_X(a, b) a##b
  99. #define __SYSCALL_CONCAT(a, b) __SYSCALL_CONCAT_X(a, b)
  100. #define __SYSCALL_DISP(b, ...) \
  101. __SYSCALL_CONCAT(b, __SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__)
  102. #define internal_syscall(...) __SYSCALL_DISP(__internal_syscall, __VA_ARGS__)
  103. // Helper function used to avoid clobbering of errno.
  104. bool internal_iserror(uptr retval, int *rverrno) {
  105. if (retval >= (uptr)-4095) {
  106. if (rverrno)
  107. *rverrno = -retval;
  108. return true;
  109. }
  110. return false;
  111. }