// SPDX-License-Identifier: GPL-2.0
#include <stdbool.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/types.h>

#include "map_symbol.h"
#include "branch.h"
#include "event.h"
#include "evsel.h"
#include "debug.h"
#include "util/synthetic-events.h"
#include "util/trace-event.h"

#include "tests.h"

#define COMP(m) do {					\
	if (s1->m != s2->m) {				\
		pr_debug("Samples differ at '"#m"'\n");	\
		return false;				\
	}						\
} while (0)

#define MCOMP(m) do {					\
	if (memcmp(&s1->m, &s2->m, sizeof(s1->m))) {	\
		pr_debug("Samples differ at '"#m"'\n");	\
		return false;				\
	}						\
} while (0)

/*
 * Hardcode the expected values for branch_entry flags.
 * These are based on the input value (213) specified
 * in branch_stack variable.
 */
#define BS_EXPECTED_BE	0xa000d00000000000
#define BS_EXPECTED_LE	0xd5000000
#define FLAG(s)	s->branch_stack->entries[i].flags

static bool samples_same(const struct perf_sample *s1,
			 const struct perf_sample *s2,
			 u64 type, u64 read_format, bool needs_swap)
{
	size_t i;

	if (type & PERF_SAMPLE_IDENTIFIER)
		COMP(id);

	if (type & PERF_SAMPLE_IP)
		COMP(ip);

	if (type & PERF_SAMPLE_TID) {
		COMP(pid);
		COMP(tid);
	}

	if (type & PERF_SAMPLE_TIME)
		COMP(time);

	if (type & PERF_SAMPLE_ADDR)
		COMP(addr);

	if (type & PERF_SAMPLE_ID)
		COMP(id);

	if (type & PERF_SAMPLE_STREAM_ID)
		COMP(stream_id);

	if (type & PERF_SAMPLE_CPU)
		COMP(cpu);

	if (type & PERF_SAMPLE_PERIOD)
		COMP(period);

	if (type & PERF_SAMPLE_READ) {
		if (read_format & PERF_FORMAT_GROUP)
			COMP(read.group.nr);
		else
			COMP(read.one.value);
		if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
			COMP(read.time_enabled);
		if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
			COMP(read.time_running);
		/* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */
		if (read_format & PERF_FORMAT_GROUP) {
			for (i = 0; i < s1->read.group.nr; i++)
				MCOMP(read.group.values[i]);
		} else {
			COMP(read.one.id);
		}
	}

	if (type & PERF_SAMPLE_CALLCHAIN) {
		COMP(callchain->nr);
		for (i = 0; i < s1->callchain->nr; i++)
			COMP(callchain->ips[i]);
	}

	if (type & PERF_SAMPLE_RAW) {
		COMP(raw_size);
		if (memcmp(s1->raw_data, s2->raw_data, s1->raw_size)) {
			pr_debug("Samples differ at 'raw_data'\n");
			return false;
		}
	}

	if (type & PERF_SAMPLE_BRANCH_STACK) {
		COMP(branch_stack->nr);
		COMP(branch_stack->hw_idx);
		for (i = 0; i < s1->branch_stack->nr; i++) {
			if (needs_swap)
				return ((tep_is_bigendian()) ?
					(FLAG(s2).value == BS_EXPECTED_BE) :
					(FLAG(s2).value == BS_EXPECTED_LE));
			else
				MCOMP(branch_stack->entries[i]);
		}
	}

	if (type & PERF_SAMPLE_REGS_USER) {
		size_t sz = hweight_long(s1->user_regs.mask) * sizeof(u64);

		COMP(user_regs.mask);
		COMP(user_regs.abi);
		if (s1->user_regs.abi &&
		    (!s1->user_regs.regs || !s2->user_regs.regs ||
		     memcmp(s1->user_regs.regs, s2->user_regs.regs, sz))) {
			pr_debug("Samples differ at 'user_regs'\n");
			return false;
		}
	}

	if (type & PERF_SAMPLE_STACK_USER) {
		COMP(user_stack.size);
		if (memcmp(s1->user_stack.data, s2->user_stack.data,
			   s1->user_stack.size)) {
			pr_debug("Samples differ at 'user_stack'\n");
			return false;
		}
	}

	if (type & PERF_SAMPLE_WEIGHT)
		COMP(weight);

	if (type & PERF_SAMPLE_DATA_SRC)
		COMP(data_src);

	if (type & PERF_SAMPLE_TRANSACTION)
		COMP(transaction);

	if (type & PERF_SAMPLE_REGS_INTR) {
		size_t sz = hweight_long(s1->intr_regs.mask) * sizeof(u64);

		COMP(intr_regs.mask);
		COMP(intr_regs.abi);
		if (s1->intr_regs.abi &&
		    (!s1->intr_regs.regs || !s2->intr_regs.regs ||
		     memcmp(s1->intr_regs.regs, s2->intr_regs.regs, sz))) {
			pr_debug("Samples differ at 'intr_regs'\n");
			return false;
		}
	}

	if (type & PERF_SAMPLE_PHYS_ADDR)
		COMP(phys_addr);

	if (type & PERF_SAMPLE_CGROUP)
		COMP(cgroup);

	if (type & PERF_SAMPLE_DATA_PAGE_SIZE)
		COMP(data_page_size);

	if (type & PERF_SAMPLE_CODE_PAGE_SIZE)
		COMP(code_page_size);

	if (type & PERF_SAMPLE_AUX) {
		COMP(aux_sample.size);
		if (memcmp(s1->aux_sample.data, s2->aux_sample.data,
			   s1->aux_sample.size)) {
			pr_debug("Samples differ at 'aux_sample'\n");
			return false;
		}
	}

	return true;
}

