/* Copyright (c) 2015-2016 Google Inc
 * Davide Libenzi <dlibenzi@google.com>
 * Barret Rhoden <brho@cs.berkeley.edu>
 * Stephane Eranian <eranian@gmail.com> (perf_show_event_info() from libpfm4)
 *
 * See LICENSE for details. */

#include <ros/arch/msr-index.h>
#include <ros/arch/perfmon.h>
#include <ros/common.h>
#include <ros/memops.h>
#include <sys/types.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <limits.h>
#include <errno.h>
#include <regex.h>
#include <parlib/parlib.h>
#include <perfmon/err.h>
#include <perfmon/pfmlib.h>
#include "xlib.h"
#include "perfconv.h"
#include "akaros.h"
#include "perf_core.h"
#include "elf.h"

struct perf_generic_event {
	char						*name;
	uint32_t					type;
	uint32_t					config;
};

struct perf_generic_event generic_events[] = {
	{ .name = "cycles",
	  .type = PERF_TYPE_HARDWARE,
	  .config = PERF_COUNT_HW_CPU_CYCLES,
	},
	{ .name = "cpu-cycles",
	  .type = PERF_TYPE_HARDWARE,
	  .config = PERF_COUNT_HW_CPU_CYCLES,
	},
	{ .name = "instructions",
	  .type = PERF_TYPE_HARDWARE,
	  .config = PERF_COUNT_HW_INSTRUCTIONS,
	},
	{ .name = "cache-references",
	  .type = PERF_TYPE_HARDWARE,
	  .config = PERF_COUNT_HW_CACHE_REFERENCES,
	},
	{ .name = "cache-misses",
	  .type = PERF_TYPE_HARDWARE,
	  .config = PERF_COUNT_HW_CACHE_MISSES,
	},
	{ .name = "branches",
	  .type = PERF_TYPE_HARDWARE,
	  .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS,
	},
	{ .name = "branch-instructions",
	  .type = PERF_TYPE_HARDWARE,
	  .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS,
	},
	{ .name = "branch-misses",
	  .type = PERF_TYPE_HARDWARE,
	  .config = PERF_COUNT_HW_BRANCH_MISSES,
	},
	{ .name = "bus-cycles",
	  .type = PERF_TYPE_HARDWARE,
	  .config = PERF_COUNT_HW_BUS_CYCLES,
	},
};

static const char *perf_get_event_mask_name(const pfm_event_info_t *einfo,
											uint32_t mask)
{
	int i;
	pfm_event_attr_info_t ainfo;

	ZERO_DATA(ainfo);
	ainfo.size = sizeof(ainfo);
	pfm_for_each_event_attr(i, einfo) {
		pfm_err_t err = pfm_get_event_attr_info(einfo->idx, i, PFM_OS_NONE,
												&ainfo);

		if (err != PFM_SUCCESS) {
			fprintf(stderr, "Failed to get attribute info: %s\n",
					pfm_strerror(err));
			exit(1);
		}
		if (ainfo.type == PFM_ATTR_UMASK) {
			if (mask == (uint32_t) ainfo.code)
				return ainfo.name;
		}
	}

	return NULL;
}

void perf_initialize(void)
{
	pfm_err_t err = pfm_initialize();

	if (err != PFM_SUCCESS) {
		fprintf(stderr, "Unable to initialize perfmon library: %s\n",
				pfm_strerror(err));
		exit(1);
	}
	symbol__elf_init();
}

void perf_finalize(void)
{
	pfm_terminate();
}

/* This is arch-specific and maybe model specific in the future.  For some
 * events, pfm4 gives us a pseudo encoding.  Those codes don't map to real
 * hardware events and are meant to be interpreted by Linux for *other* HW
 * events, e.g. in arch/x86/events/intel/core.c.
 *
 * While we're here, we can also take *real* encodings and treat them like
 * pseudo encodings.  For instance, the arch event 0x3c (unhalted_core_cycles)
 * can also be done with fixed counter 1.  This all assumes we have version 2 or
 * later of Intel's perfmon. */
