// SPDX-License-Identifier: GPL-2.0
/*
 * Written by Dave Hansen <dave.hansen@intel.com>
 */

#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/mman.h>
#include <string.h>
#include <fcntl.h>
#include "mpx-debug.h"
#include "mpx-mm.h"
#include "mpx-hw.h"

unsigned long bounds_dir_global;

#define mpx_dig_abort()	__mpx_dig_abort(__FILE__, __func__, __LINE__)
static void inline __mpx_dig_abort(const char *file, const char *func, int line)
{
	fprintf(stderr, "MPX dig abort @ %s::%d in %s()\n", file, line, func);
	printf("MPX dig abort @ %s::%d in %s()\n", file, line, func);
	abort();
}

/*
 * run like this (BDIR finds the probably bounds directory):
 *
 *	BDIR="$(cat /proc/$pid/smaps | grep -B1 2097152 \
 *		| head -1 | awk -F- '{print $1}')";
 *	./mpx-dig $pid 0x$BDIR
 *
 * NOTE:
 *	assumes that the only 2097152-kb VMA is the bounds dir
 */

long nr_incore(void *ptr, unsigned long size_bytes)
{
	int i;
	long ret = 0;
	long vec_len = size_bytes / PAGE_SIZE;
	unsigned char *vec = malloc(vec_len);
	int incore_ret;

	if (!vec)
		mpx_dig_abort();

	incore_ret = mincore(ptr, size_bytes, vec);
	if (incore_ret) {
		printf("mincore ret: %d\n", incore_ret);
		perror("mincore");
		mpx_dig_abort();
	}
	for (i = 0; i < vec_len; i++)
		ret += vec[i];
	free(vec);
	return ret;
}

int open_proc(int pid, char *file)
{
	static char buf[100];
	int fd;

	snprintf(&buf[0], sizeof(buf), "/proc/%d/%s", pid, file);
	fd = open(&buf[0], O_RDONLY);
	if (fd < 0)
		perror(buf);

	return fd;
}

struct vaddr_range {
	unsigned long start;
	unsigned long end;
};
struct vaddr_range *ranges;
int nr_ranges_allocated;
int nr_ranges_populated;
int last_range = -1;

int __pid_load_vaddrs(int pid)
{
	int ret = 0;
	int proc_maps_fd = open_proc(pid, "maps");
	char linebuf[10000];
	unsigned long start;
	unsigned long end;
	char rest[1000];
	FILE *f = fdopen(proc_maps_fd, "r");

	if (!f)
		mpx_dig_abort();
	nr_ranges_populated = 0;
	while (!feof(f)) {
		char *readret = fgets(linebuf, sizeof(linebuf), f);
		int parsed;

		if (readret == NULL) {
			if (feof(f))
				break;
			mpx_dig_abort();
		}

		parsed = sscanf(linebuf, "%lx-%lx%s", &start, &end, rest);
		if (parsed != 3)
			mpx_dig_abort();

		dprintf4("result[%d]: %lx-%lx<->%s\n", parsed, start, end, rest);
		if (nr_ranges_populated >= nr_ranges_allocated) {
			ret = -E2BIG;
			break;
		}
		ranges[nr_ranges_populated].start = start;
		ranges[nr_ranges_populated].end = end;
		nr_ranges_populated++;
	}
	last_range = -1;
	fclose(f);
	close(proc_maps_fd);
	return ret;
}

int pid_load_vaddrs(int pid)
{
	int ret;

	dprintf2("%s(%d)\n", __func__, pid);
	if (!ranges) {
		nr_ranges_allocated = 4;
		ranges = malloc(nr_ranges_allocated * sizeof(ranges[0]));
		dprintf2("%s(%d) allocated %d ranges @ %p\n", __func__, pid,
			 nr_ranges_allocated, ranges);
		assert(ranges != NULL);
	}
	do {
		ret = __pid_load_vaddrs(pid);
		if (!ret)
			break;
		if (ret == -E2BIG) {
			dprintf2("%s(%d) need to realloc\n", __func__, pid);
			nr_ranges_allocated *= 2;
			ranges = realloc(ranges,
					nr_ranges_allocated * sizeof(ranges[0]));
			dprintf2("%s(%d) allocated %d ranges @ %p\n", __func__,
					pid, nr_ranges_allocated, ranges);
			assert(ranges != NULL);
			dprintf1("reallocating to hold %d ranges\n", nr_ranges_allocated);
		}
	} while (1);

	dprintf2("%s(%d) done\n", __func__, pid);

	return ret;
}

