/*
 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
 * Copyright (c) 1999-2018 The strace developers.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "defs.h"
#include "print_fields.h"
#include <linux/aio_abi.h>

#include "xlat/aio_cmds.h"

SYS_FUNC(io_setup)
{
	if (entering(tcp))
		tprintf("%u, ", (unsigned int) tcp->u_arg[0]);
	else
		printnum_ptr(tcp, tcp->u_arg[1]);
	return 0;
}

SYS_FUNC(io_destroy)
{
	printaddr(tcp->u_arg[0]);

	return RVAL_DECODED;
}

enum iocb_sub {
	SUB_NONE, SUB_COMMON, SUB_VECTOR
};

static enum iocb_sub
tprint_lio_opcode(unsigned int cmd)
{
	static const enum iocb_sub subs[] = {
		[IOCB_CMD_PREAD]	= SUB_COMMON,
		[IOCB_CMD_PWRITE]	= SUB_COMMON,
		[IOCB_CMD_FSYNC]	= SUB_NONE,
		[IOCB_CMD_FDSYNC]	= SUB_NONE,
		[IOCB_CMD_PREADX]	= SUB_NONE,
		[IOCB_CMD_POLL]		= SUB_NONE,
		[IOCB_CMD_NOOP]		= SUB_NONE,
		[IOCB_CMD_PREADV]	= SUB_VECTOR,
		[IOCB_CMD_PWRITEV]	= SUB_VECTOR,
	};

	printxval_indexn_ex(ARRSZ_PAIR(aio_cmds), cmd, "IOCB_CMD_???",
			    XLAT_STYLE_FMT_U);

	return cmd < ARRAY_SIZE(subs) ? subs[cmd] : SUB_NONE;
}

static void
print_common_flags(struct tcb *tcp, const struct iocb *cb)
{
/* IOCB_FLAG_RESFD is available since v2.6.22-rc1~47 */
#ifdef IOCB_FLAG_RESFD
	if (cb->aio_flags & IOCB_FLAG_RESFD)
		PRINT_FIELD_FD(", ", *cb, aio_resfd, tcp);

	if (cb->aio_flags & ~IOCB_FLAG_RESFD)
		PRINT_FIELD_X(", ", *cb, aio_flags);
#endif
}

static bool
iocb_is_valid(const struct iocb *cb)
{
	return cb->aio_buf == (unsigned long) cb->aio_buf &&
	       cb->aio_nbytes == (size_t) cb->aio_nbytes &&
	       (ssize_t) cb->aio_nbytes >= 0;
}

static enum iocb_sub
print_iocb_header(struct tcb *tcp, const struct iocb *cb)
{
	enum iocb_sub sub;

	if (cb->aio_data){
		PRINT_FIELD_X("", *cb, aio_data);
		tprints(", ");
	}

	if (cb->aio_key) {
		PRINT_FIELD_U("", *cb, aio_key);
		tprints(", ");
	}

	tprints("aio_lio_opcode=");
	sub = tprint_lio_opcode(cb->aio_lio_opcode);
	if (cb->aio_reqprio)
		PRINT_FIELD_D(", ", *cb, aio_reqprio);

	PRINT_FIELD_FD(", ", *cb, aio_fildes, tcp);

	return sub;
}

static void
print_iocb(struct tcb *tcp, const struct iocb *cb)
{
	tprints("{");

	enum iocb_sub sub = print_iocb_header(tcp, cb);

	switch (sub) {
	case SUB_COMMON:
		if (cb->aio_lio_opcode == 1 && iocb_is_valid(cb)) {
			PRINT_FIELD_STRN(", ", *cb, aio_buf,
					 cb->aio_nbytes, tcp);
		} else {
			PRINT_FIELD_X(", ", *cb, aio_buf);
		}
		PRINT_FIELD_U(", ", *cb, aio_nbytes);
		PRINT_FIELD_D(", ", *cb, aio_offset);
		print_common_flags(tcp, cb);
		break;
	case SUB_VECTOR:
		if (iocb_is_valid(cb)) {
			tprints(", aio_buf=");
			tprint_iov(tcp, cb->aio_nbytes, cb->aio_buf,
				   cb->aio_lio_opcode == 8
				   ? IOV_DECODE_STR
				   : IOV_DECODE_ADDR);
		} else {
			PRINT_FIELD_X(", ", *cb, aio_buf);
			PRINT_FIELD_U(", ", *cb, aio_nbytes);
		}
		PRINT_FIELD_D(", ", *cb, aio_offset);
		print_common_flags(tcp, cb);
		break;
	case SUB_NONE:
		break;
	}

	tprints("}");
}