static void x86_handle_pseudo_encoding(struct perf_eventsel *sel)
{
	uint8_t lower_byte;

	switch (sel->ev.event & 0xffff) {
	case 0xc0:	/* arch inst_retired */
		sel->ev.flags |= PERFMON_FIXED_EVENT;
		PMEV_SET_MASK(sel->ev.event, 0);
		PMEV_SET_EVENT(sel->ev.event, 0);
		return;
	case 0x3c:	/* arch unhalted_core_cycles */
		sel->ev.flags |= PERFMON_FIXED_EVENT;
		PMEV_SET_MASK(sel->ev.event, 0);
		PMEV_SET_EVENT(sel->ev.event, 1);
		return;
	case 0x13c:	/* arch unhalted_reference_cycles */
	case 0x300:	/* pseudo encode: unhalted_reference_cycles */
		sel->ev.flags |= PERFMON_FIXED_EVENT;
		PMEV_SET_MASK(sel->ev.event, 0);
		PMEV_SET_EVENT(sel->ev.event, 2);
		return;
	};
	lower_byte = sel->ev.event & 0xff;
	if ((lower_byte == 0x00) || (lower_byte == 0xff))
		fprintf(stderr, "Unhandled pseudo encoding %d\n", lower_byte);
}

/* Parse the string using pfm's lookup functions.  Returns TRUE on success and
 * fills in parts of sel. */
static bool parse_pfm_encoding(const char *str, struct perf_eventsel *sel)
{
	pfm_pmu_encode_arg_t encode;
	int err;
	char *ptr;

	memset(&encode, 0, sizeof(encode));
	encode.size = sizeof(encode);
	encode.fstr = &ptr;
	err = pfm_get_os_event_encoding(str, PFM_PLM3 | PFM_PLM0, PFM_OS_NONE,
	                                &encode);
	if (err)
		return FALSE;
	strlcpy(sel->fq_str, ptr, MAX_FQSTR_SZ);
	free(ptr);
	if (encode.count == 0) {
		fprintf(stderr, "Found event %s, but it had no codes!\n", sel->fq_str);
		return FALSE;
	}
	sel->ev.event = encode.codes[0];
	x86_handle_pseudo_encoding(sel);
	sel->type = PERF_TYPE_RAW;
	sel->config = PMEV_GET_MASK(sel->ev.event) | PMEV_GET_EVENT(sel->ev.event);
	return TRUE;
}

static bool is_end_of_raw(char c)
{
	return (c == ':') || (c == '\0');
}

/* Helper: given a string, if the event is a raw hex code, return its numeric
 * value.  Returns -1 if it does not match a raw code.
 *
 * rNN[N][N][:,\0].  Begins with r, has at least two hexdigits, up to 4, and
 * ends with : , or \0. */
static int extract_raw_code(const char *event)
{
	int i;
	char copy[5] = {0};

	if (event[0] != 'r')
		return -1;
	event++;
	for (i = 0; i < 4; i++) {
		if (isxdigit(event[i]))
			continue;
		if (is_end_of_raw(event[i]))
			break;
		return -1;
	}
	if (!is_end_of_raw(event[i]))
		return -1;
	/* 'i' tracks how many we found (i.e. every 'continue') */
	if (i < 2)
		return -1;
	/* need a null-terminated raw code for strtol. */
	for (int j = 0; j < i; j++)
		copy[j] = event[j];
	return strtol(copy, NULL, 16);
}

