/**
 * @file daemon/opd_trans.c
 * Processing the sample buffer
 *
 * @remark Copyright 2002 OProfile authors
 * @remark Read the file COPYING
 *
 * @author John Levon
 * @author Philippe Elie
 * Modified by Aravind Menon for Xen
 * These modifications are:
 * Copyright (C) 2005 Hewlett-Packard Co.
 *
 * Modified by Maynard Johnson <maynardj@us.ibm.com>
 * These modifications are:
 * (C) Copyright IBM Corporation 2007
 */

#include "opd_trans.h"
#include "opd_kernel.h"
#include "opd_sfile.h"
#include "opd_anon.h"
#include "opd_stats.h"
#include "opd_printf.h"
#include "opd_interface.h"
 
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <errno.h>

extern size_t kernel_pointer_size;


void clear_trans_last(struct transient * trans)
{
	trans->last = NULL;
	trans->last_anon = NULL;
}


void clear_trans_current(struct transient * trans)
{
	trans->current = NULL;
	trans->anon = NULL;
}


uint64_t pop_buffer_value(struct transient * trans)
{
	uint64_t val;

	if (!trans->remaining) {
		fprintf(stderr, "BUG: popping empty buffer !\n");
		abort();
	}

	if (kernel_pointer_size == 4) {
		uint32_t const * lbuf = (void const *)trans->buffer;
		val = *lbuf;
	} else {
		uint64_t const * lbuf = (void const *)trans->buffer;
		val = *lbuf;
	}

	trans->remaining--;
	trans->buffer += kernel_pointer_size;
	return val;
}


int enough_remaining(struct transient * trans, size_t size)
{
	if (trans->remaining >= size)
		return 1;

	verbprintf(vmisc, "Dangling ESCAPE_CODE.\n");
	opd_stats[OPD_DANGLING_CODE]++;
	return 0;
}


static void opd_put_sample(struct transient * trans, unsigned long long pc)
{
	unsigned long long event;

	if (!enough_remaining(trans, 1)) {
		trans->remaining = 0;
		return;
	}

	event = pop_buffer_value(trans);

	if (trans->tracing != TRACING_ON)
		trans->event = event;

	trans->pc = pc;

	/* sfile can change at each sample for kernel */
	if (trans->in_kernel != 0)
		clear_trans_current(trans);

	if (!trans->in_kernel && trans->cookie == NO_COOKIE)
		trans->anon = find_anon_mapping(trans);

	/* get the current sfile if needed */
	if (!trans->current)
		trans->current = sfile_find(trans);

	/*
	 * can happen if kernel sample falls through the cracks, or if
	 * it's a sample from an anon region we couldn't find
	 */
	if (!trans->current)
		goto out;

	/* FIXME: this logic is perhaps too harsh? */
	if (trans->current->ignored || (trans->last && trans->last->ignored))
		goto out;

	/* log the sample or arc */
	sfile_log_sample(trans);

out:
	/* switch to trace mode */
	if (trans->tracing == TRACING_START)
		trans->tracing = TRACING_ON;

	update_trans_last(trans);
}


static void code_unknown(struct transient * trans __attribute__((unused)))
{
	fprintf(stderr, "Unknown code !\n");
	abort();
}


static void code_ctx_switch(struct transient * trans)
{
	clear_trans_current(trans);

	if (!enough_remaining(trans, 5)) {
		trans->remaining = 0;
		return;
	}

	trans->tid = pop_buffer_value(trans);
	trans->app_cookie = pop_buffer_value(trans);
	/* must be ESCAPE_CODE, CTX_TGID_CODE, tgid. Like this
	 * because tgid was added later in a compatible manner.
	 */
	pop_buffer_value(trans);
	pop_buffer_value(trans);
	trans->tgid = pop_buffer_value(trans);

	if (vmisc) {
		char const * app = find_cookie(trans->app_cookie);
		printf("CTX_SWITCH to tid %lu, tgid %lu, cookie %llx(%s)\n",
		       (unsigned long)trans->tid, (unsigned long)trans->tgid,
		       trans->app_cookie, app ? app : "none");
	}
}


static void code_cpu_switch(struct transient * trans)
{
	clear_trans_current(trans);

	if (!enough_remaining(trans, 1)) {
		trans->remaining = 0;
		return;
	}

	trans->cpu = pop_buffer_value(trans);
	verbprintf(vmisc, "CPU_SWITCH to %lu\n", trans->cpu);
}


