1 /*
2 * Copyright (c) 2021-2022 The strace developers.
3 * Copyright (c) 2021 André Almeida <andrealmeid@collabora.com>
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: LGPL-2.1-or-later
7 */
8
9 #include "defs.h"
10 #include <linux/futex.h>
11 #include "xlat/futex_waiter_flags.h"
12
13 struct print_waiter_data {
14 unsigned int count;
15 };
16
17 static bool
18 print_waiter(struct tcb * const tcp, void * const elem_buf,
19 const size_t elem_size, void * const data)
20 {
21 struct futex_waitv *waiter = elem_buf;
22 struct print_waiter_data *p = data;
23
24 if (p->count++ >= FUTEX_WAITV_MAX) {
25 tprint_more_data_follows();
26 return false;
27 }
28
29 tprint_struct_begin();
30 PRINT_FIELD_X(*waiter, val);
31
32 tprint_struct_next();
33 PRINT_FIELD_ADDR64(*waiter, uaddr);
34
35 tprint_struct_next();
36 PRINT_FIELD_FLAGS(*waiter, flags, futex_waiter_flags, "FUTEX_???");
37
38 if (waiter->__reserved) {
39 tprint_struct_next();
40 PRINT_FIELD_X(*waiter, __reserved);
41 }
42
43 tprint_struct_end();
44 return true;
45 }
46
47 static void
48 print_waiter_array(struct tcb * const tcp, const kernel_ulong_t waiters,
49 const unsigned int nr_futexes)
50 {
51 struct futex_waitv buf;
52 struct print_waiter_data data = {};
53
54 print_array(tcp, waiters, nr_futexes, &buf, sizeof(buf),
55 tfetch_mem, print_waiter, &data);
56 }
57
58 SYS_FUNC(futex_waitv)
59 {
60 const kernel_ulong_t waiters = tcp->u_arg[0];
61 const unsigned int nr_futexes = tcp->u_arg[1];
62 const unsigned int flags = tcp->u_arg[2];
63 const kernel_ulong_t timeout = tcp->u_arg[3];
64 const unsigned int clockid = tcp->u_arg[4];
65
66 print_waiter_array(tcp, waiters, nr_futexes);
67 tprint_arg_next();
68 PRINT_VAL_U(nr_futexes);
69 tprint_arg_next();
70 PRINT_VAL_X(flags);
71 tprint_arg_next();
72 print_timespec64(tcp, timeout);
73 tprint_arg_next();
74 printxval(clocknames, clockid, "CLOCK_???");
75
76 return RVAL_DECODED;
77 }