/* Takes any modifiers, e.g. u:k:etc, and sets the respective values in sel. */
static void parse_modifiers(const char *str, struct perf_eventsel *sel)
{
	char *dup_str, *tok, *tok_save = 0;

	dup_str = xstrdup(str);
	for (tok = strtok_r(dup_str, ":", &tok_save);
	     tok;
	     tok = strtok_r(NULL, ":", &tok_save)) {

		switch (tok[0]) {
		case 'u':
			PMEV_SET_USR(sel->ev.event, 1);
			break;
		case 'k':
			PMEV_SET_OS(sel->ev.event, 1);
			break;
		case 'e':
			PMEV_SET_EDGE(sel->ev.event, 1);
			break;
		case 'p':
			PMEV_SET_PC(sel->ev.event, 1);
			break;
		case 't':
			PMEV_SET_ANYTH(sel->ev.event, 1);
			break;
		case 'i':
			PMEV_SET_INVCMSK(sel->ev.event, 1);
			break;
		case 'c':
			if (tok[1] != '=') {
				fprintf(stderr, "Bad cmask tok %s, ignoring\n", tok);
				break;
			}
			errno = 0;
			PMEV_SET_CMASK(sel->ev.event, strtoul(&tok[2], NULL, 0));
			if (errno)
				fprintf(stderr, "Bad cmask tok %s, trying anyway\n", tok);
			break;
		}
	}
	free(dup_str);
}

/* Parse the string for a raw encoding.  Returns TRUE on success and fills in
 * parts of sel.  It has basic modifiers, like pfm4, for setting bits in the
 * event code.  This is arch specific, and is all x86 (intel) for now. */
static bool parse_raw_encoding(const char *str, struct perf_eventsel *sel)
{
	int code = extract_raw_code(str);
	char *colon;

	if (code == -1)
		return FALSE;
	sel->ev.event = code;
	strlcpy(sel->fq_str, str, MAX_FQSTR_SZ);
	colon = strchr(str, ':');
	if (colon)
		parse_modifiers(colon + 1, sel);
	/* Note that we do not call x86_handle_pseudo_encoding here.  We'll submit
	 * exactly what the user asked us for - which also means no fixed counters
	 * for them (unless we want a :f: token or something). */
	sel->type = PERF_TYPE_RAW;
	sel->config = PMEV_GET_MASK(sel->ev.event) | PMEV_GET_EVENT(sel->ev.event);
	return TRUE;
}

/* Helper, returns true is str is a generic event string, and fills in sel with
 * the type and config. */
static bool generic_str_get_code(const char *str, struct perf_eventsel *sel)
{
	char *colon = strchr(str, ':');
	/* if there was no :, we compare as far as we can.  generic_events.name is a
	 * string literal, so strcmp() is fine. */
	size_t len = colon ? colon - str : SIZE_MAX;

	for (int i = 0; i < COUNT_OF(generic_events); i++) {
		if (!strncmp(generic_events[i].name, str, len)) {
			sel->type = generic_events[i].type;
			sel->config = generic_events[i].config;
			return TRUE;
		}
	}
	return FALSE;
}

/* TODO: this is arch-specific and possibly machine-specific. (intel for now).
 * Basically a lot of our perf is arch-dependent. (e.g. PMEV_*). */
static bool arch_translate_generic(struct perf_eventsel *sel)
{
	switch (sel->type) {
	case PERF_TYPE_HARDWARE:
		/* These are the intel/x86 architectural perf events */
		switch (sel->config) {
		case PERF_COUNT_HW_CPU_CYCLES:
			PMEV_SET_MASK(sel->ev.event, 0x00);
			PMEV_SET_EVENT(sel->ev.event, 0x3c);
			break;
		case PERF_COUNT_HW_INSTRUCTIONS:
			PMEV_SET_MASK(sel->ev.event, 0x00);
			PMEV_SET_EVENT(sel->ev.event, 0xc0);
			break;
		case PERF_COUNT_HW_CACHE_REFERENCES:
			PMEV_SET_MASK(sel->ev.event, 0x4f);
			PMEV_SET_EVENT(sel->ev.event, 0x2e);
			break;
		case PERF_COUNT_HW_CACHE_MISSES:
			PMEV_SET_MASK(sel->ev.event, 0x41);
			PMEV_SET_EVENT(sel->ev.event, 0x2e);
			break;
		case PERF_COUNT_HW_BRANCH_INSTRUCTIONS:
			PMEV_SET_MASK(sel->ev.event, 0x00);
			PMEV_SET_EVENT(sel->ev.event, 0xc4);
			break;
		case PERF_COUNT_HW_BRANCH_MISSES:
			PMEV_SET_MASK(sel->ev.event, 0x00);
			PMEV_SET_EVENT(sel->ev.event, 0xc5);
			break;
		case PERF_COUNT_HW_BUS_CYCLES:
			/* Unhalted reference cycles */
			PMEV_SET_MASK(sel->ev.event, 0x01);
			PMEV_SET_EVENT(sel->ev.event, 0x3c);
			break;
		default:
			return FALSE;
		};
		break;
	default:
		return FALSE;
	};
	/* This will make sure we use fixed counters if available */
	x86_handle_pseudo_encoding(sel);
	return TRUE;
}