static inline int vaddr_in_range(unsigned long vaddr, struct vaddr_range *r)
{
	if (vaddr < r->start)
		return 0;
	if (vaddr >= r->end)
		return 0;
	return 1;
}

static inline int vaddr_mapped_by_range(unsigned long vaddr)
{
	int i;

	if (last_range > 0 && vaddr_in_range(vaddr, &ranges[last_range]))
		return 1;

	for (i = 0; i < nr_ranges_populated; i++) {
		struct vaddr_range *r = &ranges[i];

		if (vaddr_in_range(vaddr, r))
			continue;
		last_range = i;
		return 1;
	}
	return 0;
}

const int bt_entry_size_bytes = sizeof(unsigned long) * 4;

void *read_bounds_table_into_buf(unsigned long table_vaddr)
{
#ifdef MPX_DIG_STANDALONE
	static char bt_buf[MPX_BOUNDS_TABLE_SIZE_BYTES];
	off_t seek_ret = lseek(fd, table_vaddr, SEEK_SET);
	if (seek_ret != table_vaddr)
		mpx_dig_abort();

	int read_ret = read(fd, &bt_buf, sizeof(bt_buf));
	if (read_ret != sizeof(bt_buf))
		mpx_dig_abort();
	return &bt_buf;
#else
	return (void *)table_vaddr;
#endif
}

int dump_table(unsigned long table_vaddr, unsigned long base_controlled_vaddr,
		unsigned long bde_vaddr)
{
	unsigned long offset_inside_bt;
	int nr_entries = 0;
	int do_abort = 0;
	char *bt_buf;

	dprintf3("%s() base_controlled_vaddr: 0x%012lx bde_vaddr: 0x%012lx\n",
			__func__, base_controlled_vaddr, bde_vaddr);

	bt_buf = read_bounds_table_into_buf(table_vaddr);

	dprintf4("%s() read done\n", __func__);

	for (offset_inside_bt = 0;
	     offset_inside_bt < MPX_BOUNDS_TABLE_SIZE_BYTES;
	     offset_inside_bt += bt_entry_size_bytes) {
		unsigned long bt_entry_index;
		unsigned long bt_entry_controls;
		unsigned long this_bt_entry_for_vaddr;
		unsigned long *bt_entry_buf;
		int i;

		dprintf4("%s() offset_inside_bt: 0x%lx of 0x%llx\n", __func__,
			offset_inside_bt, MPX_BOUNDS_TABLE_SIZE_BYTES);
		bt_entry_buf = (void *)&bt_buf[offset_inside_bt];
		if (!bt_buf) {
			printf("null bt_buf\n");
			mpx_dig_abort();
		}
		if (!bt_entry_buf) {
			printf("null bt_entry_buf\n");
			mpx_dig_abort();
		}
		dprintf4("%s() reading *bt_entry_buf @ %p\n", __func__,
				bt_entry_buf);
		if (!bt_entry_buf[0] &&
		    !bt_entry_buf[1] &&
		    !bt_entry_buf[2] &&
		    !bt_entry_buf[3])
			continue;

		nr_entries++;

		bt_entry_index = offset_inside_bt/bt_entry_size_bytes;
		bt_entry_controls = sizeof(void *);
		this_bt_entry_for_vaddr =
			base_controlled_vaddr + bt_entry_index*bt_entry_controls;
		/*
		 * We sign extend vaddr bits 48->63 which effectively
		 * creates a hole in the virtual address space.
		 * This calculation corrects for the hole.
		 */
		if (this_bt_entry_for_vaddr > 0x00007fffffffffffUL)
			this_bt_entry_for_vaddr |= 0xffff800000000000;

		if (!vaddr_mapped_by_range(this_bt_entry_for_vaddr)) {
			printf("bt_entry_buf: %p\n", bt_entry_buf);
			printf("there is a bte for %lx but no mapping\n",
					this_bt_entry_for_vaddr);
			printf("	  bde   vaddr: %016lx\n", bde_vaddr);
			printf("base_controlled_vaddr: %016lx\n", base_controlled_vaddr);
			printf("	  table_vaddr: %016lx\n", table_vaddr);
			printf("	  entry vaddr: %016lx @ offset %lx\n",
				table_vaddr + offset_inside_bt, offset_inside_bt);
			do_abort = 1;
			mpx_dig_abort();
		}
		if (DEBUG_LEVEL < 4)
			continue;

		printf("table entry[%lx]: ", offset_inside_bt);
		for (i = 0; i < bt_entry_size_bytes; i += sizeof(unsigned long))
			printf("0x%016lx ", bt_entry_buf[i]);
		printf("\n");
	}
	if (do_abort)
		mpx_dig_abort();
	dprintf4("%s() done\n",  __func__);
	return nr_entries;
}

