(root)/
strace-6.5/
src/
futex.c
       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@strace.io>
       6   * Copyright (c) 2014-2022 The strace developers.
       7   * All rights reserved.
       8   *
       9   * SPDX-License-Identifier: LGPL-2.1-or-later
      10   */
      11  
      12  #include "defs.h"
      13  
      14  #ifndef FUTEX_PRIVATE_FLAG
      15  # define FUTEX_PRIVATE_FLAG 128
      16  #endif
      17  #ifndef FUTEX_CLOCK_REALTIME
      18  # define FUTEX_CLOCK_REALTIME 256
      19  #endif
      20  #ifndef FUTEX_OP_OPARG_SHIFT
      21  # define FUTEX_OP_OPARG_SHIFT 8
      22  #endif
      23  
      24  #include "xlat/futexbitset.h"
      25  #include "xlat/futexops.h"
      26  #include "xlat/futexwakeops.h"
      27  #include "xlat/futexwakecmps.h"
      28  
      29  static int
      30  do_futex(struct tcb *const tcp, const print_obj_by_addr_fn print_ts)
      31  {
      32  	const kernel_ulong_t uaddr = tcp->u_arg[0];
      33  	const int op = tcp->u_arg[1];
      34  	const int cmd = op & 127;
      35  	const kernel_ulong_t timeout = tcp->u_arg[3];
      36  	const kernel_ulong_t uaddr2 = tcp->u_arg[4];
      37  	const unsigned int val = tcp->u_arg[2];
      38  	const unsigned int val2 = tcp->u_arg[3];
      39  	const unsigned int val3 = tcp->u_arg[5];
      40  	const char *comment;
      41  
      42  	/* uaddr */
      43  	printaddr(uaddr);
      44  	tprint_arg_next();
      45  
      46  	/* futex_op */
      47  	printxval(futexops, op, "FUTEX_???");
      48  
      49  	switch (cmd) {
      50  	case FUTEX_WAIT:
      51  		tprint_arg_next();
      52  		PRINT_VAL_U(val);
      53  
      54  		tprint_arg_next();
      55  		print_ts(tcp, timeout);
      56  		break;
      57  	case FUTEX_LOCK_PI:
      58  	case FUTEX_LOCK_PI2:
      59  		tprint_arg_next();
      60  		print_ts(tcp, timeout);
      61  		break;
      62  	case FUTEX_WAIT_BITSET:
      63  		tprint_arg_next();
      64  		PRINT_VAL_U(val);
      65  
      66  		tprint_arg_next();
      67  		print_ts(tcp, timeout);
      68  
      69  		tprint_arg_next();
      70  		printxval(futexbitset, val3, NULL);
      71  		break;
      72  	case FUTEX_WAKE_BITSET:
      73  		tprint_arg_next();
      74  		PRINT_VAL_U(val);
      75  
      76  		tprint_arg_next();
      77  		printxval(futexbitset, val3, NULL);
      78  		break;
      79  	case FUTEX_REQUEUE:
      80  		tprint_arg_next();
      81  		PRINT_VAL_U(val);
      82  
      83  		tprint_arg_next();
      84  		PRINT_VAL_U(val2);
      85  
      86  		tprint_arg_next();
      87  		printaddr(uaddr2);
      88  		break;
      89  	case FUTEX_CMP_REQUEUE:
      90  	case FUTEX_CMP_REQUEUE_PI:
      91  		tprint_arg_next();
      92  		PRINT_VAL_U(val);
      93  
      94  		tprint_arg_next();
      95  		PRINT_VAL_U(val2);
      96  
      97  		tprint_arg_next();
      98  		printaddr(uaddr2);
      99  
     100  		tprint_arg_next();
     101  		PRINT_VAL_U(val3);
     102  		break;
     103  	case FUTEX_WAKE_OP:
     104  		tprint_arg_next();
     105  		PRINT_VAL_U(val);
     106  
     107  		tprint_arg_next();
     108  		PRINT_VAL_U(val2);
     109  
     110  		tprint_arg_next();
     111  		printaddr(uaddr2);
     112  
     113  		tprint_arg_next();
     114  		tprint_flags_begin();
     115  		if ((val3 >> 28) & FUTEX_OP_OPARG_SHIFT) {
     116  			tprint_shift_begin();
     117  			print_xlat(FUTEX_OP_OPARG_SHIFT);
     118  			tprint_shift();
     119  			PRINT_VAL_U(28);
     120  			tprint_shift_end();
     121  			tprint_flags_or();
     122  		}
     123  		tprint_shift_begin();
     124  		comment = printxval(futexwakeops, (val3 >> 28) & 0x7, NULL)
     125  			? NULL : "FUTEX_OP_???";
     126  		tprint_shift();
     127  		PRINT_VAL_U(28);
     128  		tprint_shift_end();
     129  		tprints_comment(comment);
     130  		tprint_flags_or();
     131  		tprint_shift_begin();
     132  		PRINT_VAL_X((val3 >> 12) & 0xfff);
     133  		tprint_shift();
     134  		PRINT_VAL_U(12);
     135  		tprint_shift_end();
     136  		tprint_flags_or();
     137  		tprint_shift_begin();
     138  		comment = printxval(futexwakecmps, (val3 >> 24) & 0xf, NULL)
     139  			? NULL : "FUTEX_OP_CMP_???";
     140  		tprint_shift();
     141  		PRINT_VAL_U(24);
     142  		tprint_shift_end();
     143  		tprints_comment(comment);
     144  		tprint_flags_or();
     145  		PRINT_VAL_X(val3 & 0xfff);
     146  		tprint_flags_end();
     147  		break;
     148  	case FUTEX_WAIT_REQUEUE_PI:
     149  		tprint_arg_next();
     150  		PRINT_VAL_U(val);
     151  
     152  		tprint_arg_next();
     153  		print_ts(tcp, timeout);
     154  
     155  		tprint_arg_next();
     156  		printaddr(uaddr2);
     157  		break;
     158  	case FUTEX_FD:
     159  	case FUTEX_WAKE:
     160  		tprint_arg_next();
     161  		PRINT_VAL_U(val);
     162  		break;
     163  	case FUTEX_UNLOCK_PI:
     164  	case FUTEX_TRYLOCK_PI:
     165  		break;
     166  	default:
     167  		tprint_arg_next();
     168  		PRINT_VAL_U(val);
     169  
     170  		tprint_arg_next();
     171  		printaddr(timeout);
     172  
     173  		tprint_arg_next();
     174  		printaddr(uaddr2);
     175  
     176  		tprint_arg_next();
     177  		PRINT_VAL_X(val3);
     178  		break;
     179  	}
     180  
     181  	return RVAL_DECODED;
     182  }
     183  
     184  #if HAVE_ARCH_TIME32_SYSCALLS
     185  SYS_FUNC(futex_time32)
     186  {
     187  	return do_futex(tcp, print_timespec32);
     188  }
     189  #endif
     190  
     191  SYS_FUNC(futex_time64)
     192  {
     193  	return do_futex(tcp, print_timespec64);
     194  }