Mirror of strace – the linux syscall tracer
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

futex.c 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /*
  2. * Copyright (c) 2002-2003 Roland McGrath <roland@redhat.com>
  3. * Copyright (c) 2007-2008 Ulrich Drepper <drepper@redhat.com>
  4. * Copyright (c) 2009 Andreas Schwab <schwab@redhat.com>
  5. * Copyright (c) 2014-2015 Dmitry V. Levin <ldv@altlinux.org>
  6. * Copyright (c) 2014-2019 The strace developers.
  7. * All rights reserved.
  8. *
  9. * SPDX-License-Identifier: LGPL-2.1-or-later
  10. */
  11. #include "defs.h"
  12. #ifndef FUTEX_PRIVATE_FLAG
  13. # define FUTEX_PRIVATE_FLAG 128
  14. #endif
  15. #ifndef FUTEX_CLOCK_REALTIME
  16. # define FUTEX_CLOCK_REALTIME 256
  17. #endif
  18. #ifndef FUTEX_OP_OPARG_SHIFT
  19. # define FUTEX_OP_OPARG_SHIFT 8
  20. #endif
  21. #include "xlat/futexbitset.h"
  22. #include "xlat/futexops.h"
  23. #include "xlat/futexwakeops.h"
  24. #include "xlat/futexwakecmps.h"
  25. static int
  26. do_futex(struct tcb *const tcp, const print_obj_by_addr_fn print_ts)
  27. {
  28. const kernel_ulong_t uaddr = tcp->u_arg[0];
  29. const int op = tcp->u_arg[1];
  30. const int cmd = op & 127;
  31. const kernel_ulong_t timeout = tcp->u_arg[3];
  32. const kernel_ulong_t uaddr2 = tcp->u_arg[4];
  33. const unsigned int val = tcp->u_arg[2];
  34. const unsigned int val2 = tcp->u_arg[3];
  35. const unsigned int val3 = tcp->u_arg[5];
  36. const char *comment;
  37. printaddr(uaddr);
  38. tprints(", ");
  39. printxval(futexops, op, "FUTEX_???");
  40. switch (cmd) {
  41. case FUTEX_WAIT:
  42. tprintf(", %u", val);
  43. tprints(", ");
  44. print_ts(tcp, timeout);
  45. break;
  46. case FUTEX_LOCK_PI:
  47. tprints(", ");
  48. print_ts(tcp, timeout);
  49. break;
  50. case FUTEX_WAIT_BITSET:
  51. tprintf(", %u", val);
  52. tprints(", ");
  53. print_ts(tcp, timeout);
  54. tprints(", ");
  55. printxval(futexbitset, val3, NULL);
  56. break;
  57. case FUTEX_WAKE_BITSET:
  58. tprintf(", %u", val);
  59. tprints(", ");
  60. printxval(futexbitset, val3, NULL);
  61. break;
  62. case FUTEX_REQUEUE:
  63. tprintf(", %u", val);
  64. tprintf(", %u, ", val2);
  65. printaddr(uaddr2);
  66. break;
  67. case FUTEX_CMP_REQUEUE:
  68. case FUTEX_CMP_REQUEUE_PI:
  69. tprintf(", %u", val);
  70. tprintf(", %u, ", val2);
  71. printaddr(uaddr2);
  72. tprintf(", %u", val3);
  73. break;
  74. case FUTEX_WAKE_OP:
  75. tprintf(", %u", val);
  76. tprintf(", %u, ", val2);
  77. printaddr(uaddr2);
  78. tprints(", ");
  79. if ((val3 >> 28) & FUTEX_OP_OPARG_SHIFT) {
  80. print_xlat(FUTEX_OP_OPARG_SHIFT);
  81. tprints("<<28|");
  82. }
  83. comment = printxval(futexwakeops, (val3 >> 28) & 0x7, NULL)
  84. ? NULL : "FUTEX_OP_???";
  85. tprints("<<28");
  86. tprints_comment(comment);
  87. tprintf("|%#x<<12|", (val3 >> 12) & 0xfff);
  88. comment = printxval(futexwakecmps, (val3 >> 24) & 0xf, NULL)
  89. ? NULL : "FUTEX_OP_CMP_???";
  90. tprints("<<24");
  91. tprints_comment(comment);
  92. tprintf("|%#x", val3 & 0xfff);
  93. break;
  94. case FUTEX_WAIT_REQUEUE_PI:
  95. tprintf(", %u", val);
  96. tprints(", ");
  97. print_ts(tcp, timeout);
  98. tprints(", ");
  99. printaddr(uaddr2);
  100. break;
  101. case FUTEX_FD:
  102. case FUTEX_WAKE:
  103. tprintf(", %u", val);
  104. break;
  105. case FUTEX_UNLOCK_PI:
  106. case FUTEX_TRYLOCK_PI:
  107. break;
  108. default:
  109. tprintf(", %u", val);
  110. tprints(", ");
  111. printaddr(timeout);
  112. tprints(", ");
  113. printaddr(uaddr2);
  114. tprintf(", %#x", val3);
  115. break;
  116. }
  117. return RVAL_DECODED;
  118. }
  119. #if HAVE_ARCH_TIME32_SYSCALLS
  120. SYS_FUNC(futex_time32)
  121. {
  122. return do_futex(tcp, print_timespec32);
  123. }
  124. #endif
  125. SYS_FUNC(futex_time64)
  126. {
  127. return do_futex(tcp, print_timespec64);
  128. }