/* Parse the string for a built-in encoding.  These are the perf defaults such
 * as 'cycles' or 'cache-references.' Returns TRUE on success and fills in parts
 * of sel. */
static bool parse_generic_encoding(const char *str, struct perf_eventsel *sel)
{
	bool ret = FALSE;
	char *colon;

	if (!generic_str_get_code(str, sel))
		return FALSE;
	switch (sel->type) {
	case PERF_TYPE_HARDWARE:
	case PERF_TYPE_HW_CACHE:
		ret = arch_translate_generic(sel);
		break;
	};
	if (!ret) {
		fprintf(stderr, "Unsupported built-in event %s\n", str);
		return FALSE;
	}
	strlcpy(sel->fq_str, str, MAX_FQSTR_SZ);
	colon = strchr(str, ':');
	if (colon)
		parse_modifiers(colon + 1, sel);
	return TRUE;
}

/* Given an event description string, fills out sel with the info from the
 * string such that it can be submitted to the OS.
 *
 * The caller can set more bits if they like, such as whether or not to
 * interrupt on overflow, the sample_period, etc.  None of those settings are
 * part of the event string.
 *
 * Kills the program on failure. */
struct perf_eventsel *perf_parse_event(const char *str)
{
	struct perf_eventsel *sel = xzmalloc(sizeof(struct perf_eventsel));

	sel->ev.user_data = (uint64_t)sel;
	if (parse_generic_encoding(str, sel))
		goto success;
	if (parse_pfm_encoding(str, sel))
		goto success;
	if (parse_raw_encoding(str, sel))
		goto success;
	free(sel);
	fprintf(stderr, "Failed to parse event string %s\n", str);
	exit(-1);
success:
	if (!PMEV_GET_OS(sel->ev.event) && !PMEV_GET_USR(sel->ev.event)) {
		PMEV_SET_OS(sel->ev.event, 1);
		PMEV_SET_USR(sel->ev.event, 1);
	}
	PMEV_SET_EN(sel->ev.event, 1);
	return sel;
}

static void perf_get_arch_info(int perf_fd, struct perf_arch_info *pai)
{
	uint8_t cmdbuf[6 * sizeof(uint32_t)];
	const uint8_t *rptr = cmdbuf;

	cmdbuf[0] = PERFMON_CMD_CPU_CAPS;

	xpwrite(perf_fd, cmdbuf, 1, 0);
	xpread(perf_fd, cmdbuf, 6 * sizeof(uint32_t), 0);

	rptr = get_le_u32(rptr, &pai->perfmon_version);
	rptr = get_le_u32(rptr, &pai->proc_arch_events);
	rptr = get_le_u32(rptr, &pai->bits_x_counter);
	rptr = get_le_u32(rptr, &pai->counters_x_proc);
	rptr = get_le_u32(rptr, &pai->bits_x_fix_counter);
	rptr = get_le_u32(rptr, &pai->fix_counters_x_proc);
}

