// SPDX-License-Identifier: GPL-2.0

/*
 * Test that MAP_FIXED_NOREPLACE works.
 *
 * Copyright 2018, Jann Horn <jannh@google.com>
 * Copyright 2018, Michael Ellerman, IBM Corporation.
 */

#include <sys/mman.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#ifndef MAP_FIXED_NOREPLACE
#define MAP_FIXED_NOREPLACE 0x100000
#endif

static void dump_maps(void)
{
	char cmd[32];

	snprintf(cmd, sizeof(cmd), "cat /proc/%d/maps", getpid());
	system(cmd);
}

static unsigned long find_base_addr(unsigned long size)
{
	void *addr;
	unsigned long flags;

	flags = MAP_PRIVATE | MAP_ANONYMOUS;
	addr = mmap(NULL, size, PROT_NONE, flags, -1, 0);
	if (addr == MAP_FAILED) {
		printf("Error: couldn't map the space we need for the test\n");
		return 0;
	}

	if (munmap(addr, size) != 0) {
		printf("Error: couldn't map the space we need for the test\n");
		return 0;
	}
	return (unsigned long)addr;
}

int main(void)
{
	unsigned long base_addr;
	unsigned long flags, addr, size, page_size;
	char *p;

	page_size = sysconf(_SC_PAGE_SIZE);

	//let's find a base addr that is free before we start the tests
	size = 5 * page_size;
	base_addr = find_base_addr(size);
	if (!base_addr) {
		printf("Error: couldn't map the space we need for the test\n");
		return 1;
	}

	flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED_NOREPLACE;

	// Check we can map all the areas we need below
	errno = 0;
	addr = base_addr;
	size = 5 * page_size;
	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);

	printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);

	if (p == MAP_FAILED) {
		dump_maps();
		printf("Error: couldn't map the space we need for the test\n");
		return 1;
	}

	errno = 0;
	if (munmap((void *)addr, 5 * page_size) != 0) {
		dump_maps();
		printf("Error: munmap failed!?\n");
		return 1;
	}
	printf("unmap() successful\n");

	errno = 0;
	addr = base_addr + page_size;
	size = 3 * page_size;
	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
	printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);

	if (p == MAP_FAILED) {
		dump_maps();
		printf("Error: first mmap() failed unexpectedly\n");
		return 1;
	}

	/*
	 * Exact same mapping again:
	 *   base |  free  | new
	 *     +1 | mapped | new
	 *     +2 | mapped | new
	 *     +3 | mapped | new
	 *     +4 |  free  | new
	 */
	errno = 0;
	addr = base_addr;
	size = 5 * page_size;
	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
	printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);

	if (p != MAP_FAILED) {
		dump_maps();
		printf("Error:1: mmap() succeeded when it shouldn't have\n");
		return 1;
	}

	/*
	 * Second mapping contained within first:
	 *
	 *   base |  free  |
	 *     +1 | mapped |
	 *     +2 | mapped | new
	 *     +3 | mapped |
	 *     +4 |  free  |
	 */
	errno = 0;
	addr = base_addr + (2 * page_size);
	size = page_size;
	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
	printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);

	if (p != MAP_FAILED) {
		dump_maps();
		printf("Error:2: mmap() succeeded when it shouldn't have\n");
		return 1;
	}

	/*
	 * Overlap end of existing mapping:
	 *   base |  free  |
	 *     +1 | mapped |
	 *     +2 | mapped |
	 *     +3 | mapped | new
	 *     +4 |  free  | new
	 */
	errno = 0;
	addr = base_addr + (3 * page_size);
	size = 2 * page_size;
	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
	printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);

	if (p != MAP_FAILED) {
		dump_maps();
		printf("Error:3: mmap() succeeded when it shouldn't have\n");
		return 1;
	}

	/*
	 * Overlap start of existing mapping:
	 *   base |  free  | new
	 *     +1 | mapped | new
	 *     +2 | mapped |
	 *     +3 | mapped |
	 *     +4 |  free  |
	 */
	errno = 0;
	addr = base_addr;
	size = 2 * page_size;
	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
	printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);

	if (p != MAP_FAILED) {
		dump_maps();
		printf("Error:4: mmap() succeeded when it shouldn't have\n");
		return 1;
	}

	/*
	 * Adjacent to start of existing mapping:
	 *   base |  free  | new
	 *     +1 | mapped |
	 *     +2 | mapped |
	 *     +3 | mapped |
	 *     +4 |  free  |
	 */
	errno = 0;
	addr = base_addr;
	size = page_size;
	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
	printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);

	if (p == MAP_FAILED) {
		dump_maps();
		printf("Error:5: mmap() failed when it shouldn't have\n");
		return 1;
	}

	/*
	 * Adjacent to end of existing mapping:
	 *   base |  free  |
	 *     +1 | mapped |
	 *     +2 | mapped |
	 *     +3 | mapped |
	 *     +4 |  free  |  new
	 */
	errno = 0;
	addr = base_addr + (4 * page_size);
	size = page_size;
	p = mmap((void *)addr, size, PROT_NONE, flags, -1, 0);
	printf("mmap() @ 0x%lx-0x%lx p=%p result=%m\n", addr, addr + size, p);

	if (p == MAP_FAILED) {
		dump_maps();
		printf("Error:6: mmap() failed when it shouldn't have\n");
		return 1;
	}

	addr = base_addr;
	size = 5 * page_size;
	if (munmap((void *)addr, size) != 0) {
		dump_maps();
		printf("Error: munmap failed!?\n");
		return 1;
	}
	printf("unmap() successful\n");

	printf("OK\n");
	return 0;
}