int search_bd_buf(char *buf, int len_bytes, unsigned long bd_offset_bytes,
		int *nr_populated_bdes)
{
	unsigned long i;
	int total_entries = 0;

	dprintf3("%s(%p, %x, %lx, ...) buf end: %p\n", __func__, buf,
			len_bytes, bd_offset_bytes, buf + len_bytes);

	for (i = 0; i < len_bytes; i += sizeof(unsigned long)) {
		unsigned long bd_index = (bd_offset_bytes + i) / sizeof(unsigned long);
		unsigned long *bounds_dir_entry_ptr = (unsigned long *)&buf[i];
		unsigned long bounds_dir_entry;
		unsigned long bd_for_vaddr;
		unsigned long bt_start;
		unsigned long bt_tail;
		int nr_entries;

		dprintf4("%s() loop i: %ld bounds_dir_entry_ptr: %p\n", __func__, i,
				bounds_dir_entry_ptr);

		bounds_dir_entry = *bounds_dir_entry_ptr;
		if (!bounds_dir_entry) {
			dprintf4("no bounds dir at index 0x%lx / 0x%lx "
				 "start at offset:%lx %lx\n", bd_index, bd_index,
					bd_offset_bytes, i);
			continue;
		}
		dprintf3("found bounds_dir_entry: 0x%lx @ "
			 "index 0x%lx buf ptr: %p\n", bounds_dir_entry, i,
					&buf[i]);
		/* mask off the enable bit: */
		bounds_dir_entry &= ~0x1;
		(*nr_populated_bdes)++;
		dprintf4("nr_populated_bdes: %p\n", nr_populated_bdes);
		dprintf4("*nr_populated_bdes: %d\n", *nr_populated_bdes);

		bt_start = bounds_dir_entry;
		bt_tail = bounds_dir_entry + MPX_BOUNDS_TABLE_SIZE_BYTES - 1;
		if (!vaddr_mapped_by_range(bt_start)) {
			printf("bounds directory 0x%lx points to nowhere\n",
					bounds_dir_entry);
			mpx_dig_abort();
		}
		if (!vaddr_mapped_by_range(bt_tail)) {
			printf("bounds directory end 0x%lx points to nowhere\n",
					bt_tail);
			mpx_dig_abort();
		}
		/*
		 * Each bounds directory entry controls 1MB of virtual address
		 * space.  This variable is the virtual address in the process
		 * of the beginning of the area controlled by this bounds_dir.
		 */
		bd_for_vaddr = bd_index * (1UL<<20);

		nr_entries = dump_table(bounds_dir_entry, bd_for_vaddr,
				bounds_dir_global+bd_offset_bytes+i);
		total_entries += nr_entries;
		dprintf5("dir entry[%4ld @ %p]: 0x%lx %6d entries "
			 "total this buf: %7d bd_for_vaddrs: 0x%lx -> 0x%lx\n",
				bd_index, buf+i,
				bounds_dir_entry, nr_entries, total_entries,
				bd_for_vaddr, bd_for_vaddr + (1UL<<20));
	}
	dprintf3("%s(%p, %x, %lx, ...) done\n", __func__, buf, len_bytes,
			bd_offset_bytes);
	return total_entries;
}

int proc_pid_mem_fd = -1;

void *fill_bounds_dir_buf_other(long byte_offset_inside_bounds_dir,
			   long buffer_size_bytes, void *buffer)
{
	unsigned long seekto = bounds_dir_global + byte_offset_inside_bounds_dir;
	int read_ret;
	off_t seek_ret = lseek(proc_pid_mem_fd, seekto, SEEK_SET);

	if (seek_ret != seekto)
		mpx_dig_abort();

	read_ret = read(proc_pid_mem_fd, buffer, buffer_size_bytes);
	/* there shouldn't practically be short reads of /proc/$pid/mem */
	if (read_ret != buffer_size_bytes)
		mpx_dig_abort();

	return buffer;
}
void *fill_bounds_dir_buf_self(long byte_offset_inside_bounds_dir,
			   long buffer_size_bytes, void *buffer)

