/* 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 <parlib/core_set.h>
#include <perfmon/err.h>
#include <perfmon/pfmlib.h>
#include "xlib.h"
#include "perfconv.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) << 8) |
	              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) << 8) |
	              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);
}