static int do_test(u64 sample_type, u64 sample_regs, u64 read_format)
{
	struct evsel evsel = {
		.needs_swap = false,
		.core = {
			. attr = {
				.sample_type = sample_type,
				.read_format = read_format,
			},
		},
	};
	union perf_event *event;
	union {
		struct ip_callchain callchain;
		u64 data[64];
	} callchain = {
		/* 3 ips */
		.data = {3, 201, 202, 203},
	};
	union {
		struct branch_stack branch_stack;
		u64 data[64];
	} branch_stack = {
		/* 1 branch_entry */
		.data = {1, -1ULL, 211, 212, 213},
	};
	u64 regs[64];
	const u32 raw_data[] = {0x12345678, 0x0a0b0c0d, 0x11020304, 0x05060708, 0 };
	const u64 data[] = {0x2211443366558877ULL, 0, 0xaabbccddeeff4321ULL};
	const u64 aux_data[] = {0xa55a, 0, 0xeeddee, 0x0282028202820282};
	struct perf_sample sample = {
		.ip		= 101,
		.pid		= 102,
		.tid		= 103,
		.time		= 104,
		.addr		= 105,
		.id		= 106,
		.stream_id	= 107,
		.period		= 108,
		.weight		= 109,
		.cpu		= 110,
		.raw_size	= sizeof(raw_data),
		.data_src	= 111,
		.transaction	= 112,
		.raw_data	= (void *)raw_data,
		.callchain	= &callchain.callchain,
		.no_hw_idx      = false,
		.branch_stack	= &branch_stack.branch_stack,
		.user_regs	= {
			.abi	= PERF_SAMPLE_REGS_ABI_64,
			.mask	= sample_regs,
			.regs	= regs,
		},
		.user_stack	= {
			.size	= sizeof(data),
			.data	= (void *)data,
		},
		.read		= {
			.time_enabled = 0x030a59d664fca7deULL,
			.time_running = 0x011b6ae553eb98edULL,
		},
		.intr_regs	= {
			.abi	= PERF_SAMPLE_REGS_ABI_64,
			.mask	= sample_regs,
			.regs	= regs,
		},
		.phys_addr	= 113,
		.cgroup		= 114,
		.data_page_size = 115,
		.code_page_size = 116,
		.aux_sample	= {
			.size	= sizeof(aux_data),
			.data	= (void *)aux_data,
		},
	};
	struct sample_read_value values[] = {{1, 5}, {9, 3}, {2, 7}, {6, 4},};
	struct perf_sample sample_out, sample_out_endian;
	size_t i, sz, bufsz;
	int err, ret = -1;

	if (sample_type & PERF_SAMPLE_REGS_USER)
		evsel.core.attr.sample_regs_user = sample_regs;

	if (sample_type & PERF_SAMPLE_REGS_INTR)
		evsel.core.attr.sample_regs_intr = sample_regs;

	if (sample_type & PERF_SAMPLE_BRANCH_STACK)
		evsel.core.attr.branch_sample_type |= PERF_SAMPLE_BRANCH_HW_INDEX;

	for (i = 0; i < sizeof(regs); i++)
		*(i + (u8 *)regs) = i & 0xfe;

	if (read_format & PERF_FORMAT_GROUP) {
		sample.read.group.nr     = 4;
		sample.read.group.values = values;
	} else {
		sample.read.one.value = 0x08789faeb786aa87ULL;
		sample.read.one.id    = 99;
	}

	sz = perf_event__sample_event_size(&sample, sample_type, read_format);
	bufsz = sz + 4096; /* Add a bit for overrun checking */
	event = malloc(bufsz);
	if (!event) {
		pr_debug("malloc failed\n");
		return -1;
	}

	memset(event, 0xff, bufsz);
	event->header.type = PERF_RECORD_SAMPLE;
	event->header.misc = 0;
	event->header.size = sz;

	err = perf_event__synthesize_sample(event, sample_type, read_format,
					    &sample);
	if (err) {
		pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",
			 "perf_event__synthesize_sample", sample_type, err);
		goto out_free;
	}

	/* The data does not contain 0xff so we use that to check the size */
	for (i = bufsz; i > 0; i--) {
		if (*(i - 1 + (u8 *)event) != 0xff)
			break;
	}
	if (i != sz) {
		pr_debug("Event size mismatch: actual %zu vs expected %zu\n",
			 i, sz);
		goto out_free;
	}

	evsel.sample_size = __evsel__sample_size(sample_type);

	err = evsel__parse_sample(&evsel, event, &sample_out);
	if (err) {
		pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",
			 "evsel__parse_sample", sample_type, err);
		goto out_free;
	}

	if (!samples_same(&sample, &sample_out, sample_type, read_format, evsel.needs_swap)) {
		pr_debug("parsing failed for sample_type %#"PRIx64"\n",
			 sample_type);
		goto out_free;
	}

	if (sample_type == PERF_SAMPLE_BRANCH_STACK) {
		evsel.needs_swap = true;
		evsel.sample_size = __evsel__sample_size(sample_type);
		err = evsel__parse_sample(&evsel, event, &sample_out_endian);
		if (err) {
			pr_debug("%s failed for sample_type %#"PRIx64", error %d\n",
				 "evsel__parse_sample", sample_type, err);
			goto out_free;
		}

		if (!samples_same(&sample, &sample_out_endian, sample_type, read_format, evsel.needs_swap)) {
			pr_debug("parsing failed for sample_type %#"PRIx64"\n",
				 sample_type);
			goto out_free;
		}
	}

	ret = 0;
