/*
 * Copyright (c) 2017-2018, Intel Corporation
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  * Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *  * 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.
 *  * Neither the name of Intel Corporation nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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 "libipt-sb.h"

#include "intel-pt.h"


#ifndef FEATURE_PEVENT

int pt_sb_alloc_pevent_decoder(struct pt_sb_session *session,
			       const struct pt_sb_pevent_config *config)
{
	(void) session;
	(void) config;

	return -pte_not_supported;
}

#else /* FEATURE_PEVENT */

#include "pt_sb_pevent.h"
#include "pt_sb_session.h"
#include "pt_sb_context.h"
#include "pt_sb_file.h"
#include "pt_compiler.h"

#include <inttypes.h>
#include <stdlib.h>
#include <string.h>

#if defined(_MSC_VER) && (_MSC_VER < 1900)
#  define snprintf _snprintf_c
#endif


#ifndef FEATURE_ELF

static int elf_get_abi(FILE *file)
{
	if (!file)
		return -pte_internal;

	return pt_sb_abi_unknown;
}

#else /* FEATURE_ELF */

#include <elf.h>


static int elf_get_abi(FILE *file)
{
	uint8_t e_ident[EI_NIDENT];
	size_t count;
	int status;

	if (!file)
		return -pte_internal;

	status = fseek(file, 0, SEEK_SET);
	if (status < 0)
		return pt_sb_abi_unknown;

	count = fread(e_ident, sizeof(e_ident), 1, file);
	if (count != 1)
		return pt_sb_abi_unknown;

	status = memcmp(e_ident, ELFMAG, SELFMAG);
	if (status != 0)
		return pt_sb_abi_unknown;

	if (e_ident[EI_VERSION] != EV_CURRENT)
		return pt_sb_abi_unknown;

	switch (e_ident[EI_CLASS]) {
	default:
		break;

	case ELFCLASS64:
		return pt_sb_abi_x64;

	case ELFCLASS32: {
		Elf32_Ehdr ehdr;

		status = fseek(file, 0, SEEK_SET);
		if (status < 0)
			break;

		count = fread(&ehdr, sizeof(ehdr), 1, file);
		if (count != 1)
			break;

		switch (ehdr.e_machine) {
		default:
			break;

		case EM_386:
			return pt_sb_abi_ia32;

		case EM_X86_64:
			return pt_sb_abi_x32;
		}
	}
		break;
	}

	return pt_sb_abi_unknown;
}

#endif /* FEATURE_ELF */

static int pt_sb_pevent_error(const struct pt_sb_session *session, int errcode,
			      const struct pt_sb_pevent_priv *priv)
{
	const char *filename;
	uint64_t offset;

	filename = NULL;
	offset = 0ull;

	if (priv) {
		const uint8_t *pos, *begin;

		pos = priv->current;
		if (!pos)
			pos = priv->next;

		begin = priv->begin;
		if (pos < begin)
			return -pte_internal;

		filename = priv->filename;
		offset = (uint64_t) (int64_t) (pos - begin);
	}

	return pt_sb_error(session, errcode, filename, offset);
}

static int pt_sb_pevent_track_abi(struct pt_sb_context *context,
				  const char *filename)
{
	FILE *file;
	int abi;

	if (!context || !filename)
		return -pte_internal;

	if (context->abi)
		return 0;

	file = fopen(filename, "rb");
	if (!file)
		return 0;

	abi = elf_get_abi(file);

	fclose(file);

	if (abi < 0)
		return abi;

	context->abi = (enum pt_sb_abi) abi;

	return 0;
}

static int pt_sb_pevent_find_vdso(const char **pvdso,
				  const struct pt_sb_pevent_priv *priv,
				  const struct pt_sb_context *context)
{
	const char *vdso;

	if (!pvdso || !priv || !context)
		return -pte_internal;

	vdso = NULL;

	switch (context->abi) {
	case pt_sb_abi_unknown:
		break;

	case pt_sb_abi_x64:
		vdso = priv->vdso_x64;
		break;

	case pt_sb_abi_x32:
		vdso = priv->vdso_x32;
		break;

	case pt_sb_abi_ia32:
		vdso = priv->vdso_ia32;
		break;
	}

	if (!vdso)
		return -pte_bad_config;

	*pvdso = vdso;

	return 0;
}

static void pt_sb_pevent_dtor(void *priv_arg)
{
	struct pt_sb_pevent_priv *priv;
	struct pt_sb_context *context;

	priv = (struct pt_sb_pevent_priv *) priv_arg;
	if (!priv)
		return;

	context = priv->next_context;
	if (context)
		pt_sb_ctx_put(context);

	context = priv->context;
	if (context)
		pt_sb_ctx_put(context);

	free(priv->filename);
	free(priv->sysroot);
	free(priv->vdso_x64);
	free(priv->vdso_x32);
	free(priv->vdso_ia32);
	free(priv->begin);
	free(priv);
}

static int pt_sb_pevent_init_path(char **dst, const char *src)
{
	size_t len;
	char *copy;

	if (!dst)
		return -pte_internal;

	if (!src) {
		*dst = NULL;
		return 0;
	}

	len = strnlen(src, FILENAME_MAX);
	if (len == FILENAME_MAX)
		return -pte_invalid;

	len += 1;
	copy = malloc(len);
	if (!copy)
		return -pte_nomem;

	memcpy(copy, src, len);

	*dst = copy;

	return 0;
}