static int perf_open_event(int perf_fd, const struct core_set *cores,
						   const struct perf_eventsel *sel)
{
	uint8_t cmdbuf[1 + 3 * sizeof(uint64_t) + sizeof(uint32_t) +
				   CORE_SET_SIZE];
	uint8_t *wptr = cmdbuf;
	const uint8_t *rptr = cmdbuf;
	uint32_t ped;
	int i, j;

	*wptr++ = PERFMON_CMD_COUNTER_OPEN;
	wptr = put_le_u64(wptr, sel->ev.event);
	wptr = put_le_u64(wptr, sel->ev.flags);
	wptr = put_le_u64(wptr, sel->ev.trigger_count);
	wptr = put_le_u64(wptr, sel->ev.user_data);

	for (i = CORE_SET_SIZE - 1; (i >= 0) && !cores->core_set[i]; i--)
		;
	if (i < 0) {
		fprintf(stderr, "Performance event CPU set must not be empty\n");
		exit(1);
	}
	wptr = put_le_u32(wptr, i + 1);
	for (j = 0; j <= i; j++)
		*wptr++ = cores->core_set[j];

	xpwrite(perf_fd, cmdbuf, wptr - cmdbuf, 0);
	xpread(perf_fd, cmdbuf, sizeof(uint32_t), 0);

	rptr = get_le_u32(rptr, &ped);

	return (int) ped;
}

static uint64_t *perf_get_event_values(int perf_fd, int ped, size_t *pnvalues)
{
	ssize_t rsize;
	uint32_t i, n;
	uint64_t *values;
	uint64_t temp;
	size_t bufsize = sizeof(uint32_t) + MAX_NUM_CORES * sizeof(uint64_t);
	uint8_t *cmdbuf = xmalloc(bufsize);
	uint8_t *wptr = cmdbuf;
	const uint8_t *rptr = cmdbuf;

	*wptr++ = PERFMON_CMD_COUNTER_STATUS;
	wptr = put_le_u32(wptr, ped);

	xpwrite(perf_fd, cmdbuf, wptr - cmdbuf, 0);
	rsize = pread(perf_fd, cmdbuf, bufsize, 0);

	if (rsize < (sizeof(uint32_t))) {
		fprintf(stderr, "Invalid read size while fetching event status: %ld\n",
				rsize);
		exit(1);
	}
	rptr = get_le_u32(rptr, &n);
	if (((rptr - cmdbuf) + n * sizeof(uint64_t)) > rsize) {
		fprintf(stderr, "Invalid read size while fetching event status: %ld\n",
				rsize);
		exit(1);
	}
	values = xmalloc(n * sizeof(uint64_t));
	for (i = 0; i < n; i++)
		rptr = get_le_u64(rptr, values + i);
	free(cmdbuf);

	*pnvalues = n;

	return values;
}

/* Helper, returns the total count (across all cores) of the event @idx */
uint64_t perf_get_event_count(struct perf_context *pctx, unsigned int idx)
{
	uint64_t total = 0;
	size_t nvalues;
	uint64_t *values;

	values = perf_get_event_values(pctx->perf_fd, pctx->events[idx].ped,
	                               &nvalues);
	for (int i = 0; i < nvalues; i++)
		total += values[i];
	free(values);
	return total;
}

static void perf_close_event(int perf_fd, int ped)
{
	uint8_t cmdbuf[1 + sizeof(uint32_t)];
	uint8_t *wptr = cmdbuf;

	*wptr++ = PERFMON_CMD_COUNTER_CLOSE;
	wptr = put_le_u32(wptr, ped);

	xpwrite(perf_fd, cmdbuf, wptr - cmdbuf, 0);
}

struct perf_context *perf_create_context(struct perf_context_config *cfg)
{
	struct perf_context *pctx = xzmalloc(sizeof(struct perf_context));

	pctx->cfg = cfg;
	pctx->perf_fd = xopen(cfg->perf_file, O_RDWR, 0);
	/* perf record needs kpctl_fd, but other perf subcommands might not.  We'll
	 * delay the opening of kpctl until we need it, since kprof is picky about
	 * multiple users of kpctl. */
	pctx->kpctl_fd = -1;
	perf_get_arch_info(pctx->perf_fd, &pctx->pai);

	return pctx;
}

