// SPDX-License-Identifier: GPL-2.0-only
/*
 * intel_pt_log.c: Intel Processor Trace support
 * Copyright (c) 2013-2014, Intel Corporation.
 */

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdarg.h>
#include <stdbool.h>
#include <string.h>

#include "intel-pt-log.h"
#include "intel-pt-insn-decoder.h"

#include "intel-pt-pkt-decoder.h"

#define MAX_LOG_NAME 256

static FILE *f;
static char log_name[MAX_LOG_NAME];
bool intel_pt_enable_logging;

void *intel_pt_log_fp(void)
{
	return f;
}

void intel_pt_log_enable(void)
{
	intel_pt_enable_logging = true;
}

void intel_pt_log_disable(void)
{
	if (f)
		fflush(f);
	intel_pt_enable_logging = false;
}

void intel_pt_log_set_name(const char *name)
{
	strncpy(log_name, name, MAX_LOG_NAME - 5);
	strcat(log_name, ".log");
}

static void intel_pt_print_data(const unsigned char *buf, int len, uint64_t pos,
				int indent)
{
	int i;

	for (i = 0; i < indent; i++)
		fprintf(f, " ");

	fprintf(f, "  %08" PRIx64 ": ", pos);
	for (i = 0; i < len; i++)
		fprintf(f, " %02x", buf[i]);
	for (; i < 16; i++)
		fprintf(f, "   ");
	fprintf(f, " ");
}

static void intel_pt_print_no_data(uint64_t pos, int indent)
{
	int i;

	for (i = 0; i < indent; i++)
		fprintf(f, " ");

	fprintf(f, "  %08" PRIx64 ": ", pos);
	for (i = 0; i < 16; i++)
		fprintf(f, "   ");
	fprintf(f, " ");
}

static int intel_pt_log_open(void)
{
	if (!intel_pt_enable_logging)
		return -1;

	if (f)
		return 0;

	if (log_name[0])
		f = fopen(log_name, "w+");
	else
		f = stdout;
	if (!f) {
		intel_pt_enable_logging = false;
		return -1;
	}

	return 0;
}

void __intel_pt_log_packet(const struct intel_pt_pkt *packet, int pkt_len,
			   uint64_t pos, const unsigned char *buf)
{
	char desc[INTEL_PT_PKT_DESC_MAX];

	if (intel_pt_log_open())
		return;

	intel_pt_print_data(buf, pkt_len, pos, 0);
	intel_pt_pkt_desc(packet, desc, INTEL_PT_PKT_DESC_MAX);
	fprintf(f, "%s\n", desc);
}

void __intel_pt_log_insn(struct intel_pt_insn *intel_pt_insn, uint64_t ip)
{
	char desc[INTEL_PT_INSN_DESC_MAX];
	size_t len = intel_pt_insn->length;

	if (intel_pt_log_open())
		return;

	if (len > INTEL_PT_INSN_BUF_SZ)
		len = INTEL_PT_INSN_BUF_SZ;
	intel_pt_print_data(intel_pt_insn->buf, len, ip, 8);
	if (intel_pt_insn_desc(intel_pt_insn, desc, INTEL_PT_INSN_DESC_MAX) > 0)
		fprintf(f, "%s\n", desc);
	else
		fprintf(f, "Bad instruction!\n");
}

void __intel_pt_log_insn_no_data(struct intel_pt_insn *intel_pt_insn,
				 uint64_t ip)
{
	char desc[INTEL_PT_INSN_DESC_MAX];

	if (intel_pt_log_open())
		return;

	intel_pt_print_no_data(ip, 8);
	if (intel_pt_insn_desc(intel_pt_insn, desc, INTEL_PT_INSN_DESC_MAX) > 0)
		fprintf(f, "%s\n", desc);
	else
		fprintf(f, "Bad instruction!\n");
}

void __intel_pt_log(const char *fmt, ...)
{
	va_list args;

	if (intel_pt_log_open())
		return;

	va_start(args, fmt);
	vfprintf(f, fmt, args);
	va_end(args);
}