int pt_sb_pevent_init(struct pt_sb_pevent_priv *priv,
		      const struct pt_sb_pevent_config *config)
{
	const char *filename;
	size_t size;
	void *buffer;
	int errcode;

	if (!priv || !config)
		return -pte_internal;

	/* This is the first version - we need all the fields. */
	if (config->size < sizeof(*config))
		return -pte_invalid;

	filename = config->filename;
	if (!filename)
		return -pte_invalid;

	buffer = NULL;
	size = 0;
	errcode = pt_sb_file_load(&buffer, &size, filename,
				  config->begin, config->end);
	if (errcode < 0)
		return errcode;

	memset(priv, 0, sizeof(*priv));
	priv->begin = (uint8_t *) buffer;
	priv->end = (uint8_t *) buffer + size;
	priv->next = (uint8_t *) buffer;

	errcode = pt_sb_pevent_init_path(&priv->filename, filename);
	if (errcode < 0) {
		pt_sb_pevent_dtor(priv);
		return errcode;
	}

	errcode = pt_sb_pevent_init_path(&priv->sysroot, config->sysroot);
	if (errcode < 0) {
		pt_sb_pevent_dtor(priv);
		return errcode;
	}

	errcode = pt_sb_pevent_init_path(&priv->vdso_x64, config->vdso_x64);
	if (errcode < 0) {
		pt_sb_pevent_dtor(priv);
		return errcode;
	}

	errcode = pt_sb_pevent_init_path(&priv->vdso_x32, config->vdso_x32);
	if (errcode < 0) {
		pt_sb_pevent_dtor(priv);
		return errcode;
	}

	errcode = pt_sb_pevent_init_path(&priv->vdso_ia32, config->vdso_ia32);
	if (errcode < 0) {
		pt_sb_pevent_dtor(priv);
		return errcode;
	}

	pev_config_init(&priv->pev);
	priv->pev.sample_type = config->sample_type;
	priv->pev.time_shift = config->time_shift;
	priv->pev.time_mult = config->time_mult;
	priv->pev.time_zero = config->time_zero;

	priv->kernel_start = config->kernel_start;
	priv->tsc_offset = config->tsc_offset;
	priv->location = ploc_unknown;

	return 0;
}

static int pt_sb_pevent_fetch(uint64_t *ptsc, struct pt_sb_pevent_priv *priv)
{
	struct pev_event *event;
	const uint8_t *pos;
	uint64_t tsc, offset;
	int size;

	if (!ptsc || !priv)
		return -pte_internal;

	pos = priv->next;
	event = &priv->event;

	/* Consume the current record early so we get the offset right when
	 * diagnosing fetch errors.
	 */
	priv->current = pos;

	size = pev_read(event, pos, priv->end, &priv->pev);
	if (size < 0)
		return size;

	priv->next = pos + size;

	/* If we don't have a time sample, set @ptsc to zero to process the
	 * record immediately.
	 */
	if (!event->sample.time) {
		*ptsc = 0ull;
		return 0;
	}

	/* Subtract a pre-defined offset to cause sideband events from this
	 * channel to be applied a little earlier.
	 *
	 * We don't want @tsc to wrap around when subtracting @offset, though.
	 * This would suddenly push the event very far out and essentially block
	 * this sideband channel.
	 *
	 * On the other hand, we want to allow 'negative' offsets.  And for
	 * those, we want to avoid wrapping around in the other direction.
	 */
	offset = priv->tsc_offset;
	tsc = event->sample.tsc;
	if (offset <= tsc)
		tsc -= offset;
	else {
		if (0ll <= (int64_t) offset)
			tsc = 0ull;
		else {
			if (tsc <= offset)
				tsc -= offset;
			else
				tsc = UINT64_MAX;
		}
	}

	/* We update the event record's timestamp, as well, so we will print the
	 * updated tsc and apply the event at the right time.
	 *
	 * Note that we only update our copy in @priv, not the sideband stream.
	 */
	event->sample.tsc = tsc;
	*ptsc = tsc;

	return 0;
}