out_free:
	free(event);
	if (ret && read_format)
		pr_debug("read_format %#"PRIx64"\n", read_format);
	return ret;
}

/**
 * test__sample_parsing - test sample parsing.
 *
 * This function implements a test that synthesizes a sample event, parses it
 * and then checks that the parsed sample matches the original sample.  The test
 * checks sample format bits separately and together.  If the test passes %0 is
 * returned, otherwise %-1 is returned.
 */
static int test__sample_parsing(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
{
	const u64 rf[] = {4, 5, 6, 7, 12, 13, 14, 15};
	u64 sample_type;
	u64 sample_regs;
	size_t i;
	int err;

	/*
	 * Fail the test if it has not been updated when new sample format bits
	 * were added.  Please actually update the test rather than just change
	 * the condition below.
	 */
	if (PERF_SAMPLE_MAX > PERF_SAMPLE_WEIGHT_STRUCT << 1) {
		pr_debug("sample format has changed, some new PERF_SAMPLE_ bit was introduced - test needs updating\n");
		return -1;
	}

	/* Test each sample format bit separately */
	for (sample_type = 1; sample_type != PERF_SAMPLE_MAX;
	     sample_type <<= 1) {
		/* Test read_format variations */
		if (sample_type == PERF_SAMPLE_READ) {
			for (i = 0; i < ARRAY_SIZE(rf); i++) {
				err = do_test(sample_type, 0, rf[i]);
				if (err)
					return err;
			}
			continue;
		}
		sample_regs = 0;

		if (sample_type == PERF_SAMPLE_REGS_USER)
			sample_regs = 0x3fff;

		if (sample_type == PERF_SAMPLE_REGS_INTR)
			sample_regs = 0xff0fff;

		err = do_test(sample_type, sample_regs, 0);
		if (err)
			return err;
	}

	/*
	 * Test all sample format bits together
	 * Note: PERF_SAMPLE_WEIGHT and PERF_SAMPLE_WEIGHT_STRUCT cannot
	 *       be set simultaneously.
	 */
	sample_type = (PERF_SAMPLE_MAX - 1) & ~PERF_SAMPLE_WEIGHT;
	sample_regs = 0x3fff; /* shared yb intr and user regs */
	for (i = 0; i < ARRAY_SIZE(rf); i++) {
		err = do_test(sample_type, sample_regs, rf[i]);
		if (err)
			return err;
	}

	return 0;
}

DEFINE_SUITE("Sample parsing", sample_parsing);