{
	unsigned char vec[buffer_size_bytes / PAGE_SIZE];
	char *dig_bounds_dir_ptr =
		(void *)(bounds_dir_global + byte_offset_inside_bounds_dir);
	/*
	 * use mincore() to quickly find the areas of the bounds directory
	 * that have memory and thus will be worth scanning.
	 */
	int incore_ret;

	int incore = 0;
	int i;

	dprintf4("%s() dig_bounds_dir_ptr: %p\n", __func__, dig_bounds_dir_ptr);

	incore_ret = mincore(dig_bounds_dir_ptr, buffer_size_bytes, &vec[0]);
	if (incore_ret) {
		printf("mincore ret: %d\n", incore_ret);
		perror("mincore");
		mpx_dig_abort();
	}
	for (i = 0; i < sizeof(vec); i++)
		incore += vec[i];
	dprintf4("%s() total incore: %d\n", __func__, incore);
	if (!incore)
		return NULL;
	dprintf3("%s() total incore: %d\n", __func__, incore);
	return dig_bounds_dir_ptr;
}

int inspect_pid(int pid)
{
	static int dig_nr;
	long offset_inside_bounds_dir;
	char bounds_dir_buf[sizeof(unsigned long) * (1UL << 15)];
	char *dig_bounds_dir_ptr;
	int total_entries = 0;
	int nr_populated_bdes = 0;
	int inspect_self;

	if (getpid() == pid) {
		dprintf4("inspecting self\n");
		inspect_self = 1;
	} else {
		dprintf4("inspecting pid %d\n", pid);
		mpx_dig_abort();
	}

	for (offset_inside_bounds_dir = 0;
	     offset_inside_bounds_dir < MPX_BOUNDS_TABLE_SIZE_BYTES;
	     offset_inside_bounds_dir += sizeof(bounds_dir_buf)) {
		static int bufs_skipped;
		int this_entries;

		if (inspect_self) {
			dig_bounds_dir_ptr =
				fill_bounds_dir_buf_self(offset_inside_bounds_dir,
							 sizeof(bounds_dir_buf),
							 &bounds_dir_buf[0]);
		} else {
			dig_bounds_dir_ptr =
				fill_bounds_dir_buf_other(offset_inside_bounds_dir,
							  sizeof(bounds_dir_buf),
							  &bounds_dir_buf[0]);
		}
		if (!dig_bounds_dir_ptr) {
			bufs_skipped++;
			continue;
		}
		this_entries = search_bd_buf(dig_bounds_dir_ptr,
					sizeof(bounds_dir_buf),
					offset_inside_bounds_dir,
					&nr_populated_bdes);
		total_entries += this_entries;
	}
	printf("mpx dig (%3d) complete, SUCCESS (%8d / %4d)\n", ++dig_nr,
			total_entries, nr_populated_bdes);
	return total_entries + nr_populated_bdes;
}

#ifdef MPX_DIG_REMOTE
int main(int argc, char **argv)
{
	int err;
	char *c;
	unsigned long bounds_dir_entry;
	int pid;

	printf("mpx-dig starting...\n");
	err = sscanf(argv[1], "%d", &pid);
	printf("parsing: '%s', err: %d\n", argv[1], err);
	if (err != 1)
		mpx_dig_abort();

	err = sscanf(argv[2], "%lx", &bounds_dir_global);
	printf("parsing: '%s': %d\n", argv[2], err);
	if (err != 1)
		mpx_dig_abort();

	proc_pid_mem_fd = open_proc(pid, "mem");
	if (proc_pid_mem_fd < 0)
		mpx_dig_abort();

	inspect_pid(pid);
	return 0;
}
#endif

long inspect_me(struct mpx_bounds_dir *bounds_dir)
{
	int pid = getpid();

	pid_load_vaddrs(pid);
	bounds_dir_global = (unsigned long)bounds_dir;
	dprintf4("enter %s() bounds dir: %p\n", __func__, bounds_dir);
	return inspect_pid(pid);
}