static int pt_sb_pevent_print_event(const struct pev_event *event,
				    FILE *stream, uint32_t flags)
{
	if (!event)
		return -pte_internal;

	switch (event->type) {
	default:
		if (flags & ptsbp_compact)
			fprintf(stream, "UNKNOWN (%x, %x)", event->type,
				event->misc);

		if (flags & ptsbp_verbose) {
			fprintf(stream, "UNKNOWN");
			fprintf(stream, "\n  type: %x", event->type);
			fprintf(stream, "\n  misc: %x", event->misc);
		}

		break;

	case PERF_RECORD_MMAP: {
		const struct pev_record_mmap *mmap;

		mmap = event->record.mmap;
		if (!mmap)
			return -pte_bad_packet;

		if (flags & ptsbp_compact)
			fprintf(stream, "PERF_RECORD_MMAP  %x/%x, %" PRIx64
				", %" PRIx64 ", %" PRIx64 ", %s",
				mmap->pid, mmap->tid, mmap->addr, mmap->len,
				mmap->pgoff, mmap->filename);

		if (flags & ptsbp_verbose) {
			fprintf(stream, "PERF_RECORD_MMAP");
			fprintf(stream, "\n  pid: %x", mmap->pid);
			fprintf(stream, "\n  tid: %x", mmap->tid);
			fprintf(stream, "\n  addr: %" PRIx64, mmap->addr);
			fprintf(stream, "\n  len: %" PRIx64, mmap->len);
			fprintf(stream, "\n  pgoff: %" PRIx64, mmap->pgoff);
			fprintf(stream, "\n  filename: %s", mmap->filename);
		}
	}
		break;

	case PERF_RECORD_LOST: {
		const struct pev_record_lost *lost;

		lost = event->record.lost;
		if (!lost)
			return -pte_bad_packet;

		if (flags & ptsbp_compact)
			fprintf(stream, "PERF_RECORD_LOST  %" PRIx64 ", %"
				PRIx64, lost->id, lost->lost);

		if (flags & ptsbp_verbose) {
			fprintf(stream, "PERF_RECORD_LOST");
			fprintf(stream, "\n  id: %" PRIx64, lost->id);
			fprintf(stream, "\n  lost: %" PRIx64, lost->lost);
		}
	}
		break;

	case PERF_RECORD_COMM: {
		const struct pev_record_comm *comm;
		const char *sfx;

		comm = event->record.comm;
		if (!comm)
			return -pte_bad_packet;

		sfx = event->misc & PERF_RECORD_MISC_COMM_EXEC ? ".EXEC" : "";

		if (flags & ptsbp_compact)
			fprintf(stream, "PERF_RECORD_COMM%s  %x/%x, %s", sfx,
				comm->pid, comm->tid, comm->comm);

		if (flags & ptsbp_verbose) {
			fprintf(stream, "PERF_RECORD_COMM%s", sfx);
			fprintf(stream, "\n  pid: %x", comm->pid);
			fprintf(stream, "\n  tid: %x", comm->tid);
			fprintf(stream, "\n  comm: %s", comm->comm);
		}
	}
		break;

	case PERF_RECORD_EXIT: {
		const struct pev_record_exit *exit;

		exit = event->record.exit;
		if (!exit)
			return -pte_bad_packet;

		if (flags & ptsbp_compact)
			fprintf(stream, "PERF_RECORD_EXIT  %x/%x, %x/%x, %"
				PRIx64, exit->pid, exit->tid, exit->ppid,
				exit->ptid, exit->time);

		if (flags & ptsbp_verbose) {
			fprintf(stream, "PERF_RECORD_EXIT");
			fprintf(stream, "\n  pid: %x", exit->pid);
			fprintf(stream, "\n  ppid: %x", exit->ppid);
			fprintf(stream, "\n  tid: %x", exit->tid);
			fprintf(stream, "\n  ptid: %x", exit->ptid);
			fprintf(stream, "\n  time: %" PRIx64, exit->time);
		}
	}
		break;

	case PERF_RECORD_THROTTLE: {
		const struct pev_record_throttle *throttle;

		throttle = event->record.throttle;
		if (!throttle)
			return -pte_bad_packet;

		if (flags & ptsbp_compact)
			fprintf(stream, "PERF_RECORD_THROTTLE  %" PRIx64 ", %"
				PRIx64 ", %" PRIx64, throttle->time,
				throttle->id, throttle->stream_id);

		if (flags & ptsbp_verbose) {
			fprintf(stream, "PERF_RECORD_THROTTLE");
			fprintf(stream, "\n  time: %" PRIx64, throttle->time);
			fprintf(stream, "\n  id: %" PRIx64, throttle->id);
			fprintf(stream, "\n  stream_id: %" PRIx64,
				throttle->stream_id);
		}
	}
		break;

	case PERF_RECORD_UNTHROTTLE: {
		const struct pev_record_throttle *throttle;

		throttle = event->record.throttle;
		if (!throttle)
			return -pte_bad_packet;

		if (flags & ptsbp_compact)
			fprintf(stream, "PERF_RECORD_UNTHROTTLE  %" PRIx64
				", %" PRIx64 ", %" PRIx64, throttle->time,
				throttle->id, throttle->stream_id);

		if (flags & ptsbp_verbose) {
			fprintf(stream, "PERF_RECORD_UNTHROTTLE");
			fprintf(stream, "\n  time: %" PRIx64, throttle->time);
			fprintf(stream, "\n  id: %" PRIx64, throttle->id);
			fprintf(stream, "\n  stream_id: %" PRIx64,
				throttle->stream_id);
		}
	}
		break;

	case PERF_RECORD_FORK: {
		const struct pev_record_fork *fork;

		fork = event->record.fork;
		if (!fork)
			return -pte_bad_packet;

		if (flags & ptsbp_compact)
			fprintf(stream, "PERF_RECORD_FORK  %x/%x, %x/%x, %"
				PRIx64, fork->pid, fork->tid, fork->ppid,
				fork->ptid, fork->time);

		if (flags & ptsbp_verbose) {
			fprintf(stream, "PERF_RECORD_FORK");
			fprintf(stream, "\n  pid: %x", fork->pid);
			fprintf(stream, "\n  ppid: %x", fork->ppid);
			fprintf(stream, "\n  tid: %x", fork->tid);
			fprintf(stream, "\n  ptid: %x", fork->ptid);
			fprintf(stream, "\n  time: %" PRIx64, fork->time);
		}
	}
		break;

	case PERF_RECORD_MMAP2: {
		const struct pev_record_mmap2 *mmap2;

		mmap2 = event->record.mmap2;
		if (!mmap2)
			return -pte_bad_packet;

		if (flags & ptsbp_compact)
			fprintf(stream, "PERF_RECORD_MMAP2  %x/%x, %" PRIx64
				", %" PRIx64 ", %" PRIx64 ", %x, %x, %" PRIx64
				", %" PRIx64 ", %x, %x, %s", mmap2->pid,
				mmap2->tid, mmap2->addr, mmap2->len,
				mmap2->pgoff, mmap2->maj, mmap2->min,
				mmap2->ino, mmap2->ino_generation, mmap2->prot,
				mmap2->flags, mmap2->filename);

		if (flags & ptsbp_verbose) {
			fprintf(stream, "PERF_RECORD_MMAP2");
			fprintf(stream, "\n  pid: %x", mmap2->pid);
			fprintf(stream, "\n  tid: %x", mmap2->tid);
			fprintf(stream, "\n  addr: %" PRIx64, mmap2->addr);
			fprintf(stream, "\n  len: %" PRIx64, mmap2->len);
			fprintf(stream, "\n  pgoff: %" PRIx64, mmap2->pgoff);
			fprintf(stream, "\n  maj: %x", mmap2->maj);
			fprintf(stream, "\n  min: %x", mmap2->min);
			fprintf(stream, "\n  ino: %" PRIx64, mmap2->ino);
			fprintf(stream, "\n  ino_generation: %" PRIx64,
				mmap2->ino_generation);
			fprintf(stream, "\n  prot: %x", mmap2->prot);
			fprintf(stream, "\n  flags: %x", mmap2->flags);
			fprintf(stream, "\n  filename: %s", mmap2->filename);
		}
	}
		break;

	case PERF_RECORD_AUX: {
		const struct pev_record_aux *aux;
		const char *sfx;

		aux = event->record.aux;
		if (!aux)
			return -pte_bad_packet;

		sfx = aux->flags & PERF_AUX_FLAG_TRUNCATED ? ".TRUNCATED" : "";

		if (flags & ptsbp_compact)
			fprintf(stream, "PERF_RECORD_AUX%s  %" PRIx64 ", %"
				PRIx64 ", %" PRIx64, sfx, aux->aux_offset,
				aux->aux_size, aux->flags);

		if (flags & ptsbp_verbose) {
			fprintf(stream, "PERF_RECORD_AUX%s", sfx);
			fprintf(stream, "\n  aux offset: %" PRIx64,
				aux->aux_offset);
			fprintf(stream, "\n  aux size: %" PRIx64,
				aux->aux_size);
			fprintf(stream, "\n  flags: %" PRIx64, aux->flags);
		}
	}
		break;

	case PERF_RECORD_ITRACE_START: {
		const struct pev_record_itrace_start *itrace_start;

		itrace_start = event->record.itrace_start;
		if (!itrace_start)
			return -pte_bad_packet;

		if (flags & ptsbp_compact)
			fprintf(stream, "PERF_RECORD_ITRACE_START  %x/%x",
				itrace_start->pid, itrace_start->tid);

		if (flags & ptsbp_verbose) {
			fprintf(stream, "PERF_RECORD_ITRACE_START");
			fprintf(stream, "\n  pid: %x", itrace_start->pid);
			fprintf(stream, "\n  tid: %x", itrace_start->tid);
		}
	}
		break;

	case PERF_RECORD_LOST_SAMPLES: {
		const struct pev_record_lost_samples *lost_samples;

		lost_samples = event->record.lost_samples;
		if (!lost_samples)
			return -pte_bad_packet;

		if (flags & ptsbp_compact)
			fprintf(stream, "PERF_RECORD_LOST_SAMPLES  %" PRIx64,
				lost_samples->lost);

		if (flags & ptsbp_verbose) {
			fprintf(stream, "PERF_RECORD_LOST_SAMPLES");
			fprintf(stream, "\n  lost: %" PRIx64,
				lost_samples->lost);
		}

	}
		break;

	case PERF_RECORD_SWITCH: {
		const char *sfx;

		sfx = event->misc & PERF_RECORD_MISC_SWITCH_OUT ? "OUT" : "IN";

		if (flags & (ptsbp_compact | ptsbp_verbose))
			fprintf(stream, "PERF_RECORD_SWITCH.%s", sfx);
	}
		break;

	case PERF_RECORD_SWITCH_CPU_WIDE: {
		const struct pev_record_switch_cpu_wide *switch_cpu_wide;
		const char *sfx, *pfx;

		if (event->misc & PERF_RECORD_MISC_SWITCH_OUT) {
			sfx = "OUT";
			pfx = "next";
		} else {
			sfx = "IN";
			pfx = "prev";
		}

		switch_cpu_wide = event->record.switch_cpu_wide;
		if (!switch_cpu_wide)
			return -pte_bad_packet;

		if (flags & ptsbp_compact)
			fprintf(stream, "PERF_RECORD_SWITCH_CPU_WIDE.%s  %x/%x",
				sfx, switch_cpu_wide->next_prev_pid,
				switch_cpu_wide->next_prev_tid);

		if (flags & ptsbp_verbose) {
			fprintf(stream, "PERF_RECORD_SWITCH_CPU_WIDE.%s", sfx);
			fprintf(stream, "\n  %s pid: %x", pfx,
				switch_cpu_wide->next_prev_pid);
			fprintf(stream, "\n  %s tid: %x", pfx,
				switch_cpu_wide->next_prev_tid);
		}
	}
		break;
	}

	return 0;
}