void perf_free_context(struct perf_context *pctx)
{
	if (pctx->kpctl_fd != -1)
		close(pctx->kpctl_fd);	/* disabled sampling */
	close(pctx->perf_fd);	/* closes all events */
	free(pctx);
}

void perf_context_event_submit(struct perf_context *pctx,
							   const struct core_set *cores,
							   const struct perf_eventsel *sel)
{
	struct perf_event *pevt = pctx->events + pctx->event_count;

	if (pctx->event_count >= COUNT_OF(pctx->events)) {
		fprintf(stderr, "Too many open events: %d\n", pctx->event_count);
		exit(1);
	}
	pctx->event_count++;
	pevt->cores = *cores;
	pevt->sel = *sel;
	pevt->ped = perf_open_event(pctx->perf_fd, cores, sel);
	if (pevt->ped < 0) {
		fprintf(stderr, "Unable to submit event \"%s\": %s\n", sel->fq_str,
		        errstr());
		exit(1);
	}
}

void perf_stop_events(struct perf_context *pctx)
{
	for (int i = 0; i < pctx->event_count; i++)
		perf_close_event(pctx->perf_fd, pctx->events[i].ped);
}

static void ensure_kpctl_is_open(struct perf_context *pctx)
{
	if (pctx->kpctl_fd == -1)
		pctx->kpctl_fd = xopen(pctx->cfg->kpctl_file, O_RDWR, 0);
}

void perf_start_sampling(struct perf_context *pctx)
{
	static const char * const enable_str = "start";

	ensure_kpctl_is_open(pctx);
	xwrite(pctx->kpctl_fd, enable_str, strlen(enable_str));
}

void perf_stop_sampling(struct perf_context *pctx)
{
	static const char * const disable_str = "stop";

	ensure_kpctl_is_open(pctx);
	xwrite(pctx->kpctl_fd, disable_str, strlen(disable_str));
}

void perf_context_show_events(struct perf_context *pctx, FILE *file)
{
	struct perf_eventsel *sel;

	for (int i = 0; i < pctx->event_count; i++) {
		sel = &pctx->events[i].sel;
		fprintf(file, "Event: %s, final code %p%s, trigger count %d\n",
		        sel->fq_str, sel->ev.event,
		        perfmon_is_fixed_event(&sel->ev) ? " (fixed)" : "",
		        sel->ev.trigger_count);
	}
}

static void perf_print_event_flags(const pfm_event_info_t *info, FILE *file)
{
	int n = 0;

	if (info->is_precise) {
		fputs("[precise] ", file);
		n++;
	}
	if (!n)
		fputs("None", file);
}

static void perf_print_attr_flags(const pfm_event_attr_info_t *info, FILE *file)
{
	int n = 0;

	if (info->is_dfl) {
		fputs("[default] ", file);
		n++;
	}
	if (info->is_precise) {
		fputs("[precise] ", file);
		n++;
	}
	if (!n)
		fputs("None ", file);
}

