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.

ipc_sem.c 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /*
  2. * Copyright (c) 1993 Ulrich Pegelow <pegelow@moorea.uni-muenster.de>
  3. * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
  4. * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
  5. * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
  6. * Copyright (c) 2003-2006 Roland McGrath <roland@redhat.com>
  7. * Copyright (c) 2006-2015 Dmitry V. Levin <ldv@altlinux.org>
  8. * Copyright (c) 2015-2019 The strace developers.
  9. * All rights reserved.
  10. *
  11. * SPDX-License-Identifier: LGPL-2.1-or-later
  12. */
  13. #include "defs.h"
  14. #include "ipc_defs.h"
  15. #ifdef HAVE_SYS_SEM_H
  16. # include <sys/sem.h>
  17. #elif defined HAVE_LINUX_SEM_H
  18. # include <linux/sem.h>
  19. #endif
  20. #include "xlat/semctl_flags.h"
  21. #include "xlat/semop_flags.h"
  22. #if defined HAVE_SYS_SEM_H || defined HAVE_LINUX_SEM_H
  23. static bool
  24. print_sembuf(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
  25. {
  26. const struct sembuf *sb = elem_buf;
  27. tprintf("{%u, %d, ", sb->sem_num, sb->sem_op);
  28. printflags(semop_flags, (unsigned short) sb->sem_flg, "SEM_???");
  29. tprints("}");
  30. return true;
  31. }
  32. #endif
  33. static void
  34. tprint_sembuf_array(struct tcb *const tcp, const kernel_ulong_t addr,
  35. const unsigned int count)
  36. {
  37. #if defined HAVE_SYS_SEM_H || defined HAVE_LINUX_SEM_H
  38. struct sembuf sb;
  39. print_array(tcp, addr, count, &sb, sizeof(sb),
  40. tfetch_mem, print_sembuf, 0);
  41. #else
  42. printaddr(addr);
  43. #endif
  44. tprintf(", %u", count);
  45. }
  46. SYS_FUNC(semop)
  47. {
  48. tprintf("%d, ", (int) tcp->u_arg[0]);
  49. if (indirect_ipccall(tcp)) {
  50. tprint_sembuf_array(tcp, tcp->u_arg[3], tcp->u_arg[1]);
  51. } else {
  52. tprint_sembuf_array(tcp, tcp->u_arg[1], tcp->u_arg[2]);
  53. }
  54. return RVAL_DECODED;
  55. }
  56. static int
  57. do_semtimedop(struct tcb *const tcp, const print_obj_by_addr_fn print_ts)
  58. {
  59. tprintf("%d, ", (int) tcp->u_arg[0]);
  60. if (indirect_ipccall(tcp)) {
  61. tprint_sembuf_array(tcp, tcp->u_arg[3], tcp->u_arg[1]);
  62. tprints(", ");
  63. #if defined(S390) || defined(S390X)
  64. print_ts(tcp, tcp->u_arg[2]);
  65. #else
  66. print_ts(tcp, tcp->u_arg[4]);
  67. #endif
  68. } else {
  69. tprint_sembuf_array(tcp, tcp->u_arg[1], tcp->u_arg[2]);
  70. tprints(", ");
  71. print_ts(tcp, tcp->u_arg[3]);
  72. }
  73. return RVAL_DECODED;
  74. }
  75. #if HAVE_ARCH_TIME32_SYSCALLS
  76. SYS_FUNC(semtimedop_time32)
  77. {
  78. return do_semtimedop(tcp, print_timespec32);
  79. }
  80. #endif
  81. SYS_FUNC(semtimedop_time64)
  82. {
  83. return do_semtimedop(tcp, print_timespec64);
  84. }
  85. SYS_FUNC(semget)
  86. {
  87. printxval(ipc_private, (unsigned int) tcp->u_arg[0], NULL);
  88. tprintf(", %d, ", (int) tcp->u_arg[1]);
  89. if (printflags(resource_flags, tcp->u_arg[2] & ~0777, NULL) != 0)
  90. tprints("|");
  91. print_numeric_umode_t(tcp->u_arg[2] & 0777);
  92. return RVAL_DECODED;
  93. }
  94. SYS_FUNC(semctl)
  95. {
  96. tprintf("%d, %d, ", (int) tcp->u_arg[0], (int) tcp->u_arg[1]);
  97. PRINTCTL(semctl_flags, tcp->u_arg[2], "SEM_???");
  98. tprints(", ");
  99. if (indirect_ipccall(tcp)
  100. #ifdef SPARC64
  101. && current_personality != 0
  102. #endif
  103. ) {
  104. printnum_ptr(tcp, tcp->u_arg[3]);
  105. } else {
  106. printaddr(tcp->u_arg[3]);
  107. }
  108. return RVAL_DECODED;
  109. }