static int pt_sb_pevent_print_samples_compact(const struct pev_event *event,
					      FILE *stream)
{
	if (!event)
		return -pte_internal;

	fprintf(stream, "  {");

	if (event->sample.pid && event->sample.tid)
		fprintf(stream, " %x/%x", *event->sample.pid,
			*event->sample.tid);

	if (event->sample.time)
		fprintf(stream, " %" PRIx64, *event->sample.time);

	if (event->sample.id)
		fprintf(stream, " %" PRIx64, *event->sample.id);

	if (event->sample.cpu)
		fprintf(stream, " cpu-%x", *event->sample.cpu);

	if (event->sample.stream_id)
		fprintf(stream, " %" PRIx64, *event->sample.stream_id);

	if (event->sample.identifier)
		fprintf(stream, " %" PRIx64, *event->sample.identifier);

	fprintf(stream, " }");

	return 0;
}

static int pt_sb_pevent_print_samples_verbose(const struct pev_event *event,
					      FILE *stream)
{
	if (!event)
		return -pte_internal;

	if (event->sample.pid && event->sample.tid) {
		fprintf(stream, "\n  pid: %x", *event->sample.pid);
		fprintf(stream, "\n  tid: %x", *event->sample.tid);
	}

	if (event->sample.time)
		fprintf(stream, "\n  time: %" PRIx64, *event->sample.time);

	if (event->sample.id)
		fprintf(stream, "\n  id: %" PRIx64, *event->sample.id);

	if (event->sample.cpu)
		fprintf(stream, "\n  cpu: %x", *event->sample.cpu);

	if (event->sample.stream_id)
		fprintf(stream, "\n  stream id: %" PRIx64,
			*event->sample.stream_id);

	if (event->sample.identifier)
		fprintf(stream, "\n  identifier: %" PRIx64,
			*event->sample.identifier);

	return 0;
}

static int pt_sb_pevent_print_samples(const struct pev_event *event,
				      FILE *stream, uint32_t flags)
{
	int errcode;

	if (flags & ptsbp_compact) {
		errcode = pt_sb_pevent_print_samples_compact(event, stream);
		if (errcode < 0)
			return errcode;
	}

	if (flags & ptsbp_verbose) {
		errcode = pt_sb_pevent_print_samples_verbose(event, stream);
		if (errcode < 0)
			return errcode;
	}

	return 0;
}

