// Copyright 2017 syzkaller project authors. All rights reserved.
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

#include <fcntl.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#if GOOS_openbsd
#include <sys/sysctl.h>
#endif

static void os_init(int argc, char** argv, void* data, size_t data_size)
{
#if GOOS_openbsd
	// W^X not allowed by default on OpenBSD.
	int prot = PROT_READ | PROT_WRITE;
#elif GOOS_netbsd
	// W^X not allowed by default on NetBSD (PaX MPROTECT).
	int prot = PROT_READ | PROT_WRITE | PROT_MPROTECT(PROT_EXEC);
#else
	int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
#endif

	if (mmap(data, data_size, prot, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0) != data)
		fail("mmap of data segment failed");

	// Makes sure the file descriptor limit is sufficient to map control pipes.
	struct rlimit rlim;
	rlim.rlim_cur = rlim.rlim_max = kMaxFd;
	setrlimit(RLIMIT_NOFILE, &rlim);
}

static intptr_t execute_syscall(const call_t* c, intptr_t a[kMaxArgs])
{
	if (c->call)
		return c->call(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]);
	return __syscall(c->sys_nr, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]);
}

#if GOOS_freebsd || GOOS_openbsd || GOOS_netbsd

// KCOV support was added to FreeBSD in https://svnweb.freebsd.org/changeset/base/342962
// KCOV support added to NetBSD in https://github.com/NetBSD/src/commit/080a26f01d79ded8a2154c128950d1d663c6ca88

#include <sys/kcov.h>

static void cover_open(cover_t* cov, bool extra)
{
	int fd = open("/dev/kcov", O_RDWR);
	if (fd == -1)
		fail("open of /dev/kcov failed");
	if (dup2(fd, cov->fd) < 0)
		fail("failed to dup2(%d, %d) cover fd", fd, cov->fd);
	close(fd);

#if GOOS_freebsd
	if (ioctl(cov->fd, KIOSETBUFSIZE, kCoverSize))
		fail("ioctl init trace write failed");
#elif GOOS_openbsd
	unsigned long cover_size = kCoverSize;
	if (ioctl(cov->fd, KIOSETBUFSIZE, &cover_size))
		fail("ioctl init trace write failed");
#elif GOOS_netbsd
	uint64_t cover_size = kCoverSize;
	if (ioctl(cov->fd, KCOV_IOC_SETBUFSIZE, &cover_size))
		fail("ioctl init trace write failed");
#endif

#if GOOS_freebsd || GOOS_netbsd
	size_t mmap_alloc_size = kCoverSize * KCOV_ENTRY_SIZE;
#else
	size_t mmap_alloc_size = kCoverSize * (is_kernel_64_bit ? 8 : 4);
#endif
	void* mmap_ptr = mmap(NULL, mmap_alloc_size, PROT_READ | PROT_WRITE,
			      MAP_SHARED, cov->fd, 0);
	if (mmap_ptr == MAP_FAILED)
		fail("cover mmap failed");
	cov->data = (char*)mmap_ptr;
	cov->data_end = cov->data + mmap_alloc_size;
}

static void cover_protect(cover_t* cov)
{
#if GOOS_freebsd || GOOS_netbsd
	size_t mmap_alloc_size = kCoverSize * KCOV_ENTRY_SIZE;
	long page_size = sysconf(_SC_PAGESIZE);
	if (page_size > 0)
		mprotect(cov->data + page_size, mmap_alloc_size - page_size,
			 PROT_READ);
#elif GOOS_openbsd
	int mib[2], page_size;
	size_t len;
	size_t mmap_alloc_size = kCoverSize * sizeof(uintptr_t);
	mib[0] = CTL_HW;
	mib[1] = HW_PAGESIZE;
	len = sizeof(page_size);
	if (sysctl(mib, ARRAY_SIZE(mib), &page_size, &len, NULL, 0) != -1)
		mprotect(cov->data + page_size, mmap_alloc_size - page_size,
			 PROT_READ);
#endif
}

static void cover_unprotect(cover_t* cov)
{
#if GOOS_freebsd || GOOS_netbsd
	size_t mmap_alloc_size = kCoverSize * KCOV_ENTRY_SIZE;
	mprotect(cov->data, mmap_alloc_size, PROT_READ | PROT_WRITE);
#elif GOOS_openbsd
	size_t mmap_alloc_size = kCoverSize * sizeof(uintptr_t);
	mprotect(cov->data, mmap_alloc_size, PROT_READ | PROT_WRITE);
#endif
}

static void cover_enable(cover_t* cov, bool collect_comps, bool extra)
{
	int kcov_mode = collect_comps ? KCOV_MODE_TRACE_CMP : KCOV_MODE_TRACE_PC;
#if GOOS_freebsd
	// FreeBSD uses an int as the third argument.
	if (ioctl(cov->fd, KIOENABLE, kcov_mode))
		exitf("cover enable write trace failed, mode=%d", kcov_mode);
#elif GOOS_openbsd
	// OpenBSD uses an pointer to an int as the third argument.
	if (ioctl(cov->fd, KIOENABLE, &kcov_mode))
		exitf("cover enable write trace failed, mode=%d", kcov_mode);
#elif GOOS_netbsd
	if (ioctl(cov->fd, KCOV_IOC_ENABLE, &kcov_mode))
		exitf("cover enable write trace failed, mode=%d", kcov_mode);

#endif
}

static void cover_reset(cover_t* cov)
{
	*(uint64*)cov->data = 0;
}

static void cover_collect(cover_t* cov)
{
	cov->size = *(uint64*)cov->data;
}

static bool cover_check(uint32 pc)
{
	return true;
}

static bool cover_check(uint64 pc)
{
	return true;
}
#else
#include "nocover.h"
#endif
