/*
 * Copyright (c) 2013 Luca Clementi <luca.clementi@gmail.com>
 * Copyright (c) 2013-2018 The strace developers.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "defs.h"
#include <limits.h>

#include "largefile_wrappers.h"
#include "mmap_cache.h"
#include "mmap_notify.h"
#include "xstring.h"

static unsigned int mmap_cache_generation;

static void
mmap_cache_invalidate(struct tcb *tcp, void *unused)
{
#if SUPPORTED_PERSONALITIES > 1
	if (tcp->currpers != DEFAULT_PERSONALITY) {
		/* disable stack trace */
		return;
	}
#endif
	mmap_cache_generation++;
	debug_func_msg("tgen=%u, ggen=%u, tcp=%p, cache=%p",
		       tcp->mmap_cache ? tcp->mmap_cache->generation : 0,
		       mmap_cache_generation, tcp,
		       tcp->mmap_cache ? tcp->mmap_cache->entry : 0);
}

void
mmap_cache_enable(void)
{
	static bool use_mmap_cache;

	if (!use_mmap_cache) {
		mmap_notify_register_client(mmap_cache_invalidate, NULL);
		use_mmap_cache = true;
	}
}

/* deleting the cache */
static void
delete_mmap_cache(struct tcb *tcp, const char *caller)
{
	debug_func_msg("tgen=%u, ggen=%u, tcp=%p, cache=%p, caller=%s",
		       tcp->mmap_cache ? tcp->mmap_cache->generation : 0,
		       mmap_cache_generation, tcp,
		       tcp->mmap_cache ? tcp->mmap_cache->entry : 0, caller);

	if (!tcp->mmap_cache)
		return;

	while (tcp->mmap_cache->size) {
		unsigned int i = --tcp->mmap_cache->size;
		free(tcp->mmap_cache->entry[i].binary_filename);
		tcp->mmap_cache->entry[i].binary_filename = NULL;
	}

	free(tcp->mmap_cache->entry);
	tcp->mmap_cache->entry = NULL;

	free(tcp->mmap_cache);
	tcp->mmap_cache = NULL;
}

/*
 * caching of /proc/ID/maps for each process to speed up stack tracing
 *
 * The cache must be refreshed after syscalls that affect memory mappings,
 * e.g. mmap, mprotect, munmap, execve.
 */
extern enum mmap_cache_rebuild_result
mmap_cache_rebuild_if_invalid(struct tcb *tcp, const char *caller)
{
	if (tcp->mmap_cache
	    && tcp->mmap_cache->generation != mmap_cache_generation)
		delete_mmap_cache(tcp, caller);

	if (tcp->mmap_cache)
		return MMAP_CACHE_REBUILD_READY;

	char filename[sizeof("/proc/4294967296/maps")];
	xsprintf(filename, "/proc/%u/maps", tcp->pid);

	FILE *fp = fopen_stream(filename, "r");
	if (!fp) {
		perror_msg("fopen: %s", filename);
		return MMAP_CACHE_REBUILD_NOCACHE;
	}

	struct mmap_cache_t cache = {
		.free_fn = delete_mmap_cache,
		.generation = mmap_cache_generation
	};

	/* start with a small dynamically-allocated array and then expand it */
	size_t allocated = 0;
	char buffer[PATH_MAX + 80];

	while (fgets(buffer, sizeof(buffer), fp) != NULL) {
		unsigned long start_addr, end_addr, mmap_offset;
		char read_bit;
		char write_bit;
		char exec_bit;
		char shared_bit;
		unsigned long major, minor;
		char binary_path[sizeof(buffer)];

		if (sscanf(buffer, "%lx-%lx %c%c%c%c %lx %lx:%lx %*d %[^\n]",
			   &start_addr, &end_addr,
			   &read_bit, &write_bit, &exec_bit, &shared_bit,
			   &mmap_offset,
			   &major, &minor,
			   binary_path) != 10)
			continue;

		/* skip mappings that have unknown protection */
		if (!(read_bit == '-' || read_bit == 'r'))
			continue;
		if (!(write_bit == '-' || write_bit == 'w'))
			continue;
		if (!(exec_bit == '-' || exec_bit == 'x'))
			continue;
		if (!(shared_bit == 'p' || shared_bit == 's'))
			continue;

		if (end_addr < start_addr) {
			error_msg("%s: unrecognized file format", filename);
			break;
		}

		struct mmap_cache_entry_t *entry;
		/*
		 * sanity check to make sure that we're storing
		 * non-overlapping regions in ascending order
		 */
		if (cache.size > 0) {
			entry = &cache.entry[cache.size - 1];
			if (entry->start_addr == start_addr &&
			    entry->end_addr == end_addr) {
				/* duplicate entry, e.g. [vsyscall] */
				continue;
			}
			if (start_addr <= entry->start_addr ||
			    start_addr < entry->end_addr) {
				debug_msg("%s: overlapping memory region: "
					  "\"%s\" [%08lx-%08lx] overlaps with "
					  "\"%s\" [%08lx-%08lx]",
					  filename, binary_path, start_addr,
					  end_addr, entry->binary_filename,
					  entry->start_addr, entry->end_addr);
				continue;
			}
		}

		if (cache.size >= allocated)
			cache.entry = xgrowarray(cache.entry, &allocated,
						 sizeof(*cache.entry));

		entry = &cache.entry[cache.size];
		entry->start_addr = start_addr;
		entry->end_addr = end_addr;
		entry->mmap_offset = mmap_offset;
		entry->protections = (
			0
			| ((read_bit   == 'r')? MMAP_CACHE_PROT_READABLE  : 0)
			| ((write_bit  == 'w')? MMAP_CACHE_PROT_WRITABLE  : 0)
			| ((exec_bit   == 'x')? MMAP_CACHE_PROT_EXECUTABLE: 0)
			| ((shared_bit == 's')? MMAP_CACHE_PROT_SHARED    : 0)
			);
		entry->major = major;
		entry->minor = minor;
		entry->binary_filename = xstrdup(binary_path);
		cache.size++;
	}
	fclose(fp);

	if (!cache.size)
		return MMAP_CACHE_REBUILD_NOCACHE;

	tcp->mmap_cache = xmalloc(sizeof(*tcp->mmap_cache));
	memcpy(tcp->mmap_cache, &cache, sizeof(cache));

	debug_func_msg("tgen=%u, ggen=%u, tcp=%p, cache=%p, caller=%s",
		       tcp->mmap_cache->generation, mmap_cache_generation,
		       tcp, tcp->mmap_cache->entry, caller);

	return MMAP_CACHE_REBUILD_RENEWED;
}

struct mmap_cache_entry_t *
mmap_cache_search(struct tcb *tcp, unsigned long ip)
{
	if (!tcp->mmap_cache)
		return NULL;

	int lower = 0;
	int upper = (int) tcp->mmap_cache->size - 1;

	while (lower <= upper) {
		int mid = (upper + lower) / 2;
		struct mmap_cache_entry_t *entry = &tcp->mmap_cache->entry[mid];

		if (ip >= entry->start_addr &&
		    ip < entry->end_addr)
			return entry;
		else if (ip < entry->start_addr)
			upper = mid - 1;
		else
			lower = mid + 1;
	}
	return NULL;
}