static int pt_sb_pevent_print(struct pt_sb_pevent_priv *priv, FILE *stream,
			      uint32_t flags)
{
	struct pev_event *event;
	const uint8_t *pos, *begin;
	const char *filename;
	int errcode;

	if (!priv)
		return -pte_internal;

	/* We should not be called before fetching the first record. */
	pos = priv->current;
	if (!pos)
		return -pte_internal;

	begin = priv->begin;
	if (pos < begin)
		return -pte_internal;

	filename = priv->filename;
	if (!filename)
		return -pte_internal;

	event = &priv->event;

	/* Print filename and/or file offset before the actual record. */
	switch (flags & (ptsbp_filename | ptsbp_file_offset)) {
	case ptsbp_filename | ptsbp_file_offset:
		fprintf(stream, "%s:%016" PRIx64 "  ", filename,
			(uint64_t) (int64_t) (pos - begin));
		break;

	case ptsbp_filename:
		fprintf(stream, "%s  ", filename);
		break;

	case ptsbp_file_offset:
		fprintf(stream, "%016" PRIx64 "  ",
			(uint64_t) (int64_t) (pos - begin));
		break;
	}

	/* Print the timestamp if requested and available. */
	if ((flags & ptsbp_tsc) && event->sample.time)
		fprintf(stream, "%016" PRIx64 "  ", event->sample.tsc);

	/* Print the actual sideband record. */
	errcode = pt_sb_pevent_print_event(event, stream, flags);
	if (errcode < 0)
		return errcode;

	/* Print samples if configured. */
	if (priv->pev.sample_type) {
		errcode = pt_sb_pevent_print_samples(event, stream, flags);
		if (errcode < 0)
			return errcode;
	}

	if (flags)
		fprintf(stream, "\n");

	return 0;
}

static int pt_sb_pevent_switch_contexts(struct pt_sb_session *session,
					struct pt_image **image,
					struct pt_sb_pevent_priv *priv)
{
	struct pt_sb_context *prev, *next;
	int errcode;

	if (!priv || !image)
		return -pte_internal;

	prev = priv->context;
	next = priv->next_context;
	if (!next)
		return -pte_internal;

	errcode = pt_sb_ctx_switch_to(image, session, next);
	if (errcode < 0)
		return errcode;

	priv->next_context = NULL;
	priv->context = next;

	return prev ? pt_sb_ctx_put(prev) : 0;
}

static int pt_sb_pevent_cancel_context_switch(struct pt_sb_pevent_priv *priv)
{
	struct pt_sb_context *context;

	if (!priv)
		return -pte_internal;

	context = priv->next_context;
	if (!context)
		return 0;

	priv->next_context = NULL;

	return pt_sb_ctx_put(context);
}

static int pt_sb_pevent_prepare_context_switch(struct pt_sb_pevent_priv *priv,
					       struct pt_sb_context *context)
{
	int errcode;

	if (!priv || !context)
		return -pte_internal;

	/* There's nothing to do if this switch is already pending.
	 *
	 * This could be the result of applying a cpu-wide switch-out followed
	 * by a cpu-wide switch-in without a chance to actually apply the
	 * context switch in-between.
	 */
	if (priv->next_context == context)
		return 0;

	/* This context switch overwrites any previously pending switch.
	 *
	 * We may skip context switches due to imprecise timing or due to
	 * re-synchronization after an error.
	 */
	errcode = pt_sb_pevent_cancel_context_switch(priv);
	if (errcode < 0)
		return errcode;

	/* There's nothing to do if we're switching to the current context.
	 *
	 * This could be the result of switching between threads of the same
	 * process or of applying a cpu-wide switch-out followed by a cpu-wide
	 * switch-in.
	 */
	if (priv->context == context)
		return 0;

	errcode = pt_sb_ctx_get(context);
	if (errcode < 0)
		return errcode;

	priv->next_context = context;

	return 0;
}

static int pt_sb_pevent_prepare_switch_to_pid(struct pt_sb_session *session,
					      struct pt_sb_pevent_priv *priv,
					      uint32_t pid)
{
	struct pt_sb_context *context;
	int errcode;

	context = NULL;
	errcode = pt_sb_get_context_by_pid(&context, session, pid);
	if (errcode < 0)
		return errcode;

	return pt_sb_pevent_prepare_context_switch(priv, context);
}

static int pt_sb_pevent_remove_context_for_pid(struct pt_sb_session *session,
					       uint32_t pid)
{
	struct pt_sb_context *context;
	int errcode;

	context = NULL;
	errcode = pt_sb_find_context_by_pid(&context, session, pid);
	if (errcode < 0)
		return errcode;

	if (!context)
		return 0;

	return pt_sb_remove_context(session, context);
}

static int
pt_sb_pevent_itrace_start(struct pt_sb_session *session,
			  struct pt_image **image,
			  struct pt_sb_pevent_priv *priv,
			  const struct pev_record_itrace_start *record)
{
	int errcode;

	if (!image || !record)
		return -pte_internal;

	errcode = pt_sb_pevent_prepare_switch_to_pid(session, priv,
						     record->pid);
	if (errcode < 0)
		return errcode;

	/* We may have already installed the starting context. */
	if (!priv->next_context)
		return 0;

	/* If we have not, let's not wait for a suitable event.
	 *
	 * We just started tracing so there's no reason to wait for a suitable
	 * location.
	 */
	return pt_sb_pevent_switch_contexts(session, image, priv);
}

static int pt_sb_pevent_fork(struct pt_sb_session *session,
			     const struct pev_record_fork *record)
{
	struct pt_sb_context *context, *parent;
	struct pt_image *image, *pimage;
	uint32_t ppid, pid;
	int errcode;

	if (!record)
		return -pte_internal;

	/* If this is just creating a new thread, there's nothing to do.
	 *
	 * We should already have a context for this process.  If we don't, it
	 * doesn't really help to create a new context with an empty process
	 * image at this point.
	 */
	ppid = record->ppid;
	pid = record->pid;
	if (ppid == pid)
		return 0;

	/* We're creating a new process plus the initial thread.
	 *
	 * That initial thread should get the same id as the process.
	 */
	if (pid != record->tid)
		return -pte_internal;

	/* Remove any existing context we might have for @pid.
	 *
	 * We're not removing process contexts when we get the exit event since
	 * that is sent while the process is still running inside the kernel.
	 */
	errcode = pt_sb_pevent_remove_context_for_pid(session, pid);
	if (errcode < 0)
		return errcode;

	/* Create a new context for this new process. */
	context = NULL;
	errcode = pt_sb_get_context_by_pid(&context, session, pid);
	if (errcode < 0)
		return errcode;

	/* Let's see if we also know about the parent process. */
	parent = NULL;
	errcode = pt_sb_find_context_by_pid(&parent, session, ppid);
	if (errcode < 0)
		return errcode;

	if (!parent)
		return 0;

	/* Both parent and child must have valid images. */
	pimage = pt_sb_ctx_image(parent);
	image = pt_sb_ctx_image(context);
	if (!pimage || !image)
		return -pte_internal;

	/* Initialize the child's image with its parent's. */
	return pt_image_copy(image, pimage);
}

