// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2019,2021  Arm Limited
 * Original author: Dave Martin <Dave.Martin@arm.com>
 */

#include "system.h"

#include <stdbool.h>
#include <stddef.h>
#include <linux/errno.h>
#include <linux/auxvec.h>
#include <linux/signal.h>
#include <asm/sigcontext.h>
#include <asm/ucontext.h>

typedef struct ucontext ucontext_t;

#include "btitest.h"
#include "signal.h"

#define EXPECTED_TESTS 18

static volatile unsigned int test_num = 1;
static unsigned int test_passed;
static unsigned int test_failed;
static unsigned int test_skipped;

static void fdputs(int fd, const char *str)
{
	size_t len = 0;
	const char *p = str;

	while (*p++)
		++len;

	write(fd, str, len);
}

static void putstr(const char *str)
{
	fdputs(1, str);
}

static void putnum(unsigned int num)
{
	char c;

	if (num / 10)
		putnum(num / 10);

	c = '0' + (num % 10);
	write(1, &c, 1);
}

#define puttestname(test_name, trampoline_name) do {	\
	putstr(test_name);				\
	putstr("/");					\
	putstr(trampoline_name);			\
} while (0)

void print_summary(void)
{
	putstr("# Totals: pass:");
	putnum(test_passed);
	putstr(" fail:");
	putnum(test_failed);
	putstr(" xfail:0 xpass:0 skip:");
	putnum(test_skipped);
	putstr(" error:0\n");
}

static const char *volatile current_test_name;
static const char *volatile current_trampoline_name;
static volatile int sigill_expected, sigill_received;

static void handler(int n, siginfo_t *si __always_unused,
		    void *uc_ __always_unused)
{
	ucontext_t *uc = uc_;

	putstr("# \t[SIGILL in ");
	puttestname(current_test_name, current_trampoline_name);
	putstr(", BTYPE=");
	write(1, &"00011011"[((uc->uc_mcontext.pstate & PSR_BTYPE_MASK)
			      >> PSR_BTYPE_SHIFT) * 2], 2);
	if (!sigill_expected) {
		putstr("]\n");
		putstr("not ok ");
		putnum(test_num);
		putstr(" ");
		puttestname(current_test_name, current_trampoline_name);
		putstr("(unexpected SIGILL)\n");
		print_summary();
		exit(128 + n);
	}

	putstr(" (expected)]\n");
	sigill_received = 1;
	/* zap BTYPE so that resuming the faulting code will work */
	uc->uc_mcontext.pstate &= ~PSR_BTYPE_MASK;
}

/* Does the system have BTI? */
static bool have_bti;

static void __do_test(void (*trampoline)(void (*)(void)),
		      void (*fn)(void),
		      const char *trampoline_name,
		      const char *name,
		      int expect_sigill)
{
	/*
	 * Branch Target exceptions should only happen for BTI
	 * binaries running on a system with BTI:
	 */
	if (!BTI || !have_bti)
		expect_sigill = 0;

	sigill_expected = expect_sigill;
	sigill_received = 0;
	current_test_name = name;
	current_trampoline_name = trampoline_name;

	trampoline(fn);

	if (expect_sigill && !sigill_received) {
		putstr("not ok ");
		test_failed++;
	} else {
		putstr("ok ");
		test_passed++;
	}
	putnum(test_num++);
	putstr(" ");
	puttestname(name, trampoline_name);
	putstr("\n");
}

#define do_test(expect_sigill_br_x0,					\
		expect_sigill_br_x16,					\
		expect_sigill_blr,					\
		name)							\
do {									\
	__do_test(call_using_br_x0, name, "call_using_br_x0", #name,	\
		  expect_sigill_br_x0);					\
	__do_test(call_using_br_x16, name, "call_using_br_x16", #name,	\
		  expect_sigill_br_x16);				\
	__do_test(call_using_blr, name, "call_using_blr", #name,	\
		  expect_sigill_blr);					\
} while (0)

void start(int *argcp)
{
	struct sigaction sa;
	void *const *p;
	const struct auxv_entry {
		unsigned long type;
		unsigned long val;
	} *auxv;
	unsigned long hwcap = 0, hwcap2 = 0;

	putstr("TAP version 13\n");
	putstr("1..");
	putnum(EXPECTED_TESTS);
	putstr("\n");

	/* Gross hack for finding AT_HWCAP2 from the initial process stack: */
	p = (void *const *)argcp + 1 + *argcp + 1; /* start of environment */
	/* step over environment */
	while (*p++)
		;
	for (auxv = (const struct auxv_entry *)p; auxv->type != AT_NULL; ++auxv) {
		switch (auxv->type) {
		case AT_HWCAP:
			hwcap = auxv->val;
			break;
		case AT_HWCAP2:
			hwcap2 = auxv->val;
			break;
		default:
			break;
		}
	}

	if (hwcap & HWCAP_PACA)
		putstr("# HWCAP_PACA present\n");
	else
		putstr("# HWCAP_PACA not present\n");

	if (hwcap2 & HWCAP2_BTI) {
		putstr("# HWCAP2_BTI present\n");
		if (!(hwcap & HWCAP_PACA))
			putstr("# Bad hardware?  Expect problems.\n");
		have_bti = true;
	} else {
		putstr("# HWCAP2_BTI not present\n");
		have_bti = false;
	}

	putstr("# Test binary");
	if (!BTI)
		putstr(" not");
	putstr(" built for BTI\n");

	sa.sa_handler = (sighandler_t)(void *)handler;
	sa.sa_flags = SA_SIGINFO;
	sigemptyset(&sa.sa_mask);
	sigaction(SIGILL, &sa, NULL);
	sigaddset(&sa.sa_mask, SIGILL);
	sigprocmask(SIG_UNBLOCK, &sa.sa_mask, NULL);

	do_test(1, 1, 1, nohint_func);
	do_test(1, 1, 1, bti_none_func);
	do_test(1, 0, 0, bti_c_func);
	do_test(0, 0, 1, bti_j_func);
	do_test(0, 0, 0, bti_jc_func);
	do_test(1, 0, 0, paciasp_func);

	print_summary();

	if (test_num - 1 != EXPECTED_TESTS)
		putstr("# WARNING - EXPECTED TEST COUNT WRONG\n");

	if (test_failed)
		exit(1);
	else
		exit(0);
}