static bool
print_iocbp(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
{
	kernel_ulong_t addr;
	struct iocb cb;

	if (elem_size < sizeof(kernel_ulong_t)) {
		addr = *(unsigned int *) elem_buf;
	} else {
		addr = *(kernel_ulong_t *) elem_buf;
	}

	if (!umove_or_printaddr(tcp, addr, &cb))
		print_iocb(tcp, &cb);

	return true;
}

SYS_FUNC(io_submit)
{
	const kernel_long_t nr =
		truncate_klong_to_current_wordsize(tcp->u_arg[1]);
	const kernel_ulong_t addr = tcp->u_arg[2];
	kernel_ulong_t iocbp;

	printaddr(tcp->u_arg[0]);
	tprintf(", %" PRI_kld ", ", nr);

	if (nr < 0)
		printaddr(addr);
	else
		print_array(tcp, addr, nr, &iocbp, current_wordsize,
			    tfetch_mem, print_iocbp, 0);

	return RVAL_DECODED;
}

static bool
print_io_event(struct tcb *tcp, void *elem_buf, size_t elem_size, void *data)
{
	struct io_event *event = elem_buf;

	PRINT_FIELD_X("{", *event, data);
	PRINT_FIELD_X(", ", *event, obj);
	PRINT_FIELD_D(", ", *event, res);
	PRINT_FIELD_D(", ", *event, res2);
	tprints("}");

	return true;
}

SYS_FUNC(io_cancel)
{
	if (entering(tcp)) {
		printaddr(tcp->u_arg[0]);
		tprints(", ");

		struct iocb cb;

		if (!umove_or_printaddr(tcp, tcp->u_arg[1], &cb)) {
			tprints("{");
			print_iocb_header(tcp, &cb);
			tprints("}");
		}
		tprints(", ");
	} else {
		struct io_event event;

		if (!umove_or_printaddr(tcp, tcp->u_arg[2], &event))
			print_io_event(tcp, &event, sizeof(event), 0);
	}
	return 0;
}

static int
print_io_getevents(struct tcb *tcp, bool has_usig)
{
	if (entering(tcp)) {
		printaddr(tcp->u_arg[0]);
		tprintf(", %" PRI_kld ", %" PRI_kld ", ",
			truncate_klong_to_current_wordsize(tcp->u_arg[1]),
			truncate_klong_to_current_wordsize(tcp->u_arg[2]));
	} else {
		struct io_event buf;
		print_array(tcp, tcp->u_arg[3], tcp->u_rval, &buf, sizeof(buf),
			    tfetch_mem, print_io_event, 0);
		tprints(", ");
		/*
		 * Since the timeout and usig parameters are read by the kernel
		 * on entering syscall, it has to be decoded the same way
		 * whether the syscall has failed or not.
		 */
		temporarily_clear_syserror(tcp);
		print_timespec(tcp, tcp->u_arg[4]);
		if (has_usig) {
			tprints(", ");
			print_aio_sigset(tcp, tcp->u_arg[5]);
		}
		restore_cleared_syserror(tcp);
	}
	return 0;
}

SYS_FUNC(io_getevents)
{
	return print_io_getevents(tcp, false);
}

SYS_FUNC(io_pgetevents)
{
	return print_io_getevents(tcp, true);
}