static int pt_sb_pevent_exec(struct pt_sb_session *session,
			     struct pt_image **image,
			     struct pt_sb_pevent_priv *priv,
			     const struct pev_record_comm *record)
{
	struct pt_sb_context *context;
	uint32_t pid;
	int errcode;

	if (!record)
		return -pte_internal;

	pid = record->pid;

	/* Instead of replacing a context's image, we replace the context.
	 *
	 * This allows us to keep the old image around until we actually switch.
	 * We are likely using it at the moment.
	 */
	errcode = pt_sb_pevent_remove_context_for_pid(session, pid);
	if (errcode < 0)
		return errcode;

	/* This creates a new context and a new image.
	 *
	 * This new image will already be initialized with kernel sections but
	 * will otherwise be empty.  We will populate it later with MMAP records
	 * that follow this COMM.EXEC record.
	 */
	context = NULL;
	errcode = pt_sb_get_context_by_pid(&context, session, pid);
	if (errcode < 0)
		return errcode;

	/* If we're not maintaining a decoder, we're done. */
	if (!image)
		return 0;

	/* We replaced the previous context of @pid with @context.  Let's
	 * (prepare to) switch to the new @context.
	 *
	 * The actual context switch is postponed until we're in kernel context.
	 *
	 * It is quite likely that we are currently using the previous context
	 * we removed earlier in order to reach the location where we transition
	 * into the kernel.  In the trace, we have not yet exec'ed.
	 */
	return pt_sb_pevent_prepare_context_switch(priv, context);
}

static int pt_sb_pevent_switch(struct pt_sb_session *session,
			       struct pt_sb_pevent_priv *priv,
			       const uint32_t *pid)
{
	if (!pid)
		return -pte_bad_config;

	return pt_sb_pevent_prepare_switch_to_pid(session, priv, *pid);
}

static int
pt_sb_pevent_switch_cpu(struct pt_sb_session *session,
			struct pt_sb_pevent_priv *priv,
			const struct pev_record_switch_cpu_wide *record)
{
	if (!record)
		return -pte_internal;

	return pt_sb_pevent_prepare_switch_to_pid(session, priv,
						  record->next_prev_pid);
}

static int pt_sb_pevent_map(struct pt_sb_session *session,
			    const struct pt_sb_pevent_priv *priv, uint32_t pid,
			    const char *filename, uint64_t offset,
			    uint64_t size, uint64_t vaddr)
{
	struct pt_sb_context *context;
	const char *sysroot;
	char buffer[FILENAME_MAX];
	int errcode;

	if (!priv || !filename)
		return -pte_internal;

	/* Get the context for this process. */
	context = NULL;
	errcode = pt_sb_get_context_by_pid(&context, session, pid);
	if (errcode < 0)
		return errcode;

	/* The optional system root directoy. */
	sysroot = priv->sysroot;

	/* Some filenames do not represent actual files on disk.  We handle
	 * some of those and ignore the rest.
	 */
	if (filename[0] == '[') {
		/* The [vdso] file represents the vdso that is mapped into
		 * every process.
		 *
		 * We expect the user to provide all necessary vdso flavors.
		 */
		if (strcmp(filename, "[vdso]") == 0) {
			errcode = pt_sb_pevent_find_vdso(&filename, priv,
							 context);
			if (errcode != 0)
				return pt_sb_pevent_error(session, errcode,
							  priv);
		} else
			return pt_sb_pevent_error(session, ptse_section_lost,
						  priv);


	} else if (strcmp(filename, "//anon") == 0) {
		/* Those are anonymous mappings that are, for example, used by
		 * JIT compilers to generate code in that is later executed.
		 *
		 * There is no general support for this in perf and JIT enabling
		 * is work-in-progress.
		 *
		 * We will likely fail with -pte_nomap later on.
		 */
		return pt_sb_pevent_error(session, ptse_section_lost, priv);

	} else if (strstr(filename, " (deleted)")) {
		/* The file that was mapped as meanwhile been deleted.
		 *
		 * We will likely fail with -pte_nomap later on.
		 */
		return pt_sb_pevent_error(session, ptse_section_lost, priv);

	} else if (sysroot) {
		/* Prepend the sysroot to normal files. */
		errcode = snprintf(buffer, sizeof(buffer), "%s%s", sysroot,
				   filename);
		if (errcode < 0)
			return -pte_overflow;

		filename = buffer;
	}

	errcode = pt_sb_pevent_track_abi(context, filename);
	if (errcode < 0)
		return errcode;

	return pt_sb_ctx_mmap(session, context, filename, offset, size, vaddr);
}

static int pt_sb_pevent_mmap(struct pt_sb_session *session,
			     const struct pt_sb_pevent_priv *priv,
			     const struct pev_record_mmap *record)
{
	if (!record)
		return -pte_internal;

	return pt_sb_pevent_map(session, priv, record->pid, record->filename,
				record->pgoff, record->len, record->addr);
}

static int pt_sb_pevent_mmap2(struct pt_sb_session *session,
			      const struct pt_sb_pevent_priv *priv,
			      const struct pev_record_mmap2 *record)
{
	if (!record)
		return -pte_internal;

	return pt_sb_pevent_map(session, priv, record->pid, record->filename,
				record->pgoff, record->len, record->addr);
}

static int pt_sb_pevent_aux(const struct pt_sb_session *session,
			    const struct pt_sb_pevent_priv *priv,
			    const struct pev_record_aux *record)
{
	if (!record)
		return -pte_internal;

	if (record->flags & PERF_AUX_FLAG_TRUNCATED)
		return pt_sb_pevent_error(session, ptse_trace_lost, priv);

	return 0;
}

