/**
 * @file opd_anon.c
 * Anonymous region handling.
 *
 * Our caching of maps has some problems: if we get tgid reuse,
 * and it's the same application, we might end up with wrong
 * maps. The same happens in an unmap-remap case. There's not much
 * we can do about this, we just hope it's not too common...
 *
 * What is relatively common is expanding anon maps, which leaves us
 * with lots of separate sample files.
 *
 * @remark Copyright 2005 OProfile authors
 * @remark Read the file COPYING
 *
 * @author John Levon
 * @Modifications Gisle Dankel
 */

#include "opd_anon.h"
#include "opd_trans.h"
#include "opd_sfile.h"
#include "opd_printf.h"
#include "op_libiberty.h"

#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define HASH_SIZE 1024
#define HASH_BITS (HASH_SIZE - 1)

/*
 * Note that this value is tempered by the fact that when we miss in the
 * anon cache, we'll tear down all the mappings for that tgid. Thus, LRU
 * of a mapping can potentially clear out a much larger number of
 * mappings.
 */
#define LRU_SIZE 8192
#define LRU_AMOUNT (LRU_SIZE/8)

static struct list_head hashes[HASH_SIZE];
static struct list_head lru;
static size_t nr_lru;

static void do_lru(struct transient * trans)
{
	size_t nr_to_kill = LRU_AMOUNT;
	struct list_head * pos;
	struct list_head * pos2;
	struct anon_mapping * entry;

	list_for_each_safe(pos, pos2, &lru) {
		entry = list_entry(pos, struct anon_mapping, lru_list);
		if (trans->anon == entry)
			clear_trans_current(trans);
		if (trans->last_anon == entry)
			clear_trans_last(trans);
		sfile_clear_anon(entry);
		list_del(&entry->list);
		list_del(&entry->lru_list);
		--nr_lru;
		free(entry);
		if (nr_to_kill-- == 0)
			break;
	}
}


static unsigned long hash_anon(pid_t tgid, cookie_t app)
{
	return ((app >> DCOOKIE_SHIFT) ^ (tgid >> 2)) & (HASH_SIZE - 1);
}
 

static void clear_anon_maps(struct transient * trans)
{
	unsigned long hash = hash_anon(trans->tgid, trans->app_cookie);
	pid_t tgid = trans->tgid;
	cookie_t app = trans->app_cookie;
	struct list_head * pos;
	struct list_head * pos2;
	struct anon_mapping * entry;

	clear_trans_current(trans);

	list_for_each_safe(pos, pos2, &hashes[hash]) {
		entry = list_entry(pos, struct anon_mapping, list);
		if (entry->tgid == tgid && entry->app_cookie == app) {
			if (trans->last_anon == entry)
				clear_trans_last(trans);
			sfile_clear_anon(entry);
			list_del(&entry->list);
			list_del(&entry->lru_list);
			--nr_lru;
			free(entry);
		}
	}

	if (vmisc) {
		char const * name = verbose_cookie(app);
		printf("Cleared anon maps for tgid %u (%s).\n", tgid, name);
	}
}


static void
add_anon_mapping(struct transient * trans, vma_t start, vma_t end, char * name)
{
	unsigned long hash = hash_anon(trans->tgid, trans->app_cookie);
	struct anon_mapping * m = xmalloc(sizeof(struct anon_mapping));
	m->tgid = trans->tgid;
	m->app_cookie = trans->app_cookie;
	m->start = start;
	m->end = end;
	strncpy(m->name, name, MAX_IMAGE_NAME_SIZE);
	list_add_tail(&m->list, &hashes[hash]);
	list_add_tail(&m->lru_list, &lru);
	if (++nr_lru == LRU_SIZE)
		do_lru(trans);
	if (vmisc) {
		char const * name = verbose_cookie(m->app_cookie);
		printf("Added anon map 0x%llx-0x%llx for tgid %u (%s).\n",
		       start, end, m->tgid, name);
	}
}


/* 42000000-4212f000 r-xp 00000000 16:03 424334 /lib/tls/libc-2.3.2.so */
static void get_anon_maps(struct transient * trans)
{
	FILE * fp = NULL;
	char buf[PATH_MAX];
	vma_t start, end;
	int ret;

	snprintf(buf, PATH_MAX, "/proc/%d/maps", trans->tgid);
	fp = fopen(buf, "r");
	if (!fp)
		return;

	while (fgets(buf, PATH_MAX, fp) != NULL) {
		char tmp[MAX_IMAGE_NAME_SIZE + 1];
		char name[MAX_IMAGE_NAME_SIZE + 1];
		/* Some anon maps have labels like
		 * [heap], [stack], [vdso], [vsyscall] ...
		 * Keep track of these labels. If a map has no name, call it "anon".
		 * Ignore all mappings starting with "/" (file or shared memory object)
		 */
		strcpy(name, "anon");
		ret = sscanf(buf, "%llx-%llx %20s %20s %20s %20s %20s",
		             &start, &end, tmp, tmp, tmp, tmp, name);
		if (ret < 6 || name[0] == '/')
			continue;

		add_anon_mapping(trans, start, end, name);
	}

	fclose(fp);
}


static int
anon_match(struct transient const * trans, struct anon_mapping const * anon)
{
	if (!anon)
		return 0;
	if (trans->tgid != anon->tgid)
		return 0;
	if (trans->app_cookie != anon->app_cookie)
		return 0;
	if (trans->pc < anon->start)
		return 0;
	return (trans->pc < anon->end);
}


struct anon_mapping * find_anon_mapping(struct transient * trans)
{
	unsigned long hash = hash_anon(trans->tgid, trans->app_cookie);
	struct list_head * pos;
	struct anon_mapping * entry;
	int tried = 0;

	if (anon_match(trans, trans->anon))
		return (trans->anon);

retry:
	list_for_each(pos, &hashes[hash]) {
		entry = list_entry(pos, struct anon_mapping, list);
		if (anon_match(trans, entry))
			goto success;
	}

	if (!tried) {
		clear_anon_maps(trans);
		get_anon_maps(trans);
		tried = 1;
		goto retry;
	}

	return NULL;

success:
	/*
	 * Typically, there's one big mapping that matches. Let's go
	 * faster.
	 */
	list_del(&entry->list);
	list_add(&entry->list, &hashes[hash]);

	verbprintf(vmisc, "Found range 0x%llx-0x%llx for tgid %u, pc %llx.\n",
	           entry->start, entry->end, (unsigned int)entry->tgid,
		   trans->pc);
	return entry;
}


void anon_init(void)
{
	size_t i;

	for (i = 0; i < HASH_SIZE; ++i)
		list_init(&hashes[i]);

	list_init(&lru);
}
