// 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 <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdarg.h>
#include <stdbool.h>
#include <string.h>

#include <linux/zalloc.h>
#include <linux/kernel.h>

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

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

#define MAX_LOG_NAME 256

#define DFLT_BUF_SZ	(16 * 1024)

struct log_buf {
	char			*buf;
	size_t			buf_sz;
	size_t			head;
	bool			wrapped;
	FILE			*backend;
};

static FILE *f;
static char log_name[MAX_LOG_NAME];
bool intel_pt_enable_logging;
static bool intel_pt_dump_log_on_error;
static unsigned int intel_pt_log_on_error_size;
static struct log_buf log_buf;

void *intel_pt_log_fp(void)
{
	return f;
}

void intel_pt_log_enable(bool dump_log_on_error, unsigned int log_on_error_size)
{
	intel_pt_enable_logging = true;
	intel_pt_dump_log_on_error = dump_log_on_error;
	intel_pt_log_on_error_size = log_on_error_size;
}

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 ssize_t log_buf__write(void *cookie, const char *buf, size_t size)
{
	struct log_buf *b = cookie;
	size_t sz = size;

	if (!b->buf)
		return size;

	while (sz) {
		size_t space = b->buf_sz - b->head;
		size_t n = min(space, sz);

		memcpy(b->buf + b->head, buf, n);
		sz -= n;
		buf += n;
		b->head += n;
		if (sz && b->head >= b->buf_sz) {
			b->head = 0;
			b->wrapped = true;
		}
	}
	return size;
}

static int log_buf__close(void *cookie)
{
	struct log_buf *b = cookie;

	zfree(&b->buf);
	return 0;
}

static FILE *log_buf__open(struct log_buf *b, FILE *backend, unsigned int sz)
{
	cookie_io_functions_t fns = {
		.write = log_buf__write,
		.close = log_buf__close,
	};
	FILE *file;

	memset(b, 0, sizeof(*b));
	b->buf_sz = sz;
	b->buf = malloc(b->buf_sz);
	b->backend = backend;
	file = fopencookie(b, "a", fns);
	if (!file)
		zfree(&b->buf);
	return file;
}

static bool remove_first_line(const char **p, size_t *n)
{
	for (; *n && **p != '\n'; ++*p, --*n)
		;
	if (*n) {
		*p += 1;
		*n -= 1;
		return true;
	}
	return false;
}

static void write_lines(const char *p, size_t n, FILE *fp, bool *remove_first)
{
	if (*remove_first)
		*remove_first = !remove_first_line(&p, &n);
	fwrite(p, n, 1, fp);
}

static void log_buf__dump(struct log_buf *b)
{
	bool remove_first = false;

	if (!b->buf)
		return;

	fflush(f); /* Could update b->head and b->wrapped */
	fprintf(b->backend, "Dumping debug log buffer\n");
	if (b->wrapped) {
		remove_first = true;
		write_lines(b->buf + b->head, b->buf_sz - b->head, b->backend, &remove_first);
	}
	write_lines(b->buf, b->head, b->backend, &remove_first);
	fprintf(b->backend, "End of debug log buffer dump\n");

	b->head = 0;
	b->wrapped = false;
}

void intel_pt_log_dump_buf(void)
{
	log_buf__dump(&log_buf);
}

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_dump_log_on_error)
		f = log_buf__open(&log_buf, f, intel_pt_log_on_error_size);
	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);
}
