/*
 * Copyright (c) 2013 Ben Noordhuis <info@bnoordhuis.nl>
 * Copyright (c) 2013-2015 Dmitry V. Levin <ldv@altlinux.org>
 * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr@gmail.com>
 * Copyright (c) 2015-2017 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 "perf_event_struct.h"

#include "xlat/hw_breakpoint_len.h"
#include "xlat/hw_breakpoint_type.h"
#include "xlat/perf_attr_size.h"
#include "xlat/perf_branch_sample_type.h"
#include "xlat/perf_event_open_flags.h"
#include "xlat/perf_event_read_format.h"
#include "xlat/perf_event_sample_format.h"
#include "xlat/perf_hw_cache_id.h"
#include "xlat/perf_hw_cache_op_id.h"
#include "xlat/perf_hw_cache_op_result_id.h"
#include "xlat/perf_hw_id.h"
#include "xlat/perf_sw_ids.h"
#include "xlat/perf_type_id.h"

struct pea_desc {
	struct perf_event_attr *attr;
	uint32_t size;
};

static void
free_pea_desc(void *pea_desc_ptr)
{
	struct pea_desc *desc = pea_desc_ptr;

	free(desc->attr);
	free(desc);
}

static int
fetch_perf_event_attr(struct tcb *const tcp, const kernel_ulong_t addr)
{
	struct pea_desc *desc;
	struct perf_event_attr *attr;
	uint32_t size;

	if (umove(tcp, addr + offsetof(struct perf_event_attr, size), &size)) {
		printaddr(addr);
		return 1;
	}

	if (size > sizeof(*attr))
		size = sizeof(*attr);

	if (!size)
		size = PERF_ATTR_SIZE_VER0;

	/*
	 * Kernel (rightfully) deems invalid attribute structures with size less
	 * than first published format size, and we do the same.
	 */
	if (size < PERF_ATTR_SIZE_VER0) {
		printaddr(addr);
		return 1;
	}

	if (abbrev(tcp))
		size = offsetofend(struct perf_event_attr, config);

	/* Size should be multiple of 8, but kernel doesn't check for it */
	/* size &= ~7; */

	attr = xcalloc(1, sizeof(*attr));

	if (umoven_or_printaddr(tcp, addr, size, attr)) {
		free(attr);

		return 1;
	}

	desc = xmalloc(sizeof(*desc));

	desc->attr = attr;
	desc->size = size;

	set_tcb_priv_data(tcp, desc, free_pea_desc);

	return 0;
}

#define PRINT_XLAT(prefix, xlat, x, dflt) \
	do { \
		tprints(prefix); \
		printxval_search(xlat, x, dflt); \
	} while (0)