static void code_cookie_switch(struct transient * trans)
{
	clear_trans_current(trans);

	if (!enough_remaining(trans, 1)) {
		trans->remaining = 0;
		return;
	}

	trans->cookie = pop_buffer_value(trans);

	if (vmisc) {
		char const * name = verbose_cookie(trans->cookie);
		verbprintf(vmisc, "COOKIE_SWITCH to cookie %s(%llx)\n",
		           name, trans->cookie);
	}
}


static void code_kernel_enter(struct transient * trans)
{
	verbprintf(vmisc, "KERNEL_ENTER_SWITCH to kernel\n");
	trans->in_kernel = 1;
	clear_trans_current(trans);
	/* subtlety: we must keep trans->cookie cached,
	 * even though it's meaningless for the kernel -
	 * we won't necessarily get a cookie switch on
	 * kernel exit. See comments in opd_sfile.c
	 */
}


static void code_user_enter(struct transient * trans)
{
	verbprintf(vmisc, "USER_ENTER_SWITCH to user-space\n");
	trans->in_kernel = 0;
	clear_trans_current(trans);
	clear_trans_last(trans);
}


static void code_module_loaded(struct transient * trans __attribute__((unused)))
{
	verbprintf(vmodule, "MODULE_LOADED_CODE\n");
	opd_reread_module_info();
	clear_trans_current(trans);
	clear_trans_last(trans);
}


/*
 * This also implicitly signals the end of the previous
 * trace, so we never explicitly set TRACING_OFF when
 * processing a buffer.
 */
static void code_trace_begin(struct transient * trans)
{
	verbprintf(varcs, "TRACE_BEGIN\n");
	trans->tracing = TRACING_START;
}

static void code_xen_enter(struct transient * trans)
{
	verbprintf(vmisc, "XEN_ENTER_SWITCH to xen\n");
	trans->in_kernel = 1;
	trans->current = NULL;
	/* subtlety: we must keep trans->cookie cached, even though it's 
	 * meaningless for Xen - we won't necessarily get a cookie switch 
	 * on Xen exit. See comments in opd_sfile.c. It seems that we can 
	 * get away with in_kernel = 1 as long as we supply the correct 
	 * Xen image, and its address range in startup find_kernel_image 
	 * is modified to look in the Xen image also
	 */
}

extern void code_spu_profiling(struct transient * trans);
extern void code_spu_ctx_switch(struct transient * trans);

handler_t handlers[LAST_CODE + 1] = {
	&code_unknown,
	&code_ctx_switch,
	&code_cpu_switch,
	&code_cookie_switch,
	&code_kernel_enter,
 	&code_user_enter,
	&code_module_loaded,
	/* tgid handled differently */
	&code_unknown,
	&code_trace_begin,
	&code_unknown,
 	&code_xen_enter,
#if defined(__powerpc__)
	&code_spu_profiling,
	&code_spu_ctx_switch,
#endif
	&code_unknown,
};

extern void (*special_processor)(struct transient *);

void opd_process_samples(char const * buffer, size_t count)
{
	struct transient trans = {
		.buffer = buffer,
		.remaining = count,
		.tracing = TRACING_OFF,
		.current = NULL,
		.last = NULL,
		.cookie = INVALID_COOKIE,
		.app_cookie = INVALID_COOKIE,
		.anon = NULL,
		.last_anon = NULL,
		.pc = 0,
		.last_pc = 0,
		.event = 0,
		.in_kernel = -1,
		.cpu = -1,
		.tid = -1,
		.embedded_offset = UNUSED_EMBEDDED_OFFSET,
		.tgid = -1
	};

	/* FIXME: was uint64_t but it can't compile on alpha where uint64_t
	 * is an unsigned long and below the printf("..." %llu\n", code)
	 * generate a warning, this look like a stopper to use c98 types :/
	 */
	unsigned long long code;

	if (special_processor) {
		special_processor(&trans);
		return;
	}

    int i;

    for (i = 0; i < count && i < 200; i++) {
        verbprintf(vmisc, "buffer[%d] is %x\n", i, buffer[i]);
    }

	while (trans.remaining) {
		code = pop_buffer_value(&trans);

        verbprintf(vmisc, "In opd_process_samples (code is %lld)\n", code);

		if (!is_escape_code(code)) {
			opd_put_sample(&trans, code);
			continue;
		}

		if (!trans.remaining) {
			verbprintf(vmisc, "Dangling ESCAPE_CODE.\n");
			opd_stats[OPD_DANGLING_CODE]++;
			break;
		}

		// started with ESCAPE_CODE, next is type
		code = pop_buffer_value(&trans);
	
        verbprintf(vmisc, "next code is %lld\n", code);
		if (code >= LAST_CODE) {
			fprintf(stderr, "Unknown code %llu\n", code);
			abort();
		}

		handlers[code](&trans);
	}
}