static int pt_sb_pevent_ignore_mmap(uint16_t misc)
{
	/* We rely on the kernel core file for ring-0 decode.
	 *
	 * Both kernel and kernel modules are modified during boot and insmod
	 * respectively.  We can't decode from the respective files on disk.
	 *
	 * Ignore kernel MMAP events so we don't overwrite useful data from
	 * kcore with useless data from binary files.
	 */
	switch (misc & PERF_RECORD_MISC_CPUMODE_MASK) {
	case PERF_RECORD_MISC_KERNEL:
		return 1;

	default:
		return 0;
	}
}

static int pt_sb_pevent_apply_event_record(struct pt_sb_session *session,
					   struct pt_image **image,
					   struct pt_sb_pevent_priv *priv,
					   const struct pev_event *event)
{
	if (!event)
		return -pte_internal;

	switch (event->type) {
	default:
		/* Ignore unknown events. */
		break;

	case PERF_RECORD_ITRACE_START:
		/* Ignore trace starts from secondary sideband channels. */
		if (!image)
			break;

		return pt_sb_pevent_itrace_start(session, image, priv,
						 event->record.itrace_start);

	case PERF_RECORD_FORK:
		return pt_sb_pevent_fork(session, event->record.fork);

	case PERF_RECORD_COMM:
		/* We're only interested in COMM.EXEC events. */
		if (!(event->misc & PERF_RECORD_MISC_COMM_EXEC))
			break;

		return pt_sb_pevent_exec(session, image, priv,
					 event->record.comm);

	case PERF_RECORD_SWITCH:
		/* Ignore context switches from secondary sideband channels. */
		if (!image)
			break;

		/* Ignore switch-out events.  We wait for the switch-in. */
		if (event->misc & PERF_RECORD_MISC_SWITCH_OUT)
			break;

		return pt_sb_pevent_switch(session, priv, event->sample.pid);

	case PERF_RECORD_SWITCH_CPU_WIDE:
		/* Ignore context switches from secondary sideband channels. */
		if (!image)
			break;

		/* For switch-in events, we use the pid sample, if available.
		 *
		 * For cpu-wide switch events, not sampling pid is acceptable
		 * since we get the pid in @prev_next_pid of a switch-out event.
		 *
		 * We will use a cpu-wide switch-in event, if possible, but we
		 * should be able to do without most of the time.
		 */
		if (!(event->misc & PERF_RECORD_MISC_SWITCH_OUT)) {
			if (!event->sample.pid)
				break;

			return pt_sb_pevent_switch(session, priv,
						   event->sample.pid);
		}

		return pt_sb_pevent_switch_cpu(session, priv,
					       event->record.switch_cpu_wide);

	case PERF_RECORD_MMAP:
		/* We intentionally ignore some MMAP records. */
		if (pt_sb_pevent_ignore_mmap(event->misc))
			break;

		return pt_sb_pevent_mmap(session, priv, event->record.mmap);

	case PERF_RECORD_MMAP2:
		/* We intentionally ignore some MMAP records. */
		if (pt_sb_pevent_ignore_mmap(event->misc))
			break;

		return pt_sb_pevent_mmap2(session, priv, event->record.mmap2);

	case PERF_RECORD_LOST:
		/* Warn about losses.
		 *
		 * We put the warning into the output.  It is quite likely that
		 * we will run into a decode error shortly after (or ran into it
		 * already); this warning may help explain it.
		 */
		return pt_sb_pevent_error(session, ptse_lost, priv);

	case PERF_RECORD_AUX:
		/* Ignore trace losses from secondary sideband channels. */
		if (!image)
			break;

		return pt_sb_pevent_aux(session, priv, event->record.aux);
	}

	return 0;
}

static int ploc_from_ip(enum pt_sb_pevent_loc *loc,
			const struct pt_sb_pevent_priv *priv, uint64_t ip)
{
	if (!loc || !priv)
		return -pte_internal;

	*loc = (ip < priv->kernel_start) ? ploc_in_user : ploc_in_kernel;

	return 0;
}

static int ploc_from_suppressed_ip(enum pt_sb_pevent_loc *loc,
				   enum pt_sb_pevent_loc from)
{
	if (!loc)
		return -pte_internal;

	switch (from) {
	default:
		*loc = ploc_unknown;
		break;

	case ploc_likely_in_kernel:
	case ploc_in_kernel:
		*loc = ploc_likely_in_user;
		break;

	case ploc_likely_in_user:
	case ploc_in_user:
		*loc = ploc_likely_in_kernel;
		break;
	}

	return 0;
}

static int ploc_from_event(enum pt_sb_pevent_loc *loc,
			   const struct pt_sb_pevent_priv *priv,
			   const struct pt_event *event)
{
	if (!loc || !priv || !event)
		return -pte_internal;

	switch (event->type) {
	default:
		break;

	case ptev_enabled:
		return ploc_from_ip(loc, priv, event->variant.enabled.ip);

	case ptev_disabled:
		if (!event->ip_suppressed)
			return ploc_from_ip(loc, priv,
					    event->variant.disabled.ip);

		return ploc_from_suppressed_ip(loc, priv->location);

	case ptev_async_disabled: {
		enum pt_sb_pevent_loc fromloc;
		int errcode;

		if (!event->ip_suppressed)
			return ploc_from_ip(loc, priv,
					    event->variant.async_disabled.ip);

		errcode = ploc_from_ip(&fromloc, priv,
				       event->variant.async_disabled.at);
		if (errcode < 0)
			return errcode;

		return ploc_from_suppressed_ip(loc, fromloc);
	}

	case ptev_async_branch:
		return ploc_from_ip(loc, priv, event->variant.async_branch.to);

	case ptev_async_paging:
		if (!event->ip_suppressed)
			return ploc_from_ip(loc, priv,
					    event->variant.async_paging.ip);

		fallthrough;
	case ptev_paging:
		*loc = ploc_likely_in_kernel;
		return 0;

	case ptev_overflow:
		if (!event->ip_suppressed)
			return ploc_from_ip(loc, priv,
					    event->variant.overflow.ip);

		break;

	case ptev_exec_mode:
		if (!event->ip_suppressed)
			return ploc_from_ip(loc, priv,
					    event->variant.exec_mode.ip);

		break;

	case ptev_tsx:
		if (!event->ip_suppressed)
			return ploc_from_ip(loc, priv,
					    event->variant.tsx.ip);

		break;

	case ptev_exstop:
		if (!event->ip_suppressed)
			return ploc_from_ip(loc, priv,
					    event->variant.exstop.ip);

		break;

	case ptev_mwait:
		if (!event->ip_suppressed)
			return ploc_from_ip(loc, priv,
					    event->variant.mwait.ip);

		break;

	case ptev_ptwrite:
		if (!event->ip_suppressed)
			return ploc_from_ip(loc, priv,
					    event->variant.ptwrite.ip);

		break;

	case ptev_tick:
		if (!event->ip_suppressed)
			return ploc_from_ip(loc, priv,
					    event->variant.tick.ip);

		break;
	}

	*loc = ploc_unknown;
	return 0;
}