/* Ported from libpfm4 */
static void perf_show_event_info(const pfm_event_info_t *info,
								 const pfm_pmu_info_t *pinfo, FILE *file)
{
	static const char * const srcs[PFM_ATTR_CTRL_MAX] = {
		[PFM_ATTR_CTRL_UNKNOWN] = "???",
		[PFM_ATTR_CTRL_PMU] = "PMU",
		[PFM_ATTR_CTRL_PERF_EVENT] = "perf_event",
	};
	pfm_event_attr_info_t ainfo;
	int i, mod = 0, um = 0;

	fprintf(file, "#-----------------------------\n"
			"IDX      : %d\n"
			"PMU name : %s (%s)\n"
			"Name     : %s\n"
			"Equiv    : %s\n",
			info->idx, pinfo->name, pinfo->desc,
			info->name, info->equiv ? info->equiv : "None");

	fprintf(file, "Flags    : ");
	perf_print_event_flags(info, file);
	fputc('\n', file);

	fprintf(file, "Desc     : %s\n", info->desc ? info->desc :
			"no description available");
	fprintf(file, "Code     : 0x%"PRIx64"\n", info->code);

	ZERO_DATA(ainfo);
	ainfo.size = sizeof(ainfo);

	pfm_for_each_event_attr(i, info) {
		const char *src;
		pfm_err_t err = pfm_get_event_attr_info(info->idx, i, PFM_OS_NONE,
												&ainfo);

		if (err != PFM_SUCCESS) {
			fprintf(stderr, "Failed to get attribute info: %s\n",
					pfm_strerror(err));
			exit(1);
		}

		if (ainfo.ctrl >= PFM_ATTR_CTRL_MAX) {
			fprintf(stderr, "event: %s has unsupported attribute source %d",
					info->name, ainfo.ctrl);
			ainfo.ctrl = PFM_ATTR_CTRL_UNKNOWN;
		}
		src = srcs[ainfo.ctrl];
		switch (ainfo.type) {
			case PFM_ATTR_UMASK:
				fprintf(file, "Umask-%02u : 0x%02"PRIx64" : %s : [%s] : ",
						um, ainfo.code, src, ainfo.name);
				perf_print_attr_flags(&ainfo, file);
				fputc(':', file);
				if (ainfo.equiv)
					fprintf(file, " Alias to %s", ainfo.equiv);
				else
					fprintf(file, " %s", ainfo.desc);
				fputc('\n', file);
				um++;
				break;
			case PFM_ATTR_MOD_BOOL:
				fprintf(file, "Modif-%02u : 0x%02"PRIx64" : %s : [%s] : "
						"%s (boolean)\n", mod, ainfo.code, src, ainfo.name,
						ainfo.desc);
				mod++;
				break;
			case PFM_ATTR_MOD_INTEGER:
				fprintf(file, "Modif-%02u : 0x%02"PRIx64" : %s : [%s] : "
						"%s (integer)\n", mod, ainfo.code, src, ainfo.name,
						ainfo.desc);
				mod++;
				break;
			default:
				fprintf(file, "Attr-%02u  : 0x%02"PRIx64" : %s : [%s] : %s\n",
						i, ainfo.code, ainfo.name, src, ainfo.desc);
		}
	}
}

void perf_show_events(const char *rx, FILE *file)
{
	int pmu;
	regex_t crx;
	pfm_pmu_info_t pinfo;
	pfm_event_info_t info;
	char fullname[256];

	if (rx && regcomp(&crx, rx, REG_ICASE)) {
		fprintf(stderr, "Failed to compile event regex: '%s'\n", rx);
		exit(1);
	}

    ZERO_DATA(pinfo);
    pinfo.size = sizeof(pinfo);
    ZERO_DATA(info);
    info.size = sizeof(info);

	pfm_for_all_pmus(pmu) {
		pfm_err_t err = pfm_get_pmu_info(pmu, &pinfo);

		if (err != PFM_SUCCESS || !pinfo.is_present)
			continue;

		for (int i = pinfo.first_event; i != -1; i = pfm_get_event_next(i)) {
			err = pfm_get_event_info(i, PFM_OS_NONE, &info);
			if (err != PFM_SUCCESS) {
				fprintf(stderr, "Failed to get event info: %s\n",
						pfm_strerror(err));
				exit(1);
			}
			snprintf(fullname, sizeof(fullname), "%s::%s", pinfo.name,
					 info.name);
			if (!rx || regexec(&crx, fullname, 0, NULL, 0) == 0)
				perf_show_event_info(&info, &pinfo, file);
		}
	}
	if (rx)
		regfree(&crx);
}

void perf_convert_trace_data(struct perfconv_context *cctx, const char *input,
							 FILE *outfile)
{
	FILE *infile;
	size_t ksize;

	infile = xfopen(input, "rb");
	if (xfsize(infile) > 0) {
		perfconv_add_kernel_mmap(cctx);
		perfconv_add_kernel_buildid(cctx);
		perfconv_process_input(cctx, infile, outfile);
	}
	fclose(infile);
}
