(root)/
strace-6.5/
src/
ipc_msg.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 MSG_H_PROVIDER
      18  
      19  #include "xlat/ipc_msg_flags.h"
      20  #include "xlat/ipc_private.h"
      21  #include "xlat/resource_flags.h"
      22  
      23  SYS_FUNC(msgget)
      24  {
      25  	/* key */
      26  	printxval(ipc_private, (unsigned int) tcp->u_arg[0], NULL);
      27  	tprint_arg_next();
      28  
      29  	/* msgflg */
      30  	tprint_flags_begin();
      31  	if (printflags_in(resource_flags, tcp->u_arg[1] & ~0777, NULL) != 0)
      32  		tprint_flags_or();
      33  	print_numeric_umode_t(tcp->u_arg[1] & 0777);
      34  	tprint_flags_end();
      35  	return RVAL_DECODED;
      36  }
      37  
      38  static void
      39  tprint_msgsnd(struct tcb *const tcp, const kernel_ulong_t addr,
      40  	      const kernel_ulong_t count, const unsigned int flags)
      41  {
      42  	/* msqid */
      43  	tprint_msgbuf(tcp, addr, count);
      44  	tprint_arg_next();
      45  
      46  	/* msgsz */
      47  	PRINT_VAL_U(count);
      48  	tprint_arg_next();
      49  
      50  	/* msgflg */
      51  	printflags(ipc_msg_flags, flags, "MSG_???");
      52  }
      53  
      54  SYS_FUNC(msgsnd)
      55  {
      56  	/* msqid */
      57  	PRINT_VAL_D((int) tcp->u_arg[0]);
      58  	tprint_arg_next();
      59  
      60  	if (indirect_ipccall(tcp)) {
      61  		tprint_msgsnd(tcp, tcp->u_arg[3], tcp->u_arg[1],
      62  			      tcp->u_arg[2]);
      63  	} else {
      64  		tprint_msgsnd(tcp, tcp->u_arg[1], tcp->u_arg[2],
      65  			      tcp->u_arg[3]);
      66  	}
      67  	return RVAL_DECODED;
      68  }
      69  
      70  static void
      71  tprint_msgrcv(struct tcb *const tcp, const kernel_ulong_t addr,
      72  	      const kernel_ulong_t count, const kernel_ulong_t msgtyp)
      73  {
      74  	/* msqid */
      75  	tprint_msgbuf(tcp, addr, count);
      76  	tprint_arg_next();
      77  
      78  	/* msgsz */
      79  	PRINT_VAL_U(count);
      80  	tprint_arg_next();
      81  
      82  	/* msgtyp */
      83  	PRINT_VAL_D(truncate_klong_to_current_klongsize(msgtyp));
      84  }
      85  
      86  static int
      87  fetch_msgrcv_args(struct tcb *const tcp, const kernel_ulong_t addr,
      88  		  kernel_ulong_t *const pair)
      89  {
      90  	if (current_wordsize == sizeof(*pair)) {
      91  		if (umoven_or_printaddr(tcp, addr, 2 * sizeof(*pair), pair))
      92  			return -1;
      93  	} else {
      94  		unsigned int tmp[2];
      95  
      96  		if (umove_or_printaddr(tcp, addr, &tmp))
      97  			return -1;
      98  		pair[0] = tmp[0];
      99  		pair[1] = (int) tmp[1];
     100  	}
     101  	return 0;
     102  }
     103  
     104  SYS_FUNC(msgrcv)
     105  {
     106  	if (entering(tcp)) {
     107  		/* msqid */
     108  		PRINT_VAL_D((int) tcp->u_arg[0]);
     109  		tprint_arg_next();
     110  	} else {
     111  		if (indirect_ipccall(tcp)) {
     112  			const bool direct =
     113  #ifdef SPARC64
     114  				current_wordsize == 8 ||
     115  #endif
     116  				get_tcb_priv_ulong(tcp) != 0;
     117  			if (direct) {
     118  				tprint_msgrcv(tcp, tcp->u_arg[3],
     119  					      tcp->u_arg[1], tcp->u_arg[4]);
     120  			} else {
     121  				kernel_ulong_t pair[2];
     122  
     123  				if (fetch_msgrcv_args(tcp, tcp->u_arg[3], pair)) {
     124  					tprint_arg_next();
     125  					PRINT_VAL_U(tcp->u_arg[1]);
     126  				} else {
     127  					tprint_msgrcv(tcp, pair[0],
     128  						      tcp->u_arg[1], pair[1]);
     129  				}
     130  			}
     131  			tprint_arg_next();
     132  
     133  			/* msgflg */
     134  			printflags(ipc_msg_flags, tcp->u_arg[2], "MSG_???");
     135  		} else {
     136  			tprint_msgrcv(tcp, tcp->u_arg[1],
     137  				tcp->u_arg[2], tcp->u_arg[3]);
     138  			tprint_arg_next();
     139  
     140  			/* msgflg */
     141  			printflags(ipc_msg_flags, tcp->u_arg[4], "MSG_???");
     142  		}
     143  	}
     144  	return 0;
     145  }