static void
print_perf_event_attr(struct tcb *const tcp, const kernel_ulong_t addr)
{
	static const char *precise_ip_desc[] = {
		"arbitrary skid",
		"constant skid",
		"requested to have 0 skid",
		"must have 0 skid",
	};

	struct pea_desc *desc;
	struct perf_event_attr *attr;
	uint32_t size;
	uint32_t new_size;
	int use_new_size = 0;

	/*
	 * Amusingly, kernel accepts structures with only part of the field
	 * present, so we making check like this (instead of checking
	 * offsetofend against size) in order to print fields as kernel sees
	 * them. This also should work great on big endian architectures.
	 */
	#define _PERF_CHECK_FIELD(_field) \
		do { \
			if (offsetof(struct perf_event_attr, _field) >= size) \
				goto print_perf_event_attr_out; \
		} while (0)

	desc = get_tcb_priv_data(tcp);

	attr = desc->attr;
	size = desc->size;

	/* The only error which expected to change size field currently */
	if (tcp->u_error == E2BIG) {
		if (umove(tcp, addr + offsetof(struct perf_event_attr, size),
		    &new_size))
			use_new_size = -1;
		else
			use_new_size = 1;
	}

	PRINT_XLAT("{type=", perf_type_id, attr->type, "PERF_TYPE_???");
	tprints(", size=");
	printxval(perf_attr_size, attr->size, "PERF_ATTR_SIZE_???");

	if (use_new_size) {
		tprints(" => ");

		if (use_new_size > 0)
			printxval(perf_attr_size, new_size,
				  "PERF_ATTR_SIZE_???");
		else
			tprints("???");
	}

	switch (attr->type) {
	case PERF_TYPE_HARDWARE:
		PRINT_XLAT(", config=", perf_hw_id, attr->config,
			   "PERF_COUNT_HW_???");
		break;
	case PERF_TYPE_SOFTWARE:
		PRINT_XLAT(", config=", perf_sw_ids, attr->config,
			   "PERF_COUNT_SW_???");
		break;
	case PERF_TYPE_TRACEPOINT:
		/*
		 * "The value to use in config can be obtained from under
		 * debugfs tracing/events/../../id if ftrace is enabled
		 * in the kernel."
		 */
		tprintf(", config=%" PRIu64, attr->config);
		break;
	case PERF_TYPE_HW_CACHE:
		/*
		 * (perf_hw_cache_id) | (perf_hw_cache_op_id << 8) |
		 * (perf_hw_cache_op_result_id << 16)
		 */
		PRINT_XLAT(", config=", perf_hw_cache_id, attr->config & 0xFF,
			   "PERF_COUNT_HW_CACHE_???");
		PRINT_XLAT("|", perf_hw_cache_op_id, (attr->config >> 8) & 0xFF,
			   "PERF_COUNT_HW_CACHE_OP_???");
		/*
		 * Current code (see set_ext_hw_attr in arch/x86/events/core.c,
		 * tile_map_cache_event in arch/tile/kernel/perf_event.c,
		 * arc_pmu_cache_event in arch/arc/kernel/perf_event.c,
		 * hw_perf_cache_event in arch/blackfin/kernel/perf_event.c,
		 * _hw_perf_cache_event in arch/metag/kernel/perf/perf_event.c,
		 * mipspmu_map_cache_event in arch/mips/kernel/perf_event_mipsxx.c,
		 * hw_perf_cache_event in arch/powerpc/perf/core-book3s.c,
		 * hw_perf_cache_event in arch/powerpc/perf/core-fsl-emb.c,
		 * hw_perf_cache_event in arch/sh/kernel/perf_event.c,
		 * sparc_map_cache_event in arch/sparc/kernel/perf_event.c,
		 * xtensa_pmu_cache_event in arch/xtensa/kernel/perf_event.c,
		 * armpmu_map_cache_event in drivers/perf/arm_pmu.c) assumes
		 * that cache result is 8 bits in size.
		 */
		PRINT_XLAT("<<8|", perf_hw_cache_op_result_id,
			   (attr->config >> 16) & 0xFF,
			   "PERF_COUNT_HW_CACHE_RESULT_???");
		tprints("<<16");
		if (attr->config >> 24) {
			tprintf("|%#" PRIx64 "<<24", attr->config >> 24);
			tprints_comment("PERF_COUNT_HW_CACHE_???");
		}
		break;
	case PERF_TYPE_RAW:
		/*
		 * "If type is PERF_TYPE_RAW, then a custom "raw" config
		 * value is needed. Most CPUs support events that are not
		 * covered by the "generalized" events. These are
		 * implementation defined; see your CPU manual (for example the
		 * Intel Volume 3B documentation or the AMD BIOS and Kernel
		 * Developer Guide). The libpfm4 library can be used to
		 * translate from the name in the architectural manuals
		 * to the raw hex value perf_event_open() expects in this
		 * field."
		 */
	case PERF_TYPE_BREAKPOINT:
		/*
		 * "If type is PERF_TYPE_BREAKPOINT, then leave config set
		 * to zero. Its parameters are set in other places."
		 */
	default:
		tprintf(", config=%#" PRIx64, attr->config);
		break;
	}

	if (abbrev(tcp))
		goto print_perf_event_attr_out;

	if (attr->freq)
		tprintf(", sample_freq=%" PRIu64, attr->sample_freq);
	else
		tprintf(", sample_period=%" PRIu64, attr->sample_period);

	tprints(", sample_type=");
	printflags64(perf_event_sample_format, attr->sample_type,
		"PERF_SAMPLE_???");

	tprints(", read_format=");
	printflags64(perf_event_read_format, attr->read_format,
		"PERF_FORMAT_???");

	tprintf(", disabled=%u"
		", inherit=%u"
		", pinned=%u"
		", exclusive=%u"
		", exclusive_user=%u"
		", exclude_kernel=%u"
		", exclude_hv=%u"
		", exclude_idle=%u"
		", mmap=%u"
		", comm=%u"
		", freq=%u"
		", inherit_stat=%u"
		", enable_on_exec=%u"
		", task=%u"
		", watermark=%u"
		", precise_ip=%u",
		attr->disabled,
		attr->inherit,
		attr->pinned,
		attr->exclusive,
		attr->exclude_user,
		attr->exclude_kernel,
		attr->exclude_hv,
		attr->exclude_idle,
		attr->mmap,
		attr->comm,
		attr->freq,
		attr->inherit_stat,
		attr->enable_on_exec,
		attr->task,
		attr->watermark,
		attr->precise_ip);
	tprints_comment(precise_ip_desc[attr->precise_ip]);
	tprintf(", mmap_data=%u"
		", sample_id_all=%u"
		", exclude_host=%u"
		", exclude_guest=%u"
		", exclude_callchain_kernel=%u"
		", exclude_callchain_user=%u"
		", mmap2=%u"
		", comm_exec=%u"
		", use_clockid=%u"
		", context_switch=%u"
		", write_backward=%u",
		attr->mmap_data,
		attr->sample_id_all,
		attr->exclude_host,
		attr->exclude_guest,
		attr->exclude_callchain_kernel,
		attr->exclude_callchain_user,
		attr->mmap2,
		attr->comm_exec,
		attr->use_clockid,
		attr->context_switch,
		attr->write_backward);

	/*
	 * Print it only in case it is non-zero, since it may contain flags we
	 * are not aware about.
	 */
	if (attr->__reserved_1) {
		tprintf(", __reserved_1=%#" PRIx64,
			(uint64_t) attr->__reserved_1);
		tprints_comment("Bits 63..28");
	}

	if (attr->watermark)
		tprintf(", wakeup_watermark=%u", attr->wakeup_watermark);
	else
		tprintf(", wakeup_events=%u", attr->wakeup_events);

	if (attr->type == PERF_TYPE_BREAKPOINT)
		/* Any combination of R/W with X is deemed invalid */
		PRINT_XLAT(", bp_type=", hw_breakpoint_type, attr->bp_type,
			   (attr->bp_type <=
				   (HW_BREAKPOINT_X | HW_BREAKPOINT_RW)) ?
					   "HW_BREAKPOINT_INVALID" :
					   "HW_BREAKPOINT_???");

	if (attr->type == PERF_TYPE_BREAKPOINT)
		tprintf(", bp_addr=%#" PRIx64, attr->bp_addr);
	else
		tprintf(", config1=%#" PRIx64, attr->config1);

	/*
	 * Fields after bp_addr/config1 are optional and may not present; check
	 * against size is needed.
	 */

	_PERF_CHECK_FIELD(bp_len);
	if (attr->type == PERF_TYPE_BREAKPOINT)
		tprintf(", bp_len=%" PRIu64, attr->bp_len);
	else
		tprintf(", config2=%#" PRIx64, attr->config2);

	_PERF_CHECK_FIELD(branch_sample_type);
	if (attr->sample_type & PERF_SAMPLE_BRANCH_STACK) {
		tprints(", branch_sample_type=");
		printflags64(perf_branch_sample_type, attr->branch_sample_type,
			     "PERF_SAMPLE_BRANCH_???");
	}

	_PERF_CHECK_FIELD(sample_regs_user);
	/*
	 * "This bit mask defines the set of user CPU registers to dump on
	 * samples. The layout of the register mask is architecture-specific and
	 * described in the kernel header
	 * arch/ARCH/include/uapi/asm/perf_regs.h."
	 */
	tprintf(", sample_regs_user=%#" PRIx64, attr->sample_regs_user);

	_PERF_CHECK_FIELD(sample_stack_user);
	/*
	 * "size of the user stack to dump if PERF_SAMPLE_STACK_USER is
	 * specified."
	 */
	if (attr->sample_type & PERF_SAMPLE_STACK_USER)
		tprintf(", sample_stack_user=%#" PRIx32,
			attr->sample_stack_user);

	if (attr->use_clockid) {
		_PERF_CHECK_FIELD(clockid);
		tprints(", clockid=");
		printxval(clocknames, attr->clockid, "CLOCK_???");
	}

	_PERF_CHECK_FIELD(sample_regs_intr);
	tprintf(", sample_regs_intr=%#" PRIx64, attr->sample_regs_intr);

	_PERF_CHECK_FIELD(aux_watermark);
	tprintf(", aux_watermark=%" PRIu32, attr->aux_watermark);

	_PERF_CHECK_FIELD(sample_max_stack);
	tprintf(", sample_max_stack=%" PRIu16, attr->sample_max_stack);

	/* _PERF_CHECK_FIELD(__reserved_2);
	tprintf(", __reserved2=%" PRIu16, attr->__reserved_2); */

print_perf_event_attr_out:
	if ((attr->size && (attr->size > size)) ||
	    (!attr->size && (size < PERF_ATTR_SIZE_VER0)))
		tprints(", ...");

	tprints("}");
}

SYS_FUNC(perf_event_open)
{
	/*
	 * We try to copy out the whole structure on entering in order to check
	 * size value on exiting. We do not check the rest of the fields because
	 * they shouldn't be changed, but copy the whole structure instead
	 * of just size field because they could.
	 */
	if (entering(tcp)) {
		if (!fetch_perf_event_attr(tcp, tcp->u_arg[0]))
			return 0;
	} else {
		print_perf_event_attr(tcp, tcp->u_arg[0]);
	}

	tprintf(", %d, %d, %d, ",
		(int) tcp->u_arg[1],
		(int) tcp->u_arg[2],
		(int) tcp->u_arg[3]);
	printflags64(perf_event_open_flags, tcp->u_arg[4], "PERF_FLAG_???");

	return RVAL_DECODED | RVAL_FD;
}
