2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
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) 1999-2019 The strace developers.
9 * SPDX-License-Identifier: LGPL-2.1-or-later
13 #include "print_fields.h"
14 #include <linux/aio_abi.h>
16 #include "xlat/aio_cmds.h"
18 #ifdef HAVE_STRUCT_IOCB_AIO_FLAGS
19 # include "xlat/aio_iocb_flags.h"
22 #ifdef HAVE_STRUCT_IOCB_AIO_RW_FLAGS
23 # define AIO_RW_FLAGS_FIELD aio_rw_flags
25 # define AIO_RW_FLAGS_FIELD aio_reserved1
31 tprintf("%u, ", (unsigned int) tcp->u_arg[0]);
33 printnum_ptr(tcp, tcp->u_arg[1]);
39 printaddr(tcp->u_arg[0]);
45 SUB_NONE, SUB_COMMON, SUB_VECTOR, SUB_POLL
49 tprint_lio_opcode(unsigned int cmd)
51 static const enum iocb_sub subs[] = {
52 [IOCB_CMD_PREAD] = SUB_COMMON,
53 [IOCB_CMD_PWRITE] = SUB_COMMON,
54 [IOCB_CMD_FSYNC] = SUB_NONE,
55 [IOCB_CMD_FDSYNC] = SUB_NONE,
56 [IOCB_CMD_PREADX] = SUB_NONE,
57 [IOCB_CMD_POLL] = SUB_POLL,
58 [IOCB_CMD_NOOP] = SUB_NONE,
59 [IOCB_CMD_PREADV] = SUB_VECTOR,
60 [IOCB_CMD_PWRITEV] = SUB_VECTOR,
63 printxval_ex(aio_cmds, cmd, "IOCB_CMD_???", XLAT_STYLE_FMT_U);
65 return cmd < ARRAY_SIZE(subs) ? subs[cmd] : SUB_NONE;
69 print_common_flags(struct tcb *tcp, const struct iocb *cb)
71 /* aio_flags and aio_resfd fields are available since v2.6.22-rc1~47 */
72 #ifdef HAVE_STRUCT_IOCB_AIO_FLAGS
74 PRINT_FIELD_FLAGS(", ", *cb, aio_flags, aio_iocb_flags,
77 if (cb->aio_flags & IOCB_FLAG_RESFD)
78 PRINT_FIELD_FD(", ", *cb, aio_resfd, tcp);
79 else if (cb->aio_resfd)
80 PRINT_FIELD_X(", ", *cb, aio_resfd);
85 iocb_is_valid(const struct iocb *cb)
87 return cb->aio_buf == (unsigned long) cb->aio_buf &&
88 cb->aio_nbytes == (size_t) cb->aio_nbytes &&
89 (ssize_t) cb->aio_nbytes >= 0;
93 print_iocb_header(struct tcb *tcp, const struct iocb *cb)
97 PRINT_FIELD_X("", *cb, aio_data);
100 PRINT_FIELD_U(", ", *cb, aio_key);
102 if (cb->AIO_RW_FLAGS_FIELD) {
103 tprints(", aio_rw_flags=");
104 printflags(rwf_flags, cb->AIO_RW_FLAGS_FIELD, "RWF_???");
107 tprints(", aio_lio_opcode=");
108 sub = tprint_lio_opcode(cb->aio_lio_opcode);
110 if (cb->aio_flags & IOCB_FLAG_IOPRIO) {
111 tprints(", aio_reqprio=");
112 print_ioprio(zero_extend_signed_to_ull(cb->aio_reqprio));
113 } else if (cb->aio_reqprio) {
114 PRINT_FIELD_D(", ", *cb, aio_reqprio);
117 PRINT_FIELD_FD(", ", *cb, aio_fildes, tcp);
123 print_iocb(struct tcb *tcp, const struct iocb *cb)
127 enum iocb_sub sub = print_iocb_header(tcp, cb);
131 if (cb->aio_lio_opcode == 1 && iocb_is_valid(cb)) {
132 PRINT_FIELD_STRN(", ", *cb, aio_buf,
133 cb->aio_nbytes, tcp);
135 PRINT_FIELD_X(", ", *cb, aio_buf);
137 PRINT_FIELD_U(", ", *cb, aio_nbytes);
138 PRINT_FIELD_D(", ", *cb, aio_offset);
139 print_common_flags(tcp, cb);
142 if (iocb_is_valid(cb)) {
143 tprints(", aio_buf=");
144 tprint_iov(tcp, cb->aio_nbytes, cb->aio_buf,
145 cb->aio_lio_opcode == 8
149 PRINT_FIELD_X(", ", *cb, aio_buf);
150 PRINT_FIELD_U(", ", *cb, aio_nbytes);
152 PRINT_FIELD_D(", ", *cb, aio_offset);
153 print_common_flags(tcp, cb);
156 PRINT_FIELD_FLAGS(", ", *cb, aio_buf, pollflags, "POLL???");
157 print_common_flags(tcp, cb);
167 print_iocbp(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
172 if (elem_size < sizeof(kernel_ulong_t)) {
173 addr = *(unsigned int *) elem_buf;
175 addr = *(kernel_ulong_t *) elem_buf;
178 if (!umove_or_printaddr(tcp, addr, &cb))
179 print_iocb(tcp, &cb);
186 const kernel_long_t nr =
187 truncate_klong_to_current_wordsize(tcp->u_arg[1]);
188 const kernel_ulong_t addr = tcp->u_arg[2];
189 kernel_ulong_t iocbp;
191 printaddr(tcp->u_arg[0]);
192 tprintf(", %" PRI_kld ", ", nr);
197 print_array(tcp, addr, nr, &iocbp, current_wordsize,
198 tfetch_mem, print_iocbp, 0);
204 print_io_event(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
206 struct io_event *event = elem_buf;
208 PRINT_FIELD_X("{", *event, data);
209 PRINT_FIELD_X(", ", *event, obj);
210 PRINT_FIELD_D(", ", *event, res);
211 PRINT_FIELD_D(", ", *event, res2);
220 printaddr(tcp->u_arg[0]);
225 if (!umove_or_printaddr(tcp, tcp->u_arg[1], &cb)) {
227 print_iocb_header(tcp, &cb);
232 struct io_event event;
234 if (!umove_or_printaddr(tcp, tcp->u_arg[2], &event))
235 print_io_event(tcp, &event, sizeof(event), 0);
241 print_io_getevents(struct tcb *const tcp, const print_obj_by_addr_fn print_ts,
245 printaddr(tcp->u_arg[0]);
246 tprintf(", %" PRI_kld ", %" PRI_kld ", ",
247 truncate_klong_to_current_wordsize(tcp->u_arg[1]),
248 truncate_klong_to_current_wordsize(tcp->u_arg[2]));
251 print_array(tcp, tcp->u_arg[3], tcp->u_rval, &buf, sizeof(buf),
252 tfetch_mem, print_io_event, 0);
255 * Since the timeout and usig parameters are read by the kernel
256 * on entering syscall, it has to be decoded the same way
257 * whether the syscall has failed or not.
259 temporarily_clear_syserror(tcp);
260 print_ts(tcp, tcp->u_arg[4]);
263 print_aio_sigset(tcp, tcp->u_arg[5]);
265 restore_cleared_syserror(tcp);
270 #if HAVE_ARCH_TIME32_SYSCALLS
271 SYS_FUNC(io_getevents_time32)
273 return print_io_getevents(tcp, print_timespec32, false);
277 #if HAVE_ARCH_OLD_TIME64_SYSCALLS
278 SYS_FUNC(io_getevents_time64)
280 return print_io_getevents(tcp, print_timespec64, false);
284 #if HAVE_ARCH_TIME32_SYSCALLS
285 SYS_FUNC(io_pgetevents_time32)
287 return print_io_getevents(tcp, print_timespec32, true);
291 SYS_FUNC(io_pgetevents_time64)
293 return print_io_getevents(tcp, print_timespec64, true);