(root)/
strace-6.5/
src/
ipc_sem.c
       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@strace.io>
       8   * Copyright (c) 2015-2022 The strace developers.
       9   * All rights reserved.
      10   *
      11   * SPDX-License-Identifier: LGPL-2.1-or-later
      12   */
      13  
      14  #include "defs.h"
      15  #include "ipc_defs.h"
      16  
      17  #include SEM_H_PROVIDER
      18  
      19  #include "xlat/semop_flags.h"
      20  
      21  static bool
      22  print_sembuf(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
      23  {
      24  	const struct sembuf *const sb = elem_buf;
      25  
      26  	tprint_struct_begin();
      27  	PRINT_FIELD_U(*sb, sem_num);
      28  	tprint_struct_next();
      29  	PRINT_FIELD_D(*sb, sem_op);
      30  	tprint_struct_next();
      31  	PRINT_FIELD_FLAGS(*sb, sem_flg, semop_flags, "SEM_???");
      32  	tprint_struct_end();
      33  
      34  	return true;
      35  }
      36  
      37  static void
      38  tprint_sembuf_array(struct tcb *const tcp, const kernel_ulong_t addr,
      39  		    const unsigned int count)
      40  {
      41  	/* sops */
      42  	struct sembuf sb;
      43  	print_array(tcp, addr, count, &sb, sizeof(sb),
      44  		    tfetch_mem, print_sembuf, 0);
      45  	tprint_arg_next();
      46  
      47  	/* nsops */
      48  	PRINT_VAL_U(count);
      49  }
      50  
      51  SYS_FUNC(semop)
      52  {
      53  	/* semid */
      54  	PRINT_VAL_D((int) tcp->u_arg[0]);
      55  	tprint_arg_next();
      56  
      57  	if (indirect_ipccall(tcp)) {
      58  		tprint_sembuf_array(tcp, tcp->u_arg[3], tcp->u_arg[1]);
      59  	} else {
      60  		tprint_sembuf_array(tcp, tcp->u_arg[1], tcp->u_arg[2]);
      61  	}
      62  	return RVAL_DECODED;
      63  }
      64  
      65  static int
      66  do_semtimedop(struct tcb *const tcp, const print_obj_by_addr_fn print_ts)
      67  {
      68  	/* semid */
      69  	PRINT_VAL_D((int) tcp->u_arg[0]);
      70  	tprint_arg_next();
      71  
      72  	if (indirect_ipccall(tcp)) {
      73  		tprint_sembuf_array(tcp, tcp->u_arg[3], tcp->u_arg[1]);
      74  		tprint_arg_next();
      75  
      76  		/* timeout */
      77  #if defined(S390) || defined(S390X)
      78  		print_ts(tcp, tcp->u_arg[2]);
      79  #else
      80  		print_ts(tcp, tcp->u_arg[4]);
      81  #endif
      82  	} else {
      83  		tprint_sembuf_array(tcp, tcp->u_arg[1], tcp->u_arg[2]);
      84  		tprint_arg_next();
      85  
      86  		/* timeout */
      87  		print_ts(tcp, tcp->u_arg[3]);
      88  	}
      89  	return RVAL_DECODED;
      90  }
      91  
      92  #if HAVE_ARCH_TIME32_SYSCALLS
      93  SYS_FUNC(semtimedop_time32)
      94  {
      95  	return do_semtimedop(tcp, print_timespec32);
      96  }
      97  #endif
      98  
      99  SYS_FUNC(semtimedop_time64)
     100  {
     101  	return do_semtimedop(tcp, print_timespec64);
     102  }
     103  
     104  SYS_FUNC(semget)
     105  {
     106  	/* key */
     107  	printxval(ipc_private, (unsigned int) tcp->u_arg[0], NULL);
     108  	tprint_arg_next();
     109  
     110  	/* nsems */
     111  	PRINT_VAL_D((int) tcp->u_arg[1]);
     112  	tprint_arg_next();
     113  
     114  	/* semflg */
     115  	tprint_flags_begin();
     116  	if (printflags_in(resource_flags, tcp->u_arg[2] & ~0777, NULL) != 0)
     117  		tprint_flags_or();
     118  	print_numeric_umode_t(tcp->u_arg[2] & 0777);
     119  	tprint_flags_end();
     120  	return RVAL_DECODED;
     121  }