static int pt_sb_pevent_apply(struct pt_sb_session *session,
			      struct pt_image **image,
			      const struct pt_event *event,
			      struct pt_sb_pevent_priv *priv)
{
	const struct pev_event *record;
	enum pt_sb_pevent_loc oldloc;
	int errcode;

	if (!priv || !event)
		return -pte_internal;

	/* If the current perf event record is due, apply it.
	 *
	 * We don't need to look at the actual event that provided the
	 * timestamp.  It suffices to know that time moved beyond the current
	 * perf event record.
	 *
	 * It is tempting to postpone applying the record until a suitable event
	 * but we need to ensure that records from different channels are
	 * applied in timestamp order.
	 *
	 * So we apply the record solely based on timestamps and postpone its
	 * effect until a suitable event.
	 *
	 * The last record in the trace won't be overridden and we have to take
	 * care to not apply it twice.  We need to keep it until we were able to
	 * place the last pending context switch.
	 */
	record = &priv->event;
	if ((priv->current != priv->next) &&
	    (!record->sample.time || (record->sample.tsc <= event->tsc)))
		return pt_sb_pevent_apply_event_record(session, image, priv,
						       record);

	/* We first apply all our sideband records one-by-one until we're in
	 * sync with the event.
	 *
	 * When we get here, we applied all previous sideband records.  Let's
	 * use the event to keep track of kernel vs user space and apply any
	 * postponed context switches.
	 *
	 * We preserve the previous location to detect returns from kernel to
	 * user space.
	 */
	oldloc = priv->location;
	errcode = ploc_from_event(&priv->location, priv, event);
	if (errcode < 0)
		return errcode;

	/* We postpone context switches until we reach a suitable location in
	 * the trace.  If we don't have a context switch pending, we're done.
	 */
	if (!priv->next_context) {
		/* Signal the end of the trace if the last event did not result
		 * in a postponed context switch or if that context switch had
		 * been applied at a previous event.
		 */
		if (priv->current == priv->next)
			return -pte_eos;

		return 0;
	}

	/* Apply a postponed context switch inside kernel mode.
	 *
	 * For our purposes it does not matter where exactly we are in the
	 * kernel.
	 *
	 * In order to catch the first event window right before a tracing
	 * enabled event after some time of tracing being disabled (or at the
	 * beginning of the trace), we also accept an unknown location.
	 */
	switch (oldloc) {
	case ploc_likely_in_kernel:
	case ploc_in_kernel:
	case ploc_unknown:
		return pt_sb_pevent_switch_contexts(session, image, priv);

	default:
		switch (priv->location) {
		case ploc_likely_in_kernel:
		case ploc_in_kernel:
		case ploc_unknown:
			return pt_sb_pevent_switch_contexts(session, image,
							    priv);

		default:
			break;
		}

		break;
	};

	return 0;
}

static int pt_sb_pevent_fetch_callback(struct pt_sb_session *session,
				       uint64_t *tsc, void *priv)
{
	int errcode;

	errcode = pt_sb_pevent_fetch(tsc, (struct pt_sb_pevent_priv *) priv);
	if ((errcode < 0) && (errcode != -pte_eos))
		pt_sb_pevent_error(session, errcode,
				   (struct pt_sb_pevent_priv *) priv);

	return errcode;
}

static int pt_sb_pevent_print_callback(struct pt_sb_session *session,
				       FILE *stream, uint32_t flags, void *priv)
{
	int errcode;

	errcode = pt_sb_pevent_print((struct pt_sb_pevent_priv *) priv, stream,
				     flags);
	if (errcode < 0)
		return pt_sb_pevent_error(session, errcode,
					  (struct pt_sb_pevent_priv *) priv);

	return 0;
}

static int pt_sb_pevent_apply_callback(struct pt_sb_session *session,
				       struct pt_image **image,
				       const struct pt_event *event, void *priv)
{
	int errcode;

	errcode = pt_sb_pevent_apply(session, image, event,
				     (struct pt_sb_pevent_priv *) priv);
	if ((errcode < 0) && (errcode != -pte_eos))
		return pt_sb_pevent_error(session, errcode,
					  (struct pt_sb_pevent_priv *) priv);

	return errcode;
}

int pt_sb_alloc_pevent_decoder(struct pt_sb_session *session,
			       const struct pt_sb_pevent_config *pev)
{
	struct pt_sb_decoder_config config;
	struct pt_sb_pevent_priv *priv;
	int errcode;

	if (!session || !pev)
		return -pte_invalid;

	priv = malloc(sizeof(*priv));
	if (!priv)
		return -pte_nomem;

	errcode = pt_sb_pevent_init(priv, pev);
	if (errcode < 0) {
		free(priv);
		return errcode;
	}

	memset(&config, 0, sizeof(config));
	config.fetch = pt_sb_pevent_fetch_callback;
	config.apply = pt_sb_pevent_apply_callback;
	config.print = pt_sb_pevent_print_callback;
	config.dtor = pt_sb_pevent_dtor;
	config.priv = priv;
	config.primary = pev->primary;

	errcode = pt_sb_alloc_decoder(session, &config);
	if (errcode < 0)
		free(priv);

	return errcode;
}

#endif /* FEATURE_PEVENT */
